I'm trying to develop an Android app that among other things, uses location services to get user location and sends it to a remote server. The user can turn this feature on and off according to his own will, but as long as it's turned on, it will get user location periodically (maybe each 30 seconds, don't know it for sure yet). Also, while it is turned on, it must keep tracking the user even if the application is closed.
So far I've considered 2 options:
Option 1 - Use Service, call startForeground to make sure Android don't kill it (the sticky notification is not an issue to me) and use a LocationListener with the said interval, but this seems rather inefficient as the service would be doing nothing most of the time, I mean, the listener would be called each 30 seconds, send the location to the server and the service itself would spend the next 29.9 seconds or whatever just waiting for the next location.
Option 2 - Doing some research, I've seen some approaches using AlarmManager to trigger some background service (like seen in this post), but I'm concerned that using alarms that often (every 30 seconds) might not be good for the battery and system general performance (in a code snippet in this page of Android's Developer guide there's a comment saying that "hopefully your alarm will have a frequency lower than 30 MINUTES").
Maybe there's another option that I still haven't thought about, or maybe there's a way to put the service from option 1 to sleep for some time or something like that. Bottom line, I'm looking for the approach that doesn't impacts on performance, consumes the minimum amount of battery and has the least chance of being killed by Android.
Any help and/or suggestions are welcome.
Related
I am developing a flutter application, however I would like a service to be able to run constantly without stopping in order to make an api request every 15 minutes and then send a notification to the user (Android /IOS). I would also like the service to start automatically with the smartphone. I've been stuck on this for more than a week now and I've been browsing the forums looking for a solution but I can't find what I'm looking for. Thank you in advance for any help
You don't do it like that on Android. You cannot count on an application not being killed in the background. Instead, you use JobScheduler or WorkManager to set an alarm and wake you up every so often to perform whatever job you need. These methods can also ensure you're scheduled at startup of the phone.
Also, 15 minutes may or may not happen- Doze mode may cause your app to be delayed and make requests less frequently than that if the phone goes to sleep (although 15 minutes is fairly safe, plus or minus a few).
I would like to develop an application - a service - that updates the user location to server, say, every 1 hour.
I understand from the Android docs that I have to use "Android Services" and I have to do the work on the onStartCommand()
But since I need to keep sending these location updates every 1 hour, then I need to run infinite loop inside onStartCommand() ... right?
Now, my questions are:
What will happen if system kill the service, I know my service will get started, but would it call onStartCommand() also?
Is there a better way to implement location update, for example, is it possible that the system call the onStartCommand() method periodically every 1 hour?
AlarmManager, as mentioned by the other posts, is what you're looking for.
However, It's against Android Best Practices to run things "forever, every hour" or so. If you start off by thinking "every hour, every day", you might take actions that would harm the user's battery life.
Turning on gps every hour, waiting for it to acquire a lock, then turning it off, uses a lot more battery life than if you were "smarter" while checking location.
If you do it right, e.g. setInexactRepeating, try to use WiFi location, set listeners for location update, then you can have your cake (long battery life for the user) and eat it too (still get the information you need).
For some good tips about how to keep your app from taking up too much battery (and possibly getting uninstalled), take a look at this video from GOogle IO 2012: http://www.youtube.com/watch?v=PwC1OlJo5VM
EDIT: Take a look at this, too:
http://developer.android.com/reference/android/location/LocationListener.html
You can set a listener that only gets called when the device's location is changed. YMMV, but take a look.
One possible way is to check out the AlarmManager. You can schedule your app to be run on an interval. You can also determine that perhaps I did not change since the last hour and lengthen the delay to extend battery life.
AlarmManager Documentation
Yes... Search for AlarmManager.. That is exactly what you need.
You can schedule intent to be called and therefore start your service every hour.
I've created an android app that is so far working quite well. It contains a local service which is responsible for getting the users location every couple of minutes and relaying that via UDP to a collection server which is in turned displayed on a web application map.
The app needs to be constantly running unless the user explicitly signs out of the application. Currently, it seems the OS is shutting down the service and restarting it as needed. I can see this because normally it would report its location consistently every 2 minutes. Instead, there are gaps in these intervals.
So I'm looking for some advice on how I can write a service which (at the battery's expense unfortunately) can stay running always and pool the location service just enough to send accurate fixes at a 2 minute interval.
I have a well working code base so far, so if demonstrating where I currently am with code would help, don't hesitate to ask.
Thanks in advance to those that lend a hand.
Your best bet is to use the AlarmManager to wake up every two minutes, do some processing and quickly go back to sleep.
If you think you're hardcore, you could even use a wake lock, but that will keep the phone's CPU turned on persistently without mercy. You don't want that.
I am coding an android application that gets the user position every 5 minutes, stores it in the database and sends it to a server.
I have read many ways of doing it, I was going to do the following:
User starts the application
The main UI activity starts a service.
The service runs in background and keeps turning on and off the gps, and creating new
threads that will save to database,and send the data to the server.
But I have seen that it can be done with a "Remote service" (http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html) or with an AlarmManager that schedules starting this service every 5 minutes.
The service will need to be running always: it is important that after every interval (5 minutes), it is executed.
I think I need some clarity here.
Thank you for your help,
I am coding an android application that gets the user position every 5 minutes, stores it in the database and sends it to a server.
Please allow the user to choose the location provider. Not everybody has GPS on their device. Not everybody has GPS enabled. And, not everybody will want the power hit of GPS being turned on every five minutes.
Please allow the user to choose the polling period, including "never poll -- I'll refresh the information manually from the activity". Also, please honor the background data setting (deprecated as of ICS).
I think I need some clarity here.
If the polling is supposed to go on even if the activity is not in the foreground, use AlarmManager. However, most recipes for using AlarmManager will have the real work (in your case, GPS fix and network I/O) be handled by an IntentService. This will not work in your case, because GPS is asynchronous -- you cannot just get a fix whenever you feel like it. It will take a long time, possibly forever, to get a fix, so you have to deal with the delay and eventually timing out the operation. Writing a Service to do this is possible, but tricky, particularly if you are aiming to collect this information even if the device falls asleep.
If, however, the polling is only supposed to go on while the activity is in the foreground and the device is on, I wouldn't bother with a Service at all. Just have the activity use postDelayed() to set up an every-five-minutes scheduled bit of code to run, then have it do the work.
I would like to write an app on Android to upload my GPS location to an external website once every ~5 minutes. This needs to have as minimal an impact on battery life as possible, but it also needs to work without any user interaction. (Background: I'm competing in an Ironman triathlon which will take me about 14 hours to complete, and want to broadcast my location in near-real-time but without having to worry about fiddling with my phone.)
So my initial thought is to write a Service which uses LocationManager.requestLocationUpdates() with a minTime of 5 minutes, but will this actually wake the device up every 5 minutes for my service to do its job?
It sounds like I would also need to use AlarmManager.setInexactRepeating() to make sure my service is awake while it completes its task but how does that play with requestLocationUpdates()? Should I instead set minTime=0 on requestLocationUpdates() but then go back to sleep as soon as the next update is obtained?
Any general guidance on how to design this is greatly appreciated. I'm a competent Java programmer & will be using Google Maps on the server to plot my location, but am pretty new to Android development so I'm basically looking for a high-level plan on how to architect the client app.
Your service must be alive all the time you want to receive updates.
http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates%28java.lang.String,%20long,%20float,%20android.location.LocationListener%29
You can tell how often you want to be informed of location change with minTime parameter. It does not however decrease battery consumption. GPS is enabled unless you use removeUpdates method no matter how often you want to receive updates.
You can use another approache:enable GPS using method above, read one value, use removeUpdates method, wait 5 minutes and all over again. Delay between enabling and retreiving a location can be between few seconds to few minutes.