app端无法直接监听亮度变化,因uni-app未暴露原生亮度变更钩子,需通过原生插件实现:android用contentobserver监听并需write_settings权限,ios只能轮询uiscreen.brightness。

App端无法直接监听亮度变化,这是能力缺失,不是你写错了
uni-app 的 uni.getScreenBrightness 是快照式 API,只返回当前值,不提供事件监听能力;uni.onThemeChange 和 uni.onOsThemeChange 都不响应亮度滑动——它们监听的是深色/浅色主题切换,和屏幕明暗无关。iOS 和 Android 原生层确实能感知亮度变更(Android 用 ContentObserver 监听 Settings.System.SCREEN_BRIGHTNESS,iOS 只能轮询 UIScreen.mainScreen().brightness),但 uni-app 官方 SDK 没暴露对应钩子。想实时响应用户拖动亮度条的动作,必须走原生插件路径。
Android 端监听需 ContentObserver + WRITE_SETTINGS 权限
Android 要监听系统亮度变化,得在原生层注册 ContentObserver,监听 Settings.System.SCREEN_BRIGHTNESS URI。但关键限制是:WRITE_SETTINGS 权限不是普通运行时权限,不能用 uni.authorize 申请,必须引导用户手动开启「修改系统设置」开关。
- 插件初始化前先调用
uni.getSetting检查res.authSetting['scope.writeSettings']是否为true - 未授权时必须调用
uni.openSetting,否则ContentObserver注册失败且无提示 - 监听到变更后,通过
uni.$emit('brightnessChange', {value: 0.32})通知 JS 层(注意:Android 返回值是 0–255 整数,插件需转为 0.0–1.0 浮点) - Android 8.0+ 才支持该监听,旧版本只能轮询(不推荐,耗电)
iOS 端只能轮询,且无变更事件
iOS 没有系统级亮度变更广播,UIScreen.mainScreen().brightness 是唯一可读接口,返回 0.0–1.0 浮点值,但它的变化不会触发通知。所以插件只能靠定时轮询——间隔建议 ≥500ms,太密会显著增加后台耗电。
- 不要在
onShow里无条件启动轮询,应用切后台时务必clearInterval - 轮询逻辑应放在原生插件内,JS 层只订阅
uni.$on('brightnessChange', callback),避免频繁 JS-Native 通信 - iOS 无法区分「用户手动拖动」和「自动亮度生效」,值变了就发事件,业务层自行判断是否需要响应
- 别依赖
uni.getSystemInfoSync().screenBrightness——这个字段在 App 端始终是undefined
JS 层统一处理的坑与建议
跨平台监听后,JS 层拿到的 value 看似都是 0–1,但实际含义不同:Android 插件转过来的值反映系统设置,iOS 轮询值可能受自动亮度干扰。业务逻辑要留余地。
- 亮度变化回调里别直接更新 UI 状态,先做防抖(如
clearTimeout(this._debounce)+setTimeout) - 若用于扫码页临时提亮,离开时还原不能简单设回原值——iOS 设的是系统值,Android 设
value: -1才同步系统,否则只是应用窗口亮度 - 别在
onUnload外的生命周期里做亮度还原(比如onHide),部分安卓机型锁屏后才触发,此时再调setScreenBrightness已无效 - 测试真机必须覆盖华为、小米——它们的省电策略常拦截
ContentObserver或轮询,fail 回调可能静默不触发











