android 11反射调用护眼模式/夜间模式
Android 10 推出了 COLOR_DISPLAY_SERVICE 系统服务,具备系统 API 接口,使系统、“设置”和系统界面能够更好地控制所有颜色转换(包括护眼模式)。
首先对应的平板或手机要能支持这个模式
设备制造商可以使用在以下文件中定义的下列标记启用该功能的默认实现
frameworks/base/core/res/res/values/config.xml
<!-- Control whether Night display is available. This should only be enabled on devices
with HWC 2.0 or higher. -->
<bool name="config_nightDisplayAvailable">false</bool>
可以用这个函数来检测是否支持
/**是否支持夜间模式
* 返回true支持,返回不支持
*/
open fun isNightModeSupport(context: Context): Boolean {
val res: Resources = context.resources
val allowId: Int = res.getIdentifier("config_nightDisplayAvailable", "bool", "android")
return res.getBoolean(allowId)
}
核心功能由 ColorDisplayManager(由 ColorDisplayService 支持)控制。
系统设置中就有控制“护眼模式”的选项,代码如下:
packages/apps/Settings/src/com/android/settings/display/NightDisplaySettings.java
里面可以看到import android.hardware.display.ColorDisplayManager;
我们可以通过反射得到ColorDisplayManager并进行控制
open fun openOrCloseNightMode(context: Context, open: Boolean) {
try {
val cl: Class<*> = Class.forName("android.hardware.display.ColorDisplayManager")
val control: Any = context.getSystemService(cl)
val md: Method = cl.getDeclaredMethod("setNightDisplayActivated", Boolean::class.javaPrimitiveType)
md.invoke(control, open)
} catch (e: ClassNotFoundException) {
Log.d(TAG, "ClassNotFoundException:" + e.message)
} catch (e: NoSuchMethodException) {
Log.d(TAG, "NoSuchMethodException:" + e.message)
} catch (e: InvocationTargetException) {
Log.d(TAG, "InvocationTargetException:" + e.message)
} catch (e: IllegalAccessException) {
Log.d(TAG, "IllegalAccessException:" + e.message)
} catch (e: InstantiationException) {
Log.d(TAG, "InstantiationException:" + e.message)
}
}
注意要加上相应权限,不然执行会报错:“InvocationTargetException:null”
AndroidManifest.xml加上
<uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
怎么知道要加什么权限呢,除了网上查,另外一种就是看安卓SDK源码,
比如这个功能真正实现的代码在这里
frameworks/base/services/core/java/com/android/server/display/color/ColorDisplayService.java
1655 public boolean mySetNightDisplayActivated(boolean activated) {
1656 getContext().enforceCallingOrSelfPermission(
1657 Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
1658 "Permission required to set night display activated");
1659 final long token = Binder.clearCallingIdentity();
1660 try {
1661 mNightDisplayTintController.setActivated(activated);
1662 return true;
1663 } finally {
1664 Binder.restoreCallingIdentity(token);
1665 }
1666 }
注意第1657行Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS, 那么转换成应用层要的就是
android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS了。
作者:帅得不敢出门