How to Create a Compass in Android Code – Tutorial and Source Code

android compass code example

Today I’m going to share a very simple compass in android code that you can use whenever you are creating an application with a compass feature.

It’s good to see the most devices nowadays has a motion sensor capability to make a compass run.

Unfortunately, there are still some android devices (like Huawei Y300 and Lenovo P700i) does not have full support of motions sensors so this code will not work for them.

We will cover the following in this post:

1.0 Android Compass Video Demo
2.0 Compass App Needed Files
3.0 Complete Compass in Android Code
3.1 MainActivity.java
3.2 activity_main.xml
3.3 Some Notes
4.0 Download Source Code
5.0 Further Readings

1.0 Compass in Android Code Video Demo

Our code for today will run just like the following video.

2.0 Compass App Needed Files

You need to create your own compass image. For this example, I’m using a stock photo. Your image must be a PNG with transparent background, do not use this jpg file I used. Please note that the “north” must be at the top part of the image.

compass in android code example

We will also need the two main code files seen in the complete code below.

3.0 Complete Android Compass Code

3.1 MainActivity.java where all the magic happens. The SensorManager was initialized in the onCreate() method and it was being moved or animated using the onSensorChanged() method.

package com.example.compassapp;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener {

    // define the display assembly compass picture
    private ImageView image;

    // record the compass picture angle turned
    private float currentDegree = 0f;

    // device sensor manager
    private SensorManager mSensorManager;

    TextView tvHeading;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // our compass image 
        image = (ImageView) findViewById(R.id.imageViewCompass);

        // TextView that will tell the user what degree is he heading
        tvHeading = (TextView) findViewById(R.id.tvHeading);

        // initialize your android device sensor capabilities
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        
        // for the system's orientation sensor registered listeners
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    protected void onPause() {
        super.onPause();
        
        // to stop the listener and save battery
        mSensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        // get the angle around the z-axis rotated
        float degree = Math.round(event.values[0]);

        tvHeading.setText("Heading: " + Float.toString(degree) + " degrees");

        // create a rotation animation (reverse turn degree degrees)
        RotateAnimation ra = new RotateAnimation(
                currentDegree, 
                -degree,
                Animation.RELATIVE_TO_SELF, 0.5f, 
                Animation.RELATIVE_TO_SELF,
                0.5f);

        // how long the animation will take place
        ra.setDuration(210);

        // set the animation after the end of the reservation status
        ra.setFillAfter(true);

        // Start the animation
        image.startAnimation(ra);
        currentDegree = -degree;

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // not in use
    }
}

3.2 activity_main.xml – Our layout file. Wrapped in RelativeLayout, the TextView is used to display the user’s current heading. The ImageView contains the compass image which is being animated like a compass using the code in our MainActivity.java

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff" >

    <TextView
        android:id="@+id/tvHeading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="40dp"
        android:layout_marginTop="20dp"
        android:text="Heading: 0.0" />

    <ImageView
        android:id="@+id/imageViewCompass"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvHeading"
        android:layout_centerHorizontal="true"
        android:src="@drawable/img_compass" />

</RelativeLayout>

3.3 Some notes

1. My app orientation is locked to portrait mode.
2. There are no special permissions in the Manifest file.
3. North Magnetic Pole is the point on the surface of Earth’s
Northern Hemisphere.
4. True north, or the geodetic north, is the direction along the earth’s surface towards the geographic North Pole.
5. Android SensorManager uses the magnetic North Pole.

5.0 Download Source Code

You can get the source code by following the whole, well detailed and free tutorial above. But isn’t it more convenient if you can just download the complete source code we used, and play around it?

There’s a small fee in getting the complete source code, it is small compared to the:

✔ Value or skill upgrade it can bring you, orYES
✔ Income you can get from your website project or business.YES
✔ Precious time you save.YES

Buy now

5.0 Further Readings

This can help you learn more about creating compass in android code. You can visit them and do more customizations!

1. Android SensorManager
2. Android RotateAnimation
3. Android Motion Sensors
4. Magnetic North Pole vs. Geographic North Pole

