MOBILE

Building Android Apps : Controlling the Phone with JavaScript (part 2) - Geolocation

1/16/2011 3:31:21 PM

2. Geolocation

Let’s update Kilo to save the location when entries are created. Once we have that information, we’ll add a Map Location button that will open the built-in Maps application and drop a pin at the point where the entry was created.

The first step is to add latitude and longitude columns to the database to store the information. To do so, replace the CREATE TABLE statement in ~/Desktop/KiloGap/assets/www/kilo.js with the following:

db.transaction(
function(transaction) {
transaction.executeSql(
'CREATE TABLE IF NOT EXISTS entries ' +
' (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
' date DATE NOT NULL, food TEXT NOT NULL, ' +
' calories INTEGER NOT NULL, ' +
' longitude TEXT NOT NULL, latitude TEXT NOT NULL);'
);
}
);

Replace the existing createEntry() function in kilo.js with this:

function createEntry() {
navigator.geolocation.getCurrentPosition(
function(position){
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
insertEntry(latitude, longitude);
},
function(){
insertEntry();
}
);
return false;
}

Wondering where the SQL INSERT statement got to? Let’s take a look at the insertEntry() function. This new function creates the entry in the database. Add the following to kilo.js:

function insertEntry(latitude, longitude) {
var date = sessionStorage.currentDate;
var calories = $('#calories').val();
var food = $('#food').val();
db.transaction(
function(transaction) {
transaction.executeSql(
'INSERT INTO entries (date, calories, food, latitude, longitude) ' +
'VALUES (?, ?, ?, ?, ?);',
[date, calories, food, latitude, longitude],
function(){
refreshEntries();
checkBudget();
jQT.goBack();
},
errorHandler
);
}
);
}

To confirm that Kilo is actually saving these location values, we’ll want to display them somewhere in the interface. Let’s add an Inspect Entry panel to display the stored values. We’ll include a Map Location button on the panel that will display where the entry was created. Add the following to index.html, right before the closing body tag (</body>):
<div id="inspectEntry">
<div class="toolbar">
<h1>Inspect Entry</h1>
<a class="button cancel" href="#">Cancel</a>
</div>
<form method="post">
<ul class="rounded">
<li><input type="text" placeholder="Food" name="food" value="" /></li>
<li><input type="tel" placeholder="Calories"
name="calories" value="" /></li>
<li><input type="submit" value="Save Changes" /></li>
</ul>
<ul class="rounded">
<li><input type="text" name="latitude" value="" /></li>
<li><input type="text" name="longitude" value="" /></li>
<li><p class="whiteButton" id="mapLocation">Map Location</p></li>
</ul>
</form>
</div>


Now we need to give the user a way to navigate to this Inspect Entry panel, so we’ll modify the behavior of the Date panel such that when the user taps an entry in the list, the Inspect Entry panel will slide up from the bottom of the screen.

The first step is to wire up the click event handler (which we’ll create next), and also modify the way clicks on the Delete button are processed. Add the three highlighted changes below to the refreshEntries() function in kilo.js:

function refreshEntries() {
var currentDate = sessionStorage.currentDate;
$('#date h1').text(currentDate);
$('#date ul li:gt(0)').remove();
db.transaction(
function(transaction) {
transaction.executeSql(
'SELECT * FROM entries WHERE date = ? ORDER BY food;',
[currentDate],
function (transaction, result) {
for (var i=0; i < result.rows.length; i++) {
var row = result.rows.item(i);
var newEntryRow = $('#entryTemplate').clone();
newEntryRow.removeAttr('id');
newEntryRow.removeAttr('style');
newEntryRow.data('entryId', row.id);
newEntryRow.appendTo('#date ul');
newEntryRow.find('.label').text(row.food);
newEntryRow.find('.calories').text(row.calories);
newEntryRow.find('.delete').click(function(e){
var clickedEntry = $(this).parent();
var clickedEntryId = clickedEntry.data('entryId');
deleteEntryById(clickedEntryId);
clickedEntry.slideUp();
e.stopPropagation();
});
newEntryRow.click(entryClickHandler);
}
},
errorHandler
);
}
);
}

