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
Flag Value | CPU | Screen | Keyboard |
---|---|---|---|
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.
設置權限
<uses-permission android:name="android.permission.WAKE_LOCK"/> 你可能還需要 <uses-permission android:name="android.permission.DEVICE_POWER"/> <!--但是 DEVICE_POWER 權限一般只適用於系統應用程序;在app中就算加入該權限,也不能獲得相應功能-->
參考:
android的PowerManager和PowerManager.WakeLock
-------------------------------------------------------------------------------------------------------------------------------------
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: 一旦有請求鎖時強制打開Screen和keyboard 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.cpp中;與Linux kernel交互是通過Power.c來實現的。Android電源管理跟Kernel的交互主要是通過sys文件的方式來實現的,具體可以參考Kernel層的介紹。