Mobile Application Development:JavaScript Frameworks
上QQ阅读APP看书,第一时间看更新

Chapter 4. Cordova API in Action

In this chapter, we will start taking a deep dive in Apache Cordova API and see Apache Cordova API in action. You will learn how to work with the Cordova accelerometer, camera, compass, connection, contacts, device, geolocation, globalization, and the InAppBrowser APIs. This chapter as well as the next one illustrates a Cordova mobile app, Cordova Exhibition (which is developed using Apache Cordova and jQuery Mobile), that explores the main features of the Apache Cordova API in order to give you real-life usage examples of the Apache Cordova API in Android, iOS, and Windows Phone 8.

Exploring the Cordova Exhibition app

The Cordova Exhibition app aims at showing the main features of the Apache Cordova API. The demo shows practical examples of the following Apache Cordova API plugins:

  • Accelerometer
  • Camera
  • Compass
  • Connection
  • Contacts
  • Device
  • Geolocation
  • Globalization
  • InAppBrowser
  • Media, file, and capture
  • Notification
  • Storage

As well as Apache Cordova, the Cordova Exhibition app uses jQuery Mobile in order to create the app's user interface. The Cordova Exhibition app is supported on the following platforms:

  • Android
  • iOS
  • Windows Phone 8

The following screenshot shows the home page of the Cordova Exhibition app. The home page displays a list from which users can choose the feature they want to try.

The Cordova Exhibition home page

In this chapter and the next one, we will explore each feature individually in its own section.

The Cordova Exhibition app structure

In order to create the Cordova Exhibition app from the Command-line Interface (CLI), we run the following cordova create command:

> cordova create cordova-exhibition com.jsmobile.cordovaexhibition CordovaExhibition

In order to add Android, iOS, and Windows Phone 8 support from the CLI, we run the usual cordova platform add commands from the app directory as follows:

> cd cordova-exhibition
> cordova platform add android
> cordova platform add ios
> cordova platform add wp8

In order to add the different plugins to our Cordova Exhibition app, we use the usual cordova plugin add command (we will show the details of every plugin URL in its corresponding section).

To build and run the Cordova Exhibition app in your emulators and devices, you can follow the same steps that we used in Chapter 3, Apache Cordova Development Tools, to build and run the Sound Recorder application.

Tip

The complete source code of our Cordova Exhibition app with all of the three supported platforms can be downloaded from the course web page, or you can access the code directly from GitHub at https://github.com/hazems/cordova-exhibition.

Now, let's understand the structure of our Cordova Exhibition code. The following screenshot shows our Cordova Exhibition app's hierarchy:

The Cordova Exhibition application's structure

The www directory contains the following files and subdirectories:

  • css: This directory contains the custom app's Cascading Style Sheet (CSS).
  • img: This directory contains the custom app's images.
  • jqueryMobile: This directory contains the files of the jQuery Mobile framework and used plugins (the jQuery Mobile page params plugin and jQuery validation plugin).
  • js: This directory contains all the custom app's JavaScript code. It has the following two subdirectories:
    • api: This directory contains the app managers that interact with the Apache Cordova API in order to decouple the Cordova API from the app event handlers. This gives us the ability to change the implementation of our app API without changing our app event handlers and, at the same time, the ability to keep our app event handlers small.
    • vc: This directory contains the app view controllers that register and implement the event handlers of every page and their user interface components. Event handlers usually call the app managers (the app API) in order to access the device's native features and, finally, they display the results in the app page.

The js directory also includes common.js file, which has common utilities. Finally, under the www directory, the index.html file contains all the app pages. The index.html file will be illustrated in Finalizing the Cordova Exhibition app section in Chapter 5, Diving Deeper into the Cordova API.

Tip

It is important to note that not all Cordova features are supported across all platforms. In order to know the unsupported features, check out the last part in the Overview of Cordova API section in Chapter 1, Introduction to Apache Cordova.

Accelerometer

The accelerometer plugin provides access to the device's accelerometer in order to get the delta in movement relative to the current device's orientation in the x, y, and z axes.

In order to use the accelerometer in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion.git

Demo

In order to access the accelerometer demo, you need to click on the accelerometer list item. You will be introduced to the Accelerometer page. You can then click on the Start Watch Acceleration button in order to start watching the accelerometer. You will then be able to get the acceleration information in the x, y, and z axes, as shown in the following screenshot:

The Accelerometer page in action

You can click on the Stop Watch Acceleration button to stop watching the accelerometer at any time.

The HTML page

The following code snippet shows the "accelerometer" page:

<div data-role="page" id="accelerometer"> 
    <div data-role="header">
        <h1>Accelerometer</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <h1>Welcome to the Accelerometer Gallery</h1>
        <p>Click 'Start Watch Acceleration' button below to start watch acceleration.</p>
        <input type="button" id="startWatchAcceleration" value="Start Watch Acceleration"/>
        <input type="button" id="stopWatchAcceleration" value="Stop Watch Acceleration"/>
        <div id="acceleration">
        </div>
    </div>
</div>

As shown in the preceding "accelerometer" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes the following main elements:
    • "startWatchAcceleration": This button is used to start watching acceleration
    • "stopWatchAcceleration": This button is used to stop watching acceleration
    • "acceleration": This div is used to display the acceleration result

View controller

The following code snippet shows the page view controller JavaScript object, which includes the event handlers of the page (accelerometer.js):

(function() {
    var accelerometerManager = AccelerometerManager.getInstance();
    var watchID;

    $(document).on("pageinit", "#accelerometer", function(e) {
        e.preventDefault();

 $("#startWatchAcceleration").on("tap", function(e) {
 e.preventDefault();

 enableStartWatchAccelerationButton(false); 

 var callback = {};

 callback.onSuccess = onSuccess;
 callback.onError = onError;

 watchID = accelerometerManager.startWatchAcceleration(callback);
 }); 

 $("#stopWatchAcceleration").on("tap", function(e) {
 e.preventDefault();

 enableStartWatchAccelerationButton(true);

 accelerometerManager.stopWatchAcceleration(watchID);
 });

        initPage();
    });

    $(document).on("pagebeforehide", "#accelerometer", function(e) {        
        accelerometerManager.stopWatchAcceleration(watchID);
        enableStartWatchAccelerationButton(true);
    });    

    function initPage() {
        $("#stopWatchAcceleration").closest('.ui-btn').hide();
    }
 function onSuccess(acceleration) {
 $("#acceleration").html("Acceleration X: " + acceleration.x + "<br/>" +
 "Acceleration Y: " + acceleration.y + "<br/>" +
 "Acceleration Z: " + acceleration.z + "<br/>" +
 "Timestamp: " + acceleration.timestamp + "<br/>"); 
 }

 function onError() {
 $("#acceleration").html("An error occurs during watching acceleration.");
 } 

    function enableStartWatchAccelerationButton(enable) {
        if (enable) {
            $("#startWatchAcceleration").button("enable");
            $("#stopWatchAcceleration").closest('.ui-btn').hide(); 
        } else {
            $("#startWatchAcceleration").button("disable");
            $("#stopWatchAcceleration").closest('.ui-btn').show(); 
        }

        $("#startWatchAcceleration").button("refresh");
    }

})();

