完美實現Android的屏幕常亮功能

  筆者所在公司作的APP是股票類的,用戶在查看股票報價頁面的時候,每每須要開啓盯盤模式,這個時候屏幕是不能黑屏的,黑屏會致使用戶看不到一些關鍵報價漲跌,錯過了買入賣出的最佳時機,就會給用戶形成損失,這是股票類軟件所不能允許的,因此通常的股票類APP都會有屏幕常亮功能。android

  當初咱們作這個功能的時候,在網上找了一些教程發現有些達不到效果,而後找到了一種比較完美的沒有兼容性的實現方案,下面給你們分享一下。git

  網上有一種解決方案是使用PowerManager來實現屏幕不鎖屏:github

 1 /**
 2  * 打開休眠鎖只能保持手機不休眠
 3  * @param context
 4  */
 5 @Deprecated
 6 public static void openWakeLock(Context context) {
 7     PowerManager powerManager = (PowerManager) context.getSystemService(Service.POWER_SERVICE);
 8     PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Lock");
 9     //是否需計算鎖的數量
10     wakeLock.setReferenceCounted(false);
11     //請求常亮,onResume()
12     wakeLock.acquire();
13 }

但這種方式在實際的測試過程當中並無達到屏幕常亮的效果,並且還須要申明權限,否則會崩潰,因此這種方式被 pass 掉了:安全

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

後來發現其實常亮功能很簡單,只須要在在當前的Activity中獲取到Window對象而後調用它的addFlags方法加上一個WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 的標識。app

1 Window window = activity.getWindow(); 2 window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

  而後關閉常亮功能的時候則只須要Window清除這個WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON標識便可框架

window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

  因此咱們簡單的封裝了一下,只要是哪一個頁面Activity想要屏幕常亮則調用以下方法便可:ide

 1 /**
 2  * 是否使屏幕常亮
 3  *
 4  * @param activity
 5  */
 6 public static void keepScreenLongLight(Activity activity) {
 7     boolean isOpenLight = CommSharedUtil.getInstance(activity).getBoolean(CommSharedUtil.FLAG_IS_OPEN_LONG_LIGHT, true);
 8     if (isOpenLight) {
 9         activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
10     } else {
11         activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
12     }
13 
14 }

  在想要屏幕常亮的Activity的onCreate()方法中調用以下方法便可:測試

1 @Override
2 protected void onCreate(Bundle savedInstanceState) {
3     super.onCreate(savedInstanceState);
4     LongLightUtils.keepScreenLongLight(this);
5 }

  由於屏幕常亮功能是能夠在設置中設置開關的,並且下次用戶進APP須要保存上一次的設置,因此咱們把是否打開常亮功能保存在了SharedPreferences中。ui

  若是整個APP的頁面都要實現屏幕常亮該怎麼作?難道在全部的Activity中的onCreate()都寫調用這個方法嗎?
  答案顯然不是,這樣太沒有效率。this

  通常狀況咱們的項目裏都會有BaseActivity,BaseFragment之類的父類,來抽離出通用的方法和樣式規範,因此咱們能夠在全部的Activity都會繼承的BaseActivity中onCreate()判斷是否須要屏幕常亮功能,這樣它的子類就具備了這個功能,像這樣:

1 public class BaseActivity extends AppCompatActivity {
2 
3     @Override
4     protected void onCreate(Bundle savedInstanceState) {
5         super.onCreate(savedInstanceState);
6         LongLightUtils.keepScreenLongLight(this);
7     }
8 }

  另外還有一種狀況,咱們的APP中不是全部的Activity都是會繼承BaseActivity,好比有些頁面咱們須要用H5和原生交互,爲了交互更加方便安全通常會選用Cordova,而負責交互打開H5頁面的Activity是須要繼承CordovaActivity,這樣才能實現交互。CordovaActivity是第三方的Activity顯然是和咱們的BaseActivity是沒有關係的。

  同時若是咱們集成了一些第三方的SDK,打開他們的SDK裏面的頁面若是也須要屏幕常亮功能的話,該怎麼辦?由於咱們也沒法去修改他們的代碼,不能在他們Activity中加入屏幕常亮功能。

  這個時候其實有個很黑科技的功能,可能你之前都沒有見到過,那就是在application中有一個方法,
registerActivityLifecycleCallbacks,能夠傳入一個回調接口,裏面有當前APP中全部的Activity的生命週期方法回調,能夠獲取到全部的Activity實例,這樣咱們就能實現全部的APP頁面都能屏幕常亮了:

 1 public class MyApplication extends Application{
 2     @Override
 3     public void onCreate() {
 4         super.onCreate();
 5         registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
 6             @Override
 7             public void onActivityCreated(Activity activity, Bundle bundle) {
 8 
 9             }
10 
11             @Override
12             public void onActivityStarted(Activity activity) {
13 
14             }
15 
16             @Override
17             public void onActivityResumed(Activity activity) {
18                 LongLightUtils.keepScreenLongLight(activity);
19             }
20 
21             @Override
22             public void onActivityPaused(Activity activity) {
23 
24             }
25 
26             @Override
27             public void onActivityStopped(Activity activity) {
28 
29             }
30 
31             @Override
32             public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
33 
34             }
35 
36             @Override
37             public void onActivityDestroyed(Activity activity) {
38 
39             }
40         });
41     }
42 }

咱們在ActivityLifecycleCallbacks的onActivityResumed方法中調用屏幕常亮的方法便可實現,Application中registerActivityLifecycleCallbacks方法在熱修復框架中應該是比較經常使用到的,很是的實用。

  最後附上屏幕常亮的示例項目地址,有須要的朋友能夠去看看  https://github.com/ganchuanpu/ScreenLongLight

相關文章
相關標籤/搜索