Thursday, June 23, 2011

How to Build Location-Based Apps That Don't Suck

If I were forced to choose between a smartphone that could make / receive voice calls, and one with Google Maps - I would choose Maps without blinking.

Here Back in London, getting a reliable 3G connection is a challenge at the best of times - getting one while sat in most venues is about as likely as a South West Trains running a good service. So it doesn't help when I go to view details for, checkin, or review a location and a lack of 3G signal thwarts my efforts.

Whether it's opening a FourSquare app to checkin, or Qype / Zagat / Where to choose where to eat, or the London Cycle Hire Widget to find a Boris Bike - I always feel like a douche standing around with my phone in my hand for half a minute while my phone gets a GPS fix and downloads the nearest locations.

High latency and a lack of offline support in location-based mobile apps is a blight that must be cleansed

Rather than (or indeed: after) shaking my fist at the sky in impudent rage, I wrote an open-source reference app that incorporates all of the tips, tricks, and cheats I know to reduce the time between opening an app and seeing an up-to-date list of nearby venues - as well as providing a reasonable level of offline support.

You can find out more in the associated deep-dive into location on the Android Developer Blog.

Android Protips: Location Best Pratices

It should came as no surprise to learn that I've borrowed heavily from my Android Protips presentation from Google I/O. Including (but not limited to) using Intents to receive location updates, using the Passive Location Provider, using Intents to passively receive location updates when your app isn't active, monitoring device state to vary refresh rate, toggling your manifest Receivers at runtime, and using the CursorLoader.

But Wait There's More!

The post on the Android Developer Blog focusses on freshness - I'll be posting another deep-dive into the code that examines how I've made the app psychic and smooth on this blog early next week. Stay tuned.

14 comments:

  1. Thanks Reto, I'm currently writing a Live Bus Schedule App, and have been running into some location road blocks. Your post is very timely!

    I can't wait to read your post on the Android Dev Blog, and put some of these good practices to work.

    ReplyDelete
  2. Score! That's a gripe of mine too, waiting for Places or Maps to get my location. Glad I wasn't alone! Hah

    ReplyDelete
  3. Looking forward to reading this! First thing tomorrow morning! :)

    ReplyDelete
  4. I think there is a bug in your code. You say, "If there is one or more locations available from within the allowed latency, we return the most accurate one. If not, we simply return the most recent result." But that isn't what your code does. If there is no location data recent enough, it doesn't return the most recent; it simply returns randomly one of the pieces of information it has. The problem is the "&& bestAccuracy == Float.MAX_VALUE" clause. Once a single provider is accepted, this becomes false, so later providers will be ignored if they are older than minTime, even if they are newer than the value that was previously accepted.

    It's a minor bug but it seems worthwhile to be pedantic in example code. It'd be nice to see this fixed in your example and in the androdid-developers.blogspot.com posting (which is where I originally saw it).

    ReplyDelete
  5. Oh, never mind me. I just noticed that you don't updated bestAccuracy when you get an out of date piece of location information. It does work as you describe, sorry about that!

    ReplyDelete
  6. Awesome Post from awesome Reto.

    ReplyDelete
  7. Nice one! I find so many apps I use just aren't designed for the flakey, or lack of 3G (on the tube), that London provides. It is good to see somebody addressing this :-)

    ReplyDelete
  8. Can you please please please tell me where to find the solution to downloading all exchange folders with the android mail app that is preinstalled on phones? It gives me the option to select them.. but i cannot see the mail that is filtered into them.
    Please and thanks

    ReplyDelete
  9. Hi Reto,
    first of all thanks very much for this post! A couple of minor things I found while going through the code, correct me if I am wrong: 1) the method "getLocationUpdateRequester" in the "PlatformSpecificImplementationFactory" class doesn't have a clause for pre-Froyo devices, and 2) the implementation for the "requestLocationUpdates" method in the "FroyoLocationUpdateRequester" class is missing (or it should extend the LegacyLocationUpdateRequester class).

    ReplyDelete
  10. Pls share inhouse with the google MyTracks team. They have a decent app but need to improve their ability to identify your location. App can take 5-10 minutes to obtain GPS location. Unacceptable. The app has been flakey on gingerbread.

    ReplyDelete
  11. Perfect post. Here’s a tool that lets your create location-based applications such as Distance Search, Map Mashups, and Automatic Geocoding without coding http://blog.caspio.com/web_apps/create-location-based-applications-with-caspio/

    ReplyDelete
  12. jack bergman7:54 p.m. GMT

    Hi, recently I came across your "Android Protips: A Deep Dive Into Location" speech and sample code. I tried to run it on emulator but it just doesn't work at all!
    There is compile error but it doesn't do anything at all, it doesn't receive new locations through DDMS. Could you please tell me, does this app works on emulator?

    thanks

    ReplyDelete
  13. Hi reto,
    I have read yr post A Deep Dive Into Location.I am following your post for my app development.I am facing one problem is that when app comes in forground at that time only I am getting location,whilewhen app runs in background I am not able to get current location as and when it changes.
    Is it like that Intentservice not runs in background as services?can you help me in this..

    Thakns.

    ReplyDelete