Showing posts with label Google Gears. Show all posts
Showing posts with label Google Gears. Show all posts

Blacklisted by Google's Geolocation Service

banned

Several months ago, I described how one could use Google Gears to easily add Geolocation and GPS to their Windows Mobile applications. Basically, this is a trick that would work with any embedded browser by adding and scripting a DOM element, or by using my unsavory window.location hack when that is not possible (as is in the case of Pocket IE).

I was recently trying to reuse this code, and I noticed that the Geolocation sample page I had hosted was not working on Windows Mobile anymore; the service seemed to be returning an invalid response. I navigated to that same URL in Google Chrome and Firefox and it worked fine. I then tried navigating to the Gears Geolocation sample in Pocket IE, and that worked as well. I verified that I still had the most up to date code hosted on my domain. Still no luck, as the code had not changed.

So out of curiosity, I hosted the geolocation page on a separate domain and navigated to it within Pocket IE. 'Lo and behold, it starts working. So mentally, I constructed this chart in my mind:

  Pocket IE Google Chrome Firefox
code.google.com Works Works Works
koushikdutta.blurryfox.com Broken! Works Works
supersecretdomain.com Works Works Works

My conclusion? Google has blacklisted my domain! And, to be honest, I'm not really sure why. I'm using their sample code on my domain to get geolocation data, but using the results outside of the context of the browser.

Congratulations Google, you have earned the first honorary YouBastard tag on my blog!

 

Edit:

Google Gears EULA. I haven't violated it as far as I can see, but they do reserve the right to cut off access to the service at their whim.

Adding Google's My Location to your Application

A few people have asked me how I get a GPS fix so fast in GL Maps. I wish I could say I had some secret sauce, but I'd be fibbing. The truth is that I'm using the Google Gears Geolocation API. Google Gears is pretty much the new hotness. The Geolocation API determines your geocode by use of several sources:

  • GPS (obviously)
  • WiFi access points
  • Cell Towers IDs
  • Your IP

Generally between the first 3, you can get a pretty accurate location. Unfortunately Google Gears is an ActiveX control that is intended to only be used through JavaScript (it is only accessible through late binding). And though accessing methods through reflection on the PC is feasible, .NET CF does not support late binding with COM. So, that left two possible solutions:

  • Create a C++ DLL that handles all the late binding with COM (very gross) and PInvoke into that
  • Figure out a way to somehow get the result back from JavaScript (hosted in a WebBrowser control)

The second option is rather tricky though; the WebBrowser class does not give you access to the DOM on Windows Mobile. So after banging my head on that for a while; I figured out a crafty way to do it: through the URI of the browser.

The Google Gears Geolocation sample looks as follows:

function successCallback(p) {
var address = p.gearsAddress.city + ', '
+ p.gearsAddress.region + ', '
+ p.gearsAddress.country + ' ('
+ p.latitude + ', '
+ p.longitude + ')';

clearStatus();
addStatus('Your address is: ' + address);
window.location = "http://deadlink?lat=" + p.latitude + "&lon=" + p.longitude;
}

function errorCallback(err) {
var msg = 'Error retrieving your location: ' + err.message;
setError(msg);
}

try {
var geolocation = google.gears.factory.create('beta.geolocation');
geolocation.watchPosition(successCallback, errorCallback, { enableHighAccuracy: false,
gearsRequestAddress: true
});
} catch (e) {
setError('Error using Geolocation API: ' + e.message);
return;
}

Note the change I made on the 9th line (where I set window.location): once we have received the geocode from the asynchronous call, the JavaScript attempts to change the browser's address to a link containing the latitude and longitude in the query string. The WebBrowser class has a Navigating event that fires whenever the URI is changing. This event also gives you the option to look at the URI being navigated to and optionally cancel it through the WebBrowserNavigatingEventArgs parameter.

So, when the Navigating event fires, I cancel it, and grab the latitude and longitude form the URI:


static readonly Regex myLatRegex = new Regex("lat=(.*?)&");
static readonly Regex myLonRegex = new Regex("lon=(.*)");
void myBrowser_Navigating(object sender, System.Windows.Forms.WebBrowserNavigatingEventArgs e)
{
// if the browser tries to navigate, cancel it, and pick up the lat and long from the uri
// it tried to navigate to
e.Cancel = true;
try
{
string url = e.Url.ToString();
Match latMatch = myLatRegex.Match(url);
Match lonMatch = myLonRegex.Match(url);
if (!latMatch.Success || !lonMatch.Success)
return;
Geocode geo = new Geocode();
geo.Latitude = double.Parse(latMatch.Groups[1].Value);
geo.Longitude = double.Parse(lonMatch.Groups[1].Value);
UpdateGeocode(geo);
}
catch (Exception ex)
{
}
}

Obviously this is a hack, but it is one that will not fail and is easy to maintain as the Google Gears API evolves. And it will work on both the PC or Windows Mobile!