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

相关推荐
Mercury Random1 小时前
Qwen 个人笔记
android·笔记
苏苏码不动了2 小时前
Android 如何使用jdk命令给应用/APK重新签名。
android
aqi002 小时前
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
android·ffmpeg·音视频·直播·流媒体
xiaoduyyy3 小时前
【Android】ToolBar,滑动菜单,悬浮按钮和可交互提示等的使用方法
android
liyy6143 小时前
Android架构组件:MVVM模式的实战应用与数据绑定技巧
android
K1t05 小时前
Android-UI设计
android·ui
吃汉堡吃到饱7 小时前
【Android】浅析MVC与MVP
android·mvc
深海呐13 小时前
Android AlertDialog圆角背景不生效的问题
android
ljl_jiaLiang13 小时前
android10 系统定制:增加应用使用数据埋点,应用使用时长统计
android·系统定制
花花鱼13 小时前
android 删除系统原有的debug.keystore,系统运行的时候,重新生成新的debug.keystore,来完成App的运行。
android