MarginalHacks.com DaveSource.com
Location Example
 

What is it?

I wanted to find a simple example Android project that only did location updates and not much else. I couldn't really find one, so I wrote this and hope that it will help others in the same situation. For fun (and because it's simple) it also calculates distance to a home location and can call up Google Maps with the current location.

Location Updates?

Originally Android had a framework for location called android.location. Then location services were moved to Google Play Services (which includes Google Maps, Google Play, etc.. etc..). Then to complicate the documentation further (but to make life easier), Google created te Fused Location provider, which fuses together the various ways that location is calculated (GPS, Wifi, Cell towers, and even using the sensors to tell if you are walking, biking or in a car). The Fused Location services is the one that we want to use, it generally provides better accuracy with less battery life and much simpler code. It also includes Geofencing capabilities (the ability to create callbacks for when we enter/leave geographic areas) though we won't be using that in this app.

Preparing The IDE/Emulator

Google Fused Location requires Google Play Services on your test android device. Unfortunately, Google does not support or desire that you have Google Play and it's buddies on your emulator. There are three ways to deal with this:
Use actual Android Device
Connect your phone and use it as a test device, it has Google Play Services already installed
Default Emulator
Install Google Play via the SDK manager. That's what the docs say, at least. It didn't do anything for me when I tried it.
Genymotion
Genymotion is a replacement Android emulator for OSX/Windows/Linux. It generally costs money, but is free for private testing with some slight limitations. It's a great and fast emulator, so it's worth testing out, and it's not difficult to install Google Play Services - see below

Genymotion setup

Here are steps to use the Genymotion emulator. Note that you may have to stop running the Android Studio emulator to start genymotion, they seemed to have a VirtualBox conflict on my system. I (mostly) followed the directions at techrepublic.com.
  1. Install VirtualBox if you don't have it already
  2. Download and install genymotion (requires signup, but free)
  3. Create an image, I used a Nexus 4 with API 21
  4. Find/download the most recent Google Play Services ZIP (either google search or check here, I used 'gapps-kk-20140606-signed.zip' as that was the most recent version)
  5. Startup the emulator
  6. Drag and drop the ZIP onto the emulator (using something like Nautilus or Finder or Explorer)
  7. Say 'OK' to flash the archive
  8. Reboot when done
  9. Genymotion doesn't seem to shutdown properly - once the shutdown process seems frozen/done, simply close the genymotion window and start it again
  10. The Google Play app should be installed, but Google Play Services will start crashing frequently. You need to update Google Play in between the crashes, so type fast!
  11. Open Settings -> Accounts and add your Google account info
  12. Open Google Play App and open settings (top left menu -> Settings) and scroll down to 'Build Version' and tap it a few times to start the Google Update
  13. Once the update is done, reboot the emulator
  14. Finally, click on 'GPS' and turn it on, and give it a starting location (by latitude/longitude or else via the map). (You'll need to turn GPS back on everytime you start the emulator)

Project Creation

  1. Project must be Android 2.3 or higher (API level 9) (though emulator must be 4.2.2 or higher)
  2. Add to AndroidManifest.xml inside <manifest>:
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    
  3. Add to build.gradle inside dependencies {}:
        compile 'com.google.android.gms:play-services:+'
    
    (Some docs specified the version of play-services, but I found this didn't work)
  4. Sync gradle
  5. Add to AndroidManifest.xml inside <application>:
    	<meta-data android:name="com.google.android.gms.version"
               android:value="@integer/google_play_services_version" />
    
The basic steps taken in the code are:
  1. Create a new GoogleApiClient with an onConnected callback
  2. Inside onConnected, create a LocationRequest and requestLocationUpdates()
  3. onLocationChanged is now called with each Location
  4. The lifecycle of an app means that when we leave the app (such as pressing the home button or even just rotating the view) the app (view code) is possibly destroyed and restarted. We need to save any state regarding the location client for when we restart. To complicate things further, even though the app is stopped, the Google client is not and will continue to call our callbacks with updates. So unless we want to process locations in the background, we need to turn off location updates and restart them every time the app is paused/resumed. Consequently, we want to:
    1. onCreate: restore values if saved and update view. If we are currently fetching locations, then restart the Google client and location updates
    2. onResume: restart location updates
    3. onStop: stop location updates so we don't process them in the background
  5. We also want to setup the code that handles google client connection problems. This can be as simple as needing to login to google services. Fortunately google can handle the error for us if we setup the dialog.

License:

This software is open source (unlike most of the software on this site which is merely free 'as in beer'), you can do what you like with it, but please read my payment spiel

Download:

You can download the entire project for Android Studio as a zip file or you can browse the project directory. Interesting files of note are:

github?

You bet.