jQWidgets Mobile PhoneGap App with Geolocation for Android

In this tutorial you will learn how to create a simple mobile application using jQWidgets and PhoneGap that pinpoints an Android device's location and shows it in a Google Maps instance situated in jqxTabs. You may also be interested how to create the same app for BlackBerry 10, iOS or Windows Phone 8.

As a prerequisite, you need to install PhoneGap and set up your Android device. You can learn how to achieve this in our PhoneGap tutorial.

1. Create the App

Open Command Prompt and type:

C:\>phonegap create geoloc -n GeoLoc -i com.example.geoloc

to create a new application with the name GeoLoc.

2. Add the Geolocation API Plugin

PhoneGap implements device-level APIs as plugins. Before installing a plugin, however, there are two prerequisites:

2.1. Install Apache Cordova

PhoneGap is a distribution of Apache Cordova and works on its own. However, Apache Cordova is needed to install PhoneGap's API plugins. To install it, type:

C:\>npm install -g cordova

2.2. Install Git

You can download Git from http://git-scm.com/.

2.3. Install the Geolocation API Plugin

Now that you have successfully installed Apache Cordova and Git, you can install PhoneGap's Geolocation plugin. Type:

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

After the plugin's installation is complete, you will be able to access PhoneGap's Geolocation API, such as the geolocation.getCurrentPosition method, which will be showcased in this tutorial.

3. Modify the www folder

The next step is to modify the contents of the application's www folder - the index.html, config.xml and js\index.js files. We will also add all required jQuery and jQWidgets JavaScript and CSS files.

Here is the source code of index.html in our example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>A jQWidgets mobile application, which demonstrates PhoneGap's Geolocation API.
</title>
<link rel="Stylesheet" type="text/css" href="css/jqx.base.css" />
<style type="text/css">
.label
{
font-size: larger;
font-weight: bold;
}
</style>
<script type="text/javascript" src="phonegap.js"></script>
<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="js/jqxcore.js"></script>
<script type="text/javascript" src="js/jqxtabs.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&amp;sensor=true&amp;libraries=places"></script>
<script type="text/javascript">
$(document).ready(function () {
app.initialize();
});
</script>
</head>
<body>
<div class="app">
<div id="jqxTabs">
<ul style='margin-left: 20px;'>
<li>Location Map</li>
<li>Location Details</li>
</ul>
<div>
<div id="map" style="width: 350px; height: 320px;">
</div>
</div>
<div>
<div id="details">
<span class="label">Latitude: </span><span id="latitude"></span>;
<br />
<span class="label">Longitude: </span><span id="longitude"></span>.
</div>
</div>
</div>
</div>
</body>
</html>

There are references to the jQWidgets main CSS file (base.css), jQuery and the jQWidgets files required for jqxTabs. The file index.js contains the code of the app's functionality. The last script reference is to the Google Maps API. Note that you also need to add a reference to the file phonegap.js, through which you can access PhoneGap's API, but you do not have to add it to the scripts folder (www\js), beacause it will be automatically added while the app is being built.

Also note that the app's initialization code is called in a $(document).ready() function to make sure that all local and external scripts have been properly loaded before the application itself initializes.