45 replies
  1. Japeth Poyaoan
    Japeth Poyaoan says:

    Hi, sir Mike. I’m having problems in the MainActivity code. I keep on getting an error on “image = (ImageView) findViewById(R.id.imageViewCompass);” that says “imageViewCompass cannot be resolved or is not a field” I tried every solutions out there but everytime I apply them there’s sorta new problem coming out. Thanks in advance! :)

    Reply
      • kris
        kris says:

        08-04 23:36:43.494: E/Trace(6020): error opening trace file: No such file or directory (2)

        08-04 23:36:43.634: I/Adreno200-EGL(6020): : EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.099_msm7627a_JB_REL_2.0.3_CL3357771_release_AU (CL3357771)

        08-04 23:36:43.634: I/Adreno200-EGL(6020): Build Date: 02/19/13 Tue

        08-04 23:36:43.634: I/Adreno200-EGL(6020): Local Branch:

        08-04 23:36:43.634: I/Adreno200-EGL(6020): Remote Branch: quic/jb_rel_2.0.3

        08-04 23:36:43.634: I/Adreno200-EGL(6020): Local Patches: NONE

        08-04 23:36:43.634: I/Adreno200-EGL(6020): Reconstruct Branch: AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.099 + NOTHING

        08-04 23:36:43.664: D/memalloc(6020): ion: Mapped buffer base:0x53d9e000 size:1536000 offset:0 fd:61

        08-04 23:36:43.664: D/memalloc(6020): ion: Mapped buffer base:0x4d778000 size:4096 offset:0 fd:63

        08-04 23:36:43.764: D/memalloc(6020): ion: Mapped buffer base:0x542f0000 size:1536000 offset:0 fd:66

        08-04 23:36:43.764: D/memalloc(6020): ion: Mapped buffer base:0x4d78f000 size:4096 offset:0 fd:68

        Reply
  2. YSN
    YSN says:

    Hey thanks for that tutorial its working really nice. Is there a way to rotate the compass to a specific point if i get the coordinates from google maps?

    Reply
    • ninjazhai
      ninjazhai says:

      Hi @YSN, what do you mean by the “specific point”? I think the compass always point to the north…

      Reply
      • Carlos Eduardo Vásquez
        Carlos Eduardo Vásquez says:

        Hello, nice and easy to implement your code. I have the same need as YSN. I need the compass to point to a specific coordinate. NOT to the north. Maybe we can´t call it a compass, but I need an arrow pointing to a specific coordinate. Is there a way to achieve that?

        Reply
  3. smb
    smb says:

    I notice that your video carefully avoids pointing the compass North. The animation breaks when passing from 359 degrees to 360/0 degrees. It’s an obvious problem that should have been fixed. Hiding this bug is just not right.

    Reply
    • ninjazhai
      ninjazhai says:

      Hey @nurzhandyussenaliyev:disqus , I think it shows the magnetic north because the device uses a magnetic sensor?

      Reply
  4. Cromm
    Cromm says:

    Hi, I’ve a question, is that “degree” that set the orientation of the north ? If yes, how can I modified it to make the compass pointing specifics geographic coordinates (like telling the apps that the north is in (x,y) and not 82.7° N 114.4° W (which are the north coordinates (geographics)) ?

    Reply
  5. Vahid
    Vahid says:

    Hi, thanks for the code, it works like a charm! But I really do not understand how to use this app. I thought it shows the magnetic north, o the app tells me which direction is north. but -as you do in the video- every time I rotate my phone the north sign on the image (N sign) points to a different direction for north!

    Reply
  6. June
    June says:

    Thank you for your tutorial, Mike!
    I’m trying to customize your code and have one question.
    Is there any way to blend compass image and background image with Multiply-like blending mode??

    Reply
  7. June Kenya
    June Kenya says:

    Thank you for your tutorial, Mike!
    I’m trying to customize your code and have one question.
    Is there any way to blend compass image and background image with Multiply-like blending mode??

    Reply
  8. June Kenya
    June Kenya says:

    Thank you for nice tutorial!
    I’m trying to customize little bit and have one question.
    Is there any way to blend compass image and background image with Multiply-like blending mode??

    Reply
  9. Anil
    Anil says:

    Image is rotating along with the mobile orientation as it wants . but its not showing the correct direction as in compass..anyone has solved this issue??

    Reply
  10. Wilson Willson
    Wilson Willson says:

    Hi I noticed running this app that it doesn’t seem to start point to north. Is there anyway to make it start at how ever many degrees it’s pointing away from true north?

    Reply
      • Mohammad Altaf
        Mohammad Altaf says:

        02-04 10:30:03.889 2398-2398/? D/dalvikvm﹕ Not late-enabling CheckJNI (already on)

        02-04 10:30:03.909 2398-2398/? I/dalvikvm﹕ Could not find method android.app.Notification$Builder.setLocalOnly, referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zza

        02-04 10:30:03.909 2398-2398/? W/dalvikvm﹕ VFY: unable to resolve virtual method 244: Landroid/app/Notification$Builder;.setLocalOnly (Z)Landroid/app/Notification$Builder;

        02-04 10:30:03.909 2398-2398/? D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x00c8

        02-04 10:30:03.909 2398-2398/? I/dalvikvm﹕ Could not find method android.content.pm.PackageManager.getPackageInstaller, referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zzh

        02-04 10:30:03.909 2398-2398/? W/dalvikvm﹕ VFY: unable to resolve virtual method 547: Landroid/content/pm/PackageManager;.getPackageInstaller ()Landroid/content/pm/PackageInstaller;

        02-04 10:30:03.909 2398-2398/? D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x000b

        02-04 10:30:03.929 2398-2404/? D/dalvikvm﹕ Debugger has detached; object registry had 1 entries

        02-04 10:30:03.959 2398-2414/? I/GMPM﹕ App measurement is starting up

        02-04 10:30:03.969 2398-2402/? D/dalvikvm﹕ GC_CONCURRENT freed 250K, 10% free 2765K/3068K, paused 10ms+0ms, total 12ms

        02-04 10:30:04.069 2398-2398/? D/﹕ HostConnection::get() New Host Connection established 0xb86cb9f0, tid 2398

        02-04 10:30:04.259 2398-2398/? W/EGL_emulation﹕ eglSurfaceAttrib not implemented

        02-04 10:30:04.269 2398-2398/? D/OpenGLRenderer﹕ Enabling debug mode 0

        02-04 10:30:05.839 2398-2404/? I/jdwp﹕ Ignoring second debugger — accepting and dropping

        02-04 10:30:22.889 2398-2398/? V/GCMRegistrar﹕ Registering receiver

        02-04 10:30:22.889 2398-2398/? D/GCMRegistrar﹕ resetting backoff for com.androidhive.pushnotifications

        02-04 10:30:22.889 2398-2398/? V/GCMRegistrar﹕ Registering app com.androidhive.pushnotifications of senders 1002468668191

        02-04 10:30:22.909 2398-2398/? D/dalvikvm﹕ GC_FOR_ALLOC freed 245K, 9% free 3033K/3328K, paused 14ms, total 14ms

        02-04 10:30:22.979 2398-2398/? W/EGL_emulation﹕ eglSurfaceAttrib not implemented

        02-04 10:30:27.369 2398-2398/? V/GCMBroadcastReceiver﹕ onReceive: com.google.android.c2dm.intent.REGISTRATION

        02-04 10:30:27.369 2398-2398/? V/GCMBroadcastReceiver﹕ GCM IntentService class: com.androidhive.pushnotifications.GCMIntentService

        02-04 10:30:27.369 2398-2398/? V/GCMBaseIntentService﹕ Acquiring wakelock

        Reply
  11. Phouthasak
    Phouthasak says:

    Nice and simple tutorial, but the animation to the compass can be a little choppy because of the unfiltered parsing and apply the data to the animation.

    Reply
  12. amit
    amit says:

    hey,

    i am getting this error….

    Error:Execution failed for task ‘:app:mergeDebugResources’.
    > Some file crunching failed, see logs for details

    can you please help me out.

    Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *