17. Events

The PhoneGap Events API provides an application with the ability to register event listeners for different events that occur on a supported smartphone device. The following is a list of the types of events supported by PhoneGap:

deviceready event

• Application status events

• Network events

• Button events

The subsequent sections in this chapter will describe each of these event types in detail.

Creating an Event Listener

To create an event listener in a PhoneGap application, execute the following code:

document.addEventListener("eventName", functionName,
  useCapture);

The parameters passed to addEventListener are as follows:

eventName: String value specifying the name of the event the listener will be listening for

functionName: The function that will be executed when the event fires

useCapture: Boolean value that specifies the scope of the event; since with PhoneGap we’re capturing system events rather than object events, you will most likely just use false for this parameter

The following sections will cover the different categories of events supported by PhoneGap.

To remove an event listener, simply call the JavaScript removeEventListener method.

deviceready Event

The deviceready event is a fundamental part of any PhoneGap application. The event is fired by PhoneGap to indicate that PhoneGap has completed initialization and that PhoneGap APIs are available to be used by the application. An application does not have to listen for this event; it can try to use a PhoneGap API any time it wants, but a well-behaved application will perform actions using PhoneGap APIs only after the deviceready API has fired.

Example 17-1 shows the typical implementation of an event listener that listens for the deviceready event.


Example 17-1

<!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() {
        //PhoneGap is ready, so go ahead and call PhoneGap APIs

      }

    </script>
  </head>
  <body onload="onBodyLoad()">
      <h1>Example 17-1</h1>
      <p>This is a sample PhoneGap application.</p>
      </body>
  </html>


Application Status Events

Most modern smartphones allow a user to switch between applications. As a running application transitions from the foreground to paused or to running in the background (depending on the smartphone platform), PhoneGap will fire the pause event. As a suspended application becomes active or an application running in the background transitions to the foreground, PhoneGap will fire the resume event.

Most smartphone platforms automatically switch an application into the background whenever another application is launched or when the user switches to another application. This allows the application to continue to process in the background, retrieving data from a server, for example. On iOS, Apple has decided that only certain applications have the right to run in the background, so your PhoneGap application will automatically be suspended whenever the user switches to another application.

The purpose of each event is to allow an application to perform whatever cleanup tasks are needed before an application makes the transition. As an example, a running application might want to close data or database connections and turn off any media files being played before suspending or transitioning to the background. A suspended or background application transitioning to the foreground may want to reestablish those network or database connections and restart any media files once the application is restarted.

Example 17-2 shows a sample application that implements pause and resume event listeners. It is a simple application that updates the screen every time one of the events fire. When the resume event fires, the application indicates how long the application was suspended or running in the background.


Example 17-2

<!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">

      //Start time variable
      var startTime, endTime;
      //pauseInfo page content variable
      var pi;
      //FirstTime variable
      var firstTime;

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

      function onDeviceReady() {
        pName = device.platform;
        if ((pName == "Android") || (pName == "3.0.0.100")) {
          firstTime = true;
        } else {
          firstTime = false;
        }
        //Add our Pause event listener
        document.addEventListener("pause", processPause, false);
        //Add our Resume event listener
        document.addEventListener("resume", processResume,
          false);
        //Get a handle to the pauseInfo page element
        pi = document.getElementById("pauseInfo");
      }

      function processPause() {
        //Clear the previous counter
        pi.innerHTML = "Application paused.";
        //Set startTime to the current date/time
        startTime = new Date();
      }

      function processResume() {
        //We want to skip the first time this fires
        if(firstTime == true) {
          //Clear our firstTime variable
          firstTime = false;
          pi.innerHTML = "Skipping first Resume.";
        } else {
          //Get the current date
          endTime = new Date();
          timeDiff = (endTime - startTime) / 1000;
          //Update the screen
          pi.innerHTML = "Paused for " + timeDiff + " seconds.";
        }
      }

   </script>
   </head>
   <body onload="onBodyLoad()">
     <h1>Pause Counter</h1>
     <p id="pauseInfo">Waiting for pause.</p>
   </body>
</html>


As I worked through this example, I learned something about these events that is not documented in the PhoneGap API documentation. An Android or BlackBerry application will fire the resume event as soon as the application starts. On iOS, the resume event is fired only when the application resumes from being suspended in the background. Because of this quirk, I had to create a Boolean variable called firstTime, which is used by the application to control whether the first firing of the resume event is ignored by the program. Also, because of a quirk in the Device API, for a BlackBerry device the application has to look for a number in the device name rather than the word BlackBerry.

pName = device.platform;
if ((pName == "Android") || (pName == "3.0.0.100")) {
  firstTime = true;
} else {
  firstTime = false;
}