And here is the contents of the file index.js:

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var app = {
// Application Constructor
initialize: function () {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function () {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function () {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function (id) {
// create jqxtabs.
$('#jqxTabs').jqxTabs({ width: 350, height: 350 });
navigator.geolocation.getCurrentPosition(this.onSuccess, this.onError);
},
// successfully determined position
onSuccess: function (position) {
$("body").append("Locaton set.<br />");
var lat = position.coords.latitude;
var lng = position.coords.longitude;
$("#latitude").text(lat);
$("#longitude").text(lng);
$("body").append("Loading map...<br />");
// initializes the map
var myLocation = new google.maps.LatLng(lat, lng);
map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: myLocation,
zoom: 15
});
$("body").append("Map loaded.");
},
// unsuccessfully determined position
onError: function (error) {
alert(error.message);
}
};

Everything must be executed within the deviceready event handler, which fires when PhoneGap has fully loaded. In the receivedEvent handler, we initialize the tabs and pinpoint the device's location using the method geolocation.getCurrentPosition. The callback function onSuccess is called when the location has been successfully determined. The callback function onError is called when there has been an error during location getting.

For an instance of Google Maps to load correctly, the file config.xml must also be modified by allowing external resources(in this case, the Google Maps API script) to be loaded in your mobile application. To achieve this, add the following to the config.xml file:

<access origin="*" />

This means that all external resources are allowed to be loaded in our mobile app. Here is the whole contents of config.xml:

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.geoloc" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
<name>GeoLoc</name>
<description>
A jQWidgets mobile application, which demonstrates PhoneGap's Geolocation API.
</description>
<author email="support@phonegap.com" href="http://phonegap.com">
jQWidgets Team
</author>
<feature name="http://api.phonegap.com/1.0/device" />
<preference name="permissions" value="none" />
<preference name="orientation" value="default" />
<preference name="target-device" value="universal" />
<preference name="fullscreen" value="true" />
<preference name="webviewbounce" value="true" />
<preference name="prerendered-icon" value="true" />
<preference name="stay-in-webview" value="false" />
<preference name="ios-statusbarstyle" value="black-opaque" />
<preference name="detect-data-types" value="true" />
<preference name="exit-on-suspend" value="false" />
<preference name="show-splash-screen-spinner" value="true" />
<preference name="auto-hide-splash-screen" value="true" />
<preference name="disable-cursor" value="false" />
<preference name="android-minSdkVersion" value="7" />
<preference name="android-installLocation" value="auto" />
<icon src="icon.png" />
<icon gap:density="ldpi" gap:platform="android" src="img/android_icon-36-ldpi.png" />
<icon gap:density="mdpi" gap:platform="android" src="img/android_icon-48-mdpi.png" />
<icon gap:density="hdpi" gap:platform="android" src="img/android_icon-72-hdpi.png" />
<icon gap:density="xhdpi" gap:platform="android" src="img/android_icon-96-xhdpi.png" />
<icon gap:platform="blackberry" src="res/icon/blackberry/icon-80.png" />
<icon gap:platform="blackberry" gap:state="hover" src="res/icon/blackberry/icon-80.png" />
<icon gap:platform="ios" height="57" src="res/icon/ios/icon-57.png" width="57" />
<icon gap:platform="ios" height="72" src="res/icon/ios/icon-72.png" width="72" />
<icon gap:platform="ios" height="114" src="res/icon/ios/icon-57-2x.png" width="114" />
<icon gap:platform="ios" height="144" src="res/icon/ios/icon-72-2x.png" width="144" />
<icon gap:platform="webos" src="res/icon/webos/icon-64.png" />
<icon gap:platform="winphone" src="res/icon/windows-phone/icon-48.png" />
<icon gap:platform="winphone" gap:role="background" src="res/icon/windows-phone/icon-173.png" />
<gap:splash gap:density="ldpi" gap:platform="android" src="img/android_screen-ldpi-portrait.png" />
<gap:splash gap:density="mdpi" gap:platform="android" src="img/android_screen-mdpi-portrait.png" />
<gap:splash gap:density="hdpi" gap:platform="android" src="img/android_screen-hdpi-portrait.png" />
<gap:splash gap:density="xhdpi" gap:platform="android" src="img/android_screen-xhdpi-portrait.png" />
<gap:splash gap:platform="blackberry" src="res/screen/blackberry/screen-225.png" />
<gap:splash gap:platform="ios" height="480" src="res/screen/ios/screen-iphone-portrait.png" width="320" />
<gap:splash gap:platform="ios" height="960" src="res/screen/ios/screen-iphone-portrait-2x.png" width="640" />
<gap:splash gap:platform="ios" height="1024" src="res/screen/ios/screen-ipad-portrait.png" width="768" />
<gap:splash gap:platform="ios" height="768" src="res/screen/ios/screen-ipad-landscape.png" width="1024" />
<gap:splash gap:platform="winphone" src="res/screen/windows-phone/screen-portrait.jpg" />
<access origin="http://127.0.0.1*" />
<access origin="*" />
</widget>

You can download the full source code of the example here.

4. Install and run the app

To install and run the GeoLoc application, connect your Android device to the computer and type:

C:\geoloc>phonegap run android

After a successful installation, the app is opened. The map of your location is shown in the first tab and the latitude and longitude in the second: