Android应用如何实现后台调节屏幕颜色及蓝光过滤功能
安卓蓝光过滤功能实现方案
实现思路:采用全局悬浮窗蒙层方案,不需要修改系统底层配置,兼容性强,绝大多数安卓版本都能运行,你已经申请的两个权限刚好适配需求,且可以后台持续生效。
具体实现步骤
1. 补充动态权限申请逻辑
manifest里已经配置的两个权限是正确的,Android 6.0及以上版本需要额外增加动态申请逻辑:
- 悬浮窗权限校验:
if (!Settings.canDrawOverlays(this)) { // 跳转悬浮窗授权页 val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName")) startActivityForResult(intent, REQUEST_OVERLAY_PERMISSION) }
- 系统设置修改权限校验:
if (!Settings.System.canWrite(this)) { // 跳转系统设置修改授权页 val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:$packageName")) startActivityForResult(intent, REQUEST_WRITE_SETTINGS_PERMISSION) }
2. 创建前台服务管理悬浮窗蒙层
要实现后台生效,必须将悬浮窗管理逻辑放在前台服务中,避免被系统后台查杀:
- 服务中创建悬浮窗核心代码:
val overlayView = View(this) val params = WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY else WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.TRANSLUCENT ) val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager windowManager.addView(overlayView, params) // 服务启动时读取之前保存的过滤强度,自动设置蒙层效果 val savedIntensity = getSharedPreferences("filter_config", MODE_PRIVATE).getInt("intensity", 0) val alpha = (savedIntensity * 2.55).toInt() overlayView.setBackgroundColor(Color.argb(alpha, 255, 180, 0))
- 服务启动时必须调用
startForeground()方法弹出前台通知,Android 8.0及以上需要先创建通知渠道,服务才能正常运行。
3. 接入SeekBar调节逻辑
调节SeekBar的取值范围可设置为0-100,对应蓝光过滤强度从关闭到最大:
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { val alpha = (progress * 2.55).toInt() // 暖黄色蒙层,RGB值可根据需求调整,实现你想要的过滤效果 val filterColor = Color.argb(alpha, 255, 180, 0) overlayView.setBackgroundColor(filterColor) // 保存当前强度到本地,重启服务后自动生效 getSharedPreferences("filter_config", MODE_PRIVATE) .edit() .putInt("intensity", progress) .apply() } override fun onStartTrackingTouch(seekBar: SeekBar?) {} override fun onStopTrackingTouch(seekBar: SeekBar?) {} })
注意事项
- 蒙层添加了FLAG_NOT_TOUCHABLE标记,不会拦截用户操作其他应用
- 想要关闭过滤功能只需要将蒙层透明度设为0,或者直接从WindowManager中移除蒙层即可
- 应用退出后只要不停止前台服务,过滤效果会一直生效
内容的提问来源于stack exchange,提问作者Nishit Panchal
相关产品推荐
相关产品推荐