Now let’s add the entryClickHandler() function to kilo.js:
function entryClickHandler(e){
sessionStorage.entryId = $(this).data('entryId');
db.transaction(
function(transaction) {
transaction.executeSql(
'SELECT * FROM entries WHERE id = ?;',
[sessionStorage.entryId],
function (transaction, result) {
var row = result.rows.item(0);
var food = row.food;
var calories = row.calories;
var latitude = row.latitude;
var longitude = row.longitude;
$('#inspectEntry input[name="food"]').val(food);
$('#inspectEntry input[name="calories"]').val(calories);
$('#inspectEntry input[name="latitude"]').val(latitude);
$('#inspectEntry input[name="longitude"]').val(longitude);
$('#mapLocation').click(function(){
window.location = 'http://maps.google.com/maps?z=15&q='+
food+'@'+latitude+','+longitude;
});
jQT.goTo('#inspectEntry', 'slideup');
},
errorHandler
);
}
);
}


To test your changes, open a command prompt, cd into the KiloGap directory, and run the following commands to recompile and install the app on your phone:

ant debug
adb -d install -r ~/Desktop/KiloGap/bin/Kilo-debug.apk
Other  
  •  Building Your First Windows Phone 7 Application (part 5) - Styling Your Application
  •  Building Your First Windows Phone 7 Application (part 4) - Customizing Your First Windows Phone Application
  •  Building Your First Windows Phone 7 Application (part 3) - Writing Your First Windows Phone Code
  •  Building Your First Windows Phone 7 Application (part 2) - Using Your First Windows Phone Silverlight Controls
  •  Building Your First Windows Phone 7 Application (part 1) - Creating a Windows Phone Project
  •  Introducing Windows Phone 7 and the Windows Phone Platform
  •  Windows Phone Application Platform
  •  iPhone Application Development : Basic User Input and Output
  •  Mobile Phone Game Programming : A Quick J2ME Primer
  •  Mobile Phone Game Programming : Java As a Mobile Game Platform
  •  Mobile Phone Game Programming : Getting to Know Mobile Platforms
  •  Mobile Application Security : The Apple iPhone - Local Data Storage: Files, Permissions, and Encryption
  •  Mobile Application Security : The Apple iPhone - Permissions and User Controls
  •  iPhone Application Developmen : Using the View-Based Application Template (part 3)
  •  iPhone Application Developmen : Using the View-Based Application Template (part 2) - Preparing the View Controller Outlets and Actions
  •  iPhone Application Developmen : Using the View-Based Application Template (part 1)
  •  Mobile Application Security: Application Format
  •  Mobile Application Security: Security Testing
  •  Mobile Application Security: The Apple iPhone - Development
  •  Building Android Apps : Installing KiloGap in the Emulator
  •  
    Most View
    Big Shot Rivals: Sony vs. Samsung
    500px - The Stunning Photography Gallery Comes To iPhone
    The Complete Guide To Photography On Your Mac! (Part 1)
    Installing the HP-UX 11i Operating Environment (part 1) - Integrity Early Boot and Begin Loading HP-UX from an Ignite-UX Server, Integrity Early Boot and Begin Loading HP-UX from Media
    Maingear Alpha 24 Super Stock - No Retreat, No Surrender
    Synology 4-Bay NAS: Three Models Review (Part 4)
    Get Yourself A Portable DAC
    HTC Butterfly - Smartphone With Full HD Display
    Windows 8 Explorer : Diagnosis and Recovery - The Processes Tab
    Microsoft Dynamics Sure Step 2010 : A repeatable process for the sales teams (part 2)
    Top 10
    Zotac GeForce GTX Titan Black
    Toshiba Q Series 256GB and 512GB, Toshiba Q Series Pro 256GB
    The Gaming Mouse: Ozone Neon
    SanDisk Ultra Plus 256GB And X110 256GB
    SanDisk Extreme II 480GB, Plextor M5 Pro Extreme 256GB and 512GB
    Samsung SSD 840 Evo 250GB, 500GB And 1TB
    PNY XLR8 240GB and XLR8 PRO 240GB
    OCZ Vector 150 240GB And 480GB, And Vertex 460 240GB
    Nvidia GeForce GTX 750 Ti
    Nokia Lumia 1020 41 Megapixels Of Awesome