大部分手机都有跟随外界光照强度自动调节屏幕亮度的功能,如果用手挡住前置摄像头区域屏幕会自动变暗,移开手后会自动变亮。本文介绍如何使用光线传感器实现类似的效果。
实现自动调节页面亮度
调节系统亮度需要申请权限,调节App中页面的亮度则不需要权限,本文以调节App中页面的亮度为例进行演示。
调节页面亮度
通过设置WindowManager.LayoutParams
的screenBrightness
来调节App中页面的亮度,screenBrightness
的取值范围为 0(最暗)~ 1(最亮),只对当前设置的页面生效,代码如下:
kotlin
class SensorExampleActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.attributes = window.attributes.apply {
screenBrightness = 1f
}
}
}
照度
光线传感器返回的数值为照度,单位为lx
或lux
,照度用于描述特定区域或表面上接收到的光的强度。它表示单位面积上接收到的光能量的数量。照度是衡量环境光亮度的指标,它可以用来描述室内和室外环境的亮度水平,以及人眼感知到的光的强度。较高的照度值表示较亮的环境,而较低的照度值表示较暗的环境。光线传感器通过将光转换为电信号来检测光的强度,并返回一个数值表示当前环境的照度水平。
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.LayoutParams
的screenBrightness
传入的值即为设备最大亮度的比例值。通过光线传感器获取到照度之后,需要通过一个参考值来计算获取到的照度值占参考照度值的比例。本文简单以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中添加。