Adding Cordova APIs to Android via CLI: Geolocation, Globalization, Notification


In this article, we are in part 3 of exploring the Cordova APIs, which started in https://iphonedevlog.wordpress.com/2014/01/31/adding-cordova-apis-to-android-via-cli-accelerometer-and-camera/ Refer to that article to set up your Cordova PhoneGap project files. You’ll need to follow the “Set Up the Android Project” section through step 9 inclusive. On this page, we’ll explore the Geolocation, Globalization, Notification APIs from the perspective of getting our feet wet.

You can continue the code by copying/pasting from this page into that project’s index.html page, or start a new page and link to it via a button on that page to access it (which is what I did). If you are starting a new page, copy/paste this HTML skeleton into a page3.html page to follow along:

<!-- ********************* HMTL5 Skeleton begin *********************** -->
<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8" />
 <meta name="format-detection" content="telephone=no" />
 <!-- WARNING from Cordova: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
 <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<title>Cordova APIs</title>
<style type="text/css">
 .buttonClass {
 border-radius:8px; background-color:#fff;
 border:#878787 solid 1px; padding:1em .5em;margin:.5em;
 width: 46%;
 font-family: "Helvetica"; color: #000; font-size:1em; text-align:center;
 -webkit-appearance:none;
 } 
 .segment {
 display:block; border-radius:8px; background-color:#eee;
 border:#878787 solid 1px; padding:1em; margin:.5em;
 font-family: "Helvetica"; color: #000; font-size:1.3em; text-align:left;
 -webkit-appearance:none; 
 }
 @media screen and (max-width:700px) {
 .buttonClass { width: 100%;}
 }
 </style>
 <script type="text/javascript" src="cordova.js"></script> 
</head> 
<body>
</body> 
</html> 
<!-- ********************* HMTL5 Skeleton end *********************** -->

Geolocation

An application programming interface (API) to indicate the device’s location on earth. We’ll follow this page from the docs to set it up: http://docs.phonegap.com/en/3.3.0/cordova_geolocation_geolocation.md.html#Geolocation Please review the page to gain an understanding of the steps we’ll be following.

1. Set the project’s directory in Terminal (type cd in the terminal, drag the folder to the terminal, click on the terminal to select it, hit Enter) and download the plugin:

cordova plugin add org.apache.cordova.geolocation

2. Use the ls (list) command to make sure it’s downloaded:

cordova plugin ls

3. Open CordovaAPI/platforms/android/res/xml/config.xml (NOT the config.xml in your www root folder!) in a text file and add the following to just above </widget> and save:

<feature name="Geolocation">
 <param name="android-package" value="org.apache.cordova.geolocation.GeoBroker" />
</feature>

5. In platforms/android/AndroidManifest.xml make sure these lines are there, or add them:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

7. In index.html (or page3.html), remove everything between the <body></body> tags and replace with the following.

<!-- ********************* Read Geolocation begin *********************** -->
<div class="segment">
 <h2>Geolocation</h2>
<p style="font-style:italic;">"Heading:" 360 or 0 = North. 90 = East. 180 = South. 270 = West.</p>
<p id="geolocation"></p>
<input type="button" class="buttonClass" onclick="clearGeoWatch();" value="Stop Geolocation">
<input type="button" class="buttonClass" onclick="startGeolocation();" value="Start Geolocation">
<br><br>
 <input type="button" class="buttonClass" onclick='window.location="https://iphonedevlog.wordpress.com/2014/02/20/adding-cordova-apis-to-android-via-cli-geolocation-globalization-notification/"' value="View Code On iPhoneDevLog">
</div>
<script type="text/javascript" charset="utf-8">
// Wait for device API libraries to load
 document.addEventListener("deviceready", onDeviceReady, false);
