Geolocation Gotcha

I’ve been working on an Air for Android app for the past month or so and I’ve been finding some significant little holes in the current version of the Air/Android SDK. I’ll start with the latest fist-shaking issue I’ve come across.

The Geolocation class, only supported on Mobile applications, is a small, straightforward class with a quirk or two up it’s sleeve.  The following code example snippet comes from Adobe’s livedocs for the class (slightly modified):

1
2
3
4
5
6
7
8
9
10
if (Geolocation.isSupported)
{
       geo = new Geolocation();
       geo.setRequestedUpdateInterval(100);
       geo.addEventListener(GeolocationEvent.UPDATE, geolocationUpdateHandler);
}
else
{
       trace( "No geolocation support." );
}

This is a pretty straightforward way to use the Geolocation class. Check to see if Geolocation is supported on the mobile device, if it is, create a new Geolocation instance, set the interval of how long you want it to check the GPS sensors and update your GPS coordinates (every 100ms in this example), and add an event listener/handler function listening for when those coordinates have been updated.

The problem here is: What happens when you have a mobile device that HAS gps capabilities, but the user has disabled the GPS for privacy/security reasons? Geolocation.isSupported returns TRUE because the phone does in fact have Geolocation capabilities. But your code will never reach the geolocationUpdateHandler function because the user has disabled GPS Geolocation. You will not receive an error, you will not hear a peep from your app, you will not pass Go and you most certainly will not collect anything near $200.

There is one more significant check we need to do that should have been added to Adobe’s example to make it complete.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
if (Geolocation.isSupported)
{
       geo = new Geolocation();
       if( geo.muted )
       {
              trace( "Sorry, your paranoid user has disabled GPS Geolocation" );
              // Handle disabled GPS Geolocation stuff here
       }
       else
       {
              geo.setRequestedUpdateInterval(100);
              geo.addEventListener(GeolocationEvent.UPDATE, geolocationUpdateHandler);
       }
}
else
{
       trace( "No geolocation support." );
}

Adobe added a very tricky and (in my opinion) mislabeled parameter, “muted” to the Geolocation instance (Not as a static class variable, like ‘isSupported’, but to the actual instance). I don’t know why they call it ‘muted’ but the variable is TRUE when the user has DISABLED access to GPS Geolocation, and FALSE when everything is cool and everyone is happy and you can actually use Geolocation how you want within the limits of satellite technology.

Tricksy little adobe hobbitses….

I had looked forever for some sort of Error event to fire… maybe a GeolocationEvent.ERROR or something that let you know you could not use the geolocation services, and this blog began as me pointing out how Adobe must’ve made a mistake. But no, no mistakes, just a really weird class that doesn’t seem to follow the conventional model of other Adobe classes.

I hope this helps.

Update – 18th Jan 2011 –
I did some further testing with this “muted” flag. As long as you have “Use wireless networks” or “Use GPS satellites” (verbiage from Droid X Settings -> Location & Security ) checked, muted will be FALSE and you can use the Geolocation class just fine. If both are unchecked, muted will be TRUE and you need to tell the user to turn stuff on. Makes sense.
That is all.

Share

Air, Android, and cookies

What: In using an Android app, I need to send an authentication request (username/password) to the server and the server needs to send me back a cookie.  We all know how you would use JavaScript to grab cookie/session data and then you could send it right into flash.

Problem: How or where would you find cookie being sent to you in your Air/Android app that uses no browser?

Solution:  Headers can be found in the HTTPStatusEvent object!  Hurray!  It took me way too long to find the answer to this issue.  Everyone on google is happy to tell you “Hey there’s a manageCookies setting on the URLRequest object!”  Great, how do you find the damn headers?  In fact, as you’ll see in the following code, you dont even need to mess with that manageCookies setting.  I set it to true and got headers.  I set it to false and god headers.  I didn’t include it at all and got headers.  Sweet.
Read More

Share