How to release a wake lock? - android

I am setting a wake lock using wl.acquire(). This works fine. I need that wake lock as long as my application lives, so calling release() can only be done when the application is left.
Do I have to call release() somewhere? For example in onStop()? I would say no, but I am not sure.

if you refer yourself to these 2 pages:
http://developer.android.com/reference/android/os/PowerManager.html
http://developer.android.com/reference/android/os/PowerManager.WakeLock.html#release()
You should release the wake lock as soon as you can: therefore if your app is closing/pausing release it!
Also, word of advice, make absolutely sure you need a wake lock, when you need it and for ho long.
in my case I put one only for the in game screen to avoid the users screen going black while thinking (since it is an opengl app it takes a few seconds to fully load), but in the other views I release it.
Trust me when I say that it is annoying for a user to end up with a empty battery because an app was forcing itself to stay awake.

Beside the others useful answers you already received, I just found this interesting answer about how to force screen on, maybe you'll find it useful too, if you don't really need a wake lock.

as long as my application lives
how many activities your application has? you can release it in onDestroy() of last activity that gets popped by activitymanager.
And yes, you must release the lock especially if you are going to keep the screen brightness on, to avoid battery drain.

Related

PARTIAL_WAKE_LOCK kills my mediaplayer

I implemented a wakelock to avoid stopping my MediaPlayer (playing local files only) when screen goes off. Since I don't want to drain battery, I tried a PARTIAL_WAKE_LOCK. But it has no effect: screen off kills my player. FULL_WAKE_LOCK works fine, but screen stays on, as expected, draining the battery...
What am I doing wrong?
Thanks!
L.
It looks like you are using the wake lock for the wrong purpose. From what I understood based on your explanation: you need the playback to continue when the screen goes off:
To do that - I would recommend you try the following logic.
Try to have the player running in a service (not in the activity)
Start the service with startForeground method (this will need you to include a notification as well)
Use a Messenger to communicate between your activity and service.
But the wake lock may come handy; as this may be helpful in handling a audio stutter issue in future. I am not very sure about this part as I myself is yet to try out the wake lock as a solution to stuttering issue.
(I am not a professional/commercial programmer ; rather an ad-hoc developer who finds a requirement designs a solution, develops it and uses it for myself. So my solution might not be a 100% professional approach but I am sure it does the job)
Good Luck and happy coding
- S.Mani
Wake Lock is to make sure the device does NOT go into standby.
What you want is to listen for Intent.ACTION_SCREEN_OFF that tells you that the screen is now off

Is it possible to hold multiple Wake Locks?

I'm developing a small utility app that scans 2D barcodes, and then submits each barcode to an IntentService where a longer task is performed.
When the activity is shown, it should prevent the device from sleeping, until the barcode is processed in the service. If the service finishes the processing, it stops itself, but the activity should still be visible.
I'd like to hold a SCREEN_DIM_WAKE_LOCK WakeLock during the activity lifecycle, but as this type doesn't prevent the CPU from sleeping, I'd also need to acquire a PARTIAL_WAKE_LOCK in the activity when a new 2D code is scanned, and release it in the intent service after it has been processed.
The SCREEN_DIM_WAKE_LOCK purpose is to avoid the user the inconvenience of pushing the power button each few seconds to wake up the device and be able to read a new barcode. The user will have to read a great number of codes one after another and the activity should be around even for the short intervals where there's no user interaction.
I know in Android there's no 100% guarantee of the app being on top, not closed, or foregrounded due to several conditions my app can't control, but I'd like to go as far as I can.
So it is possible to hold multiple WakeLocks? Where could they be declared to be accesed both by the activity and the service? (Singleton, extending Application?)
It is possible to hold multiple WakeLocks. In fact it's done all the time when multiple applications sync at the same time when the screen is off. (Imagine your GMail and Facebook apps sync at the same time when the screen is locked. They don't know about each other will have different WakeLocks. May or may not be different types of WakeLocks)
Android will make sure everyone's expectations are met (maximum battery drain in other words.)
In my opinion, I think you're over-thinking the fact that you need a SCREEN_DIM_WAKE_LOCK as this can accidentally drain a LOT of battery, but I may be wrong depending on your use case.
So the short answer is YES. You can hold multiple WakeLocks and Android will (should) act as expected. Only thing to keep in mind is that you release both Wakelocks properly.
In the issue of getting on top of the screen, I think you should release the WakeLock of your activity when it goes to Paused state (when somehow another activity is on top, or use intentionally press the power button). Because at this point, user is interacting with another app, and you should respect it and let it control its own behaviour. You don't have to give up the partial wake lock from your service until you're done.
Hope This Helps.

Are wake_locks automatically released when an Activity/Service holding it is terminated or finishes?