var watchGeoID = null;
// device APIs are available
 function onDeviceReady() {
 startGeolocation();
 }

 // Throw an error if no update is received every 30 seconds
 // show notice
 function startGeolocation() {
 var element = document.getElementById('geolocation');
 element.innerHTML = 'Finding geolocation every 30 seconds...'
 var options = { enableHighAccuracy: true, timeout: 30000 };
 watchGeoID = navigator.geolocation.watchPosition(onSuccess, onError, options);
 }
// onSuccess Geolocation, show information
 function onSuccess(position) {
 var element = document.getElementById('geolocation');
 element.innerHTML = 
'<strong>Latitude:</strong> ' + position.coords.latitude + '<br />' +
'<strong>Longitude: </strong> ' + position.coords.longitude + ' <br />' +
'<strong>Altitude</strong> (in meters): ' + position.coords.altitude + ' <br />' +
'<strong>Accuracy</strong> (in meters): ' + position.coords.accuracy + ' <br />' +
'<strong>Altitude Accuracy:</strong> ' + position.coords.altitudeAccuracy + ' <br />' +
'<strong>Heading</strong> (direction of travel): ' + position.coords.heading + ' <br />' +
'<strong>Speed</strong> (meters per second): ' + position.coords.speed + ' <br />' +
'<strong>Timestamp:</strong> ' + position.timestamp + ' <br />';
 }
// stop the function and show notice
function clearGeoWatch() {
 var element = document.getElementById('geolocation');
 element.innerHTML = '<span style="color:red">Geolocation turned off.</span>';
 if (watchGeoID) {
 navigator.geolocation.clearWatch(watchGeoID);
 watchGeoID = null;
 }
 }

 // onError Callback receives a PositionError object
 function onError(error) {
 // alert('code: ' + error.code + '\n' +
 // 'message: ' + error.message + '\n');
 var element = document.getElementById('geolocation');
 element.innerHTML =+ '<br>' + error.code + error.message;
 }
</script>
<!-- ********************* Geolocation end *********************** -->

6. Prepare the files:

cordova prepare android

7. Compile the project:

cordova compile android

It is saved as platforms/android/bin/CordovaAPI-debug.apk

8. Install the apk in your device.

9. Make sure your device has been enabled for location access in your device’s Settings.

10. A moment after opening the page, the geolocation information should appear and refresh every 30 seconds.

If you have any problems getting any Android-related PG code to work, then open ADT or Eclipse then type in terminal:

cordova emulate android

Then in the console in Eclipse (navigate to Window > Show View > Debug) look for meaningful, related error messages as code executes when clicking on buttons or whatever. You’ll want to post that error message to the https://groups.google.com/ or https://stackoverflow.com web sites along with your environment information, such as:
Mac OS X 10.9.1 on latest Mac Mini
PG 3.3
for Android 4.3, 4.4 v19
not for PG Build
ADT v22.0.1 with Eclipse platform
Test device: Nexus 7 with 4.3

geolocation

Globalization

Globalization “obtains information and performs operations specific to the user’s locale and timezone.”

We’ll follow this page from the docs to set it up: http://docs.phonegap.com/en/3.3.0/cordova_globalization_globalization.md.html#Globalization Please review the page to gain an understanding of the steps we’ll be following.

1. Set the project’s directory in Terminal and download the plugin:

cordova plugin add org.apache.cordova.globalization

2. Use the ls (list) command to make sure it’s downloaded:

cordova plugin ls

3. Open CordovaAPI/platforms/android/res/xml/config.xml in a text file and add the following to just above </widget> and save:

<feature name="Globalization">
 <param name="android-package" value="org.apache.cordova.globalization.Globalization" />
</feature>

4. In index.html (or page3.html), add the following to just above the </body> tag:

<!-- ********************* Globalization begin *********************** -->
<div class="segment">
 <h2>Globalization</h2>

<!-- <input type="button" class="buttonClass" id="checkLanguageButton" value="checkLanguage"> -->
 <input type="button" class="buttonClass" onclick='checkLocale()' value="checkLocale">
