2. PhoneGap Development, Testing, and Debugging

As mentioned in the previous chapter, a PhoneGap application can do anything that can be coded in standard, everyday HTML, CSS, and JavaScript. There are web applications and PhoneGap applications, and the distinction between them can be minor or can be considerable. In this chapter, we’ll analyze the anatomy of a PhoneGap application, identifying what makes an application a PhoneGap application and then highlighting ways to make a PhoneGap application ... better.

The following sections will highlight different versions of the requisite Hello-World application found in every developer book, article, and training class. For the purpose of highlighting aspects of the applications’ web content, rather than how they were created, the steps required to create the applications are omitted. Refer to the chapters that follow for specific information on how to create and test PhoneGap projects for each of the supported mobile platforms.

Hello, World!

As with any developer book, we’re going to start with the default HelloWorld application and then build upon it to highlight different aspects of a PhoneGap application. The following HTML content describes a simple web page that displays some text on a page.


HelloWorld1 Application

<!DOCTYPE HTML> 
<html> 
<head> 
  <title>HelloWorld1</title>   
</head> 
<body> 
  <h1>Hello World</h1>   
  <p>This is a sample PhoneGap application</p>   
</body> 
</html> 


If you package that page into a PhoneGap application and run it on a smartphone or device emulator (in this case an Android emulator), you will see something similar to what is shown in Figure 2-1.

Image

Figure 2-1 HelloWorld1 application running on an Android emulator

This is technically a PhoneGap application because it’s a web application running within the PhoneGap native application container. There is, however, nothing PhoneGap-ish about this application. It’s running in the PhoneGap native container, but it isn’t leveraging any of the APIs provided by the PhoneGap framework.

Therefore, any web application can be built into a PhoneGap application; there’s nothing forcing you to use the PhoneGap APIs. If you have a simple web application that simply needs a way to be deployed through a smartphone app store, then this is one way to accomplish that goal.

PhoneGap Initialization

Now let’s take the previous example application and add some PhoneGap-specific stuff to it. The HelloWorld2 application listed next has been updated to include code that recognizes when the PhoneGap application has completed initialization and displays an alert dialog letting you know PhoneGap is ready.


HelloWorld2 Application

<!DOCTYPE html> 
<html> 
  <head> 
    <meta http-equiv="Content-type" content="text/html; 
      charset=utf-8"> 
    <meta name="viewport" id="viewport" 
      content="width=device-width, height=device-height, 
      initial-scale=1.0, maximum-scale=1.0, 
      user-scalable=no;" /> 
    <script type="text/javascript" charset="utf-8" 
      src="phonegap.js"/script> 

    <script type="text/javascript" charset="utf-8"> 

      function onBodyLoad() { 
        document.addEventListener("deviceready",onDeviceReady, 
        false); 
      } 
      function onDeviceReady() { 
        navigator.notification.alert("PhoneGap is ready!"); 
      } 
    </script> 

  </head> 
  <body onload="onBodyLoad()"> 
    <h1>HelloWorld2</h1> 
    <p>This is a sample PhoneGap application.</p> 
  </body> 
</html> 


On the iPhone simulator, the application will display the screen shown in Figure 2-2.

Image

Figure 2-2 HelloWorld2 application running on an iOS simulator

Within the <Head> section of the web page are two new entries: meta tags that describe the content type for the application and viewport settings.

The content-type setting is a standard HTML setting and should look the same as it would for any other HTML 5 application.

The viewport settings tell the web browser rendering the content how much of the available screen real estate should be used for the application and how to scale the content on the screen. In this case, the HTML page is configured to use the maximum height and width of the screen (through the width=device-width and height=device-height attributes) and to scale the content at 100% and not allow the user to change that in any way (through the initial-scale=1.0, maximum-scale=1.0, and user-scalable=no attributes).


Image Note

The viewport and associated attributes are not required; if they’re omitted, the browser will revert to its default behavior, which may result in the application’s content not consuming the full screen area available to it or zooming beyond it. Because there’s not much content in the HelloWorld2 application, it could, for example, consume only the upper half of the screen on some devices.

You may find that on some platforms the settings have no effect. On the BlackBerry Torch simulator, the height and width attributes are respected; on the BlackBerry Storm simulator, the application doesn’t consume the entire height of the screen no matter how the attributes are set.


There’s also a new script tag in the code that loads the PhoneGap JavaScript library:

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

This loads the PhoneGap API library and makes the PhoneGap APIs available to the program. In this example, and all of the examples throughout the rest of the book, I’ll load the PhoneGap JavaScript library using this standard snippet of code. In reality, the PhoneGap file being loaded by your application will include version information in the file name. As I wrote the chapter, PhoneGap 1.0 had just been released, so the code in reality looked like this when I wrote the application:

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

