Sunday, April 18, 2010

Facebook and Google Map with PhoneGap

I have been experimenting with a neat little framework created by the folks at PhoneGap recently, and I am quite impressed by the results. This framework allows developer to build HTML and Javascript applications that take advantage of the special features, such as GPS, on iPhone, iPad, Android, Palm, and Blackberry.

The first thing I tried is to get the GPS location and display the coordinates on Google Map. It works quite perfectly. Next, I want to connect the application to Facebook. Things get a little trickier. Since the HTML and Javascript code are stored and run locally on the device as part of the application, I need to find a way to get the session key and the session secret from Facebook. While there exists third party libraries for developing Desktop Facebook applications, I prefer to write my own code.

Loading the session key and the session secret from Facebook is rather trivial. I simply tell Facebook to post the information to a callback page on a server and remit the information. The problem is, however, that the callback page and the local javascript run in separate security sandboxes; the local javascript cannot access the information remitted by the callback page. Here is where HTML5 comes to the rescue.



Here is a simple example demonstrating the GPS function, and the Facebook login function:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PhoneGap</title>
<style>
html,body, iframe, #console{
margin:0;
padding:0;
height:100%;
width:100%;
border: none;
overflow: hidden;
}
#facebook, #console{
position: absolute;
}
</style>
<script type="text/javascript" charset="utf-8" src="phonegap.js"></script>
</head>
<body>
<iframe id="facebook"></iframe>
<div id="console">
<input class="buttons" value="Vibrate" type="button" onClick="navigator.notification.vibrate(250)"/>
<input class="buttons" value="Facebook" type="button" onClick="login()"/>
<input class="buttons" value="GPS" type="button" onClick="navigator.geolocation.getCurrentPosition(gpsSuccess,gpsFail);"/>
<img id="googlemap" width="400" height="400"/>
<div id="output"></div>
</div>
<script language="javascript" type="text/javascript">
var api_key = "FaceookAPIKEY";
var callback_url = "callback.php?result=";
var url = "http://www.facebook.com/login.php?&api_key="+api_key+"&connect_display=popup&v=1.0&next="+callback_url+"success&cancel_url="+callback_url+"failure&fbconnect=true&return_session=true";
function gpsSuccess(e) {
document.getElementById("googlemap").src = "http://maps.google.com/maps/api/staticmap?center="+e.latitude + "," + e.longitude+"&zoom=14&size=400x400&sensor=false&markers=color:blue|label:S|"+e.latitude + "," + e.longitude;
}
function gpsFail(e) {
}
function messageHandler(e) {
if (e.data == "failure") {
document.getElementById("facebook").src = url;
} else {
var obj = eval('('+e.data+')');
document.getElementById("facebook").style.display = "none";
document.getElementById("console").style.display = "inherit";
document.getElementById("output").innerHTML = "session key: "+ obj.session_key + "<BR/>session secret: " + obj.secret + "<BR/>uid: "+ obj.uid;
}
}
function login() {
document.getElementById("console").style.display = "none";
document.getElementById("facebook").style.display = "inherit";
document.getElementById("facebook").src = url;

}
window.addEventListener("message", messageHandler, false);
document.getElementById("facebook").style.display = "none";
</script>
</body>
</html>

Here is the callback page:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Facebook Connect Callback</title>
</head>
<body>
<script language="javascript" type="text/javascript">
<?php
$cb_result = preg_replace("/[^a-zA-Z]/",'', $_GET['result']);
if ($cb_result == "success") {
echo "window.parent.postMessage('".$_GET['session']."', '*');";
} else {
echo "window.parent.postMessage('failure', '*');";
}
?>
</script>
</body>
</html>

No comments:

Post a Comment