I's like my Android app to close down after a period of disuse. Without screen rotation, I've easily implemented a solution with Timer/TimerTask. Alas, when the screen rotates, everything is (understandably) messed up.
The time out period is typically 10 minutes and the user has to be able to reset the clock to zero at anytime, invoking another 10 minute period.
So what's the preferred approach to do the timing in the background, be able to reset the clock, and ultimately receive a shutdown notice, despite an occasional screen rotation? I've looked at IntentService, but don't see how to reset the clock, or know the preferred way of getting the shutdown notice back. And everything must be set up so that access to the timer is available after the app reconstruction on rotation.
Thanks,
Chris
Related
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
My application should detect whether the user was sleeping to start itself with a welcome message when the user wakes up and powers up his phone for the first time in the morning, afternoon, or whenever he wakes up, by pressing the power putton and entering the pattern on the homescreen or pin or whatever.
I want to do this by measuring the time the device was used the last time. I presume 8 hours of sleep, so if 8 hours passed since the last switching off, the next time the mobile phone is being switched on, the application starts(respectively a function inside).
The screen going on because of an alarm or anything but user interaction should not count.
I looked at logcat and it gave me the useful information I/PowerManagerService: Going to sleep due to power button. So a PowerManagerServiceListener could be a way. I found https://developer.android.com/reference/android/os/PowerManager.html but it is for actively keeping the display on, not for passively reporting it.
Another candidate is KeyguardViewMediator: onStartedGoingToSleep(2) and KeyguardServiceDelegate: onScreenTurnedOff().
Sure, I could create a polling application, that looks through logcat, but that sounds like a strongly battery draining approach.
Which performance friendly way is there to accomplish what I want?
According to your description, you are interested in a granularity of hours. Then you can schedule a repeating alarm every hour (see Scheduling Repeating Alarms), save the time in a Shared Preference, receive a BOOT_COMPLETED broadcast, compare the times and decide what to do.
However, I guess a lot of users don't turn their devices off, so I would try to find out if the assumption your approach is based on is valid.
You can also try getDetectedActivity() from Snapshot Awareness API and check if DetectedActivity is for example STILL at some specified interval.
my application collects periodically Activity Recognition's Detected activity data.
I implemented it exactly as described in the documentation , but with one minute interval.
as long as the user is logged in - the application registered with a PendingIntent to receive updates from google play process..
please not lecture me about battery usage, network, and performance problem derived from request updates each minute, unless it have something to do with my problem:
the problem: in some devices (in Nexus 5 it happens the most), for a 5-6 hours in the middle of the night - the IntentService stopped been called.
I'm not sure, but suspects it have something to do with Google optimizations and the significant motion sensor not detecting any motion entering the activity recognition mechanism to be in sort of idle mode, as described in the documentation that can happened.
it's important to my app to know what is the current activity each minute approximately even if it stay the same, or idle for a long time..
my question:
how can I know if the periodically activity recognition stopped been called because of the significant motion sensor or from any other reason?
it there a way to force somehow the Google play process to perform activity updates without stop it for a time it assumes not needed?
Per ActivityRecognitionClient.requestActivityUpdates:
To conserve battery, activity reporting may stop when the device is 'STILL' for an extended period of time. It will resume once the device moves again. This only happens on devices that support the Sensor.TYPE_SIGNIFICANT_MOTION hardware.
As you suspected. There's no reason you cannot save the last value using the many data storage techniques - a simple SharedPreference might be enough for your case.
If you are directly triggering actions based on the IntentService being called (a bad idea since other apps may cause it to trigger extremely quickly) rather than only on changes in activity, then you should decouple those actions and instead set an alarm or trigger a periodic sync adapter for whatever specific time interval you need, reading the current value from the last activity you received.
I'm developing an application which needs to run small chunks of code frequently (once every two seconds, for example). I've tried to make it work using the simple Thread.sleep() (or android.os.SystemClock.sleep() to avoid interrupts, and finally I've tried with Timer and Handler), but the result is that the time that the program sleeps is random (or it simply doesn't run if I use Timer or Handler as the system discards they messages when the screen is off), as the system goes to a deep sleep mode during screen off.
For example the code works right if I have the phone plugged into the charger, or is playing music (that avoids the deep sleep mode), but when the phone isn't doing anything the time can grow from two seconds sleep up to minutes of sleep.
From https://groups.google.com/forum/#!topic/android-developers/Eqwp8Uiy2f0 seems that the only alternative is to use the AlarmManager to force the wake, but that way will probably cause too much battery drain.
Is there any alternative?
If not, is there any way to detect when the system goes into the deep sleep mode?
It is too late but may be useful for somebody else.
Yes, Timers does not work in deep sleep mode.I think there is no other better way than AlarmManager to run something periodically in deep sleep mode.
Also, as your frequency is just 2 seconds I think you may have to go for exact alamrs (setExact() ) as the regular alarm may not serve you better if your requirement is critical in time. And sometimes even setExact might not capture the wake lock I observed. So you have to acquire your own (PARTIAL_..) wake lock and, do stuff and release the lock.
But is it must that you have to run evvery 2 seconds ?
If not continue using Timers which will continue working automatically after the device wake up.
Take a look at Should I use AlarmManager or Handler?
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