Wednesday, July 11

Project update: location

In my project, the mobile application is supposed to periodically obtain user's current location and record it into a database; this process should be done even when user quits the app. Previously, my solution is to set a recurring task using AlarmManager, which will send an alarm every 30 seconds after user starts it; another class, extends AlarmReceiver, will start a service every time it receives the alarm task; lastly, in the service class, I create a location manager to obtain location using getLastKnownLocation().

This implementation, technically, issues location tracking task exact every 30 seconds. Two problems with this. First is, although the alarm is generated every 30 seconds, the location tracking might not be finished within 30 seconds every time. There might a situation that the mobile phone has not got any location for the current alarm task when the next one is generated. I am not so sure if this is 100% correct, but I do find sometimes there will be delay in updating location, like no location update for 5 minutes, then several new location updates appear in database with the same coordinates. Anyway, I am suspecting it is because my Activity Alarm -> Service -> LocationManager process take too much time. Another problem is, every task the mobile phone creates a new service, which seems inefficient and unnecessary.

Several days ago I find this post writing about LocationManager and LocationListener, come to my rescue. Basically it explains how the method requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent) works. This methods aims at saving energy while giving accurate location tracking. The minTime parameter gives the time duration that the location provider will rest (status changes into unavailable) before it activates and obtain location again. The actual time interval will be equal or greater than minTime, due to several reasons: location update only be sent to the app if the difference between new and old location is greater than minDistance, also the provider might take some time to obtain the latest location. This definitely takes longer time than getLastKnownLocation(), since the latter one uses cached location.

Anyway, it seems I could use this request method directly for my periodically update, while it is not exact update, it has several advantages: there will only updates if necessary, if user does not move, my previous version will still update as alarms go on and off; also it is definitely more efficient than multiple services. Now my activity will start the service after user presses the start button, which will then register a LocationListener and request location update. Note this request will not stop until the service stops or I explicitly use removeUpdate method. Lastly, in my class of Location Listener, I put location into database in the onLocationChanged method: it gets invoked every time there is a location update from the location listener.

Some digress, I just find this Notification class which could perfectly display the app status in the notification bar. Previously, I use a textview to hold the status passed from service, but setting it globally visible is better, especially when user quits the app.


I use the sample code comes with SDK. But it is somehow deprecated, thus I change a little. This snippet of code would be put in the onCreate method of my service, so that every time my service starts there will be a notification in the bar. I also put a cancel method in the onDestroy method so that it gets killed when the service stops. Note Notification class is in API level 11 (Honeycomb), which means if you are using the same API level I use (2.3.3, level 10, GingerBread) or lower, you need to import support package in your project.

I will test this new version tomorrow.

No comments:

Post a Comment