The "pageinit" event handler, which is called once in the page initialization, registers the "startWatchAcceleration" tap event handler. The "startWatchAcceleration" tap event handler does the following:

  • It disables the "startWatchAcceleration" button and shows the "stopWatchAcceleration" button by calling enableStartWatchAccelerationButton(false)
  • It starts watching the acceleration by calling accelerometerManager.startWatchAcceleration(callback), specifying a callback object that contains the following:
    • The onSuccess callback that will be called if the operation succeeds
    • The onError callback that will be called if the operation fails

The accelerometerManager.startWatchAcceleration(callback) function returns watchID, which will be used in order to stop watching the acceleration.

The "pageinit" event handler, which is called once in the page initialization, registers the "stopWatchAcceleration" tap event handler. The "stopWatchAcceleration" tap event handler does the following:

  • It hides the "stopWatchAcceleration" button and enables the "startWatchAcceleration" button by calling enableStartWatchAccelerationButton(true)
  • It stops watching the acceleration by calling accelerometerManager.stopWatchAcceleration(watchID) and specifying watchID, which we get from the accelerometerManager.startWatchAcceleration(callback) call

The "pageinit" event handler also calls initPage() in order to hide the "stopWatchAcceleration" button at the beginning. In onSuccess(acceleration), which will be called if accelerometerManager.startWatchAcceleration(callback) succeeds, the x, y, and z acceleration is shown with the current timestamp. In onError(), which will be called if accelerometerManager.startWatchAcceleration(callback) fails, an error message is displayed.

Finally, in order to stop watching acceleration before leaving the page, accelerometerManager.stopWatchAcceleration() is called in the "pagebeforehide" event, which will be called every time we transition away from the page.

API

The following code snippet shows the accelerometer manager JavaScript object that interacts with the Apache Cordova Accelerometer API (AccelerometerManager.js). Note that the manager files are always included in the index.html file before the view controller files so that the manager objects can be used by view controller objects:

var AccelerometerManager = (function () {     
  var instance;

  function createObject() {
      return {
 startWatchAcceleration: function (callback) {
 return navigator.accelerometer.watchAcceleration(callback.onSuccess,
callback.onError,
{frequency: 2000});
 },
 stopWatchAcceleration: function (watchID) { 
 if (watchID) {
 navigator.accelerometer.clearWatch(watchID);
 }
 }
      };
  };

  return {
    getInstance: function () {
      if (!instance) {
          instance = createObject();
      }

      return instance;
    }
  }; 
})();

As you can see, AccelerometerManager is a singleton object that has the following two methods, as highlighted in the preceding code:

  • startWatchAcceleration(callback): This uses the Cordova navigator.accelerometer.watchAcceleration() method to watch acceleration. The navigator.accelerometer.watchAcceleration(accelerometerSuccess, accelerometerError,[accelerometerOptions]) method has the following parameters:
    • accelerometerSuccess: This will be called if the operation succeeds with an object that contains the current acceleration along the x, y, and z axes and the timestamp. In AccelerometerManager, accelerometerSuccess is set to callback.onSuccess.
    • accelerometerError: This will be called if the operation fails. In AccelerometerManager, accelerometerError is set to callback.onError.
    • accelerometerOptions: This is an optional parameter that holds the accelerometer's configuration. It has a frequency attribute to specify how often to retrieve acceleration in milliseconds. In AccelerometerManager, the frequency parameter is set to 2000 milliseconds (note that this parameter is 10000 milliseconds by default).
  • stopWatchAcceleration(watchID): This uses the Cordova navigator.accelerometer.clearWatch() method to remove watching acceleration. navigator.accelerometer.clearWatch(watchID) has the following parameter:
    • watchID: This represents the ID returned by navigator.accelerometer.watchAcceleration().

We are now done with the Accelerometer functionality in our Cordova Exhibition app. However, before exploring the Camera functionality, note that the navigator.accelerometer object has also the method shown in the following table:

Camera

The camera plugin provides access to the device's camera in order to take pictures. This plugin also allows you to pick images from the device's image library.

In order to use the camera in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git

Demo

In order to access the camera demo, you need to click on the camera list item. You will be introduced to the Camera page. You can click on the Get Picture button in order to select whether to get a picture from the device's gallery or the device's camera. If you choose the Camera menu item, the default camera application of the device will be launched for you to capture a picture. If you choose the Gallery menu item, the device's gallery will be opened for you to pick an image. After getting the image from the camera or the gallery, you will be able to view the image on the Camera page, as shown in the following screenshot:

A selected image is shown on the camera page

The HTML page

The following code snippet shows the "camera" page:

<div data-role="page" id="camera">
    <div data-role="header">
        <h1>Camera</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <h1>Welcome to the Camera Gallery</h1>
        <p>Click 'Get Picture' button below</p>
        <div class="center-wrapper">
            <input type="button" id="getPicture" data-icon="camera" value="Get Picture" 
                   class="center-button" data-inline="true"/>
        </div>
        <br/>
        
        <div style="width: 100%;">
            <img id="imageView" style="width: 100%;"></img>
        </div>
        
        <div data-role="popup" id="pictureTypeSelection">
            <ul data-role="listview" data-inset="true" style="min-width:210px;">
                <li data-role="divider" data-theme="a">Get Picture From</li>
                <li><a id="pictureFromGallery" href="#">Gallery</a></li>
                <li><a id="pictureFromCamera" href="#">Camera</a></li>
            </ul>
        </div>
    </div>
</div>

As shown in the preceding "camera" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes the following main elements:
    • "getPicture": This button is used to get a picture
    • "imageView": This is used in order to display the selected or captured image
    • "pictureTypeSelection": This div element is a pop up that will be displayed to allow the user to select whether to get a picture from the camera or from the gallery

View controller

The following code snippet shows the page view controller JavaScript object that includes the action handlers of the page (camera.js):