<!-- <input type="button" class="buttonClass" onclick='checkDateString()' value="checkDateString"> -->
 <input type="button" class="buttonClass" onclick='checkStringDate()' value="checkStringDate">
 <input type="button" class="buttonClass" onclick='checkDatePattern()' value="checkDatePattern">
 <input type="button" class="buttonClass" onclick='checkDateNames()' value="checkDateNames">
 <input type="button" class="buttonClass" onclick='checkDayLightSavings()' value="checkDayLightSavings">
 <input type="button" class="buttonClass" onclick='checkFirstDay()' value="checkFirstDay">
 <input type="button" class="buttonClass" onclick='checkNumber()' value="checkNumber">
 <input type="button" class="buttonClass" onclick='checkParsedNumber()' value="checkParsedNumber">
 <input type="button" class="buttonClass" onclick='checkPattern()' value="checkPattern">
 <input type="button" class="buttonClass" onclick='checkError()' value="checkError">
<br><br> 
 <input type="button" class="buttonClass" onclick='window.location="https://iphonedevlog.wordpress.com/2014/02/20/adding-cordova-apis-to-android-via-cli-geolocation-globalization-notification/"' value="View Code On iPhoneDevLog">
</div>

<script type="text/javascript" charset="utf-8">
/*
function checkLanguage() {
 navigator.globalization.getPreferredLanguage(
 function (language) {alert('language: ' + language.value + '\n');},
 function () {alert('Error getting language\n');}
 );
 }
*/
function checkLocale() {
 navigator.globalization.getLocaleName(
 function (locale) {alert('locale: ' + locale.value + '\n');},
 function () {alert('Error getting locale\n');}
 );
 }
/*
function checkDateString() {
 navigator.globalization.dateToString(
 new Date(),
 function (date) {alert('date: ' + date.value + '\n');},
 function () {alert('Error getting dateString\n');,
 {formatLength:'short', selector:'date and time'}}
 );
 }
*/
function checkStringDate() {
 navigator.globalization.stringToDate(
 '9/25/2012',
 function (date) {alert('month:' + date.month +
 ' day:' + date.day +
 ' year:' + date.year + '\n');},
 function () {alert('Error getting date\n');},
 {selector:'date'}
 );
 }
function checkDatePattern() {
 navigator.globalization.getDatePattern(
 function (date) {alert('pattern: ' + date.pattern + '\n');},
 function () {alert('Error getting pattern\n');},
 {formatLength:'short', selector:'date and time'}
 );
 }
function checkDateNames() {
 navigator.globalization.getDateNames(
 function (names) {
 for (var i=0; i<names.value.length; i++) {
 alert('month: ' + names.value[i] + '\n');
 }
 },
 function () {alert('Error getting names\n');},
 {type:'wide', item:'months'}
 );
 }
function checkDayLightSavings() {
 navigator.globalization.isDayLightSavingsTime(
 new Date(),
 function (date) {alert('dst: ' + date.dst + '\n');},
 function () {alert('Error getting names\n');}
 );
 }
function checkFirstDay() {
 navigator.globalization.getFirstDayOfWeek(
 function (day) {alert('day: ' + day.value + '\n');},
 function () {alert('Error getting day\n');}
 );
 }
function checkParsedNumber() {
 navigator.globalization.numberToString(
 3.1415926,
 function (number) {alert('number: ' + number.value + '\n');},
 function () {alert('Error getting number\n');},
 {type:'decimal'}
 );
 }
function checkNumber() {
 navigator.globalization.stringToNumber(
 '1234.56',
 function (number) {alert('number: ' + number.value + '\n');},
 function () {alert('Error getting number\n');},
 {type:'decimal'}
 );
 }
function checkPattern() {
 navigator.globalization.getNumberPattern(
 function (pattern) {alert('pattern: ' + pattern.pattern + '\n' +
 'symbol: ' + pattern.symbol + '\n' +
 'fraction: ' + pattern.fraction + '\n' +
 'rounding: ' + pattern.rounding + '\n' +
 'positive: ' + pattern.positive + '\n' +
 'negative: ' + pattern.negative + '\n' +
 'decimal: ' + pattern.decimal + '\n' +
 'grouping: ' + pattern.grouping);},
 function () {alert('Error getting pattern\n');},
 {type:'decimal'}
 );
 }
