Android 传感器(一)— 使用加速度传感器实现摇一摇打开页面

大部分手机都内置了传感器,App可以使用这些传感器实现一些功能,例如统计步数、摇一摇打开页面(特指恶心的开屏广告)、根据光线调节屏幕亮度等。本文介绍如何使用加速度计传感器实现摇一摇打开页面。

传感器框架官方文档

传感器简介

大多数Android设备中都内置传感器,可以用于测量运动、环境条件以及屏幕方向等。同时Android提供了传感器框架API,可以通过此框架API访问多种类型的传感器。

坐标系

传感器通常使用标准的3轴坐标系来表示数据值,坐标系不会随设备的移动而改变。当设备处于默认屏幕方向时,x轴从左向右水平延伸,y轴从下往上垂直延伸,z轴垂直于屏幕向外延伸,如下图:

axis_device.png

传感器简单使用

传感器可用性

使用传感器之前,可以先检测设备是否支持要使用的传感器。

  • 获取所有支持的传感器
class SensorExampleActivity : AppCompatActivity() {





    private lateinit var sensorManager: SensorManager



    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager



        // 获取设备支持的所有类型的传感器
        val sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL)
    }
}
  • 获取某个类型的传感器
class SensorExampleActivity : AppCompatActivity() {





    private lateinit var sensorManager: SensorManager



    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager



        // 获取加速度计传感器
        val accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
        if (accelerometerSensor != null) {
            // 可以使用加速度计传感器
        } else {
            // 无法使用加速度计传感器
        }
    }
}

手机摇晃时打开新页面

可以使用加速度计传感器(Sensor.TYPE_ACCELEROMETER)来检测手机是否有摇晃,实现方案为通过加速度计传感器获取设备在3个轴上的加速度,每两次之间相减,当差值超过阈值时,代表在某个轴上发生了移动,可以判定为发生了摇晃,具体代码如下:

class SensorExampleActivity : AppCompatActivity() {





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

    private val accelerometerData = FloatArray(3)
    
    private val thresholds = 2
    
    private var enterNextPage = AtomicBoolean(false)

    private val sensorEventListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent?) {
            // 传感器数据变化时回调此方法
            when (event?.sensor?.type) {
                Sensor.TYPE_ACCELEROMETER -> {
                    val oldX = accelerometerData[0]
                    val oldY = accelerometerData[1]
                    val oldZ = accelerometerData[2]

                    val currentX = event.values[0]
                    val currentY = event.values[1]
                    val currentZ = event.values[2]

                    // 判断3个轴的加速度变化是否超过阈值,超过则代表发生了移动
                    val xMove = oldX != 0f && currentX - oldX > thresholds
                    val yMove = oldY != 0f && currentY - oldY > thresholds
                    val zMove = oldZ != 0f && currentZ - oldZ > thresholds

                    accelerometerData[0] = currentX
                    accelerometerData[1] = currentY
                    accelerometerData[2] = currentZ

                    // 任意一个方向发生了位移,打开新页面
                    if (xMove || yMove || zMove) {
                        // 避免打开多个页面
                        if (!enterNextPage.get()) {
                            enterNextPage.set(true)
                            startActivity(Intent(this@SensorExampleActivity, CameraActivity::class.java))
                            finish()
                        }
                    }
                }
            }
        }

        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"

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    }

    override fun onResume() {
        super.onResume()
        accelerometerSensor?.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, 10 * 1000 * 1000)
        }
    }

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

效果如图:

Screen_recording_202 -original-original.gif

示例

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

ExampleDemo github

ExampleDemo gitee

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYHRrjIt' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片