(function() {
    var cameraManager = CameraManager.getInstance();

    $(document).on("pageinit", "#camera", function(e) {
        e.preventDefault();
        $("#imageView").hide();  

        $("#getPicture").on("tap", function(e) {
            e.preventDefault();

            $("#pictureTypeSelection").popup("open");
        });        

        $("#pictureFromGallery").on("tap", function(e) {
            e.preventDefault();
            $("#pictureTypeSelection").popup("close");

            getPhoto(true);
        });    

        $("#pictureFromCamera").on("tap", function(e) {
            e.preventDefault();
            $("#pictureTypeSelection").popup("close");

            getPhoto(false);
        });
    });

    function getPhoto(fromGallery) {
        var callback = {};

        callback.onSuccess = onSuccess;
        callback.onError = onError;

        cameraManager.getPicture(callback, fromGallery);
    }

    function onSuccess(fileURI) {
        $("#imageView").show();  
        $("#imageView").attr("src", fileURI);
    }

    function onError(message) {
        console.log("Camera capture error");
    }
})();

The "pageinit" event handler registers the following event handlers:

  • "getPicture" tap event handler: This opens the "pictureTypeSelection" pop up to allow the user to select the way to get a picture
  • "pictureFromGallery" tap event handler: This closes the currently opened "pictureTypeSelection" pop up and calls getPhoto(true) to pick a photo from the device's gallery
  • "pictureFromCamera" tap event handler: This closes the currently opened "pictureTypeSelection" pop up and calls getPhoto(false) to capture a photo using the device's camera

The getPhoto(fromGallery) method can get a photo (from the gallery or using the camera) by calling cameraManager.getPicture(callback, fromGallery) and specifying the following parameters:

  • The callback object that contains the following attributes:
    • onSuccess: This callback will be called if the operation succeeds. It receives the fileURI of the picked image as a parameter, this allows the callback to display the picked image in "imageView".
    • onError: This callback will be called if the operation fails.
  • The fromGallery parameter informs cameraManager.getPicture() to get the photo from the device's gallery if it is set to true, and if fromGallery is set to false, then it informs cameraManager.getPicture() to get the photo using the device's camera

API

The following code snippet shows the camera manager JavaScript object that interacts with the Apache Cordova Camera API (CameraManager.js):

var CameraManager = (function () {     
  var instance;

  function createObject() {
      var fileManager = FileManager.getInstance();      

      return {
 getPicture: function (callback, fromGallery) { 
 var source = Camera.PictureSourceType.CAMERA;

 if (fromGallery) {
 source = Camera.PictureSourceType.PHOTOLIBRARY; 
 }

 navigator.camera.getPicture(callback.onSuccess, 
 callback.onError, 
 { 
 quality: 80, 
 destinationType: Camera.DestinationType.FILE_URI, 
 sourceType: source,
 correctOrientation: true 
 });
 }
    };
  };

  return {
    getInstance: function () {
      if (!instance) {
          instance = createObject();
      }

      return instance;
    }
  }; 
})();

As you can see, CameraManager is a singleton object that has a single method as highlighted in the preceding code. The getPicture(callback, fromGallery) function uses the Cordova navigator.camera.getPicture() method to get a picture.

The navigator.camera.getPicture(cameraSuccess, cameraError, [cameraOptions]) function has the following parameters:

  • cameraSuccess: This callback will be called if the operation succeeds. It receives a parameter that represents a file URI, or a native URI, or a Base-64 encoded string based on the specified cameraOptions parameter. In CameraManager, cameraSuccess is set to callback.onSuccess.
  • cameraError: This parameter will be called if the operation fails. In CameraManager, cameraError is set to callback.onError. Note that CameraError receives a string that represents the error description.
  • cameraOptions: This is an optional parameter that holds the camera's configuration.

The cameraOptions parameter has many attributes. The attributes in the following table are used by our CameraManager object:

We are now done with the Camera functionality in our Cordova Exhibition app. However, before exploring the compass functionality, note that the navigator.camera.getPicture() function's CameraOptions parameter has also the attributes shown in the following table:

The navigator.camera object has also the method shown in the following table:

Compass

The compass plugin provides access to the device's compass in order to detect the direction (heading) that the device is pointed to (the compass measures the heading in degrees from 0 to 359.99, where 0 represents north). In order to use the compass in our Apache Cordova project, we need to use the following cordova plugin add command:

>cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-orientation.git

Demo

In order to access the compass demo, you need to click on the Compass list item. You will be introduced to the Compass page. Then, you can click on the Start Watch Heading button in order to start watching the compass heading. You will be able to get the heading value, as shown in the following screenshot:

The Compass page in action

You can click on the Stop Watch Heading button to stop watching the compass heading at any time.

The HTML page

The following code snippet shows the "compass" page:

<div data-role="page" id="compass">
    <div data-role="header">
        <h1>Compass</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <h1>Welcome to the Compass Gallery</h1>
        <p>Click 'Start Watch Heading' button below to start watch heading using your device's compass.</p>
        <input type="button" id="startWatchHeading" value="Start Watch Heading"/>
        <input type="button" id="stopWatchHeading" value="Stop Watch Heading"/><br/>
        
        <div id="compassHeading">
        </div>
    </div>
</div>

As shown in the preceding "compass" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes the following main elements:
    • "startWatchHeading": This button is used to start watching the compass heading
    • "stopWatchHeading": This button is used to stop watching the compass heading
    • "compassHeading": This div is used to display the compass heading result

View controller

The following code snippet shows the page view controller JavaScript object that includes the event handlers of the page (compass.js):

(function() {
    var compassManager = CompassManager.getInstance();
    var watchID;

    $(document).on("pageinit", "#compass", function(e) {
        e.preventDefault();

        $("#startWatchHeading").on("tap", function(e) {
            e.preventDefault();

            enableStartWatchHeadingButton(false); 

            var callback = {};

            callback.onSuccess = onSuccess;
            callback.onError = onError;

            watchID = compassManager.startWatchHeading(callback);
        });       

        $("#stopWatchHeading").on("tap", function(e) {
            e.preventDefault();

            enableStartWatchHeadingButton(true);

            compassManager.stopWatchHeading(watchID);
        });

        initPage();
    });
    $(document).on("pagebeforehide", "#compass", function(e) {
        compassManager.stopWatchHeading(watchID);
        enableStartWatchHeadingButton(true);
    });    

    function initPage() {
        $("#stopWatchHeading").closest('.ui-btn').hide();     
    }

    function onSuccess(heading) {
        $("#compassHeading").html("Heading: " + heading.magneticHeading);    
    }

    function onError(error) {
        $("#compassHeading").html("An error occurs during watch heading: " + error.code);
    }  

    function enableStartWatchHeadingButton(enable) {

        if (enable) {
            $("#startWatchHeading").button("enable");
            $("#stopWatchHeading").closest('.ui-btn').hide(); 
        } else {
            $("#startWatchHeading").button("disable");
            $("#stopWatchHeading").closest('.ui-btn').show(); 
        }

        $("#startWatchHeading").button("refresh");
    }

})();

