Skip to content

March 3, 2012

Accessing the accelerometer in PhoneGap

by Colin

In this tutorial we will take a look at how we can capture the devices motion in the x, y and z direction. The accelerometer is a motion sensor which detects movement changes relative to the current device orientation.
At the end of this tutorial we will make an object move around the screen.

This tutorial was made on a Mac using Aptana Studio 3 and was tested on a HTC Desire device running on Android 2.2.

End result:



Download the sources and follow up on the code.

We have two pages, in the Tech page we will demonstrate accelerometer properties by looking at some coordinates from various device orientations and on the second page we will make use of these properties to make an object move on the screen.

In order to have accelerometer you need to test this on a device.

You can get access to the acceleration functionality in PhoneGap with the Accelerometer method. The Accelerometer method has x, y, z and timestamp properties. The x, y and z represent the amount of motion on the x, y and z axis, a number ranging from 0 to 1 and the timestamp represents the creation time in milliseconds.

To get the current acceleration of the device we need to call the accelerometer.getCurrentAcceleration() method navigator.accelerometer.getCurrentAcceleration(accelerometerSuccess, accelerometerError);

This is supported on the Android, BlackBerry WebWorks(OS 5.0 and higher) and iPhone platforms.

For our first example we will show the x, y and z coordinates when our application starts.
To do this we call the accelerometer.getCurrentAcceleration() method when the devices is ready.

[js]
// PhoneGap is ready
function onDeviceReady() {
        navigator.accelerometer.getCurrentAcceleration(onSuccess, onError);
    }
[/js]

The onSuccess callback function is triggered and will display the x,y and z coordinates and the timestamp in milliseconds of our devices initial orientation.

[js]
// onSuccess: Display the current acceleration
function onSuccess(acceleration) {
var element = document.getElementById(‘accelerometer’);
element.innerHTML = ‘Acceleration X: ‘ + acceleration.x + ‘<br />’ +
‘Acceleration Y: ‘ + acceleration.y + ‘<br />’ +
‘Acceleration Z: ‘ + acceleration.z + ‘<br />’ +
‘Timestamp: ‘ + acceleration.timestamp + ‘<br />';
}
[/js]

On the iPhone you can’t get the current acceleration at a given point, instead you must watch the acceleration and capture data at given time intervals as we will example below.

For our second example we will watch the coordinates change. To accomplish this we need to call the accelerometer.watchAcceleration() method var watchID = navigator.accelerometer.watchAcceleration(accelerometerSuccess, accelerometerError, [accelerometerOptions]);

At specified interval we can get the acceleration coordinates along the x, y and z axis. We will display the coordinates at a 2 second time delay.

To do this we use a startWatch() function placed inside the onDeviceReady() function which will update every 2 seconds.

[js]
// PhoneGap is ready
function onDeviceReady() {
// Start Watch Button
var startWatchBtn = $(‘#startWatch’);
startWatchBtn.click(function(){
startWatch();
});
}

// Start watching the acceleration
function startWatch() {

// Update acceleration every 2 seconds
var options = { frequency: 2000 };

watchID = navigator.accelerometer.watchAcceleration(onSuccess, onError, options);
}
[/js]

The onSuccess trigger will display our current coordinates.

[js]

// onSuccess: Display the current acceleration
function onSuccess(acceleration) {
var element = document.getElementById(‘accelerometer’);
element.innerHTML = ‘Acceleration X: ‘ + acceleration.x + ‘<br />’ +
‘Acceleration Y: ‘ + acceleration.y + ‘<br />’ +
‘Acceleration Z: ‘ + acceleration.z + ‘<br />’ +
‘Timestamp: ‘ + acceleration.timestamp + ‘<br />';
}
[/js]

If there is an error it will be handled by the onError callback function display an error message.

[js]

// onError: Failed to get the acceleration
function onError() {
alert(‘onError!’);
}
[/js]

Also we can stop the accelerometer.watchAcceleration() method by using accelerometer.clearWatch() method: navigator.accelerometer.clearWatch(watchID);

[js]
// PhoneGap is ready
function onDeviceReady() {
// Stop Watch Button
var stopWatchBtn = $(‘#stopWatch’);
stopWatchBtn.click(function(){
stopWatch();
});
}

// Stop watching the acceleration
function stopWatch() {
if (watchID) {
navigator.accelerometer.clearWatch(watchID);
watchID = null;
}
}
[/js]

That’s all for the Tech page. In the Object page we will see how these information help us to actually move something around the screen using the accelerometer.

In the content area I used a div and gave it an id called “obj_wall”. I use this div to set up boundaries for our object so it doesn’t get out of our screen. Inside the object wall div as I’ve called it I used another div with the id “obj” representing the actual object. When you press the Start Moving button the object will go in the direction your holding your device.

The HTML:

[html]
<div data-role="content">
<div id="obj_wall">
<div id="obj"></div>
</div>
<div>
<a href="#" id="startMove" data-role="button">Start Moving</a>
</div>
</div>
[/html]

To style these elements the following css was used

[css]
#obj{
width:50px;
height:50px;
background-color:red;
position:absolute;
top:0;
left:0;
}

#obj_wall{
margin:10px auto;
width:200px;
height:200px;
border:1px solid blue;
position:relative;
}
[/css]

Our object has a 50px width and 50px height and a red color, it is positioned with position:absolute; over the wall. The object wall has a 200px width and a 200px height with a thin border so we can see that the object doesn’t get out of it’s boundaries.

In the script file the startMoving() function is called once we click the Start Moving button.

[js]
// Start moving the object
var startMove = $(‘#startMove’);
startMove.live("click",function(){
startMoving();
$(this).hide();
});
[/js]

The startMoving() function watches for any acceleration movement from the phone and the moveObject callback handles the actual moving.

[js]
// Start watching the acceleration
function startMoving(){

var options = { frequency: 500 };

watchMove = navigator.accelerometer.watchAcceleration(moveObject, onError, options);
}
[/js]

In the moveObject() function we set up the boundaries for our object. To check the position of the object I used .position() method from jQuery which gives me the left and top coordinates of the object. With these coordinates I’m able to check if my object doesn’t get out of the boundaries.

[js]
// moveObject
function moveObject(acceleration) {
var myObj = $(‘#obj’);
var wall = $(‘#obj_wall’);
var objPosition = myObj.position();
var leftBoundary = 0;
var topBoundary = 0;
var rightBoundary = wall.width() – myObj.width() – 10; // 10 represents the 10px for the margin
var bottomBoundary = wall.height() – myObj.height() – 10; // 10 represents the 10px for the margin

if( acceleration.x < 0 && objPosition.left <= rightBoundary ) {
myObj.animate({
left:’+=10′
},100);
} else if( acceleration.x > 0 && objPosition.left > leftBoundary ) {
myObj.animate({
left:’-=10′
},100);
}
if( acceleration.y < 0 && objPosition.top > topBoundary ) {
myObj.animate({
top:’-=10′
},100);
} else if(acceleration.y > 0 && objPosition.top <= bottomBoundary ) {
myObj.animate({
top:’+=10′
},100);
}
}
[/js]

That’s all. Good luck with mobile web development!

Read more from Mobile

Leave a Reply

required
required

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments