使用SeekBar调节屏幕亮度时应用崩溃,已加WRITE_SETTINGS权限求排查
解决SeekBar调节屏幕亮度时应用崩溃的问题
嘿,我之前开发亮度调节功能时也踩过这个坑!你的代码本身逻辑没问题,但崩溃的根源在于Android 6.0(API 23)及以上版本的特殊权限机制——WRITE_SETTINGS不是普通的危险权限,只在Manifest里声明根本不够,必须让用户手动去系统设置里授权才行。
问题原因
从API 23开始,WRITE_SETTINGS被归为「特殊权限」,这类权限无法通过普通的动态权限请求弹窗获取,必须引导用户跳转到系统设置页面手动开启。如果没有授权就调用Settings.System.putInt(),系统会直接抛出SecurityException,导致应用崩溃。
解决步骤
我给你整理了完整的处理流程,照着做就能解决问题:
先检查是否拥有权限
在执行亮度设置代码前,先用Settings.System.canWrite()判断当前应用是否已获得权限。无权限时引导用户授权
如果没有权限,跳转到系统设置的「修改系统设置」页面,让用户开启权限。处理授权结果并执行设置
用户授权完成后,在onActivityResult里回调处理,再执行亮度设置逻辑。
完整代码示例
在onProgressChanged中的处理:
@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { int newBrightness = progress; // 针对API23+做权限检查 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!Settings.System.canWrite(getApplicationContext())) { // 跳转到系统设置页面请求权限 Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, 1001); // 1001是自定义的请求码 return; } } // 有权限后执行亮度设置 try { Settings.System.putInt(getApplicationContext().getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, newBrightness); // 可选:让当前窗口立刻刷新亮度,避免用户需要重启应用才能看到变化 Window window = getWindow(); WindowManager.LayoutParams layoutParams = window.getAttributes(); layoutParams.screenBrightness = newBrightness / 255f; // 亮度范围0-255,转成0.0-1.0的浮点数 window.setAttributes(layoutParams); } catch (SecurityException e) { e.printStackTrace(); Toast.makeText(this, "权限不足,无法调节亮度", Toast.LENGTH_SHORT).show(); } }
处理授权结果的onActivityResult:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1001) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Settings.System.canWrite(this)) { // 用户授权成功,重新执行当前进度的亮度设置 int currentProgress = seekBar.getProgress(); Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, currentProgress); // 刷新窗口亮度 Window window = getWindow(); WindowManager.LayoutParams layoutParams = window.getAttributes(); layoutParams.screenBrightness = currentProgress / 255f; window.setAttributes(layoutParams); } else { // 用户拒绝授权,给出提示 Toast.makeText(this, "未获得权限,无法调节屏幕亮度", Toast.LENGTH_SHORT).show(); } } } }
额外提醒
- 别忘了在Manifest里保留原有的权限声明:
<uses-permission android:name="android.permission.WRITE_SETTINGS"/> - 亮度值的范围是0-255,所以你的SeekBar最大值最好设为255,这样调节更精准。
内容的提问来源于stack exchange,提问作者TRose
相关产品推荐
相关产品推荐

