Android 传感器(四)— 使用光线传感器实现自动调节页面亮度

大部分手机都有跟随外界光照强度自动调节屏幕亮度的功能,如果用手挡住前置摄像头区域屏幕会自动变暗,移开手后会自动变亮。本文介绍如何使用光线传感器实现类似的效果。

实现自动调节页面亮度

调节系统亮度需要申请权限,调节App中页面的亮度则不需要权限,本文以调节App中页面的亮度为例进行演示。

调节页面亮度

通过设置WindowManager.LayoutParamsscreenBrightness来调节App中页面的亮度,screenBrightness的取值范围为 0(最暗)~ 1(最亮),只对当前设置的页面生效,代码如下:

kotlin 复制代码
class SensorExampleActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
            window.attributes = window.attributes.apply {
                screenBrightness = 1f
            }
    }
}

照度

光线传感器返回的数值为照度,单位为lxlux,照度用于描述特定区域或表面上接收到的光的强度。它表示单位面积上接收到的光能量的数量。照度是衡量环境光亮度的指标,它可以用来描述室内和室外环境的亮度水平,以及人眼感知到的光的强度。较高的照度值表示较亮的环境,而较低的照度值表示较暗的环境。光线传感器通过将光转换为电信号来检测光的强度,并返回一个数值表示当前环境的照度水平。

SensorManager中定义了几个常量,表示在某些特定环境下照度对应的数值,如下:

常量值 取值 备注
LIGHT_SUNLIGHT_MAX 120000.0F 阳光直射时的最大光照强度
LIGHT_SUNLIGHT 110000.0F 阳光直射时的光照强度
LIGHT_SHADE 20000.0F 有树荫或遮挡物时的光照强度
LIGHT_OVERCAST 10000.0F 阴天时的光照强度
LIGHT_SUNRISE 400.0F 日出时的光照强度
LIGHT_CLOUDY 100.0F 多云天气时的光照强度
LIGHT_FULLMOON 0.25F 满月时的光照强度
LIGHT_NO_MOON 0.001F 无月光时的光照强度

使用光线传感器自动调节页面亮度

显然WindowManager.LayoutParamsscreenBrightness传入的值即为设备最大亮度的比例值。通过光线传感器获取到照度之后,需要通过一个参考值来计算获取到的照度值占参考照度值的比例。本文简单以LIGHT_CLOUDY作为参考,实现代码如下:

kotlin 复制代码
class SensorExampleActivity : AppCompatActivity() {

    private lateinit var binding: LayoutSensorExampleActivityBinding
    private lateinit var sensorManager: SensorManager
    private var lightSensor: Sensor? = null

    private val sensorEventListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent?) {
            // 传感器数据变化时回调此方法
            when (event?.sensor?.type) {
                Sensor.TYPE_LIGHT -> {
                    // 改变窗口的亮度
                    window.attributes = window.attributes.apply {
                        // 以多云天气时的光照强度作为参考值计算屏幕亮度该设置多少
                        binding.tvTextContent.run { post { text = "照度:${event.values[0]}, 屏幕亮度:${event.values[0] / SensorManager.LIGHT_CLOUDY}" } }
                        screenBrightness = event.values[0] / SensorManager.LIGHT_CLOUDY
                    }
                }
            }
        }

        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
            // 传感器的精度发生变化时回调此方法,通常无需做处理
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = LayoutSensorExampleActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.includeTitle.tvTitle.text = "Sensor Example"
        binding.tvTextContent.visibility = View.VISIBLE

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
    }

    override fun onResume() {
        super.onResume()
        lightSensor?.let {
            // 注册传感器监听并且设置数据采样延迟
            // SensorManager.SENSOR_DELAY_FASTEST 延迟0微妙
            // SensorManager.SENSOR_DELAY_GAME 演示20000微妙
            // SensorManager.SENSOR_DELAY_UI 延迟60000微妙
            // SensorManager.SENSOR_DELAY_NORMAL 延迟200000微秒
            sensorManager.registerListener(sensorEventListener, it, SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_GAME)
        }
    }

    override fun onPause() {
        super.onPause()
        // 移除传感器监听
        sensorManager.unregisterListener(sensorEventListener)
    }
}

效果如图:

示例

演示代码已在示例Demo中添加。

ExampleDemo github

ExampleDemo gitee

相关推荐
openinstall全渠道统计41 分钟前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
双鱼大猫1 小时前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫1 小时前
一句话说透Android里面的SystemServer进程的作用
android
双鱼大猫1 小时前
一句话说透Android里面的View的绘制流程和实现原理
android
双鱼大猫2 小时前
一句话说透Android里面的Window的内部机制
android
双鱼大猫2 小时前
一句话说透Android里面的为什么要设计Window?
android
双鱼大猫2 小时前
一句话说透Android里面的主线程创建时机,frameworks层面分析
android
苏金标3 小时前
android 快速定位当前页面
android
雾里看山6 小时前
【MySQL】内置函数
android·数据库·mysql
风浅月明6 小时前
[Android]页面间传递model列表
android