筆者所在公司作的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