The "pageinit" event handler registers the "startWatchHeading" tap event handler. The "startWatchHeading" tap event handler does the following:

  • It disables the "startWatchHeading" button and shows the "stopWatchHeading" button by calling enableStartWatchHeadingButton(false)
  • It starts to watch the heading by calling compassManager.startWatchHeading(callback) and specifying the callback object parameter, which contains the following attributes:
    • onSuccess: This callback will be called if the operation succeeds
    • onError: This callback will be called if the operation fails

The compassManager.startWatchHeading(callback) function returns watchID that we will be using in order to stop watching the compass heading.

The "pageinit" event handler also registers the "stopWatchHeading" tap event handler. The "stopWatchHeading" tap event handler does the following:

  • It hides the "stopWatchHeading" button and enables the "startWatchHeading" button by calling enableStartWatchHeadingButton(true)
  • It stops watching the heading by calling compassManager.stopWatchHeading(watchID) and specifying watchID parameter, which we get from the compassManager.startWatchHeading(callback) call

The "pageinit" event handler also calls initPage() in order to hide the "stopWatchHeading" button at the beginning.

In onSuccess(heading), which will be called if compassManager.startWatchHeading(callback) succeeds, heading.magneticHeading (which represents the heading in degrees) is displayed in the "compassHeading" div. In onError(), which will be called if compassManager.startWatchHeading(callback) fails, an error message is displayed in the "compassHeading" div. Finally, in order to make sure to stop watching the heading before leaving the page, compassManager.stopWatchHeading() is called in the "pagebeforehide" event.

API

The following code snippet shows the compass manager JavaScript object that interacts with the Apache Cordova Compass API (CompassManager.js):

var CompassManager = (function () {     
  var instance;

  function createObject() {
      return {
 startWatchHeading: function (callback) {
 return navigator.compass.watchHeading(callback.onSuccess, 
 callback.onError, 
 {frequency: 2000});
 },
 stopWatchHeading: function (watchID) { 
 if (watchID) {
 navigator.compass.clearWatch(watchID);
 }
 }
      };
  };

  return {
    getInstance: function () {
      if (!instance) {
          instance = createObject();
      }

      return instance;
    }
  }; 
})();

As you can see in the preceding code, CompassManager is a singleton object that has the following two methods, as highlighted in the code:

  • startWatchHeading(callback): This uses the Cordova navigator.compass.watchHeading() method to watch the compass heading. The navigator.compass.watchHeading(compassSuccess, compassError, [compassOptions]) method has the following parameters:
    • compassSuccess(heading): This callback will be called if the operation succeeds. It receives an object (heading) that contains the current heading's information as a parameter. In CompassManager, compassSuccess is set to callback.onSuccess.
    • compassError: This callback will be called if the operation fails. In CompassManager, compassError is set to callback.onError.
    • compassOptions: This is an optional parameter that holds the compass' configuration. It has a frequency attribute to specify how often to retrieve the compass heading in milliseconds. In CompassManager, the frequency parameter is set to 2000 milliseconds (note that this parameter is 100 milliseconds by default).
  • stopWatchHeading(watchID): This uses the Cordova navigator.compass.clearWatch() method to remove the compass heading. The navigator.compass.clearWatch(watchID) method has the following parameter:
    • watchID: This represents the ID returned by navigator.compass.watchHeading().

This compassOptions object (which is passed as the last parameter to navigator.compass.watchHeading method) has the attributes shown in the following table:

The heading object (which is passed as a parameter to the compassSuccess callback) has the attributes shown in the following table:

We are now done with the Compass functionality in our Cordova Exhibition app. However, before exploring the Connection functionality, note that the navigator.compass object has also the method shown in the following table:

Connection

The connection plugin provides information about the connection type of the device. In order to use the connection plugin in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-network-information.git

Demo

In order to access the connection demo, you can click on the Connection list item. You will be introduced to the Connection page. You can click on the Get Connection Type button in order to know the current connection type of your device, as shown in the following screenshot:

Getting the device's connection type

The HTML page

The following code snippet shows the "connection" page:

<div data-role="page" id="connection">
    <div data-role="header">
        <h1>Connection</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <h1>Welcome to the Connection Gallery</h1>
        <p>Click 'Get Connection Type' button below to know the connection type.</p>
        <input type="button" id="getConnectionType" value="Get Connection Type"/><br/>
        <div id="connectionType">
        </div>
    </div>
</div>

As shown in the preceding "connection" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes only one button, "getConnectionType", and one div, "connectionType", to display the connection type

View controller

The following code snippet shows the page view controller JavaScript object that includes the action handlers of the page (connection.js):

(function() {
    var connectionManager = ConnectionManager.getInstance();
    $(document).on("pageinit", "#connection", function(e) {
        e.preventDefault();

        $("#getConnectionType").on("tap", function(e) {
            e.preventDefault();

            $("#connectionType").html("Current Connection: " + connectionManager.getCurrentConnection());          
        }); 
    });
})();

The "pageinit" event handler registers the "getConnectionType" tap event handler. In the "getConnectionType" tap event handler, it displays the current connection of the device, which is retrieved by calling the connectionManager.getCurrentConnection() method.

API

The following code snippet shows the connection manager JavaScript object that interacts with the Apache Cordova Connection API (ConnectionManager.js):

var ConnectionManager = (function () {     
  var instance;
 
  function createObject() {
      return {
 getCurrentConnection: function () {
 var connectionType = navigator.connection.type;

 switch(connectionType) {
 case Connection.UNKNOWN:
 return "Unknown connection";
 case Connection.ETHERNET:
 return "Ethernet connection";
 case Connection.WIFI:
 return "WiFi connection";
 case Connection.CELL_2G:
 return "Cell 2G connection";
 case Connection.CELL_3G:
 return "Cell 3G connection";
 case Connection.CELL_4G:
 return "Cell 4G connection";
 case Connection.CELL:
 return "Cell generic connection";
 case Connection.NONE:
 return "No network connection";
 default:
 return "Un-recognized connection";
 }
 }
      };
  };
   return {
    getInstance: function () {
      if (!instance) {
          instance = createObject();
      }
 
      return instance;
    }
  }; 
})();

As you can see, ConnectionManager is a singleton object that has a single method as highlighted in the code. The getCurrentConnection() method uses the Cordova navigator.connection.type property in order to get the currently active network connection (Ethernet, Wi-Fi, cell 2G, cell 3G, and so on).

