Some applications, in some cases, need to prevent the device from going to sleep to maintain a good user experience even if the user is not interacting with the device for an extended period of time. The simplest example, and probably the most relevant, is when a user is watching a video or movie on the device. In such a case, the CPU needs to decode the video while the screen needs to be on for the user to be able to watch it. Also, the screen should not be dimmed while the video is playing.
The WakeLock class allows for such scenarios, as shown in Listing 7–19.
private void runInWakeLock(Runnable runnable, int flags) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(flags, "My WakeLock");
wl.acquire();
runnable.run();
wl.release();
}
NOTE: Your application needs the WAKE_LOCK
permission to be able to use WakeLock objects.
How the system will behave depends on which flag is used when the WakeLock object is created. Android defines the following flags:
The flags can be combined with two more flags:
While their use is trivial, WakeLocks can cause significant problems if they are not released. A buggy application may simply forget to release a WakeLock, causing, for example, the display to remain on for a very long time, emptying the battery very quickly. In general, WakeLocks should be released as soon as possible. For example, an application acquiring a WakeLock when a video is playing should most likely release it when the video is paused, and acquire it again when the user starts playing the video again. It should also release the WakeLock when the application is paused and acquire it again when the application is resumed (if the video is still playing at that time). As you can see, the number of different cases to handle can grow quickly, making your application prone to have bugs.
To prevent possible problems, it is recommended you use the timeout version of WakeLock.acquire()
, which will guarantee the WakeLock will be released after the given timeout. For example, an application playing a video could use the duration of the video as the WakeLock timeout.
Alternatively, if keeping the screen on is associated with a view in an activity, you can use the XML attribute android:keepScreenOn
in your layout files. A benefit of using that approach is that you don’t take the risk of forgetting to release the WakeLock, as it is handled by the system and no additional permission is needed in the application’s manifest file. Listing 7–20 shows how to use the attribute with a linear layout element.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:keepScreenOn="true"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
…
</LinearLayout>
TIP: android:keepScreenOn
can be used in any view. As long as one visible view specifies the screen should remain on, the screen will remain on. You can also control whether the screen should remain on with the View.setKeepScreenOn()
method.
Despite the problems they may cause, WakeLocks are sometimes necessary. If you have to use them, make sure you carefully think about when they should be acquired and when they should be released. Also make sure you fully understand your application’s lifecycle, and make sure the test cases are exhaustive. WakeLocks are only problematic when bugs exist!
3.139.83.96