I'm currently struggling to keep my service alive when trying to get information about the user for a study. We are using a foreground service, which runs a timer on a 5-sec interval checking a resource of the user. As that resource is only relevant if the screen is on, we could stop the timer whenever the screen goes off. For this, we are using a broadcast service. All in all, this works well. The problem occurs, if the user closes the app and then puts the device on standby -> screen goes off. We would like to stop the timer and restart the timer inside that service if the screen goes on again. Now theoretically that works. I tested it with a counter variable which increments each time the run is called inside the timer. After that, I update my notification and show that variable. If however I close the app and the screen goes off, this variable is no longer updated in the notification and ergo, my resource check is not running. But I found out, that once I restart the app, the variable did indeed increase every 5sec and is then updated in the notification again. Furthermore, it is working if the device is on power/getting charged. So I guess it is a power management thing.
Summary: The ForegroundService/BroadcastReceiver is not acting like I would want to if the app is closed and the screen goes off, even though a part of it is working as intended. Works completely if the device is charging.
Do you have any ideas on how to avoid this behavior and allow the service to rerun the timer correctly so that the methods inside will work again?
Best regards,
Yukko
Hello I've a basically simple question to ask, what happens to the android OS when my smartphone's screen goes off ? I've noticed a couple of misleading behaviours into my application like :
When screen is off I cannot anymore get results from bluetooth scan, it's like there are no more active devices around me while actually there are like 3-4.
When screen is off most of the times I cannot send or receive messages from other devices via bluetooth.
As soon as I turn the screen on everything start to work fine again, then I turn off the screen again and after like 5-10 my phone stops working properly. I don't have anything inside the onPause method.
Is there somekind of trigger that get fired every X minutes that leads the devices into sleep/hibernate mode?
EDIT :
I decided to call every X min a full wake lock but for some reason my application started to behave weirdly. Yesterday I noticed that the system killed on purpose my application calling the onDestroy() method. Is this even possible? I mean my application uses like 32 MB of RAM and on my test phones I have like hundreds MB of free memory.
In another case the system closed my app and restarted it, how can this happen?
Sometime after the screen turns off, based on user settings for inactivity.
CPU might sleep and threads might suspend..
so you WAKE_LOCK or AlarmManager ...
AlarmManager has a method to setRepeating Alarm every X seconds
i've got a problem with my Android FileObserver.
I have a background service running (returns START_STICKY), which references two FileObservers.
Everything is working fine until the device is set to sleep mode, which will stop the service, as far as i know.
Does anybody know what exactly happens to the Service/FileObserver when a device is put to sleep mode?
Can the service get notified before freezing so I can save a file list of the observed folder and compare it to a new list when the device gets waked up again?
I don't want to use a wakelock because of its impact on battery life.
Will the FileObserver Event be fired for changes to folders which happend while my service was set to sleep, as soon as I turn the screen back on?
That can't really test it because usb debugging keeps the device awake.
Thanks for your help!
Everything is working fine until the device is set to sleep mode, which will stop the service, as far as i know
No, it stops the CPU.
Does anybody know what exactly happens to the Service/FileObserver when a device is put to sleep mode?
The CPU is stopped. Stopped CPUs will not execute instructions. It is reminiscent of putting your development computer in suspend mode.
(the details are significantly more complicated but usually are not relevant at the SDK level, IMHO)
Can the service get notified before freezing so I can save a file list of the observed folder and compare it to a new list when the device gets waked up again?
No.
Will the FileObserver Event be fired for changes to folders which happend while my service was set to sleep, as soon as I turn the screen back on?
I haven't tried that.
That can't really test it because usb debugging keeps the device awake.
Then unplug the USB cable. Use Log statements to record the results that you wish to monitor. Plug in the USB cable after your test period to examine LogCat and see your logs.
Generally speaking, your overall solution (continuously-running service) is user-hostile. Please don't complain when users attack you with task killers and the Force Stop button.
Whenever I leave my app running for awhile (~9 hours last time) whatever activity the phone has up will stop responding and need to be force closed, after which there's just a black screen below the slide down notification area and pressing back or home changes nothing. I cannot turn the phone off normally either, as it just spins endlessly when trying to turn the phone off. I need to remove and reinsert the battery.
My app has a background service which monitors for a bluetooth device and runs accept threads with 30 second timeouts. I believe I'm handling them properly as there's only ever 1 shown in my debug screen. I have seen this phone freezing behavior while having the device connected for the entire duration and not having it connect at all.
I have tried keeping the phone connected to logcat to see what happens when the phone freezes up but it always stops receiving updates from the phone after some time, maybe an hour or two at best? Hard to estimate since I'm usually doing something else while waiting.
Does anyone have any tips for what could be causing this or how I can get some additonal feedback to work with?
if your service runs in the background , the OS might kill it after some time , and you must know how to handle it within the service .
services that do a lot of work will be good candidates of being killed .
if you wish your service to do long work (30 seconds is quite a long time) , you should set your service as a foreground service , with a notification .
if you don't wish your service to be a foreground service , try to recover your state when being killed , and try to optimize your code further .
for more information of how services run on android , read this link .
Is there a notion of sleep stages/levels on Android?
From browsing the mailing lists, I'm aware that there exist a stage called "Deep Sleep". Do execution for all apps halt when device reaches this state? If so, besides user hitting the power button, what else could wake the device back up?
From browsing the mailing lists, I'm aware that there exist a stage called "Deep Sleep".
There is not really a separate stage called "deep sleep". There is only "awake", "asleep", and "off".
Do execution for all apps halt when device reaches this state?
Execution of all processes ceases when the device goes to sleep or is powered off.
If so, besides user hitting the power button, what else could wake the device back up?
An alarm from AlarmManager
An incoming phone call
An incoming text message
If you have a socket open on wireless data (not WiFi), an incoming packet on that socket
Those are the big ones. There might be others.
I've noticed the following behaviour:
You have your activity open and stop interacting with it
After a few seconds (it depends on how the device is configured) the screen will go off.
When the screen goes off, onSaveInstance and onPause are called.
A few seconds later (usually ~15s) the device enters into sleep mode (is this the correct name?)
When this happens, the following methods are invoked: onStop (calling isFinishing returns false), onRetainNonConfigurationInstance and onDestroy.
So far so good. Now, the strange behaviour begins: just after the last onDestroy finishes, another activity is created: onCreate, onStart, onRestoreInstanceState, onResume and finally onPause are invoked.
I find no reason for this strange behaviour. Why would another activity be created just to go straight to pause mode? This happens immediatly after onDestroy of the original activity!
This was tested on Galaxy S. I didn't test what happens after a few hours with no activity. I'm not sure if anything else will happen.
I hope this will help you.
A short addition to the commonsware's list. After looking for a way to run methods periodically while phone is asleep, I've found out that TimerTask functions during sleep mode.
TimerTask is, in my experience, easier to work with if all you want is to run methods from a service and not to start an activity.
In Android API 23 the way 'sleep' works was been changed. They have added Doze and App Standby. You can read about both of them here.
Doze: This would be 'sleep'. A few minutes after the screen shuts off the phone will enter this mode shutting down all network connections. Then at certain intervals (maybe a linear back-off policy for example) the apps will be 'allowed' to access the network for ~10 seconds. There is no real way around this if you want to publish your app to Google Play outside of using Google FCM. It might also be worth noting that uptimeMillis is not guaranteed to be updated during Doze because the CPU can enter deep sleep mode (elapsedRealtime will still be accurate).
App Standby: This will essentially stop your app if the device determines that the app is 'idle'. An idle app is a state that is determined by these factors
Has the app been launched by the user?
Has the app run a foreground service?
Has the app generated a notification?
Is the app an active device admin app?
If the answer to all of these is no, the app will be set to 'idle' and have greatly restricted network access (allowed once a day and/or while charging only). I am not sure how long an app must meet these criteria. However, it seems to be at least a few days before the App Standby state will be entered.
Bonus: Device States (managed by DeviceIdleController)
ACTIVE - In use, or connected to a power source.
INACTIVE - Device has come out of the active state (user turned off the screen or unplugged it)
IDLE_PENDING - About to enter idle mode.
IDLE - Device is idle (Different than an app being flagged as idle from App Standby. This is the entire device.).
IDLE_MAINTENANCE - Open for applications to do processing (10 second window).
If you want a background service or worker to check if the app is in the IDLE state then you can use the function isDeviceIdleMode (only works when entering Deep Doze, see below).
Example
(getSystemService(Context.POWER_SERVICE) as PowerManager).isDeviceIdleMode
Some more complications
API 24 added more complexities to the Doze mode (Light Doze and Deep Doze). This essentially puts nested states inside the device states.
API 28 added "Adaptive Battery" prediction, which makes use of Doze to hibernate user apps the OS determines the user will not use.
API 28 also added "App Standby Buckets" to add more states to App Standby than just idle and active.
Besides the "awake", "asleep", and "off" states that #CommonsWare mentioned, there is the distinction between whether the CPU is asleep, or just the screen is. For example, the official docs here describe it this way:
To avoid draining the battery, an Android device that is left idle
quickly falls asleep. However, there are times when an application
needs to wake up the screen or the CPU and keep it awake to complete
some work. [emphasis added]
In the three-stage framework that CommonsWare described, a device whose screen is dark is probably not categorized as "asleep" unless the CPU is also stopped. But as the above paragraph implies, the screen-dark state can legitimately be referred to as "asleep." No doubt this is why people refer to "deep sleep" to clarify that they're talking about the CPU being asleep.
This doc page also mentions
When an Android device is left idle, it will first dim, then turn off
the screen, and ultimately turn off the CPU. This prevents the
device's battery from quickly getting drained.
So if you want to be comprehensive, you could add "dim" to the list of "sleep stages/levels":
awake
dim
screen off
CPU off (true "sleep" or "deep sleep")
power off
Apparently the transition from 2 to 3 to 4 is pretty fast when the idle timeout occurs. But there are other times when the screen can be off without a transition to deep sleep; e.g. when playing audio (at least in certain apps).
I wish I could tell you how to predict when the device will transition from screen off to CPU off -- e.g. how long the timeout is -- but I haven't found that information. What I have found is FLAG_KEEP_SCREEN_ON and WAKE_LOCK to prevent one or the other from happening.
P.S. If you want to be exhaustive, you could count daydream in your list of "sleep stages":
Daydream is a new [as of Android 4.2] interactive screensaver mode for Android devices. It
activates automatically when the device is inserted into a dock or
when the device is left idle while plugged in to a charger (instead of
turning the screen off).
From the point of view of the previously-running app, it sounds like daydream behaves like switching to a different app. So it's not really a matter of the device sleeping, though your activity does get stopped, I would assume.