function successCallback(date) {
 alert('month:' + date.month +
 ' day:' + date.day +
 ' year:' + date.year + '\n');
 }
function errorCallback(error) {
 alert('code: ' + error.code + '\n' +
 'message: ' + error.message + '\n');
 }
function checkError() {
 navigator.globalization.stringToDate(
 'notADate',
 successCallback,
 errorCallback,
 {selector:'foobar'}
 );
 }
</script>
<!-- ********************* Globalization end *********************** -->

7. Prepare the files:

cordova prepare android

8. Compile the project:

cordova compile android

It is saved as platforms/android/bin/CordovaAPI-debug.apk

9. Install the apk in your device.

10. Start the app and go to this page. When the page opens, click on the buttons to get the readouts of the device’s settings.

globalization

Notification

“Visual, audible, and tactile device notifications.” We’ll follow this page from the docs to set it up: http://docs.phonegap.com/en/3.3.0/cordova_notification_notification.md.html#Notification Please review the page to gain an understanding of the steps we’ll be following.

1. Set the project’s directory in Terminal and download the plugin:

cordova plugin add org.apache.cordova.dialogs

2. Download this plugin too:

cordova plugin add org.apache.cordova.vibration

3. Use the ls command to make sure it’s downloaded:

cordova plugin ls

4. Open CordovaAPI/platforms/android/res/xml/config.xml in a text file and add the following to just above </widget> and save:

<feature name="Notification">
 <param name="android-package" value="org.apache.cordova.dialogs.Notification" />
</feature>
<feature name="Vibration">
 <param name="android-package" value="org.apache.cordova.vibration.Vibration" />
</feature>

5. In platforms/android/AndroidManifest.xml make sure these lines are there, or add them:

<uses-permission android:name="android.permission.VIBRATE" />

6. In index.html (or page3.html), put the following just before the </body> tag:

<!-- ********************* Notification begin *********************** -->
<div class="segment">
 <h2>Notification</h2>
<input type="button" id="showAlertButton" class="buttonClass" onclick='showAlert(); return false;' value="Show Alert popup">
<input type="button" id="showConfirmButton" class="buttonClass" onclick='showConfirm(); return false;' value="Show Confirm popup">
<input type="button" id="showPromptButton" class="buttonClass" onclick='showPrompt(); return false;' value="Show Prompt popup">
<br><br>
<input type="button" id="playBeepButton" class="buttonClass" onclick='playBeep(); return false;' value="Play Beep sound">
<input type="button" id="vibrateButton" class="buttonClass" onclick='vibrate(); return false;' value="Vibrate the device">
<input type="button" id="vibrateButtonHtml" class="buttonClass" onclick='vibrateHtml(); return false;' value="Vibrate - HTML5 API">
<br><br>
 <input type="button" id="" class="buttonClass" onclick='window.location="https://iphonedevlog.wordpress.com/2014/02/20/adding-cordova-apis-to-android-via-cli-geolocation-globalization-notification/"' value="View Code On iPhoneDevLog">
</div>
<script type="text/javascript" charset="utf-8">
// alert dialog dismissed
 function alertDismissed() {
 alert('You dismissed the Alert.');
 }

 // Show a custom alertDismissed
 function showAlert() {
 navigator.notification.alert(
 'Alert dialog: You are on fire!', // message
 alertDismissed, // callback (do this function next)
 'Game Over', // title
 'Done' // buttonName
 );
 }

function onConfirm(buttonIndex) {
 alert('You selected button ' + buttonIndex + '\n(button 1 = Restart, button 2 = Exit.)');
 }