As I wrote subsequent chapters, the PhoneGap team released three additional versions of the framework. Rather than have inconsistent PhoneGap JavaScript file names in the book, I chose to just show phonegap.js as illustrated in the first example. In reality, many of the example applications used throughout the book were actually built using PhoneGap Build, which requires only the simple phonegap.js reference (or no reference at all), which is then replaced with the appropriate JavaScript file version PhoneGap Build is currently using.

Beginning with PhoneGap 1.5, the project team changed the name for the open source project to Cordova and changed the JavaScript file (for most but not all of the supported platforms) from phonegap.js to cordova.js. So, even though you’re working with PhoneGap, the JavaScript file name no longer matches the commercial name for the project.

JavaScript code in a PhoneGap application does not have immediate access to the PhoneGap APIs after the web application has loaded. The native PhoneGap application container must complete its initialization process before it can respond to calls JavaScript made using the PhoneGap APIs. To accommodate this delay in API availability, a web developer building PhoneGap applications must instruct the container to notify the web application when the PhoneGap APIs are available. Any application processing that requires the use of the APIs should be executed by the application only after it has received its notification that the APIs are available.

In the HelloWorld2 application, this notification is accomplished through the addition of an onload event defined in the page’s body section, as shown here:

<body onload="onBodyLoad()">

Within the onBodyLoad function, the code registers an event listener that instructs the application to call the onDeviceReady function when the device is ready, when the PhoneGap application container has finished its initialization routines:

document.addEventListener("deviceready", onDeviceReady, false);

In this example application, the onDeviceReady function simply displays a PhoneGap alert dialog (which is different from a JavaScript alert dialog), letting the user know everything is OK:

navigator.notification.alert("PhoneGap is ready!")

In production applications, this function could update the user interface (UI) with content created through API calls or do whatever other processing is required by the application. You’ll see an example of this in the next sample application.


The PhoneGap Navigator

Many of the APIs implemented by PhoneGap are instantiated from the Navigator object. Unfortunately, it’s not consistent; some do and some do not. Be sure to check the API documentation before calling an API.


Leveraging PhoneGap APIs

Now that we know how to configure an application to wait until the PhoneGap APIs are available, let’s build an application that actually uses the PhoneGap APIs as shown in the following HelloWorld3 application.


HelloWorld3 Application

<!DOCTYPE html> 
<html> 
  <head> 
    <meta http-equiv="Content-type" content="text/html; 
      charset=utf-8"> 
    <meta name="viewport" id="viewport" 
      content="width=device-width, height=device-height, 
      initial-scale=1.0, maximum-scale=1.0, 
      user-scalable=no;" /> 
    <script type="text/javascript" charset="utf-8" 
      src="phonegap.js"></script> 

    <script type="text/javascript" charset="utf-8"> 

      function onBodyLoad() { 
        document.addEventListener("deviceready", onDeviceReady, 
        false); 
      } 
      function onDeviceReady() { 
        //Get the appInfo DOM element 
        var element = document.getElementById('appInfo'), 
        //replace it with specific information about the device 
        //running the application 
        element.innerHTML = 'PhoneGap (version '+
          device.phonegap + ')<br />' + device.platform + ' '+
          device.name + ' (version ' + device.version +   ').'; 
        } 
     </script> 

   </head> 
   <body onload="onBodyLoad()"> 
     <h1>HelloWorld3</h1> 
     <p>This is a PhoneGap application that makes calls to the 
     PhoneGap APIs.</p> 
     <p id="appInfo">Waiting for PhoneGap Initialization to 
     complete</p> 
   </body> 
 </html> 


Figure 2-3 shows a portion of the application’s screen when running on the BlackBerry Torch 9800 simulator.

Image

Figure 2-3 HelloWorld3 application running on a BlackBerry simulator

