I'm writing an Android app whose main Activity starts a Service that makes itself sticky. The Service makes repeated HTTP POSTs to a server, exchanging some information. This process works perfectly as long as the phone's screen is on, but once I turn the screen off, the service stops after a while. Is there any way to guarantee that my Service keeps running indefinitely?
Is there any way to guarantee that my Service keeps running indefinitely?
No.
Furthermore, you should not want your service to be "running indefinitely". Certainly your users do not want your service "running indefinitely", as that is why they will attack you with task killers, the force-stop operation in Manage Services in Settings, and so on. Not to mention all the lovely one-star ratings on the Market, choice comments in discussion boards, and the like that such applications will trigger.
Moreover, your problem here is not that your service is not running, per se, but that the device is falling asleep. This is perfectly normal. Users want their device to fall asleep -- otherwise, their battery life will be horrific.
The Service makes repeated HTTP POSTs to a server, exchanging some information.
The proper way to do this is to use AlarmManager, to trigger your code to execute periodically. Your user should be able to control the period (perhaps via a SharedPreference), including an option of "I'll manually request the data transfer, thanks". And, via an IntentService or similar means, you arrange for your code to be started by AlarmManager, do its work, and then shut down to get out of RAM.
Getting AlarmManager to wake up the device out of sleep mode is not that difficult (use a _WAKEUP flavor of alarm), but keeping the device awake long enough for you to do your HTTP request can be. The HTTP request cannot be performed on the main application thread, as it may take too long. One recipe is to use my WakefulIntentService component, which is an IntentService that keeps the device awake long enough for your work to be complete, then shuts down and allows the device to fall back asleep.
First Way: What you can also do to make HTTP POSTS to a server continuously is, you can make a timer and inside the task of the timer ie. in run() of class TimerTask you can make startService() and as soon as you are done with the HTTP POST work you destroy the service. Thus on a periodic basis, the timer will start the service and there won't be any background service.
Second: You can also use the PowerManager.WakeLock
Third: You can use AlarmManager as discussed in the previous answer.
Related
I'm fighting with the Android desire of killing everything which isn't active on the screen. My problem in few words:
I have a microcontroller which communicates with a processor on which Android runs;
the processor must keep active a watchdog on the microcontroller, resetting periodically (every one second) one of its registers; an application, say App B, accomplishes this duty;
on the processor I can be sure about the persistent existence of another application, say App A (or, however, if App A dies App B can die too because the system is compromised) which for now does nothing, in the future will accomplish other duties.
Which is the best way to implement App B?
I tried the following solution: App B contains a Bound Service, say Service A, to which App A can bind on; Service A starts a thread, say Thread A, which periodically resets the microcontroller watchdog. Thread A is launched when app A sends a command to Service A (e.g. START_WATCHDOG).
In my idea, Service A lives until App A lives (thanks to the binding), and so the process to which Service A belongs lives, and so also Thread A.
Unfortunately, from tests I see that sometimes (in a sporadic manner), after some time (sporadic time, too), with almost no work running on the system (except for App A, Service A and Thread A) the system kills Service A process, and so Thread A stops and the watchdog elapses.
When Service A dies, it is restarted (because it is a Bound Service and App A is still running) but, for now, I don't save the current state of Service (which simply consists on the START_WATCHDOG command arrival or not) and this is the reason for which the watchdog elapses.
So, I've got several questions about my solution:
is it ok and I simply need to save the current state of Service A in order to restore it when restarted?
should I discover better the reasons for which Service A, or better its process, is killed?
is there a better solution for my problem?
Thank you very much to everyone who will spend some time to help me.
Being not sure about periods in which your service runs you can try these:
Use foreground service. However, you might need to acquire a wakelock within your service start point if you need cpu in long time. Plus, a notification needs to be shown on phone status bar.
Use WorkManager-new api part of jetpack simplifying the use of alarm managers and jobschedulers- to schedule your tasks periodically. However if your frequency is higher than 1 per 5-10minute then you will need to take care of doze mode. If phone gets into doze, your tasks might be delayed till maintenance periods. A trick to apply here might be starting a foreground service when you catch activation of doze mode and return back to Workmanager logic in deactivation(if you don't want user to see the foreground service's notification). Do whatever you want in the foreground service like.
Use Firebase Cloud Messaging to push notification from your server to your users periodically for you to have a small amount of time to do work in background. When notification comes, OS grants you an interval to run a task.
Use Work manager it is easy to implement.
I'm building a monitoring app that will capture as much info as possible from the mobile device, like running processes / active connections / networking statistics / active interfaces etc. Obviously I will need a service that will be running in the background for that, but I'm not entirely sure how to implement it.
Someone suggested that I create an IntentService that will execute at specific intervals using AlarmManager, do its thing and then die again.
In this thread people suggest an implementation using an always-on Service that starts its own thread to do the work, put it to sleep and then again. One also suggested that AlarmManager is used too to make sure that the service will be restarted if the OS kills it.
What's the mpst appropriate implementation for monitoring real time data? (or the up/downsides of each). Note that many of the info I'm capturing do not produce intents (so I can't just register receivers)
Thanks a lot:)
Note that many of the info I'm capturing do not produce intents (so I can't just register receivers)
Then you won't be able to use an IntentService, since your app won't know when to fire it up.
If you want "real time" updating of info, then you will have to use a Service (with or without it's own background thread). You cannot use an AlarmManager because it will almost always run too late (not "real time").
Do note that it takes some effort to have your service run always as there are a couple of different scenarios where it can stop running, and even when you have done all you can to achieve it, there are still ways for OS or user to stop it from running.
I am working on an Android project and I need the app to work even when the device is locked.
The idea is to open the app that will start the (Intent)Service, the service processes the data all the time. The device can be locked/put away and after some time when the app is opened the service is manually stopped. The service should be running all the time in the background.
I have found information online, but I am not sure what to use and in which way..
I have found that the IntentService can be used. Also the service should run in a new thread. I need to process the data from gps all the time, should I use WakefulBroadcastReceiver?
Thank you.
IntentService is not necessarily what you want to use. It will automatically spawn a new thread just to handle an incoming Intent. Once all incoming Intents have been handled it will stop the Service. To have a long running Service, you would need to derive from Service and when it is started return START_STICKY from the onStartCommand() method, plus spawn your own thread to handle your background work.
If you need to monitor GPS, you'll have to manage that along with keeping the device awake using a WakeLock. Note that in Marshmallow, this gets more complicated because of the new Doze mode where even wakelocks are ignored.
Also, note that the way Android is architected there is still a chance that your application running the background Service may be killed. Android uses a unique process management technique based on memory pressure and user perceived priority to determine how long a process should stick around. I recommend reading up on the Service lifecycle in the documentation.
In android their is no fool proof way to ensure that your service runs forever because the LMK(low memory killer) when the system needs resources (based on a certain memory threshold) , kills the service then if it can restarts it. If you handle the restart properly the service will continue to run.
Services that are given foreground priority are significantly less likely to be killed off, so this might be your best bet. However their will be a notification of your service running the in the background on the menu bar up top. Foreground Service
I have an IntentService that downloads data from a server and I would like the IntentService to check for server updates at a certain interval. The following posts however advice against repeating a Service using a Timer - and instead emphasize on using an AlarmManager:
Why doesn't my Service work in Android? (I just want to log something ever 5 seconds)
Android - Service: Repeats only once
Android service stops
From Android's reference manual, an IntentService is described as:
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
The part I don't really understand is why an IntentService (the posts have questions that are directed towards a Service and not an IntentService) is not allowed to execute repetitively using a Timer as it creates its own worker thread for execution. Is it permissible to use a Timer within an IntentService ? Or are AlarmManagers the only solution to periodically execute an IntentService ?
An explanation to this would be most appreciated .
Or are AlarmManagers the only solution to periodically execute an IntentService ?
If you want it to work reliably, yes. Using AlarmManager is also much more friendly to the user.
First, do not have a Service of any form running except when it is actively delivering value to the user. Watching the clock tick is not actively delivering value to the user. Having a Service running gives your process a bit higher priority than other processes, in terms of what processes get terminated to free up system RAM for future work. Having a Service around unnecessarily -- such as simply watching the clock tick -- hampers the user's ability to multitask well, as you tie up system RAM unnecessarily.
This behavior will cause some users to attack you with task killers, such as swiping your app off the recent-tasks list. This will terminate your process, and therefore your Timer goes away too. Similarly, because too many sloppy developers keep their Service around for a long time, Android will automatically terminate such processes after some time, Service notwithstanding.
Finally, usually one facet of "check for server updates at a certain interval" is that you want this work to occur even if the device goes into sleep mode. With your everlasting-service approach, that will require you to keep the CPU on all the time, using a WakeLock. This will significantly impact the user's battery, causing your app to appear on the Settings app's "battery blame screen". That, in combination with the tying-up-system-RAM "feature", will likely incite some poor ratings for your app.
Instead, by using AlarmManager:
Your IntentService only needs to be running while it is doing its work ("check the server updates"), going away in between these events, so your process can be terminated to free up system RAM for other things that the user is doing
By use of the WakefulBroadcastReceiver or WakefulIntentService patterns, you can wake up the device briefly to do this work, then let the device go back to sleep again, thereby minimizing the impact on the battery
I need to run a background service in Android mobile which runs 24*7, And on Start & On mobile low battery and Hit a webservice every 1hr. Can you please suggest me any approach. I tried reading few articles but did not get any idea. I know here I need to paste some code after trying something. But I did not get any clue. Please let me know how to approach?
You will probably need to use the method startForeground(int id, Notification notification) to prevent the system from killing your Service as stated here:
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
Then you would need some kind of scheduled task to run every hour. Something like a ScheduledThreadPoolExecutor is ideal for this purpose, using the method scheduleAtFixedRate (Runnable command, long initialDelay, long period, TimeUnit unit).
The task that needs to be done each hour must be implemented as a Runnable and submitted to your ScheduledThreadPoolExecutor:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor( 1 );
executor.scheduleAtFixedRate( new MyRunnableTask(), 0, 1, TimeUnit.HOURS );
The Runnable task should be something like:
private class MyRunnableTask implements Runnable {
public void run() {
//Do what needs to be done.
}
I need to run a background service in Android mobile which runs 24*7
Please don't. For starters, it is not possible.
Users complain loudly and often about services that "run 24*7", because the services are tying up system resources (e.g., RAM) for no value. As a result, between third-party task killers and Force Stop options in Settings, users get rid of such services. When they do, particularly on Android 3.1+, your application will not run again, ever until the user manually launches an activity of yours from the launcher.
Android itself will get rid of such services on its own, because too many developers are too sloppy with their service management.
And on Start & On mobile low battery and Hit a webservice every 1hr.
Based on this list, you do not need "a background service in Android mobile which runs 24*7". You need to do work:
when the device starts up
when the device's battery is low
every hour
You can find out when the device starts up by the ACTION_BOOT_COMPLETED broadcast Intent. You can find out when the device's battery is low via the ACTION_BATTERY_LOW broadcast Intent. You can find out when time elapses via AlarmManager, where you establish your own alarm schedule (e.g., every hour).
All three of these triggers should call startService() on an IntentService. The IntentService will allow you to "Hit a Webservice" via its built-in background thread. And, the IntentService goes away when that work is complete, so you are not taking up memory all of the time.
And, if you want to wake up the device out of sleep mode for the every-hour condition, you will probably need to use something like my WakefulIntentService, as otherwise the device may fall back asleep while you are trying to "Hit a Webservice".
This way, your service is only running and taking up resources while it is actively delivering value to the user. It is not running and taking up resources when it is simply waiting for some other event to occur (e.g., the next 59 minutes).