I know that it is best practice to release a wake_lock as soon as it is no more needed, but what happens if the Activity or Service, for example, that has acquired it finishes or is stopped before you release the lock? Is it automatically released by the system? I think the system should release them automatically in that case, but I can not find anything on the API docs..
EDIT: added more info
Looking at the PowerManager.WakeLock documentation, I've seen that the wake_locks are reference counted by default (read setReferenceCounted here), i.e. if we retrieve a wake lock in an activity with PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myWakeLock"); wl.acquire(); and then the reference variable wl that holds it goes out of scope, then the wake lock is released because its reference count goes to zero... is it right?
EDIT: wrong understanding above
I think I've misunderstood the reference count concept above... it should mean that if I acquire twice the lock and release it only once, then the reference count is 1 and the lock is not yet released. If it is not reference counted, then I can acquire x times and then with a single release it is released.
There seems to be a lot of misinformation spread on the web about this. WakeLocks as exposed in the Android API have a pretty complex lifecycle and there is really no other way than be super diligent about managing it.
If an Activity or Service stops without you releasing a wakelock the state is undefined. If you inspect the code (https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/PowerManager.java, search for "class WakeLock") you will see that they are released when they are garbage collected.
This, "when they are garbage collected", however, is an extremely loose statement. In practice it seems that devices pre-Lollipop er really slow to GC the wakelocks (we can pretend it's not happening at all for practical purposes), but on post-Lollipop devices with the ART runtime it seems that stray WakeLocks are garbage collected within a few seconds.
On your questions about reference counting, you can see in the Android code that the lock is released disregarding what count it has.
If you do a blame on the Android code you can also see that it has not changed much over the years - so it all comes down to how the GC behaves. So you need to be diligent, store the lock in a field on your activity/service and release/acquire in sensible places in the app lifecycle. But if at all possible you should not be using a wakelock, but just the Force Screen On trick that Gatekeeper links to in one of the other answers.
Only if the process is destroyed then will the wakelocks be released. Just by finishing the service / Activity wake_lock will not be released.
I believe this answer will help you leaps and bounds Force Screen On
The PowerManager API states that you should release a wakelock as soon as possible, using the PowerManager API is known for draining more battery. Also in it API it states:
*If you hold a partial wakelock, the CPU will continue to run, irrespective of any timers and even after the user presses the power
button. In all other wakelocks, the CPU will run, but the user can
still put the device to sleep using the power button.
http://developer.android.com/reference/android/os/PowerManager.html
As detailed in this answer if the process is killed then yes the wakelock is released. But if the service or activity finishes normally without releasing the answer should be no.

Android battery usage keep awake explanation

In the Battery usage screen there is a time for "Keep awake". What does that mean exactly? Is there any documentation somewhere about those numbers?
This appears to show the amount of time that an app has asked the OS to stay in a waking state.
You can see the options available to the developer in the PowerManager class.
For example, an app can request a PARTIAL_WAKE_LOCK. As long as at least one app has requested a partial wake lock, the device will stay active (and consuming battery) even when the screen is off. From the docs:
If the user presses the power button, then the screen will be turned
off but the CPU will be kept on until all partial wake locks have been
released.
I believe the Keep awake time is reporting for how long a given app had this flag set.
Examples on my phone right now,
Google Chrome Beta has an extremely short Keep awake time, 5s. This looks very well behaved.
Another app known to be a terrible battery hog has a Keep awake of nearly 2 hours, despite being actively used for only a few minutes. I would guess this app is not releasing its partial wake lock.
This talk from Google IO on Coding for Battery life kind of clears it a little better:
http://developer.android.com/videos/index.html#v=OUemfrKe65c
It keeps the screen awake while charging. You can check this discussion.
http://www.droidforums.net/forum/team-d1-miui/103349-battery-settings-question-stay-awake.html
You may also note that this time that you talk about seems like the time which this phone uses this function.
I believe it is to keep your screen from sleeping while you recharge your battery.
Here's a relevant topic:
http://www.droidforums.net/forum/team-d1-miui/103349-battery-settings-question-stay-awake.html

Android: Change delay before the phone is put to sleep while my app is running

This question sounds so easy I can't believe I can't find information on it (maybe I have the wrong key words in mind...)
I'm looking for a way to change the delay before the phone is put to sleep when my app is running.
I was using wake locks until now to prevent my app from being closed to frequently (its and opengl app and the loading time is a killer specially on slow phones).
I don't like the idea of indefinitely leaving the phone on (mainly because it empties the battery fast to have a full opengl app running).
Is there a way then to change the delay before the phones goes to sleep to 2~3min ?
I would also like to add that I do not wish to change the settings of the phone (that is only the users decision)
Jason
edited to correct the term "application going to sleep" which was pointed out as being incorrect.
Create a Timer object and release() your wake lock in the timer task. I'm relatively sure you can release a lock in a worker thread, but worst case, you'd need to use runOnUiThread if I'm incorrect.
Be sure to handle the case when onPause() is called and cancel your timer in that case and release the lock immediately.
In general, I'm not a fan of wake locks, but if this is to make your boss happy, wake-lock away.
EDIT: Btw, the system setting for the UI timeout is accessible by apps: SCREEN_OFF_TIMEOUT in android.provider.Settings.System. But really, this is for private applications only, public applications have no business changing this value.

Categories

Resources