Contacts

The contacts plugin provides access to the device's contacts database in order to find and create contacts. In order to use the contacts plugin in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts.git

Demo

In order to access the contacts demo, you can click on the Contacts list item. You will be introduced to the Contacts page. You can search for contacts by typing in the search field (you have to type at least three characters), as shown in the following screenshot:

Searching for contacts

You can click on any of the filtered contacts, and you will be introduced to the Contact Details page in order to check the contact details, as shown in the following screenshot:

Viewing contact details

The HTML page

The following code snippet shows the "contacts" page:

<div data-role="page" id="contacts">
    <div data-role="header">
        <h1>Contacts</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <ul data-role="listview" id="contactList" data-filter="true" data-filter-placeholder="Enter 3+ chars to search ...">
        </ul>
    </div>
</div>

As shown in the preceding "contacts" page code snippet, it contains the following:

  • A page header that includes a back button.
  • Page content that includes a jQuery Mobile list view element ("contactList") that is defined by setting the data-role attribute to "listview". Setting the data-filter attribute to true tells jQuery Mobile to provide a search field for our list view. Finally, the placeholder attribute informs the user to enter at least three characters in order to search for contacts.

When the user clicks on any of the filtered contacts, the user will be introduced to the "contactDetails" page. The following code snippet shows the "contactDetails" page:

<div data-role="page" id="contactDetails">
    <div data-role="header">
        <h1>Contact Details</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <div id="contactInfo"></div>
    </div>
</div>

As shown in the preceding "contact details" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes a "contactInfo" div to display information on contact details

View controller

The following code snippet shows the contacts page view controller JavaScript object that includes the event handlers of the page (contacts.js):

(function() {
    var contactsManager = ContactsManager.getInstance();

    $(document).on("pageinit", "#contacts", function(e) {
        e.preventDefault();

        $("#contactList").on("filterablebeforefilter", function (e, data) {
            e.preventDefault();
    
            var filterText = data.input.val();

            if (filterText && filterText.length > 2) {
                var callback = {};

                callback.onSuccess = function (contacts) {
                    updateContactsList(contacts);
                };

                callback.onError = function (error) {       
                    $("#contactList").empty();
                    $("<li>Error displaying contacts</li>").appendTo("#contactList");
                };        

                contactsManager.getAllContacts(callback, filterText);
            }
        });
    });    

    function updateContactsList(contacts) {
        $("#contactList").empty();

        if (jQuery.isEmptyObject(contacts)) {
            $("<li>No Contacts Available</li>").appendTo("#contactList");
        } else {
            var i;

            //Display the top 50 elements
            for (i = 0; i < contacts.length || i < 50; ++i) {
                if (contacts[i]) {
                    $("<li><a href='#contactDetails?contact=" + encodeURIComponent(JSON.stringify(contacts[i])) + "'>" + 
                            contacts[i].name.formatted + "</a></li>").appendTo("#contactList");
                }
            }
        }

        $("#contactList").listview('refresh');        
    }    
})();

As highlighted in the preceding code snippet, the "pageinit" event handler registers the "filterablebeforefilter" event handler on the "contactList" list view in order to create our custom contacts filter. In the "filterablebeforefilter" event handler, the current filter text entered by the user is retrieved by calling data.input.val(). In order to minimize the search space, the filter text has to be at least three characters. If the filter text's length exceeds two characters, then a call to the contactsManager.getAllContacts(callback, filterText) method is performed in order to get all the contacts that match the entered filter text.

In order to call the contactsManager.getAllContacts(callback, filterText) method, we specified a callback object that contains two attributes: the onSuccess attribute (which represents a success callback) and the onError attribute (which represents a failure callback). The onSuccess callback receives the filtered contacts list and then calls the updateContactsList() method in order to update the current contacts list view with the new filtered contacts list. The onError callback just displays an error message to the user. The second parameter filterText represents the input filter text.

The updateContactsList(contacts) method clears the "contactList" list view, and if the contacts list (contacts) is not empty, contacts are appended to the "contactList" list view, and finally, the "contactList" list view is refreshed with new updates.

You might notice that every contact item in the list view is linked to the "contactDetails" page and passes the item's contact object as a parameter (after converting the contact object to an encoded JSON string).