The application registers a listener for the pause event using the following code:

document.addEventListener("pause", processPause, false);

This indicates that the processPause function should be called before the application transitions to the background. Within the function, the sample application simply updates the screen and stores the current timestamp in a variable. When the application runs on an Android device, you can see the screen update before the application moves to the background. On iOS, the screen update is not visible before the application suspends.

The sample application registers a listener for the resume event using the following code:

document.addEventListener("resume", processResume, false);

In this case, the processResume function is called when the application activates. The function first checks to see whether it should be skipping the first firing of the resume event by checking, and then resetting if necessary, the value of the firstTime variable. After that, it retrieves the stored timestamp indicating when the application suspended and uses the value to update the screen with the amount of time the application was suspended.

Figure 17-1 shows Example 17-2 running on an Android device.

Image

Figure 17-1 Example 17-2 running on an Android device

Network Status Events

Any mobile application that uses network-based resources should in some way monitor network availability and attempt to send or receive data across a network connection only when the network connection is available. An application can manually check the status of the device’s network connection using the PhoneGap Connection object (described in Chapter 14) before trying to utilize a network connection.

In other cases, an application will use the PhoneGap online and offline events to listen for changes in a network connection and adjust accordingly. Whenever the device loses its network connection, it will fire the offline event. When a connection becomes available again, the online event will fire. A network-savvy application will use these events to track the status of the connection and queue data for transmission only when the connection is available.

Example 17-3 shows a simple network tracker application that leverages the online and offline events to update the screen as the network comes and goes.


Example 17-3

<!DOCTYPE html>
<html>
  <head>
    <title>Example 17-3</title>
    <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="jquery.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() {
        //Add the online event listener
        document.addEventListener("online", isOnline, false);
        //Add the offline event listener
        document.addEventListener("offline", isOffline, false);
      }

      function isOnline() {
        var d = new Date();
        $(’#networkInfo’).prepend("Online: " +
          d.toLocaleString() + "<br />");
      }

      function isOffline() {
        var d = new Date();
        $(’#networkInfo’).prepend("Offline: " +
          d.toLocaleString() + "<br />");
      }
    </script>
  </head>
  <body onload="onBodyLoad()">
    <h1>Network Tracker</h1>
    <p id="networkInfo"></p>
  </body>
</html>


The application registers two event listeners, one for each of the network events we’re monitoring. The isOnline function is executed when the online event fires, and the isOffline function executes when the offline event fires.

To keep the application as simple as possible, the application uses jQuery to manage appending the network status updates to the top of the networkInfo paragraph tag:

$('#networkInfo').prepend("some_value<br />");

In this example, jQuery will locate the networkInfo page element and prepend the supplied text to the content that’s already there.

Figure 17-2 shows Example 17-3 running on an Android device.

Image

Figure 17-2 Example 17-3 running on an Android device

Button Events

Smartphones typical use physical buttons to allow users to interact more directly with the OS. iOS devices have only a single button (not counting the volume buttons), one that depending on how it’s used, either allows the user to return to the OS home screen or opens a list of paused applications. Android and BlackBerry devices, on the other hand, offer the user several buttons and are therefore simpler for more advanced users to operate.

To allow for PhoneGap applications to respond to these buttons, PhoneGap will fire the following events whenever the corresponding buttons are pressed:

backbutton: Fires when the user presses the back button on a device. This is typically the Escape button on Android and BlackBerry devices; iOS devices do not have a back button.

menubutton: Fires when the user presses the device’s menu button. iOS devices do not have a menu button.

searchbutton: Fires when the user presses the dedicated search button on an Android device.

startcallbutton: Fires when a BlackBerry user presses the dedicated start call button (located to the left of the BlackBerry menu button).

endcallbutton: Fires when a BlackBerry user presses the dedicated end call button (located to the right of the BlackBerry escape button).

volumedownbutton: Fires when a BlackBerry user presses the device’s volume down button.

volumeupbutton: Fires when a BlackBerry user presses the device’s volume up button.

To respond to these buttons, simply implement the appropriate event listeners and write the code that executes when the button is pressed.

As you can see from the list, many of the events are device specific; even though volume up and down buttons are available on most smartphones, event listeners are for some reason available only in BlackBerry PhoneGap applications. It’s rare in this day in age, with Android and iOS devices much more popular than BlackBerry, for BlackBerry to receive more attention than other platforms when it comes to framework features.

It’s important to note that when a PhoneGap application overrides one of these buttons by registering an event listener for the button, the default behavior of the button no longer applies while the listener is in place. For example, on most devices, pressing the escape button causes the application to return to a previous screen or exit the application if on the main screen. When the escape button is overridden (by creating a backbutton event listener) as shown in the following code, pressing the escape button causes only the code specified in the onBackButton function to execute.

