1. 程式人生 > >android之PowerManager 與電源管理,解決滅屏狀態下來簡訊螢幕不會點亮問題

android之PowerManager 與電源管理,解決滅屏狀態下來簡訊螢幕不會點亮問題

  可解決滅屏狀態下來簡訊螢幕不會點亮問題   

PowerManager這個類主要是用來控制電源狀態的. 通過使用該類提供的api可以控制電池的待機時間,一般情況下不要使用。如果確實需要使用,那麼儘可能的使用最低級別的WakeLocks鎖,並且確保使用完後釋放它。

首先獲取例項,通過context.getSystemService(Context.POWER_SERVICE)的方式獲得PowerManager的例項。

在PowerManager中,最主要的newWakeLock方法,如下:

    public WakeLock newWakeLock(int flags, String tag)
    {
        return new WakeLock(flags, tag);
    }
    這個方法將建立WakeLock物件,通過呼叫此物件的方法你就可以方便的去控制電源的狀態。方法如下:
   
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
    wl.acquire();
      螢幕將停留在設定的狀態,一般為亮、暗狀態
    wl.release();
      釋放掉正在執行的cpu或關閉螢幕。


下面定義的flag是在newWakeLock方法中要接收的引數,通過該flag,你可以定義系統的電源的展示效果。比如:
 *                                               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
 
  這些flag是相互排斥的,一次只能定義一個。

如果你持有PARTIAL_WAKE_LOCK鎖,不論任何定時器甚至是按下電源按鈕,cpu都將繼續執行,無法進入休眠狀態。除非你釋放掉它。
其他鎖的話,雖然cpu也在執行,但是當用戶按下電源按鈕時,裝置將立刻進入休眠狀態。

 正常情況下wakelocks實際上是沒有被開啟的,當需要時,它將通過特定的flag啟動螢幕和鍵盤。 比如在應用中,涉及到向用戶傳送訊息時,需要讓使用者立刻看到。此時會點亮螢幕。當WakeLock鎖被釋放的時候,activity的定時器將被重設,這將導致螢幕亮更長的時間

下面的程式碼是我在開發中遇到的關於滅屏狀態下來簡訊螢幕不會點亮問題的修改,由於程式碼較多,此處只貼出修改過的地方

 packages/apps/Messaging/src/com/android/messaging/receiver/SmsReceiver.java -
index cee7c5b..d1d3216 100644
@@ -27,6 +27,7 @@ import android.text.TextUtils;
 import android.util.Log;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;

+import android.os.PowerManager;
 import android.provider.Telephony;
 import android.provider.Telephony.Sms;
 import android.support.v4.app.NotificationCompat;
@@ -76,6 +77,8 @@ public final class SmsReceiver extends BroadcastReceiver {
     private static final String TAG = LogUtil.BUGLE_TAG;
 
     private static ArrayList<Pattern> sIgnoreSmsPatterns;
+    private static final int WAKE_LOCK_TIMEOUT = 5000;
+    private static PowerManager.WakeLock mWakeLock;

 
     /**
      * Enable or disable the SmsReceiver as appropriate. Pre-KLP we use this receiver for
@@ -89,7 +92,6 @@ public final class SmsReceiver extends BroadcastReceiver {
         boolean mmsWapPushReceiverEnabled;
         boolean respondViaMessageEnabled;
         boolean broadcastAbortEnabled;
-
         if (OsUtil.isAtLeastKLP()) {
             // When we're running as the secondary user, we don't get the new SMS_DELIVER intent,
             // only the primary user receives that. As secondary, we need to go old-school and
@@ -198,6 +200,9 @@ public final class SmsReceiver extends BroadcastReceiver {
             LogUtil.e(TAG, "processReceivedSms: null or zero or ignored message");
             return;
         }
+        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "updateNewMessageIndicator");
+         mWakeLock.setReferenceCounted(true);

         
         final int errorCode = intent.getIntExtra(EXTRA_ERROR_CODE, 0);
         // Always convert negative subIds into -1
@@ -209,6 +214,7 @@ public final class SmsReceiver extends BroadcastReceiver {
             final String format = null;
             DebugUtils.dumpSms(messages[0].getTimestampMillis(), messages, format);
         }
+        mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
     }
 
     public static void deliverSmsMessages(final Context context, final int subId,