Thanks to the jQuery Mobile page parameters plugin (which can be downloaded from https://github.com/jblas/jquery-mobile-plugins/tree/master/page-params) and its inclusion in the index.html file, we can pass parameters between pages easily using "#pageID?param1=value1&param2=value2 ...etc.

However, in our application, in the js/common.js file (which contains common utilities across all of the app pages and is included after the plugin, that is, the jqm.page.params.js file), we added a small utility over the plugin in order to retrieve page parameters at any event of the "to" page. In order to implement this, we create an event handler for the "pagebeforechange" event in order to get the passed parameter(s), as shown in the following code snippet:

$(document).bind("pagebeforechange", function(event, data) {
    $.mobile.pageData = (data && data.options && data.options.pageData) 
                      ? data.options.pageData : null;
});

By checking data.options.pageData, we can determine whether there are any passed parameters from the "from" page to the "to" page, thanks to the page parameters plugin. After getting the passed parameters, we set them in $.mobile.pageData, which can be accessible from any event in the "to" page. If there are no passed parameters, then $.mobile.pageData will be set to null.

The following code snippet shows contactDetails.js, which is the view controller of the "contactDetails" page:

(function() {    
    $(document).on("pageshow", "#contactDetails", function(e) {
        e.preventDefault();

        var contactDetailsParam = $.mobile.pageData.contact || null;
        var contactDetails = JSON.parse(decodeURIComponent(contactDetailsParam));        
        var i;
        var numbers = "";

        if (contactDetails.phoneNumbers) {
            for (i = 0; i < contactDetails.phoneNumbers.length; ++i) {
                numbers = "<a href='tel:" + contactDetails.phoneNumbers[i].value + "'>" +
                          contactDetails.phoneNumbers[i].value + "</a><br/>";
            }
        } else {
            numbers = "NA<br/>";
        }

        $("#contactInfo").html("<p>" +
                "Name: <strong>" + contactDetails.name.formatted + "</strong><br/><br/>" +
                "Phone(s): " + "<br/>" + 
                numbers +
                "</p>");
    });
})();

In the "pageshow" event handler of the "contactDetails" page, contactDetails is retrieved using $.mobile.pageData.contact and then decoded and parsed to be converted to a JavaScript object. Finally, the contact names and numbers are acquired from contactDetails using contactDetails.name.formatted and contactDetails.phoneNumbers and are displayed in the "contactInfo" div.

Tip

The jQuery Mobile "pageshow" event is triggered on the "to" page after the transition completes.

API

The following code snippet shows the contacts manager JavaScript object that wraps the Apache Cordova Contacts API (ContactsManager.js):

var ContactsManager = (function () {     
    var instance;

    function createObject() {
        return {
 getAllContacts: function (callback, filterText) {
 var options = new ContactFindOptions();

 options.filter = filterText || "";
 options.multiple = true;

 var fields = ["id", "name", "phoneNumbers"];

 navigator.contacts.find(callback.onSuccess, callback.onError, fields, options);
 }
        };
    };

    return {
        getInstance: function () {
            if (!instance) {
                instance = createObject();
            }

            return instance;
        }
    }; 
})();

As you can see, ContactsManager is a singleton object that has a single method as highlighted in the preceding code. The getAllContacts(callback, filterText) method uses the Cordova navigator.contacts.find() method to retrieve contacts.

The navigator.contacts.find(contactSuccess, contactError, contactFields, contactFindOptions) method has the following parameters:

  • contactSuccess: This callback will be called if the operation succeeds. It receives the retrieved contacts array as a parameter. In ContactsManager, contactSuccess is set to callback.onSuccess.
  • contactError: This callback will be called if the operation fails. In ContactsManager, contactError is set to callback.onError.
  • contactFields: This object specifies the fields of every contact object in the returned result of navigator.contacts.find(). In ContactsManager, we specified the ["id", "name", "phoneNumbers"] contact fields.
  • contactFindOptions: This is an optional parameter that is used to filter contacts.

The contactFindOptions parameter has the attributes shown in the following table:

We are now done with the Contacts functionality in the Cordova Exhibition app. However, before exploring the device's API functionality, note that the navigator.contacts.find() method's contactFields parameter can have one or more attribute(s) from the Contact object, whose attributes are specified in the following table:

The ContactName object has the attributes shown in the following table:

The ContactField object has the attributes shown in the following table:

The ContactAddress object has the attributes shown in the following table:

The ContactOrganization object has the attributes shown in the following table:

The navigator.contacts object has also the method shown in the following table:

Device

The device plugin defines a global device object that describes the device's hardware and software. It is very important to note that the device object is available after the "deviceready" event occurs. In order to use the device plugin in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

Demo

In order to access the device demo, you can click on the Device list item. You will be introduced to the Device page. You can click on the Get Device Info button in order to get your device information, as shown in the following screenshot:

Getting device information

The HTML page

The following code snippet shows the "device" page:

<div data-role="page" id="device">
    <div data-role="header">
        <h1>Device</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <h1>Welcome to the Device Gallery</h1>
        <p>Click 'Get Device Info' button below to get the device information.</p>
        <input type="button" id="getDeviceInfo" value="Get Device Info"/><br/>
        
        <div id="deviceInfo">
        </div>
    </div>
</div>

As shown in the preceding "device" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes a "getDeviceInfo" button to get the device information and a "deviceInfo" div in order to display device information

View controller

The following code snippet shows the "device" page view controller JavaScript object that includes the event handlers of the page (device.js):

(function() {
    var deviceManager = DeviceManager.getInstance();

    $(document).on("pageinit", "#device", function(e) {
        e.preventDefault();

        $("#getDeviceInfo").on("tap", function(e) {
            e.preventDefault();

            $("#deviceInfo").html(deviceManager.getDeviceInfo());
        }); 
    });
})();

As shown in the preceding code snippet, the "pageinit" event handler registers the "tap" event handler on the "getDeviceInfo" button. In the "tap" event handler of the "getDeviceInfo" button, the device information is displayed in the "deviceInfo" div and retrieved by calling the deviceManager.getDeviceInfo() method.

API

The following code snippet shows the device manager JavaScript object that uses the Apache Cordova device object (DeviceManager.js):

var DeviceManager = (function () {     
    var instance;

    function createObject() {
        return {
 getDeviceInfo: function () {
 return "Device Model: " + device.model + "<br />" +
 "Device Cordova: " + device.cordova + "<br />" +
 "Device Platform: " + device.platform + "<br />" +
 "Device UUID: " + device.uuid + "<br />" +
 "Device Version: " + device.version + "<br />";
 }
        };
    };

    return {
        getInstance: function () {
            if (!instance) {
                instance = createObject();
            }

            return instance;
        }
    }; 
})();

The DeviceManager object is a singleton object that has a single method as highlighted in the preceding code. The getDeviceInfo() function uses the Cordova device object to retrieve the device information.

The DeviceManager object uses the attributes of the device object, as shown in the following table:

Geolocation

The geolocation plugin provides information about the device's current location that can be retrieved via Global Positioning System (GPS), network signals, and GSM/CDMA cell IDs. Note that there is no guarantee that the API returns the device's actual location.

In order to use the geolocation plugin in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git

Demo

In order to access the geolocation demo, you can click on the Geolocation list item. You will be introduced to the Geolocation page. You can click on the Get Current Position button in order to get your device's current position, as shown in the following screenshot:

Getting the device's position

The HTML page

The following code snippet shows the "geolocation" page:

<div data-role="page" id="geolocation">
    <div data-role="header">
        <h1>Geolocation</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <h1>Welcome to the Geolocation Gallery</h1>
        <p>Click 'Get Current Position' button below to know where you are.</p>
        <input type="button" id="getCurrentPosition" value="Get Current Position"/><br/>
    
        <div id="position">
        </div>
    </div>
</div>

As shown in the preceding "geolocation" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes a "getCurrentPosition" button to get the device's current position and a "position" div in order to display it

View controller

The following code snippet shows the "geolocation" page view controller JavaScript object that includes the event handlers of the page (geolocation.js):

(function() {
    var geolocationManager = GeolocationManager.getInstance();

    $(document).on("pageinit", "#geolocation", function(e) {
        e.preventDefault();

        $("#getCurrentPosition").on("tap", function(e) {
            e.preventDefault();

            var callback = {};

            callback.onSuccess = onSuccess;
            callback.onError = onError;

            geolocationManager.getCurrentPosition(callback);
        });
    });

    function onSuccess(position) {
        console.log("position is retrieved successfully");

        $("#position").html("Latitude: "  + position.coords.latitude + "<br />" +
                            "Longitude: " + position.coords.longitude);    
    }

    function onError(error) {
        $("#position").html("Error code: " + error.code + ", message: " + error.message);
    }     
})();

As shown in the preceding code snippet, the "pageinit" event handler registers the "tap" event handler on the "getCurrentPosition" button. In the "tap" event handler of the "getCurrentPosition" button, the device's current position is retrieved by calling the geolocationManager.getCurrentPosition() method.

The geolocationManager.getCurrentPosition(callback) method takes a callback object as a parameter that contains two attributes (onSuccess and onError) that refer to the following callbacks:

  • onSuccess(position): This callback will be called if the operation succeeds. It receives a position object (which represents the device's current position) as a parameter. Inside the success callback, the position's longitude and latitude information are displayed in the "position" div.
  • onError(error): This callback will be called if the operation fails. It receives an error object that contains the error information (error code and error message) as a parameter.

API

The following code snippet shows the geolocation manager JavaScript object that interacts with the Apache Cordova geolocation API (GeolocationManager.js):

var GeolocationManager = (function () {     
    var instance;

    function createObject() {
        return {
            getCurrentPosition: function (callback) {
                navigator.geolocation.getCurrentPosition(callback.onSuccess, 
callback.onError, 
                                                         {
timeout: 15000, 
enableHighAccuracy: true 
                                                         });
            }
        };
    };

    return {
        getInstance: function () {
            if (!instance) {
                instance = createObject();
            }

            return instance;
        }
    }; 
})(); 

As shown, GeolocationManager is a singleton object that has a single method, getCurrentPosition(callback), as highlighted in the preceding code. This method uses the Cordova navigator.geolocation.getCurrentPosition() method in order to retrieve the device's current position.

The navigator.geolocation.getCurrentPosition(geolocationSuccess, [geolocationError], [geolocationOptions]) method has the following parameters:

  • geolocationSuccess: This represents the successful callback that will be called when the operation succeeds. It receives a Position object that holds the current position information as a parameter. In GeolocationManager, geolocationSuccess is set to callback.onSuccess.
  • geolocationError: This is an optional parameter that represents the error callback that will be called when the operation fails. It receives a PositionError object that holds the error information (the code that represents the error code and the message that represents the error message) as a parameter. In GeolocationManager, geolocationError is set to callback.onError.
  • geolocationOptions: This is an optional parameter that represents the geolocation options.

The geolocationOptions object has the attributes shown in the following table:

The Position object has the attributes shown in the following table:

The Coordinates object has the attributes shown in the following table:

Note that navigator.geolocation has the following two more methods:

  • watchPosition(geolocationSuccess, [geolocationError], [geolocationOptions]): This can watch for changes in the device's current position. It returns a watch ID that should be used with clearWatch() to stop watching for changes in position.
  • clearWatch(watchID): This can stop watching the changes to the device's position referenced by the watchID parameter.

We are now done with the geolocation functionality in the Cordova Exhibition app.

Globalization

The globalization plugin can be used in order to get the user locale and language and to perform operations specific to the user's locale and time zone.

In order to use the globalization plugin in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-globalization.git

Demo

In order to access the globalization demo, you can click on the Globalization list item. You will be introduced to the Globalization page. You can click on the Get Locale Name button in order to get the user's locale name or the Get Preferred Language button in order to get the user's preferred language, as shown in the following screenshot:

Getting the user's locale and preferred language

The HTML page

The following code snippet shows the "globalization" page:

<div data-role="page" id="globalization">
    <div data-role="header">
        <h1>Globalization</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <h1>Welcome to the Globalization Gallery</h1>
        <p>Click the buttons below to explore globalization.</p>
        <input type="button" id="getLocaleName" value="Get Locale Name"/>
        <input type="button" id="getPreferredLanguage" value="Get Preferred Language"/><br/>
                            
        <div id="globInfo">
        </div>
    </div>
</div>

As shown in the preceding "globalization" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes a "getLocaleName" button to get the user locale, a "getPreferredLanguage" button to get the user preferred language, and a "globInfo" div in order to display the results

View controller

The following code snippet shows the "globalization" page view controller JavaScript object that includes the event handlers of the page (globalization.js):

(function() {
    var globalizationManager = GlobalizationManager.getInstance();

    $(document).on("pageinit", "#globalization", function(e) {
        e.preventDefault();

        $("#getLocaleName").on("tap", function(e) {
            e.preventDefault();

            var callback = {};

            callback.onSuccess = handleLocaleSuccess;
            callback.onError = handleLocaleError;

            globalizationManager.getLocaleName(callback);
        }); 

        $("#getPreferredLanguage").on("tap", function(e) {
            e.preventDefault();

            var callback = {};

            callback.onSuccess = handleLangSuccess;
            callback.onError = handleLangError;

            globalizationManager.getPreferredLanguage(callback);
        });
    });

    function handleLocaleSuccess(locale) {            
        $("#globInfo").html("Locale Name: " + locale.value + "<br/>");
    }

    function handleLocaleError() {
        $("#globInfo").html("Unable to get Locale name<br/>");
    }

    function handleLangSuccess(language) {
        $("#globInfo").html("Preferred language name: " + language.value + "<br/");
    }

    function handleLangError() {
        $("#globInfo").html("Unable to get preferred language name<br/>");
    }    
})();

As shown in the preceding code snippet, the "pageinit" event handler registers the "tap" event handler on the "getLocaleName" button. In the "tap" event handler of the "getLocaleName" button, the user locale is retrieved by calling the globalizationManager.getLocaleName() method.

The globalizationManager.getLocaleName(callback) method takes a callback object as a parameter that contains two attributes (onSuccess and onError) that refer to the following callbacks in order:

  • handleLocaleSuccess(locale): This callback will be called if the operation succeeds; it receives a locale object that represents the user's current locale as a parameter. In the success callback, the locale value is displayed in the "globInfo" div.
  • handleLocaleError(): This callback will be called if the operation fails.

The "pageinit" event handler also registers the "tap" event handler on the "getPreferredLanguage" button. In the "tap" event handler of the "getPreferredLanguage" button, the user's preferred language is retrieved by calling the globalizationManager.getPreferredLanguage() method.

The globalizationManager.getPreferredLanguage(callback) method takes a callback object as a parameter that contains two attributes (onSuccess and onError) that refer to the following callbacks in order:

  • handleLangSuccess(language): This callback will be called if the operation succeeds; it receives a language object that represents the user's preferred language as a parameter. In the success callback, the preferred language value is displayed in the "globInfo" div.
  • handleLangError(): This callback will be called if the operation fails.

API

The following code snippet shows the globalization manager JavaScript object that interacts with the Apache Cordova Globalization API (GlobalizationManager.js):

var GlobalizationManager = (function () {     
    var instance;

    function createObject() {
        return {
            getLocaleName: function (callback) {
                navigator.globalization.getLocaleName(callback.onSuccess, callback.onError);
            },
            getPreferredLanguage: function (callback) {    
                navigator.globalization.getPreferredLanguage(callback.onSuccess, 
callback.onError);
            }
        };
    };

    return {
        getInstance: function () {
            if (!instance) {
                instance = createObject();
            }

            return instance;
        }
    }; 
})();

As shown, GlobalizationManager is a singleton object that has two methods as highlighted in the preceding code. The first one is getLocaleName(callback), which uses the Cordova navigator.globalization.getLocaleName() method in order to retrieve the user's current locale.

The navigator.globalization.getLocaleName(successCallback, errorCallback) method has the following parameters:

  • successCallback: This represents the successful callback that will be called when the operation succeeds. It receives a locale object that holds the current locale information as a parameter. In GlobalizationManager, sucessCallback is set to callback.onSuccess.
  • errorCallback: This represents the error callback that will be called when the operation fails. It receives a GlobalizationError object that holds the error information (the code that represents the error code and the message that represents the error message) as a parameter. In GlobalizationManager, errorCallback is set to callback.onError.

The second method is getPreferredLanguage(callback) that uses the Cordova navigator.globalization.getPreferredLanguage() method in order to retrieve the user's preferred language.

The navigator.globalization.getPreferredLanguage(successCallback, errorCallback) method has the following parameters:

  • successCallback: This represents the successful callback that will be called when the operation succeeds. It receives a language object that holds the user's preferred language information as a parameter. In GlobalizationManager, sucessCallback is set to callback.onSuccess.
  • errorCallback: This represents the error callback that will be called when the operation fails. It receives a GlobalizationError object that holds the error information (the code that represents the error code and the message that represents the error message). In GlobalizationManager, errorCallback is set to callback.onError.

    Tip

    The navigator.globalization object has more methods that you can check out in the Apache Cordova documentation at https://github.com/apache/cordova-plugin-globalization/blob/master/doc/index.md.

We are now done with the globalization functionality in the Cordova Exhibition app.

InAppBrowser

The InAppBrowser plugin can provide a web browser view that is displayed when calling the window.open() function or when opening a link formed as <a target="_blank">.

In order to use the InAppBrowser plugin in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git

Demo

In order to access the InAppBrowser demo, you can click on the InAppBrowser list item. You will be introduced to the InAppBrowser page. As shown in the following screenshot, you can click on the Open and Close web page button in order to open the http://www.google.com/ web page using InAppBrowser. Note that the opened web page will be closed after 10 seconds.

Opening an external page using InAppBrowser

The HTML page

The following code snippet shows the "inAppBrowser" page:

<div data-role="page" id="inAppBrowser">
    <div data-role="header">
        <h1>InAppBrowser</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <h1>Welcome to the InAppBrowser Gallery</h1>
        <p>Click the button below to open the inAppBrowser which will close after 10 seconds.</p>
        
        <input type="button" id="openGoogleSearchPage" value="Open and Close web page"/>
    </div>
</div>

As shown in the preceding "inAppBrowser" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes a "openGoogleSearchPage" button to open a web page (http://www.google.com/) and close it after 10 seconds

View controller

The following code snippet shows the InAppBrowser page view controller JavaScript object that includes the event handlers of the page (inAppBrowser.js):

(function() {
    var inAppBrowserManager = InAppBrowserManager.getInstance();

    $(document).on("pageinit", "#inAppBrowser", function(e) {
        e.preventDefault();

        $("#openGoogleSearchPage").on("tap", function(e) {
            e.preventDefault();

            var windowRef = inAppBrowserManager.openWindow("http://www.google.com");    

            //Close the window after 10 seconds...
            window.setTimeout(function() {
                console.log("It is over. Time to close the window...");
                inAppBrowserManager.closeWindow(windowRef);
            }, 10000);
        });         
    });    
})(); 

As shown in the preceding code snippet, the "pageinit" event handler registers the "tap" event handler on the "openGoogleSearchPage" button. In the "tap" event handler of the "openGoogleSearchPage" button, a new window is opened by calling the inAppBrowserManager.openWindow() method that specifies the URL to open "http://www.google.com/".

When the window.setTimeout() function is executed after 10 seconds using windowRef, which is returned from the inAppBrowserManager.openWindow() method, the opened window is closed by calling inAppBrowserManager.closeWindow(windowRef).

API

The following code snippet shows InAppBrowserManager.js:

var InAppBrowserManager = (function () {     
    var instance;

    function createObject() {
        return {
 openWindow: function (url) {
 var windowRef = window.open(url, '_blank', 'location=no');

 return windowRef; 
 },
 closeWindow: function (windowRef) { 
 if (windowRef) {
 windowRef.close();
 }
 }
        };
    };

    return {
        getInstance: function () {
            if (!instance) {
                instance = createObject();
            }

            return instance;
        }
    }; 
})();

As shown in the preceding code, InAppBrowserManager is a singleton object that has two simple methods, as highlighted in the preceding code:

  • openWindow(url): This is used to open a new window by calling the window.open() method. The window.open(url, target, options) method has the following parameters:
    • url: This represents the URL to be loaded.
    • target: This represents the target in which to load the URL. It can be _self (default value), which means that the URL opens in the Cordova WebView if it is in the white list; otherwise, it opens in InAppBrowser or _blank (a specified value by InAppBrowserManager). This _blank means that the URL opens in InAppBrowser or _system, which means that the URL opens in the web browser of the system.
    • options: This represents the options for the InAppBrowser. It is a string that must not have any empty spaces, and it consists of key/value pairs, where key represents a feature's name and value represents a feature's value. The separator between any two features in the options string must be a comma. A location string is one of the available features that can be used in the options string. It specifies whether the location bar will be shown or not. In InAppBrowserManager, the location feature is set to no to hide the location bar, as it is by default set to yes.

window.open() returns a reference to the InAppBrowser window. This can be used to close the opened window later.

  • closeWindow(windowRef): This is used to close an opened window by calling the close() method of the reference to the InAppBrowser window (the windowRef object).

Tip

InAppBrowser has more methods that you can check out in the Apache Cordova documentation at https://github.com/apache/cordova-plugin-inappbrowser/blob/master/doc/index.md.

We are now done with the InAppBrowser functionality in the Cordova Exhibition app.

Summary

In this chapter, we covered a lot of information regarding the Apache Cordova API. You saw the Apache Cordova API in action by exploring some features of the Cordova Exhibition app. You learned how to work with the Cordova accelerometer, camera, compass, connection, contacts, device, geolocation, globalization, and InAppBrowser APIs. In the next chapter, we will continue our look at the Apache Cordova API by exploring the remaining features of the Cordova Exhibition app.