• 完美实现Android的屏幕常亮功能


      笔者所在公司做的APP是股票类的,用户在查看股票报价页面的时候,往往需要开启盯盘模式,这个时候屏幕是不能黑屏的,黑屏会导致用户看不到一些关键报价涨跌,错过了买入卖出的最佳时机,就会给用户造成损失,这是股票类软件所不能容许的,所以一般的股票类APP都会有屏幕常亮功能。

      当初我们做这个功能的时候,在网上找了一些教程发现有些达不到效果,然后找到了一种比较完美的没有兼容性的实现方案,下面给大家分享一下。

      网上有一种解决方案是使用PowerManager来实现屏幕不锁屏:

     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 的标识。

    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想要屏幕常亮则调用如下方法即可:

     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中。

      如果整个APP的页面都要实现屏幕常亮该怎么做?难道在所有的Activity中的onCreate()都写调用这个方法吗?
      答案显然不是,这样太没有效率。

      一般情况我们的项目里都会有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





    
    
    
    
    
    



  • 相关阅读:
    myBatis学习笔记(10)——使用拦截器实现分页查询
    电影院的设计与实现(改进更新)
    软件设计师自我修炼1:怎样让用户对软件产生依赖
    jQuery.ajax()方法中參数具体解析
    王立平--Gallery:实现图片的左右滑动
    USB设备驱动概述
    Android中的多线程编程(一)附源代码
    Shannon-Fano-Elias编码的C语言实现
    互联网协议入门深入
    linux内核中创建线程方法【转】
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/6221102.html
Copyright © 2020-2023  润新知