代码改变世界

WakeLock的使用

2012-10-30 21:12  ...平..淡...  阅读(5104)  评论(0编辑  收藏  举报

android系统在手机无操作的情况下,为了省电,一般会变暗,关闭屏幕。而系统的电源管理,主要由PowerManager 和PowerManager.WakerLock类进行控制。

PowerManager:  This class gives you control of the power state of the device.

PowerManager.WakeLock:  lets you say that you need to have the device on.

Android中通过各种Lock锁对电源进行控制,需要注意的是加锁和解锁必须成对出现。

 

注意项:

(1) 创建和使用WakeLock会对应用程序造成的电池电量消耗产生显著的影响。因此,最好只在确实有必要时使用WakeLock,并且使用它们的时间越少越好,只要有可能就释放它们。屏幕WakeLock通常用于在用户观看屏幕但是很少与屏幕进行交互期间(例如,播放视频)防止屏幕变暗。

(2) 如果在广播接收器的onReceive处理程序中启动一个服务或广播一个意图,那么有可能在服务启动以前,所使用的WakeLock就会被释放。为了确保服务能够执行,需要放置一个独立的WakeLock。

 

PowerManager和WakeLock的使用:

private void acquireWakeLock() {
if (wakeLock ==null) {
        Logger.d("Acquiring wake lock");
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, this.getClass().getCanonicalName());
        wakeLock.acquire();
    }
}


private void releaseWakeLock() {
    if (wakeLock !=null&& wakeLock.isHeld()) {
        wakeLock.release();
        wakeLock =null;
    }
}

acquireWakeLock()方法中获取了 SCREEN_DIM_WAKE_LOCK锁,该锁使CPU保持运转,屏幕保持亮度(可以变灰)。releaseWakeLock()方法则是释放该锁。

步骤分析:

1.通过 Context.getSystemService()方法获取PowerManager实例。

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);

2.然后通过PowerManager的newWakeLock((int flags, String tag)来生成WakeLock实例。int Flags指示要获取哪种WakeLock,不同的Lock对cpu/屏幕/键盘灯有不同影响。

WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock"); 

 

3.获取WakeLock实例后通过acquire()获取相应的锁,然后进行其他业务逻辑的操作

wakeLock.acquire();

4.最后使用release()释放WakeLock(释放是必须的)

wakeLock.release(); 

 

关于int flags

各种锁的类型对CPU 、屏幕、键盘的影响:
 
Flag ValueCPUScreenKeyboard
PARTIAL_WAKE_LOCK On* Off Off
SCREEN_DIM_WAKE_LOCK On Dim Off
SCREEN_BRIGHT_WAKE_LOCK On Bright Off
FULL_WAKE_LOCK On Bright Bright
 

 

PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。

SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯

SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯

FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度

还有以下两种,只影响屏幕的行为:

ACQUIRE_CAUSES_WAKEUP:Normal wake locks don't actually turn on the illumination. Instead, they cause the illumination to remain on once it turns on (e.g. from user activity). This flag will force the screen and/or keyboard to turn on immediately, when the WakeLock is acquired. A typical use would be for notifications which are important for the user to see immediately.

ON_AFTER_RELEASE:f this flag is set, the user activity timer will be reset when the WakeLock is released, causing the illumination to remain on a bit longer. This can be used to reduce flicker if you are cycling between wake lock conditions.

 

设置权限

要进行电源的操作需要在AndroidManifest.xml中声明该应用有设置电源管理的权限。
<uses-permission android:name="android.permission.WAKE_LOCK"/>
你可能还需要
<uses-permission android:name="android.permission.DEVICE_POWER"/>   
<!--但是 DEVICE_POWER 权限一般只适用于系统应用程序;在app中就算加入该权限,也不能获得相应功能-->
另外WakeLock的设置是 Activiy 级别的,不是针对整个Application应用的。

 

参考:

android的PowerManager和PowerManager.WakeLock

android电源管理

 

-------------------------------------------------------------------------------------------------------------------------------------

Android提供了现成android.os.PowerManager,该类用于控制设备的电源状态的切换。

该类对外有三个接口函数:

1.void goToSleep(long time);//强制设备进入Sleep状态

Note:

尝试在应用层调用该函数,却不能成功,出现的错误好象是权限不够,但在Framework下面的Service里调用是可以的

 

2.newWakeLock(int flags, String tag);   //取得相应层次的锁

flags参数说明(同上):

PARTIAL_WAKE_LOCK: Screen off, keyboard light off

SCREEN_DIM_WAKE_LOCK: screen dim, keyboard light off

SCREEN_BRIGHT_WAKE_LOCK: screen bright, keyboard light off

FULL_WAKE_LOCK: screen bright, keyboard bright

ACQUIRE_CAUSES_WAKEUP: 一旦有请求锁时强制打开Screenkeyboard light

ON_AFTER_RELEASE: 在释放锁时reset activity timer

Note:

如果申请了partial wakelock,那么即使按Power键,系统也不会进入Sleep,如Music播放时,即时屏幕已经关闭,但是系统不会停止,继续运行;

如果申请了其它的wakelocks,按Power键,系统还是会进入Sleep

 

3.void userActivity(long when, boolean noChangeLights);

//User activity事件发生,设备会被切换到Full on的状态,同时Reset Screen off timer.

 

PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);

PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, “My Tag”);

wl.acquire();

.…….

wl.release();

 

Note:

1.在使用以上函数的应用程序中,必须在其Manifest.xml文件中加入下面的权限:

< uses-permission android:name="android.permission.WAKE_LOCK" />

< uses-permission android:name="android.permission.DEVICE_POWER" />

2. 所有的锁必须成对的使用,如果申请了而没有及时释放会造成系统故障.如申请了partial wakelock,而没有及时释放,那系统就永远进入不了Sleep模式.

其主要代码文件如下:

frameworks\base\core\java\android\os\PowerManager.java

frameworks\base\services\java\com\android\server\PowerManagerService.java

frameworks\base\core\java\android\os\Power.java

frameworks\base\core\jni\android_os_power.cpp

hardware\libhardware\power\power.c

其中PowerManagerService.java是核心;Power.java提供底层的函数接口,JNI层进行交互;JNI层的代码主要在文件android_os_Power.cppLinux kernel交互是通过Power.c来实现的。Android电源管理跟Kernel的交互主要是通过sys文件的方式来实现的,具体可以参考Kernel层的介绍