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.
Related
I have implemented a foreground service to get GPS updates for longer runs, like 3 hours, when the app is in background. It is our business requirement. But the app stops getting updates after a few minutes. I see the "location icon" on top bar go disappear, even though my foreground service notification is still there.
I have also excluded my app from Battery Optimization list from the settings, so that Android doesn't kill my app. It helps to keep gps updates alive for about half an hour only, then again the location icon goes away and i stop getting gps updates.
What can I do to keep it always ON?
I am posting this answer based on my short comment and OP request
You can start that service by separate process by adding android:process=":FusedLocationService" in your Service component in manifest.xml.
I had done this and work in most of the device except some of the manufactures like Honor and other because they customized Android AOSP for better user experience
https://developer.android.com/about/versions/oreo/background-location-limits.html
Apart form this you can use JobScheduler to fetch location data after a particular interval (approx 15 mins)
You can build logic a/c to OS version as well.
And while fetching the location use FLP (FusedLocationProvider)
Hope this will help, But after all this depend on Mobile brand(like ONE PLUS) you will face the issues. You need to handle these scenario as well.
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.
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.
My company has, in essence, undertaken a project to replace some of its pagers with stock smartphones running Android. As long as they are signed in, the device should be listening on a particular socket to receive "pages" from a server. My naive implementation was to create a foreground service that 1) kicked off a listening thread, and 2) holds a PARTIAL_WAKE_LOCK.
This works fine unless the device has a long period of inactivity, 1+ hours. Then, it appears that the OS shuts down my app's process, understandably believing it to be not in use.
I completely understand their reasons for doing so, but I'm wondering if I can somehow get around this restriction. Are there ways to signal Android that my process really is important enough to keep alive/the device awake? I learned both Java and the Android API for this project, so there are plenty of areas where my knowledge is incomplete.
Failing that, given the description of my business needs, how would you suggest implementing this functionality? While the user is signed in to our custom app, the device should always be listening.
Thanks to everyone for reading this question.
The OS won't kill your process if you are using Service.startForground(). This is what things like music playback use, and you wouldn't want those to be killed after some amount of time.
That said, for this kind of thing you generally wouldn't need to make your service foreground -- when the system does kill your process because it has been sitting around or needs the memory, it still knows the service wants to remaining running so will restart the service shortly after that. This is how Google's own services work, they have one .apk that has a background service running that keeps a network connection open to a Google service which reports back when interesting things should be done like sync new e-mail, retrieve and deliver a C2DM Intent, etc.
Also you should not hold a wake lock during all of that time. You will kill the battery, especially on some devices like those with Samsung's Hummingbird processor. The right way to do this is to just leave the socket open and let the device fall asleep. If data is delivered to the socket, the CPU will wake up to deliver that data and at that point you should acquire a partial wake lock just for the time you need to read and process the data.
What you describe sounds like a job for Android Cloud to Device Messaging Framework.
It's currently not completely open but there is a signup link on that page. I signed up and was accepted within 20 minutes of my application. Worth a look IMO.
I am new to Android, and I need some advices for start up.
I want to build an application, which will show up, when the user gets into some hot situation.
By hot situation I mean:
the GPS/cell coordinates are in known zone;
known Bluetooth device detected;
known Wi-Fi network detected;
weather info has change;
I see something running in background and when one of the clauses hit, it will trigger and open the app.
How to get started?
How do I make sure my app won't be shut down?
As I read somewhere that Android OS will terminate apps if memory out occurs or consumes too much, and my app would consume a lot, making repeated measures/checks to see if situation changed.
Regards,
Pentium10
You need to use a Service for the part of your application that runs in the background.
You might find the Application Fundamentals document in the Android Developer Documentation helpful. It says this about Services:
A service doesn't have a visual user interface, but rather runs in the background for an indefinite period of time. For example, a service might play background music as the user attends to other matters, or it might fetch data over the network or calculate something and provide the result to activities that need it.
In you case you might find the LocationManager Service helpful. It is a system Service which will you can use to notify your application based on GPS position.
However, I think you'll have to write your own Services to monitor Wi-fi, Bluetooth and weather.
You can use the AlarmManager Service to get your Service to perform particular tasks at certain intervals.
It depends on how & where you want to deploy your application. In my experience it boils down to
you create an application for a specific use case where battery drain matters less than accurate results (showcase situations, prototyping, ...)
you want to distribute the application to users.
In case 1) just create one service that aggressively polls the sensors / web services. Use the AlarmManager to send a REFRESH intent (AlarmService.setRepeating(...) ).
That REFRESH intent will restart the synchronization service everytime, even if it was killed by the system. onStart() will be called everytime the REFRESH intent is emitted. You can do heavyweight setup logic in onCreate() as this will be called everytime the service is created after it was destroyed. WARNING: This will possibly drain the battery very quickly.
In case 2) I would create several services and let the user configure different polling intervals for each service to limit battery drain. I can see for example that bluetooth should be polled more regulary than GPS as it is more likely that a bluetooth device suddenly appears than a user moving extremely fast.
Weather sounds extremely expensive (network lookup, possibly triggering a network connection!)
Please do not try to be too persistent with your app in case 2). It usually makes a lot of sense for a phone to kill memory / power draining services.