// Show a custom confirmation dialog
 function showConfirm() {
 navigator.notification.confirm(
 'Confirm dialog: You are the winner!', // message
 onConfirm, // callback to invoke with index of button pressed
 'Game Over', // title
 ['Restart','Exit'] // buttonLabels
 );
 }
function onPrompt(results) {
 alert("You selected button number " + results.buttonIndex + " and entered " + results.input1 + '\n(button 2 = Exit, button 1 = OK.)');
 }
// Show a custom prompt dialog. Android: 3 buttons maximum
 function showPrompt() {
 navigator.notification.prompt(
 'Please enter your name', // message
 onPrompt, // callback (do this function next)
 'Registration', // title
 ['Ok','Exit'], // buttonLabels
 'Jane Doe?' // defaultText
 );
 }
/* Android plays the default Notification ringtone specified under the Settings/Sound & Display panel */
function playBeep() {
 navigator.notification.beep(3);
 }
// Vibrate for 2 seconds using the PhoneGap API
 function vibrate() {
 navigator.notification.vibrate(2000);
 }
// Vibrate for 2 seconds using the HTML5 API
 function vibrateHtml() {
 navigator.vibrate(2000);
 }
</script>
<!-- ********************* Notification end *********************** -->

7. Prepare the files:

cordova prepare android

8. Compile the project:

cordova compile android

It is saved as platforms/android/bin/CordovaAPI-debug.apk

9. Install the apk in your device.

10. Make sure your device has been enabled for sounds and vibration in your device’s Settings. (My device did not have vibration capability.)

11. Start the app and go to this page. When the page opens, click on the buttons to get the readouts of the device’s settings.

notification

Advertisements

3 thoughts on “Adding Cordova APIs to Android via CLI: Geolocation, Globalization, Notification

  1. 1/11/2016
    Geolocation:
    I would suggest you build a tiny app that does nothing but start up
    geolocation and see that it works (or fails). here is the simplest steps to
    recreate this. I used these steps to demonstrate how simple writing a
    geolocation app could be for ios. It will work on android with a few
    changes.

    1. cordova create geolocationtest com.example.geolocation GeoLocation

    2. cordova plugins add org.apache.cordova.console

    3. cordova plugin add org.apache.cordova.geolocation

    4. cordova platform add iOS

    5. Replace the www/js/index.js with the below below. This is basically the
    starter code and only two functions have been added, onSuccess and
    onFailure along with a timer call to
    navigator.geolocation.getCurrentPosition()

    function onSuccess(position)

    { console.log(“Success…”); }

    function onFailure(error)

    { console.log(“Failed…”); }

    var app = {

    // Application Constructor

    initialize: function()

    { this.bindEvents(); }

    ,

    bindEvents: function()

    { document.addEventListener(‘deviceready’, this.onDeviceReady, false); }

    ,

    onDeviceReady: function() {

    app.receivedEvent(‘deviceready’);

    setInterval(function ()

    { navigator.geolocation.getCurrentPosition(onSuccess , onFailure); }

    , 1000);

    },

    receivedEvent: function(id)

    { var parentElement = document.getElementById(id); var listeningElement =
    parentElement.querySelector(‘.listening’); var receivedElement =
    parentElement.querySelector(‘.received’);
    listeningElement.setAttribute(‘style’, ‘display:none;’);
    receivedElement.setAttribute(‘style’, ‘display:block;’);
    console.log(‘Received Event: ‘ + id); }

    };

    app.initialize();

    6. cordova build ios
    Once you have read the start page, used the code above which works (I know
    it works as we submitted it to check a bug in the geolocation plugin, other
    people used to to check it as well), applied it to your code and then put
    some effort into working out what a proper question should be, come back
    with some decent information and we can see if there is a problem.

    To summarise, the cordova geolocation plugin does work, some parts used to
    have a memory leak but now appear to be fixed, the geolocation plugin may
    not work on hardware and OS’s from six (!) years ago, but works fine on
    modern hardware. If your use case is supporting kit from that long ago, you
    may struggle.

Leave a Reply

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

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s