Part 5: Build a Compass App

Let’s start from where we left off last time – we were in the compass directory after using cordova to add an android platform for our project and after adding the plugin to enable us to access the device orientation (compass) from our web application.

Before we use the device orientation functions from within our web app – lets just build the project and run it as it is to see that it works so far.

To build the project for android, simply

$ cordova build android

Then, assuming all went well, make sure your android device is plugged in to the USB port and invoke

$ cordova run android

You’ll see the first web application running as a mobile application on your android phone.


Now lets replace the html code that created the above application with an html page that shows the compass heading of our device. For that, open index.html in the compass/www/ directory and replace it’s content with the sample of reading the device orientation from the API documentation here

<!DOCTYPE html>
<html>
  <head>
    <title>Compass Example</title>

    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
    <script type="text/javascript" charset="utf-8">

    // The watch id references the current `watchHeading`
    var gWatchID = null;

    // Wait for device API libraries to load
    //
    document.addEventListener("deviceready", onDeviceReady, false);

    // device APIs are available
    //
    function onDeviceReady() {
        startWatch();
    }

    // Start watching the compass
    //
    function startWatch() {

        // Update compass every 3 seconds
        var options = { frequency: 3000 };

        if (gWatchID)
            gWatchID = navigator.compass.watchHeading(onSuccess, onError, options);
    }

    // Stop watching the compass
    //
    function stopWatch() {
        if (gWatchID) {
            navigator.compass.clearWatch(watchID);
            gWatchID = null;
        }
    }

    // onSuccess: Get the current heading
    //
    function onSuccess(heading) {
        var element = document.getElementById('heading');
        element.innerHTML = 'Heading: ' + heading.magneticHeading;
    }

    // onError: Failed to get the heading
    //
    function onError(compassError) {
        alert('Compass error: ' + compassError.code);
    }

    </script>
  </head>
  <body>
    <div id="heading">Waiting for heading...</div>
    <button onclick="startWatch();">Start Watching</button>
    <button onclick="stopWatch();">Stop Watching</button>
  </body>
</html>

Now save the new version of www/index.html. As you can see, this is a regular HTML page with JavaScript code, the difference being that the JavaScript code accesses methods of an object named navigator.compass. This is the bridge between JavaScript and the plugin that we added to the project which enables us to access the native API on the mobile device.

We’re ready to build and run, though it would be best to note these two things first:

1. Make sure that in compass/platforms/android/res/xml/config.xml it is mentioned that we will be accessing the device orientation plugin that we added to the android platform. Verify that the following appears in the file:

<feature name="Compass">
    <param name="android-package" value="org.apache.cordova.deviceorientation.CompassListener" />
</feature>

2. Make sure that we ask for permission to access the compass device on the android platform in compass/platforms/android/AndroidManifest.xml – check that these two appear there:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

The above configurations are automatically added to the xml files when the device orientation plugin was added to the project when the android platform was in it (and vice versa)

Ok, we’re set to go:

$ cordova build android
$ cordova run android

You should be able to see the direction that the top part of your device is pointing to as an azimuth in degrees where 0, 90, 180 and 270 represnt North, East, South and West respectively.

Next post – changing the display of degrees to a arrow pointing North regardless of how we turn the device by using HTML5’s Canvas element to draw and rotate the arrow.

One Comment

  1. Hi,

    nice tutorial, really, but it’s just not working (at least not for me). I’ve done everything as described here, but each time the error handler is called with error code 3. I couldn’t find it in the API docs, but I searched the native Java code and found it:

    public static int STOPPED = 0;
    public static int STARTING = 1;
    public static int RUNNING = 2;
    public static int ERROR_FAILED_TO_START = 3;

    So obviously the plugin is installed correctly, gets called but fails to start. But why?

    I’ve installed the latest version of cordova 4.0.0 and I’m testing on a Galaxy S5 (but also tried a HTC One V).

    Is there anything I’m missing?

    It would really be nice to hear from you,
    Michael

Leave a Reply

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