Android开发小技巧-屏幕常亮与高亮的管理
前言
在使用我们国民应用微信和支付宝的时候,打开付款码给别人扫码的时候,那个页面简直亮瞎我的眼,做为一个Android开发者,我就想这个功能是怎么实现的呢?
问题:如何实现屏幕的常量与亮度控制呢?又有哪些方式来实现呢?
一、WakeLock机制
说起应用程序App的耗电,其本质就是硬件的消耗电量,硬件耗电单元分为CPU、基带、GPU、WIFI、BT、GPS、LCD/OLED等等。
耗电量的层级 基带非通话时间的能耗基本上在 5mA 左右, 而CPU只要处于非休眠状态,能耗至少在 50mA 以上,GPU执行图形运算时会更高, 另外 LCD/OLED, GPS等硬件又更高。
一般手机待机时,CPU、LCD、WIFI均进入休眠状态,这时 Android 中应用程序的代码也会停止执行,只会有基带处理器的耗电。 这也就是为什么微信比短信相比更加的耗电,答案就是短信使用基带耗电小, 而微信使用CUP耗电大。
Android 为了确保应用程序中关键代码的正确执行,提供了 WakeLock 的API,使得应用程序有权限通过代码阻止CPU进入休眠状态。
WakeLock 阻止应用处理器 CPU 的挂起,确保关键代码的运行,通过中断唤起应用处理器 CPU,可以阻止屏幕变暗。所有的 WakeLock 被释放后,系统会挂起。
例如以下音乐播放器,我们申请了 WakeLock 的情况下,就算按下电源键锁屏了,我们的音乐还是会播放。CPU不会休眠照样会处理我们的应用。
但是如果我们不释放 WakeLock,或者滥用 WakeLock 就会导致电池续航尿崩,用户查看电池消耗查看你的 App 耗电量高就会卸载了。
除了阻止 CPU 休眠,WakeLock 还可以让屏幕常亮,通过设置对应的 levelAndFlags
即可实现,常用的几个levelAndFlags:
- PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。
- SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯
- SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,允许关闭键盘灯
- FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
- ACQUIRE_CAUSES_WAKEUP:不会唤醒设备,强制屏幕马上高亮显示,键盘灯开启。有一个例外,如果有notification弹出的话,会唤醒设备。
- ON_AFTER_RELEASE:WakeLock 被释放后,维持屏幕亮度一小段时间,减少 WakeLock 循环时的闪烁情况
怎么使用呢?先声明权限
<uses-permission android:name="android.permission.WAKE_LOCK"/>
然后直接使用:
override fun init() {
val powerManager = commContext().getSystemService(Service.POWER_SERVICE) as PowerManager
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Lock")
//是否需计算锁的数量
wakeLock.setReferenceCounted(false)
}
override fun onResume() {
super.onResume()
wakeLock.acquire()
}
override fun onStop() {
super.onStop()
wakeLock.release();
}
这样就可以实现一个简单的屏幕常亮的控制了。
虽然是可以实现逻辑,但是按照上面说的,谷歌可能也是怕我们滥用,导致手机续航尿崩,然后甩锅到Android系列上,说Android系列辣椒续航不行什么什么的,谷歌老早就标记过时了,并提供了新的 Api 实现此功能 SCREEN_ON。
二、KEEP_SCREEN_ON
有两种方式设置,一种是xml内部设置,另一种是通过Activity的window添加flag来设置
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:keepScreenOn="true"
android:orientation="vertical"/>
或者oncreate方法中添加flags
override fun init() {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
两种方法都能实现,并且是和Activity生命周期绑定的,当我们退出这个页面就可以退出常量的状态,使用起来也是非常的方便。
那如果是这样一样场景,比如我们使用单Activity+多Fragment的方式,我们需要为其中一个Fragment设置为常亮,切换Fragment的时候动态的切换亮度,那怎么办?
我们需要动态的开关这个flag
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
又或者找到跟视图动态设置keepScreenOn属性 setKeepScreenOn
也是可行的,下面我们会以window的方式做一个工具封装类。
二、最大亮度的设置
最大亮度可以通过当前 Activity 的 window 对象设置 windowLayoutParams ,设置对应的 screenBrightness
值即可实现。
我们可以实现一个工具类来控制常亮的开关和最大亮度的开关,特别适用于单Activity+多Fragment的使用场景。
public class ScreenUtils {
/**
* 获取屏幕宽度
*/
public static int getScreenWidth(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int width = wm.getDefaultDisplay().getWidth();
return width;
}
/**
* 获取屏幕高度
*/
public static int getScreenHeith(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int height = wm.getDefaultDisplay().getHeight();
return height;
}
/**
* 是否使屏幕常亮
*
* @param activity 当前的页面的Activity
*/
public static void keepScreenLongLight(Activity activity, boolean isOpenLight, boolean maxBrightness) {
Window window = activity.getWindow();
if (isOpenLight) {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
WindowManager.LayoutParams windowLayoutParams = window.getAttributes();
windowLayoutParams.screenBrightness = maxBrightness ?
WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL : WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
window.setAttributes(windowLayoutParams);
}
}
使用的时候在页面显示的时候常亮且最大亮度即可,然后我们可以在任意地方关闭这些设置。
override fun onResume() {
super.onResume()
ScreenUtils.keepScreenLongLight(this, true, true)
}
override fun onStop() {
super.onStop()
ScreenUtils.keepScreenLongLight(this, false, false)
}
最大亮度打开页面简直亮瞎我的眼!
OK,完结!
来源:juejin.cn/post/7130424225147387935