In this version of the HelloWorld application, the code in the onDeviceReady function has been updated so the program updates a portion of the application’s content with an ID of appInfo with information about the device running the application and the version of PhoneGap used to build the application. Device-specific information is available via the PhoneGap device API (http://docs.phonegap.com/phonegap_device_device.md.html), and this sample application uses only a subset of the available methods in this API.

Figure 2-3 highlights one of the problems with the PhoneGap APIs: inconsistent implementation of an API across different mobile device platforms. The call to the device.platform API is supposed to return the name of the mobile device platform the application is running on. In this case, the call should return “BlackBerry,” but instead it returns “3.0.0.100” for some bizarre reason. For iOS devices, the call returns “iPhone” when in reality it should be returning “iOS.” It’s important to keep in mind that any function call might not return what you expect depending on the mobile platform the application is running on. Be sure to test your application on each platform you plan on supporting and make adjustments to your code as needed to deal with inconsistencies with the PhoneGap APIs. Expect the values returned by this property to change over time as well.

Enhancing the User Interface of a PhoneGap Application

As you can see from the application examples highlighted so far, the PhoneGap framework doesn’t do anything to enhance the UI of a PhoneGap application. The framework provides access to device-specific features and applications and leaves it up to developers to theme their applications however they see fit. Web developers should use the capabilities provided by HTML, CSS, and even Java-Script to enhance the UI of their PhoneGap applications as needed; we’re not going to cover mobile web UI design here.

As Android and iOS-based smartphones became more popular, web developers found themselves needing to be able to build web applications that mimic the look and feel of native applications on these mobile platforms. To accommodate this need, many open source and commercial JavaScript mobile frameworks were created to simplify this task such as jQuery Mobile (www.jquerymobile.com), Dojo Mobile (www.dojotoolkit.org/features/mobile), and Sencha Touch (www.sencha.com/products/touch).

Although not directly related to PhoneGap development, the use of these frameworks is very common for PhoneGap applications, so it’s useful to highlight them here. In this section, we’ll discuss how to enhance the UI of a PhoneGap application using jQuery Mobile (jQM), an offshoot of the popular jQuery project. The jQuery and jQM libraries work together to provide some pretty useful UI elements and theming for any mobile web application.


Image Note

jQM currently supports most of the mobile platforms supported by PhoneGap. As of this writing, the Samsung bada OS has not been tested but is expected to work, and support has not yet been added for the Windows Phone OS.


In the following HelloWorld4 application, we’ll take the HelloWorld3 application and apply an enhanced UI using the jQuery Mobile framework.


HelloWorld4 Application

<!DOCTYPE html> 
<html> 
  <head> 
    <meta http-equiv="Content-type" content="text/html; 
      charset=utf-8"> 
    <meta name="viewport" id="viewport" 
      content="width=device-width, height=device-height, 
      initial-scale=1.0, maximum-scale=1.0, 
      user-scalable=no;" /> 
    <link rel="stylesheet" href="jquery.mobile-1.0b3.css" /> 
    <script type="text/javascript" charset="utf-8" 
      src="jquery-1.6.4.js"></script> 
    <script type="text/javascript" charset="utf-8" 
      src="jquery.mobile-1.0b3.js"></script> 
    <script type="text/javascript" charset="utf-8" 
      src="phonegap.js"></script> 

    <script type="text/javascript" charset="utf-8"> 

      function onBodyLoad() { 
        document.addEventListener("deviceready", onDeviceReady, 
          false); 
      } 

      function onDeviceReady() { 
        //Get the appInfo DOM element 
        var element = document.getElementById('appInfo'), 
        //replace it with specific information about the device 
        //running the application 
        element.innerHTML = 'PhoneGap (version ' + 
          device.phonegap + ')<br />' + device.platform + ' ' + 
          device.name + ' (version ' + device.version + ').';
      } 
    </script> 

  </head> 
  <body onload="onBodyLoad()"> 
    <div data-role="page"> 
      <div data-role="header" data-position="fixed"> 
        <h1>HelloWorld4</h1> 
      </div> 
      <div data-role="content"> 
        <p>This is a PhoneGap application that makes calls to 
        the PhoneGap APIs and uses the jQuery Mobile 
        framework.</p> 
        <p id="appInfo">Waiting for PhoneGap Initialization to 
        complete</p> 
       </div> 
       <div data-role="footer" data-position="fixed"> 
         <h1>PhoneGap Essentials</h1> 
       </div> 
     </div> 
   </body> 
 </html> 


Figure 2-4 shows the application running on the Android simulator.

Image

Figure 2-4 HelloWorld4 application running on an Android emulator

Notice that the device.platform call is working correctly on the Android emulator; in Figure 2-4, it lists “google_sdk” as the platform for the emulator.

Notice how jQM has a problem rendering the “PhoneGap Essentials” text in the footer. Just so you can see how this looks on a different mobile platform, Figure 2-5 shows the exact same web content running within a PhoneGap application on the BlackBerry Torch simulator. This isn’t an issue with PhoneGap but instead is an issue related to available screen width and how jQM renders content leaving space on the left and right for buttons (which aren’t used in this example).

Image

Figure 2-5 HelloWorld4 application running on a BlackBerry simulator

In this version of the application, some additional resources have been added to the page’s header:

<link rel="stylesheet" href="jquery.mobile-1.0b3.css" /> 
<script type="text/javascript" charset="utf-8" 
  src="jquery-1.6.4.js"></script>   
<script type="text/javascript" charset="utf-8" 
  src="jquery.mobile-1.0b3.js"></script>   

The first line points to a CSS file provided by the jQM framework. It contains the style information used to render the iPhone-ish UI shown in the figure. Next come references to the jQuery and jQuery Mobile JavaScript libraries that are used to provide the customized UI plus add additional capabilities to the application. The files referenced in the example application are the full versions of the CSS and JavaScript files. These files are used during testing of the application and should be replaced with the min versions of the files, as shown in the following code snippet, before rolling the application into production.

<link rel="stylesheet" href="jquery.mobile-1.0b3.min.css" /> 
<script type="text/javascript" charset="utf-8" 
  src="jquery-1.6.4.min.js"></script>   
<script type="text/javascript" charset="utf-8" 
  src="jquery.mobile-1.0b3.min.js"></script>   

The min versions are compressed so comments, white space, line breaks, and so on, are removed from the files. This allows the files to take up less space within the packaged application, helping reduce the overall file size for the application, and allows these resources to load more quickly when the user launches the application.

The body of the HTML page has been updated to include several HTML <div> tags wrapped around the content for the application. These <div>s include a data-role attribute that is used by jQM to define specific areas of the content page that are then styled appropriately depending on which role is assigned.

In Figure 2-5, the content in the section of the page given the header data-role is styled with a gradient background and forced to the top of the page by the data-position=”fixed” attribute. Similarly, the content in the section of the page given the footer data-role is styled with a gradient background and forced to the bottom of the page by the data-position=”fixed” attribute. The page content defined within the data-role=”content” <div> will be rendered between the header and footer, with the middle section scrollable as needed to display all of the content within the section.

These examples only lightly cover the capabilities of jQM; there’s so much more you can do with this framework to enhance the user experience within your PhoneGap applications. Refer to the jQM online documentation or several of the new books on jQM for additional information about the capabilities provided by the framework.

Testing and Debugging PhoneGap Applications

Each of the mobile platforms supported by PhoneGap has a mechanism a developer can use to test and, in the unlikely event your code has bugs, debug PhoneGap applications. In general, you can load a PhoneGap application into a device simulator or emulator, provided as part of the mobile platform’s SDK, or you can load an application onto a physical device. There are also third-party solutions you can use to test your PhoneGap applications within a desktop browser interface.

Running a PhoneGap Application on a Device Simulator or Emulator

Each smartphone operating system supported by PhoneGap has a device emulator or simulator (E/S) provided by the originator of the OS. In some cases, what’s provided is a generic emulator that simply mimics the capabilities of the specific OS version, while for other mobile platforms there are simulators available that mimic specific devices. Either way, there’s a software-only solution available that developers can use to test PhoneGap applications in an almost real-world scenario (I’ll explain “almost real-world” in the following section).

An E/S is typically included with the native development tools for each mobile platform, but in some cases there are options that can be downloaded individually. Research In Motion, for example, includes a set of simulators with each BlackBerry Device Software version SDK but also provides individual downloads for specific BlackBerry Device Software versions or for older devices that have software updates available for them. Either way, there are likely options available for each and every device or device OS you want to test your application on. The chapters that follow provide detailed information on how to configure a development environment for each of the mobile devices platforms supported by PhoneGap. That’s where you will find instructions on how to test PhoneGap applications on the appropriate E/S for the target platform.

Running a PhoneGap Application on a Physical Device

While the device E/S is a great option for developer and system testing of a PhoneGap application, final testing should always be performed on a physical device. As good as these options are, there is always something that doesn’t work quite right on a simulator or emulator.

To run a PhoneGap application on a physical device, you will create the PhoneGap application first using the native SDK or package the application for platforms that use a widget approach. Once you have a deployable application, you will connect the device to your development computer via a Universal Serial Bus (USB) cable and transfer the application to the mobile device using some component of the native SDKs. The process varies depending on the mobile platform you are working with.

For iOS applications, for example, Apple requires a special provisioning process for every iOS device on which you want to install your application. The process requires membership in Apple’s developer program and involves the Xcode development environment, Apple’s developer portal, a provisioning profile, and a physical device.

For Android and BlackBerry devices, the native SDK includes command-line utilities you can use to copy an application to a target device. There’s no special provisioning process; you simply connect the device to the developer computer, issue the command, and test away. In some cases, you can deploy to devices directly from the Eclipse IDE. For Android devices, there are steps you must complete to configure the device for testing applications. On BlackBerry, you’ll need to secure a set of signing keys (they’re free at https://bdsc.webapps.blackberry.com/java/documentation/ww_java_getting_started/Code_signing_1977871_11.html) and sign the application before it will run on a physical device.

Regardless of the platform you use, digging into the details of on-device testing is beyond the scope of this book. Please refer to the documentation for the appropriate native SDK for additional information about how to test applications on physical devices.

Leveraging PhoneGap Debugging Capabilities

As mentioned earlier, there are two types of PhoneGap applications: PhoneGap applications that consist of a web application packaged inside of a native application container (for Android, BlackBerry, iOS, and Windows Phone) and PhoneGap applications deployed simply as packaged web applications (on bada, Symbian, and webOS).

For the mobile platforms where PhoneGap applications are simply packaged web applications, the freely available native SDK typically includes support for debugging web content running in a device emulator or simulator. In the chapters that follow, you will find instructions on how to leverage native debugging tools for these platforms when testing PhoneGap applications. You will, however, need to refer to the native SDK documentation for detailed information on how to use these tools.

The problem with the native application options for PhoneGap is that the native tools designed to help developers debug applications for each platform are designed to debug native applications; they have none or limited capabilities for debugging web content that is packaged within native applications. The BlackBerry WebWorks development tools originally supported the ability to debug web content packaged within a BlackBerry WebWorks application (which is essentially what a PhoneGap application is on BlackBerry). In 2011, RIM abandoned the Eclipse and Visual Studio IDEs and switched to an entirely command-line-driven approach.

To help debug your PhoneGap applications, you can fill your code with calls to the alert() function. This is what I have always called a poor man’s debugger, but it works quite well for certain types of application debugging tasks. If you see an event that’s not firing within your application or some variable that’s not being set or read correctly, you can simply insert an alert that displays a relevant message and use that to see what’s going on. There’s an example of this approach in the HelloWorld2 application shown earlier with the use of PhoneGap’s navigator.notification.alert("") function. In this case, I used the alert to help debug what was happening in the onDeviceReady() function. It seemed to be working on Android, but not BlackBerry, so I used the alert to help confirm my suspicion and to help test different approaches as I attempted to fix the problem.

The problem with this approach is that when you fill your buggy code with alerts, you’re constantly interrupting the application flow to dismiss the alerts as they come up. For a simple problem, this approach works pretty well, but when debugging more troublesome errors, you will need an approach that allows you to let the application run and then analyze what is happening in real time or after the application or a process within the application has completed, without interrupting the application. PhoneGap applications can do this through the JavaScript console object implemented by the WebKit browser rendering engine.

Using the console object, developers can write messages to the browser’s console, which can be viewed outside of the running program through capabilities provided by the native SDKs or device simulators or emulators. The console object has scope at the window level, so it’s essentially a global object accessible by any JavaScript code within the application. WebKit supports several options; the most common ones used are as follows:

console.log(“message”);

console.warn(“message”);

console.error(“message”);

Example 2-1 shows a sample application that illustrates the use of this feature.


Example 2-1

<!DOCTYPE html> 
<html> 
  <head> 
    <meta name="viewport" content="width=device-width, 
      height=device-height, initial-scale=1.0, 
      maximum-scale=1.0, user-scalable=no;" /> 
    <meta http-equiv="Content-type" content="text/html; 
      charset=utf-8"> 
    <script type="text/javascript" charset="utf-8" 
      src="phonegap.js"></script> 

    <script type="text/javascript" charset="utf-8"> 

      function onBodyLoad() { 
        document.addEventListener("deviceready", onDeviceReady, 
          false); 
      } 

      function onDeviceReady() { 
        //Just writing some console messages 
        console.warn("This is a warning message!"); 
        console.log("This is a log message!"); 
        console.error("And this is an error message!"); 
      } 

    </script> 
  </head> 
  <body onload="onBodyLoad()"> 
    <h1>Debug Example</h1> 
    <p>Look at the console to see the messages the application 
    has outputted</p> 
  </body> 
</html> 


As you can see from the code, all the application has to do is call the appropriate method and pass in the text of the message that is supposed to be written to the console.

In some cases, the browser component executing your application’s web content won’t throw an error if you try to do something that’s not supported in your Java-Script code (calling a PhoneGap API function that doesn’t exist, for example, because you’ve misspelled it). In this scenario, simply wrap the errant call in a try/catch block so your application will have a chance to write its error to the console, as shown in the following example:

try { 
  console.log("Validating the meaning of life"); 
  somefunctioncall("42"); 
} catch (e) { 
  console.error("Hmmm, not sure why this happened here: " + 
    e.message); 

Figure 2-6 shows the messages from Example 2-1 highlighted in the Xcode console window. This window is accessible while the program is running on an iOS simulator, so you can debug applications in real time.

Image

Figure 2-6 Viewing console messages in Xcode

When working with the BlackBerry simulator, you can access the logs by holding down the simulator’s Alt key and typing lglg. The simulator will display the Event Log, as shown in Figure 2-7.

Image

Figure 2-7 BlackBerry Event Log application

When you open an Event Log entry, you can see the details behind the entry, as shown in Figure 2-8. Press the keyboard’s n and p keys to navigate to the next and previous entries in the log.

Image

Figure 2-8 Viewing console messages on BlackBerry


Image Note

In my testing with the BlackBerry simulator, only the console.log messages appear within the Event Log application; the BlackBerry implementation of the WebKit engine doesn’t seem to respond to console.warn and console.error messages.


Within the BlackBerry Event Log application, you have the ability to clear the log, filter what’s displayed in the log, and copy the contents of the log to the clipboard so you can use them in another application or send them to yourself via email. Additionally, when working with a physical device, you can connect the device to your development system and use the BlackBerry Java Loader application (javaloader.exe) to copy the logs from the device. Many of these options are described in detail in my other mobile development book, BlackBerry® Development Fundamentals (www.bbdevfundamentals.com).

The Android SDK includes utilities that allow a developer to monitor log activity, while an application runs within an Android emulator. This functionality is provided by the LogCat utility, which is an integral part of the Eclipse plug-in but also available through the command line or a stand-alone utility.

To open the LogCat window in Eclipse, open the Window menu, select Show View, and then select Other. In the dialog that appears, expand the Android category and select LogCat, as shown in Figure 2-9, and then click OK. Eclipse will open a new pane in the messages area of the IDE, as shown in Figure 2-10.

Image

Figure 2-9 Eclipse Show window dialog

Image

Figure 2-10 Eclipse messages area

This pane will display all messages generated by the Android device emulator as well as console messages written by your PhoneGap application; you can see the three messages written by the sample application. Use the V (verbose), D (debug), I (info), W (warning), and E (error) buttons at the top of the pane to filter the contents of the pane as needed to allow you to more quickly locate the entries you are looking for while debugging an application.

Google also offers a stand-alone utility called the Dalvik Debug Monitor Server (DDMS) that you can use to monitor the Android emulator console when testing PhoneGap applications outside of the Eclipse IDE. To launch the DDMS utility, you must first launch an Android emulator. Once the emulator is running, open a file explorer (Finder on Macintosh or Windows Explorer on Windows), navigate to the Android SDK tools folder, and execute the DDMS utility located therein. The file is called ddms.bat on Microsoft Windows and ddms on Macintosh.

When the utility launches, it will display a window similar to the one shown in Figure 2-11. At the top of the utility are windows that show the different processes running in the emulator on the left and a list of additional options on the right. The lower half of the application’s window displays the same LogCat pane from the Eclipse plug-in.

Image

Figure 2-11 Android DDMS application window

To access the LogCat content from the command line on Windows, open a command prompt, navigate to the Android SDK platform-tools folder, and issue the following command:

adb logcat

On Macintosh, open a terminal window, navigate to the Android SDK platform-tools folder, and issue the following command:

./adb logcat

The adb utility will connect to the emulator and retrieve and display in real time the contents of the logcat from the Android emulator, as shown in Figure 2-12. In the figure, the three console messages generated by the application are highlighted.

Image

Figure 2-12 Viewing console messages on Android

Third-Party PhoneGap Debugging Tools

There’s a very active partner community supporting PhoneGap with additional tools for PhoneGap developers. In this section, I’ll introduce several of the available tools that help developers test and debug PhoneGap applications. This is by no means a complete list of options; refer to the PhoneGap wiki (http://wiki.phonegap.com) for information on additional tools that might be available.

Ripple Mobile Environment Emulator

When developing a PhoneGap application, it’s quite time-consuming to build the application and load it into a simulator or emulator for testing. The Ripple Mobile Environment Emulator (RMEE) is a freely available tool that helps alleviate this problem by providing a desktop browser–based interface you can use to test your PhoneGap applications. The RMEE emulates the execution of the PhoneGap APIs within the browser container. You should use the emulator for quick testing of PhoneGap application features during development and then switch to packaging/building PhoneGap applications and testing them on actual devices or device emulators or simulators for more thorough testing. The RMEE is not designed to replace testing on real devices, device simulators, or device emulators.


RIM and the Ripple Emulator

Tiny Hippos, the company that produced of the Ripple Mobile Environment Emulator, was recently purchased by RIM and is expected to become the default way to test BlackBerry WebWorks applications. The emulator has supported PhoneGap for quite a while and is expected to continue to support the project under RIM’s ownership.


The RMEE is implemented as an extension to the Google Chrome browser, so before you can start using the emulator, you must first install the latest version of Chrome from www.google.com/chrome. Once you have Chrome up and running, launch the browser and navigate to http://ripple.tinyhippos.com. From the Tiny Hippos home page, click the Get Ripple link, and follow the prompts to install the latest version of the emulator.

Before you can start emulating PhoneGap within the RMEE, you must first configure the browser to allow the emulator access to files on the local file system. Open the Chrome browser, right-click the Ripple icon to the right of the browser’s address bar, and select Manage extensions. The browser will display a page similar to the one shown in Figure 2-13. Enable the “Allow access to file URLs” option for the RMEE as shown in the figure and then close the page by clicking the X to the right of the Extensions tab.

Image

Figure 2-13 Configuring the Ripple Emulator in Google Chrome

Once the browser has been configured, open your application’s index.html file in the browser. You can press Ctrl+O on Windows or Command+O on Macintosh to open the File Open dialog. Once the page has loaded, you need to enable Ripple for the selected page. To do this, complete one of the following options:

• Click the Ripple icon to the right of the browser’s address bar to open a window, allowing you to enable Ripple for the loaded page.

• Right-click the page, open the Emulator menu, and then select Enable.

• Append ?enableripple=true to the file URL to enable Ripple directly within the address bar when loading an application’s index.html file.

Once the RMEE is enabled for the loaded page, the browser will display a page, shown in Figure 2-14, that prompts you to identify which type of emulation you want to enable for this page. As you can see, the RMEE supports PhoneGap plus several other platforms and frameworks. Click the PhoneGap button to continue.

Image

Figure 2-14 Enabling PhoneGap emulation in the Ripple emulator

At this point, the RMEE will display a page with the content from the index.html file rendered within the boundaries of a simulated smartphone screen, as shown in Figure 2-15. Wrapped around the simulated smartphone are properties panes that can be used to configure options and status for the simulated smartphone such as simulated device screen resolution, accelerometer, network, geolocation, and more.

Image

Figure 2-15 PhoneGap application running in the Ripple emulator

You can click each of the tabs to expand the options for the tab and make changes to the simulated device’s configuration. At this point, you would simply click around within the simulated smartphone screen and interact with the options presented within your application. When you find a problem or a change you want to make within the PhoneGap application, simply return to your HTML editor, make the necessary changes, write the changes to disk, and then reload the page in the Chrome browser to continue with testing.

Weinre

Web Inspector Remote (Weinre) is a community-built remote debugger for web pages. It has been donated to the PhoneGap project and is currently implemented as part of the PhoneGap Build service. You can find the download files and instructions at http://phonegap.github.com/weinre. Weinre consists of a debug server, debug client, and debug target. The debug server runs on Macintosh or Windows, and the debug client runs in any compatible desktop browser.

For PhoneGap development, it allows a developer to debug a web application on physical device or a device emulator or simulator. To configure Weinre, perform the following steps:

1. Install a debug server on a desktop computer.

2. Launch the debug server.

3. Windows only: Point a compatible desktop browser at the debug server.

4. Connect the remote web application to the server.

The server component of Weinre consists of a stand-alone Macintosh executable or a Java JAR file for Windows. On Macintosh, load the debug server by double-clicking the application’s executable in Finder. The debug server and debug client are packaged together in the same application, so there are no additional steps needed to launch the debug client.

On Windows, the debug server consists of a single JAR file that, assuming Java is on the Windows Path, can be loaded using the following command:

java -jar path/to/weinre.jar

There are additional command-line options that can be passed to the JAR file while it’s loading to allow you to configure the host address the server will respond to, the server port number, and more. Refer to the Weinre documentation for additional information about the available command-line options. When the server starts, it will display a message indicating the URL to use to start the debug client; by default it should be http://localhost:8080. Point a compatible WebKit-based browser at the server to open the debug client.

To connect the PhoneGap application to the debug server, add the following <script> tag to the <body> section of the application’s index.html file,

<script src="http://debug_server:8080/target/ 
  target-script-min.js"></script>   

replacing the debug_server portion of the URL with the correct host name or IP address for the debug server. This provides the code needed for the PhoneGap application to upload information to the debug server. The Android emulator does not have the ability to connect to host-side resources using an IP address, so for the Android emulator, you must use the host address http://10.0.2.2, as shown in the following example:

<script src="http://10.0.2.2:8080/target/ 
  target-script-min.js"></script>   


Image Note

Be sure to remove the Weinre <script> tag from your PhoneGap application before releasing it into production. The application will likely hang if attempting to connect to debug server that isn’t available.


Figure 2-16 shows the debug server running on a Macintosh. On the bottom of the window are tabs that control the server while the toolbar on the top of the window contain options for the remote debugger client.

Image

Figure 2-16 Weinre server/debug client on a Macintosh

The debug client provides the means to view and optionally manipulate many of the page elements and other aspects of your application’s web content. You can view the browser console, as shown in Figure 2-17, to see console messages written by the PhoneGap application, or you can change application values or properties to tweak the application while it’s running.

Image

Figure 2-17 Weinre debug client console

The available documentation for Weinre is pretty light, but since the project’s capabilities are based upon the Google Chrome Developer Tools, you can find additional information on the Google Code web site at http://code.google.com/chrome/devtools/docs/overview.html.

Dealing with Cross-Platform Development Issues

As interesting as all of these PhoneGap capabilities are, there are a lot of issues that make cross-platform development tasks difficult. The PhoneGap project is supported by developers from all over the world, including developers who may have experience with only one or a small number of mobile platforms and developers who have a strong opinion about how something should be done. The problem with this is that when you take development projects written by different people and try to collect them into a single framework, you can bump up against inconsistencies. Add to this that every mobile platform supported by PhoneGap is different and has different ways of doing things, and you have a difficult task to make everything work cleanly and seamlessly.


Image Note

To the PhoneGap project’s credit, things move pretty quickly, and the issues I’m complaining about here could very well be fixed in any subsequent release of the framework. Be sure to check the latest documentation before working around any of the issues listed in the sections that follow.


Let’s look at some examples.

API Consistency

Figure 2-18 shows the supported feature matrix from the PhoneGap web site; you can find the page at www.phonegap.com/about/features. As you can see, the table is pretty complete; there are some gaps, but it’s more full than empty. On the other hand, since PhoneGap is supposed to be a cross-platform framework, the gaps in this table make it very hard to truly create a cross-platform application using those APIs. If a particular feature you want to use in your application is supported on only some mobile platforms, then you’ll have to make special accommodation within your application for platforms that do not support the particular API.

Image

Figure 2-18 PhoneGap-supported feature matrix

Another problem arises when you look through the API documentation found at http://docs.phonegap.com/. For most of the PhoneGap APIs, the documentation lists that the APIs are supported only on Android, BlackBerry, and iOS devices. It’s likely the issue here is that the PhoneGap developers are like most developers and don’t like to write (or update) documentation; the impact on you is huge. Do you rely upon the API documentation? Do you instead ignore the documentation and use feature matrix as the correct reference? Or do you cover your bases and assume it is all wrong and test everything?

No matter what, this can be quite a challenge; ideally the PhoneGap project team will get more organized and make sure all of the documentation is up-to-date as each new version is released.

Multiple PhoneGap JavaScript Files

One of the first issues I bumped up against when learning to do cross-platform PhoneGap development was that the PhoneGap JavaScript library is different between mobile platforms. So, the JavaScript code within the PhoneGap Java-Script file for BlackBerry projects is different from what is found in the PhoneGap Java-Script file for Android projects. My original thought when I started was that I could just copy the web content folder between projects, build the application, and be done, but since each platform’s JavaScript file is different, I would have to copy over the web content and then also make sure the correct PhoneGap JavaScript file was in the folder as well.

To make things work, with earlier versions of the PhoneGap framework, the BlackBerry and bada PhoneGap JavaScript libraries had different file names than on other platforms. This has supposedly been fixed, but you better check to make sure when building applications.

Web Content Folder Structure

As you will see in the chapters that follow, in some cases, some PhoneGap project developers have created nonstandard project folder structures for PhoneGap projects. For example, for a typical Symbian project (described in Chapter 7), the application’s web content files would normally be placed in the root of the project’s folder structure. The HTML, JavaScript, and CSS files should be placed right at the top of the folder hierarchy, so they can be easily accessed when working with the project. For some bizarre reason, the PhoneGap project places the files in a framework/www folder, complicating the project’s folder structure and making it more difficult to get to the application’s content files.

Application Requirements

One of the things you might bump into as you build cross-platform PhoneGap applications is the need to supply additional files in your application to accommodate the requirements for a particular OS version. For example, in the default PhoneGap project for iOS, you will find the following note:

<!-- If your application is targeting iOS BEFORE 4.0 you MUST
put json2.js from http://www.JSON.org/json2.js into your www
directory and include it here -->

Apparently a feature was added in PhoneGap 0.9 that requires the use of the JSON.stringify() function, so you will have to make sure you include the appropriate JSON library in your application. This further complicates a developer’s ability to use an application’s web content across multiple device platforms since an iOS application in this example might have additional lines of code needed to support this iOS-specific feature.

Application Navigation and UI

Mobile device platforms typically share some common elements but at the same time implement unique features or capabilities that help set them apart from competitors. The Android and iOS operating systems support many of the same features but sometimes implement them in a different way. Because of this, any mobile application designed to run on different mobile operating systems must take into consideration the differences between mobile platforms.

As you build PhoneGap applications for multiple mobile device platforms, you will need to implement different UI capabilities on different operating systems. On the Android and BlackBerry platforms, there’s a physical Escape button that can be pressed to return to a previous screen; on iOS, there will need to be a back button added to the bar at the top of the application screen.

Because of this, a PhoneGap application will need to either contain additional code that checks to see what platform it’s running on and update the UI accordingly or it will need to have different versions of the application’s web content depending on which OS the application is running on. Neither approach is easy. There are several books on mobile web development available that deal directly with these types of issues.

Application Icons

Each mobile platform and often different versions of a particular device OS have different requirements for application icons. A developer building PhoneGap applications for multiple device platforms will need to be prepared to create a suite of icons for their application that addresses the specific requirements for each target device platform and/or device OS. The PhoneGap project maintains a wiki page listing the icon requirements for the different supported operating systems at http://wiki.phonegap.com/w/page/36905973/Icons%20and%20Splash%20Screens.

Additionally, for some devices on some carriers (older BlackBerry devices, for example), the mobile carrier applies a specific theming to the OS in order to help distinguish themselves in the market. Any application icon designed for one of these devices will need to accommodate, as best as possible, rendering pleasantly within different themes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset