Cannot keep sensor update rate after screen-off - android

My application needs to collect data from both sensors and GPS, but it seems that after I turn the screen off, the update rate slows down considerably (to 500ms, down from 20ms, or stops completely, in another phone).
I've read several workarounds: one of them involved using a wake-lock, to keep the process running, and another that says to register a broadcast receiver to re-register the event listeners after a screen-off event.
Both don't return errors while executing, but somehow the sensors stop behaving exactly after the screen turns off (and coincidentally, they start behaving right after I press the power button, nevermind unlocking the screen).
I'm registering the BroadcastReceiver from within an activity, to the "ACTION_SCREEN_OFF" event, an acquiring the wake lock from there aswell, on the 'onCreate'method.
I'm using a Lenovo A60 with Android 2.3.5, and an LG Optimus Pro with Android 2.3.4.

At this time, there are two possible answers to this question:
If your cellphone is a part of this list (or one that still isn't, but has a similar underlying sensor implementation), then you can use the method described here to implement a workaround using BroadcastReceivers to restart sensor listening after the screen turns off;
You can use a wake-lock or another method to keep the screen on and
use a "press back twice to exit" schemes in order to safeguard the
user from closing the activity

Related

'Sleep' issue with GPS location updates on some devices

I have an app that uses GPS for regular updates. It used to be the case that when the device was put to sleep (screen turned off, screen timeout etc), the location updates kept on coming through. This was on an HTC Desire running 2.2.
I need that behaviour for various reasons.
However, now being tested on an HTC Desire S running 4.0.4, and what seems to happen is that updates continue (1/sec) for about 5 seconds after entering sleep mode, but then stop. However, exactly the same code running on a Google Nexus 7 running 4.4.2, and the updates keep coming through.
The activity life cycle seems to be doing all the right things (onPause when entering sleep, onResume when exiting sleep), but on the Desire S, the location updates stop.
Whilst no doubt it is more power efficient to turn them off, I need them on. The behaviour seems OS and/or device dependant. How can I achieve that?
Edit: actually I've found that location updates do keep coming, just much less frequently than requested.
First of all only the onPause() is called with 100% of probability by OS, onStop() and onDestroy() could be not called by OS. You should unregister in onPause(), in addition the design is wrong because to do it you have two options:
1) Use a pending intent with a broadcast receiver/intent service to manage the position;
2) Use a foreground service to install a location listener.
Activity it's not the good place to do this thing.
Actually the simplest way of doing this seems to be a partial wake lock.

What happens when phone's screen is off?

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

Injecting screen_on event to make sensors work when screen is off

I am trying to make sensors work when screen is off. It is well known bug. And there is no any soution for this on all phones. I have the hypothesis that i can can cheat kernel if I send(inject) screen_on event while actually the screen will be turned off. Do you have any ideas how can i check my hypothesis and inject such event?
Why don't you start a background service that monitors the sensors?
And then send/use the results back to your application's activities.
Your activity will still pause when screen goes off, but you will continue to read the sensor data.
Also a good idea to do the heavy processing the background service as well...
This works great for me.

Android: Sleep stages/levels on an Android device?

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.

Problem with thread after SCREEN_OFF in Android

I’m doing an application that listens to the android.intent.action.SCREEN_OFF in a Service (if that matter) and then it is supposed to wait a few seconds and launch an action, I’ve tried a timer schedule method, thread and handler postDelay method but all of them seems to fail, they are never executed on a device, it seems like it’s being freezed/killed after phone is locked. It works on emulator and on device attached to USB, but never with device working on battery only, which actually is a main scenario.
Do you know any solutions to this?
I cannot test this now (not near my Android device at the moment), but...
Does the broadcast receiver fire at all?
If so, right as you get called, you will need to grab a partial Wake Lock so the CPU stays awake until the timer fires.
chances are you have your phone set so that when it is plugged in, it never actually locks or sleeps (its one of the developer settings) and imagine the emulator behaves the same way. so you will either have to override the phone's lock settings or change your method. the general rule is that when the screen shuts off, your activity ends.
A partial wake lock keeps the CPU running, so you should acquire it inside your broadcast receiver for screen_off, and release it after you're done with whatever you're doing. When you're plugged into the USB, the CPU stays on to service the USB connection (in fact, the usb stuff in the kernel holds its own wake lock).
And to answer your other question, yes, even background threads. As soon as everyone is done handling the screen_off broadcast, the CPU is turned off, and you won't run again until someone turns the CPU back on.

Categories

Resources