tools:ignore=“ProtectedPermissions” />

之所以加上tools:ignore="ProtectedPermissions"是因为改变系统设置的权限一般只归系统App所有,所以编译器会报一个警告,加上这个可以忽略警告。

4.2 申请动态权限

如果你的手机系统是Android6.0以上的,那么还得动态申请权限。系统设置权限的动态申请有点特别,它需要跳转到系统的“可修改系统设置”界面,让用户决定是否允许当前应用修改系统设置,然后再在onActivityResult中处理回调结果。

我们在进入BrightnessActivity时就动态申请权限,代码如下:

//修改系统屏幕亮度需要修改系统设置的权限
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
 //如果当前平台版本大于23平台
 if (!Settings.System.canWrite(mContext)) {
 val intent = with(Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)) {
 data = Uri.parse(“package:$packageName”)
 this
 }
 startActivityForResult(intent, RQ_WRITE_SETTINGS)
 } else {
 changeSystemBrightness()
 }
 } else {
 //Android6.0以下的系统则直接修改亮度
 changeSystemBrightness()
 }

首先调用Settings.System.canWrite(Context)判断手机系统,Android6.0以下的直接允许修改亮度的操作;Android6.0以上的则要进一步判断是否已经获得了修改系统设置的权限,没有的话就要打开如下界面去设置。

androidT 设置调整屏幕亮度最小值 安卓修改屏幕最低亮度_Android

无论用户是否授权,我们都需要一个回调,这时onActivityResult就可以派上用场了:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
 super.onActivityResult(requestCode, resultCode, data)
 when (requestCode) {
 RQ_WRITE_SETTINGS -> {
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
 if (Settings.System.canWrite(mContext)) {
 shortToast(“已获取权限”)
 changeSystemBrightness()
 } else {
 shortToast(“你拒绝了权限”)
 }
 }
 }
 }
 }

代码很简单,就不做过多解释了。

4.3 去除自动亮度

前面我们虽然解决了权限问题,但是还要考虑到一个实际情况,那就是用户可能会设置了自动亮度,在这个前提下是无法改变系统屏幕亮度的。所以这里要做两步处理:

  1. 判断用户是否开启了自动亮度;
  2. 如果当前开启了自动亮度,则需要将其关闭。
4.3.1 判断是否自动亮度

我们在工具类中添加isAutoBrightness属性,它只有Getter方法,返回一个布尔值。这里调用Settings.System.getInt()方法,第二个参数传入 Settings.System.SCREEN_BRIGHTNESS_MODE表示我们要获取系统屏幕亮度模式,如果是Settings.System.SCREEN_BRIGHTNESS_MODE,则表示当前自动亮度模式。

val isAutoBrightness:Boolean
 get() = try {
 Settings.System.getInt(
 AndUtil.appContext.contentResolver,
 Settings.System.SCREEN_BRIGHTNESS_MODE
 ) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
 } catch (e: Settings.SettingNotFoundException) {
 e.printStackTrace()
 false
 }
4.3.2 设置开启和关闭自动亮度

前面我们获取了系统亮度模式,通过设置它的值,我们就可以控制自动亮度模式的开关了。
在工具类中创建一个setAutoBrightness()函数,如果设置成功就返回true。这里用到的是Settings.System.putInt(),第二个参数即为我们要设置的亮度模式。当参数enable为true时就是自动模式了。


/**
• 设置是否开启自动亮度
• @param enable : 为true时开启,false时关闭
• @return 设置成功返回true
 */
 fun setAutoBrightness(enable: Boolean) = Settings.System.putInt(
 AndUtil.appContext.contentResolver, Settings.System.SCREEN_BRIGHTNESS_MODE,
 if (enable) Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC else Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL
 )

4.4 封装改变系统屏幕亮度属性

现在我们总算可以编写修改系统亮度的代码了。跟修改窗口亮度一样,我们这里也使用了一个属性,命名为systemBrightness

/**
• 系统屏幕亮度,需要WRITE_SETTINGS权限,并在代码中申请系统设置权限
• 范围为0~255
 */
 var systemBrightness
 get() = try {
 Settings.System.getInt(AndUtil.appContext.contentResolver, Settings.System.SCREEN_BRIGHTNESS)
 } catch (e: Settings.SettingNotFoundException) {
 e.printStackTrace()
 -1
 }
 @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
 set(@IntRange(from = 0, to = 255) brightness) {
 if (isAutoBrightness) {
 //如果当前是自动亮度,则关闭自动亮度
 setAutoBrightness(false)
 }
 val uri = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS)
 Settings.System.putInt(AndUtil.appContext.contentResolver, Settings.System.SCREEN_BRIGHTNESS, brightness)
 AndUtil.appContext.contentResolver.notifyChange(uri, null)
 }

这里我们重点来看设置系统亮度,也就是set()里面的代码。首先判断当前是否开启了自动亮度模式,如果是则将其关闭。后面的代码类似于setAutoBrightness(),都是在Settings.System.putInt()中赋值,不同的是还要调用Context.contentResolver.notifyChange()方法去通知系统我们已经修改了屏幕亮度,这样设置的值才会起作用。另外,要注意系统屏幕亮度的取值范围是0~255。