Jetpack Compose中如何从应用内控制设备屏幕亮度?
屏幕亮度切换功能实现方案
核心逻辑非常简单,只要做好「存原始值-切最高-读存值恢复」的流程就行,大部分人实现失效都是踩了权限、作用域、自动亮度的坑,以下是两个主流移动端平台的可直接运行的实现:
常见失效原因汇总:
- 未申请修改系统设置的对应权限(Android)
- 没有提前关闭自动亮度模式,导致手动设置值被覆盖
- 混淆了应用内亮度和系统全局亮度的调整接口
- 原始亮度值存储时机不对,在调整亮度之后才读取导致存错值
Android 平台实现
前置配置
在AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
Android 6.0及以上版本需要动态申请修改系统设置的权限,在页面加载逻辑中加入权限判断:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!Settings.System.canWrite(this)) { startActivity(Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)) } }
功能代码
在对应Activity中定义全局变量存储原始亮度值:
// 初始值设为-1,作为「未处于最高亮度状态」的标记 private var originBrightness = -1 private lateinit var brightnessButton: Button
在页面初始化时绑定按钮点击逻辑:
brightnessButton = findViewById(R.id.brightness_toggle_btn) brightnessButton.setOnClickListener { when(originBrightness) { -1 -> { // 第一次点击:先存原始亮度,再切最高 // 读取当前系统亮度,取值范围0-255 originBrightness = Settings.System.getInt( contentResolver, Settings.System.SCREEN_BRIGHTNESS ) // 关闭自动亮度模式,避免设置值被系统覆盖 Settings.System.putInt( contentResolver, Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL ) // 设置最高亮度 Settings.System.putInt( contentResolver, Settings.System.SCREEN_BRIGHTNESS, 255 ) brightnessButton.text = "恢复原亮度" } else -> { // 第二次点击:恢复存储的原始亮度 Settings.System.putInt( contentResolver, Settings.System.SCREEN_BRIGHTNESS, originBrightness ) // 重置标记位 originBrightness = -1 brightnessButton.text = "设为最高亮度" } } }
轻量替代方案
如果不需要修改系统全局亮度,只需要在当前应用页面内生效,不需要申请任何权限,直接修改当前窗口的亮度属性即可,退出页面后自动恢复:
// 设为最高亮度 window.attributes = window.attributes.apply { screenBrightness = 1.0f } // 恢复系统默认亮度 window.attributes = window.attributes.apply { screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE }
iOS 平台实现
iOS受系统权限限制,只能调整应用在前台时的屏幕亮度,退到后台会自动恢复系统亮度,不需要申请额外权限,实现逻辑更简单:
// 全局变量存储原始亮度,-1为未激活状态标记 var originBrightness: CGFloat = -1 @IBAction func brightnessToggleTapped(_ sender: UIButton) { if originBrightness == -1 { originBrightness = UIScreen.main.brightness // 设为最高亮度,取值范围0-1.0 UIScreen.main.brightness = 1.0 sender.setTitle("恢复原亮度", for: .normal) } else { UIScreen.main.brightness = originBrightness originBrightness = -1 sender.setTitle("设为最高亮度", for: .normal) } }
注意事项
- Android修改全局亮度的方案必须等用户授权后才能生效,授权页跳转后记得在
onResume里重新判断权限状态,避免用户拒绝授权后功能异常 - 如果用户之前开了自动亮度,恢复亮度的时候如果需要同步恢复自动亮度模式,可以额外存一下之前的亮度模式值,恢复的时候一起写回即可
内容的提问来源于stack exchange,提问作者Mati Yelicich
相关产品推荐
相关产品推荐

