I am running a Web service that allows users to record their trips (kind of like Google's MyTracks) as part of a larger app. The thing is that it is easy to pass data, including coords and other items, to the server when a user starts a trip or ends it. Being a newbie, I am not sure how to set up a background service that sends the location updates once every (pre-determined) period (min 3 minutes, max 1 hr) until the user flags the end of the trip, or until a preset amount of time elapses.
Once the trip is started from the phone, the server responds with a polling period for the phone to use as the interval between updates. This part works, in that I can display the response on the phone, and my server registers the user's action. Similarly, the trip is closed server-side upon the close trip request.
However, when I tried starting a periodic tracking method from inside the StartTrack Activity, using requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener) where minTime is the poll period from the server, it just did not work, and I'm not getting any errors. So it means I'm clueless at this point, never having used Android before.
I have seen many posts here on using background services with handlers, pending intents, and other things to do similar stuff, but I really don't understand how to do it. I would like the user to do other stuff on the phone while the updates are going on, so if you guys could point me to a tutorial that shows how to actually write background services (maybe these run as separate classes?) or other ways of doing this, that would be great.
You need to create a separate class that is a subclass of the
Service
class.Service Documentation
Your primary application should can call
startService
andstopService
to start up the background process. Theres also some other useful calls in the context class to manage the service:Context Documentation
I recently wrote one of these and decided it is not a good idea to leave a background service running. It will probably be shut down by the operating system anyway, or it could be. What I did was use a filter for the boot intent and then set an alarm using the alarm manager so that my app was restarted at regular intervals, and then it sent the data. You can find good info on services and the alarm manager in the Android documentation.
First I created a broadcast receiver that simply starts my service when an internet connection is opened (I'm only interested if there is a connection - you might want to filter for the boot event as well). The launch receiver must be short-lived, so just start your service:
In the manifest I have:
Notice how I have a filter for my own alarm, which is what allows me to shut the service and have it restarted after it's done its work.
The top of my monitor service looks like:
executeLogger starts an asyncTask, which is probably me being excessively cautious (this was only my third Android app). The asyncTask grabs the GPS data, sends it to the internet and finally sets the next alarm:
I notice that I am not calling stopSelf() after setting the alarm, so my service will sit around doing nothing unless shut down by the op sys. Since I am the only user of this app, that doesn't matter but for a public app, the idea is you set the alarm for the next interval then stopSelf to close down.
Update See the comment from @juozas about using 'alarms.setRepeating()'.
I agree with Rob Kent, and in additional I think could be beter to extends WakefulBroadcastReceiver in your BroadcastReceiver and use it's static method
startWakefulService(android.content.Context context,android.content.Intent intent)
, because it garanted your service will not shut by os.Official documentation