document.addEventListener("backbutton", onBackButton, false);

If you want the application to exhibit default behavior when one of the overridden buttons is pressed, then you’ll have to implement the code to do so in your application. Using the previous code as an example, the onBackButton function might first do any cleanup required by the application and then call the navigator.app.exitApp() function, as shown here:

function onBackButton() {
  //Do whatever you need to do before closing the application
  ...

  //Then close the application
  navigator.app.exitApp();
};

This is very important for the escape button as shown but for the menu button as well. Unless your application doesn’t need a menu and you’re replacing the functionality behind the menu button with something specific to your application, Android and BlackBerry users are used to a menu appearing within an application when the menu button is pressed. If you want your own menu and override the menu button, your application is responsible for creating and displaying the appropriate menu when the button is pressed. The OS-specific menu will not appear when an overridden menu button is pressed.

The call buttons on BlackBerry cause additional problems for the PhoneGap developer. If you override the phone call buttons to use for other purposes in a game, for example, the user would have to leave the application in order to be able to press the phone button to bring up the phone application. This isn’t a big deal, but it’s important to pay attention to as you design your applications.

Example 17-4 shows a sample application that registers event listeners for each of the supported buttons. It doesn’t do much, but it does illustrate how to use these events.


Example 17-4

<!DOCTYPE html>
<html>
  <head>
    <title>Example 17-4</title>
    <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="jquery.js"></script>
    <script type="text/javascript" charset="utf-8"
      src="phonegap.js"></script>
    <script type="text/javascript" charset="utf-8">

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

      function onDeviceReady() {
        alert("onDeviceReady");

        //Check to see if we've registered any events
        var eventCount = 0;

        //What platform are we running on?
        pName = device.platform;

        if((pName == "Android") || (pName == "3.0.0.100")) {
          eventCount += 2;
          //Android & BlackBerry only events
          document.addEventListener("backbutton", onBackButton,
            false);
          document.addEventListener("menubutton", onMenuButton,
            false);
        }

        if(pName == "Android") {
          eventCount += 1;
          //Android only event
          document.addEventListener("searchbutton",
            onSearchButton, false);
        }

        if(pName == "3.0.0.100") {
          eventCount += 4;
          //BlackBerry only events
          document.addEventListener("startcallbutton",
            onStartCallButton, false);
          document.addEventListener("endcallbutton",
            onEndCallButton, false);
          document.addEventListener("volumedownbutton",
            onVolumeUpButton, false);
          document.addEventListener("volumeupbutton",
            onVolumeDownButton, false);
        }

        //did we register any event listeners?
        if(eventCount < 1) {
          //0, must be running on an iOS device
          alert("Must be running on an iOS device, No event
            listeners registered");
        } else {
          //Android or BlackBerry
          alert("Registered " + eventCount +
            " event listeners.");
        }
      }

      function onBackButton() {
        $('#buttonInfo').prepend("Back button pressed<br />");
        //Do button processing here
      };

      function onMenuButton() {
        $('#buttonInfo').prepend("Menu button pressed<br />");
        //Do button processing here
      };

      function onSearchButton() {
        $('#buttonInfo').prepend("Search button pressed<br />");
        //Do button processing here
      };

      function onStartCallButton() {
        $('#buttonInfo').prepend(
          "Start Call button pressed<br />");
        //Do button processing here
      };

      function onEndCallButton() {
        $('#buttonInfo').prepend(
          "end Call button pressed<br />");
        //Do button processing here
      };

      function onVolumeUpButton() {
        $('#buttonInfo').prepend(
          "Volume Up button pressed<br />");
        //Do button processing here
      };

      function onVolumeDownButton() {
        $('#buttonInfo').prepend(
          "Volume Down button pressed<br />");
        //Do button processing here
      };
    </script>
  </head>
  <body onload="onBodyLoad()">
    <h1>Button Tracker</h1>
    <p id="buttonInfo">Waiting for button press</p>
  </body>
</html>


In Example 17-4, the code checks to see which platform it’s running on before registering the events. While not necessary, there’s no reason to try to register an event that will never fire on the mobile device. Of course, since the PhoneGap device.name property returns the BlackBerry platform version rather than the word BlackBerry, the check for BlackBerry is a hack and would have to be updated for production use. As written, it checks only for a particular version of the platform and would not work correctly for other devices.

Figure 17-3 shows Example 17-4 running on an Android device.

Image

Figure 17-3 Example 17-4 running on an Android device

To restore a button to its default behavior, simply make a call to the JavaScript removeEventListener method, as shown here:

document.removeEventListener("backbutton", onBackButton, false);

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

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