Home > Mobile Development, PhoneGap > PhoneGap Tutorial Series – #2 Using the PhoneGap API

PhoneGap Tutorial Series – #2 Using the PhoneGap API

 

Using the PhoneGap API

 
Welcome to the second installment of my PhoneGap Tutorial Series! This post is a continuation of PhoneGap Project Structure and Internals so if you haven’t already, you may want to peruse that post before continuing on.

We already know that PhoneGap is an open source framework for writing applications using typical web technologies like HTML, CSS, and JavaScript and that the PhoneGap architecture supplies JavaScript wrappers to access native phone features. What you may NOT know is how extensive those features really are or how to actually use them.

This article is all about getting familiar with the current features of the PhoneGap API and how to use them with the iPhone iOS.
 

So What Can PhoneGap Do For Me???

 
Well, turns out it can do a lot – right out of the box with “no coding” required (hahahahahaha! yeah right). No really, PhoneGap has an extensive library that already provides access to many of the iPhone’s basic features.

The following table outlines the PhoneGap API’s current features:

API Details
Accelerometer Tap into the device’s motion sensor.
Camera Capture a photo using the device’s camera.
Compass Obtain the direction that the device is pointing.
Contacts Work with the devices contact database.
Device Gather device specific information.
Events Hook into native events through JavaScript.
File Hook into native file system through JavaScript.
Geolocation Make your application location aware.
Media Record and play back audio files.
Network Quickly check the network state.
Notification Visual, audible, and tactile device notifications.
Storage Hook into the devices native storage options.

 

So How Do I Use These Great Features?

 
It’s actually pretty simple. If you have read the previous post on PhoneGap Project Structure and Internals then you already have a PhoneGap project started – if not – you can get the starter project here.

The PhoneGap documentation has a lot of examples to help you figure out how to code against the API. I have put together a project that exercises these examples and provides a working iPhone application for you to tinker with to see what PhoneGap can really do for you right out of the box.

In later posts I will extend the PhoneGap functionality, add additional third party plugins, and write my own plugin. All of the source code for the project is located on my github repository – https://github.com/hutley/HelloPhoneGap.

Note: I am updating the sample for each API as I get to it so if it says “Under Construction” just check back later for that sample.


Basic Pattern

Each PhoneGap API typically follows a pretty basic pattern where you provide onSuccess and onFailure JavaScript callback functions to each API call which means that when you call a PhoneGap method you will explicitly provide pointers to the JavaScript methods that are to be invoked when the API either succeeds or fails.

Some of the APIs perform this as an asynchronous operation so you cannot count on a specific order of events. If you need a synchronous pipeline – then you need to chain the events through the callback methods. Check the API…



Accelerometer Example

The following code snippet is an HTML page that includes PhoneGap and exercises the Accelerometer API.

There are several things to notice here:

  • Line 5 – PhoneGap.js must be included on the page (at least before third party plugins or custom plugins).
  • Line 9 – onBodyLoad() function adds a event listener for “deviceready”, when this event is triggered, then PhoneGap is initialized.
  • Line 18 – navigator.accelerometer. getCurrentAcceleration(onAccelerationSuccess, onError) – call to PhoneGap API passing OUR success/failure functions.
  • Line 34 – button to execute the getCurrentAcceleration() function


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
         <meta http-equiv="Content-type" content="text/html; charset=utf-8">
            <script type="text/javascript" charset="utf-8" src="phonegap.0.9.4.min.js"></script>
            <script type="text/javascript" charset="utf-8">
                function onBodyLoad()
                {
                    document.addEventListener("deviceready",onDeviceReady,false);
                }
                
                /* When this function is called, PhoneGap has been initialized */
                function onDeviceReady()
                {
                }
                
                function getCurrentAcceleration() {
                    navigator.accelerometer.getCurrentAcceleration(onAccelerationSuccess, onError);
                }
                
                // onSuccess: Get a snapshot of the current acceleration
                function onAccelerationSuccess(acceleration) {
                    alert( 'Acceleration X: ' + acceleration.x + '<BR>' + 'Acceleration Y: ' + acceleration.y + '<BR>' 
                             + 'Acceleration Z: ' + acceleration.z + '<BR>');
                }

                // onError: Failed to get the acceleration
                function onError() {
                    alert ("onError");
                }
                </script>
            </head>
    <body onload="onBodyLoad()">
                        <button  onclick="getCurrentAcceleration();">getCurrentAcceleration()</button>  
    </body>
</html>


Little Gotchas!

So in the course of putting this together, I noticed that lots of the samples that I was trying to get working just seemed to do nothing. Turns out that there are a lot of little things that just don’t work in the simulator and PhoneGap chooses to silently perform a no-op. So instead of calling the onFailure methods, PhoneGap just returns from the API call without doing anything.

Awesome? No. Now maybe it should be obvious to me that I can’t take a pic from the simulator – BUT my MacBook has a nice little camera so it wasn’t…. Anyway – after stepping through the Objective-C code – I stumbled on this:

- (void) getPicture:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
	NSUInteger argc = [arguments count];
	NSString* successCallback = nil, *errorCallback = nil;
	
	if (argc > 0) successCallback = [arguments objectAtIndex:0];
	if (argc > 1) errorCallback = [arguments objectAtIndex:1];
	
	if (argc < 1) {
		NSLog(@"Camera.getPicture: Missing 1st parameter.");
		return;
	}
	
	NSString* sourceTypeString = [options valueForKey:@"sourceType"];
	UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera; // default
	if (sourceTypeString != nil) {
		sourceType = (UIImagePickerControllerSourceType)[sourceTypeString intValue];
	}

	bool hasCamera = [UIImagePickerController isSourceTypeAvailable:sourceType];
	if (!hasCamera) {
		NSLog(@"Camera.getPicture: source type %d not available.", sourceType);
		return;
	}

Notice that in both line 11 and line 23 there are return statements that basically perform a silent failure – yes there are log entries but since I am providing an onFailure method I would think it would get called. That is not the case – so just beware of the quirks when using some of these features.

Well that’s all for now – stay posted for the next installment….

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: