I have an Android app that runs a background service that collects sensor reading every second.
I have found out that if there are other apps running, I do not collect my data every second (I have missing seconds).
I assume that the OS does not give me sufficient CPU time.
Can I change my service's priority, among the running tasks, so it will get a sufficient amount of CPU and complete it purpose?
(The service is called from an activity using StartService(mIntentService).)
The easiest would be to use startForeground() function that notifies the system to treat the service as a task user know about and would be disruptive to pause or terminate, so it will receive the same attention as the running apps.
You need to provide Notification object so the user is informed about the running service.
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 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
Question:
What are best practices for a persistent/always-on sensor data collection service in an embedded setting? Permanently attached power source and no user to aggravate with another running service, so no battery life or usability concerns.
Plan:
A local Service, startForeground(), START_STICKY, probably acquiring a PARTIAL_WAKE_LOCK, starting on BOOT_COMPLETED. This will not be a Play Store application. I will have an activity which can bind to the service to get feedback, set preferences, and manually start/stop the service if so desired. Since this will be running on a dedicated device with no UI and will not be reliant on battery power, which should bypass most of the usual concerns with services, is there anything else I can/should do to ensure the service runs at a high priority with the least likely chance it will be killed? Is there a better option than a service implemented in this way?
Background (optional reading):
I've written a multi-threaded Activity-based app which starts via a broadcast receiver on boot completed, runs through validations, runs a data collection thread, a data transmission thread which connects to a remote service, and executes other tasks which aren't pertinent to this discussion. I need to transition to a Service-based solution. From what I've read, best practices for a service which collects sensor data usually involve periodically starting the service via an AlarmManager. This will not work in my case.
In general, there's no issue with a Service receiving sensor data. But, be sure that you are processing any data on a background thread rather than in the SensorListener callbacks. If you need to keep receiving data even when the screen turns off, you'll need to hold a partial wakelock to prevent the system from going to a lower power state. Battery life is affected with the "foreground" service only because you are leaving the sensor activated at some interval. Otherwise, there's nothing magical about a service being considered foreground, other than it has a very low chance of being killed off by the framework.
You may also need to make sure the accuracy of the sensor doesn't change (via the listener callback) and if it is different than what your algorithms expect, you'll have to re-configure it with the SensorManager. An Activity based solution won't really do what you are talking about as the Activity is only "running" when it is visible to the user.
I would like to create an Android application with real-time monitoring functions. One monitoring function is to audit the audio flow. The other function is to interact with a peripheral sensor. These monitoring functions can be triggered by others.
Besides, in order to save power consumption, the audio function will be running in a polling mode, i.e. sleep for a certain amount of time and wake for a certain amount of time.
I am considering how to design the Android application.
Whether to design the audio function as a Service or an Activity?
The problem is if it is designed as an Activity, the audio function will be off if screen turns off after a period of time.
How to design the polling function? Use an AlarmManager or a inner-thread with Timer?
My goal is to save the power consumption as much as possible. Thanks.
I would recommend following
a) Use a Service. Activity is short lived entity (it works only while it's on the screen)
b) Make the service foreground (read this: http://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification). This will decrease the chance that system will kill your service
c) In the service, start a thread and do everything you need in the thread.
d) If you want execute periodically, just do Thread.sleep() in the thread (when Thread sleeps it doesn't consume CPU cycles).
I believe c) and d) is preferable to AlarmManager.
Here is piece from documentation (http://developer.android.com/reference/android/app/AlarmManager.html) : "Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler."
Since your application running it's better to have some permanently running thread and execute something on it. Generally speaking Handler, HandlerThread, MessageQueue are just convenience classes for more complex message handling and scheduling. It looks like your case is quite simple and usual Thread should be enough.
Concurring with Victor, you definitely want to use a Service, and pin it into memory by calling startForeground()
However I suggest you look into utilizing the built in system Handler ; place your functionality in a Runnable and call mhandler.postDelayed(myRunnable, <some point in future>) ; this will allow the android framework to make the most of power management.
That's a service.
And you may want some extra robustness: the service can be killed and NOT restarted later, even being a foreground service. That will stop your monitoring.
Start your service from the UI. If you want the service to survive device reboot, also start it from a BroadcastReceiver for android.intent.action.BOOT_COMPLETED.
Create a thread in the service as described in other answers here.
Additionally, use Alarm Manager to periodically start your service again. Multiple startService() calls are OK. If already running, the service will keep running. But if it's been forgotten by the system, say, after a series of low resource conditions, it will be restarted now.
Schedule those alarms responsibly: to be a good citizen, set the absolutely minimal frequency. After all, Android had some good reasons to kill the service.
With some services, even more steps may be needed, but in this case this approach seems to be sufficient.
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).