Android

Android 指北針

1.取得SensorManager

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

2.監聽感測器 實現SensorEventListener

//加速度Sensor (選擇低延遲)
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME)
//磁場Sensor (選擇低延遲)
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME)

override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {

}

override fun onSensorChanged(event: SensorEvent) {
    //數值在這邊取得
}

3.指北針角度計算

private var mGravity = FloatArray(3)
private var mGeomagnetic = FloatArray(3)
private var azimuth = 0f
private var currentAzimuth = 0f

override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_main)
}

override fun onSensorChanged(event: SensorEvent) {
    val alpha = 0.97f
    synchronized(this) {
       if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            mGravity[0] = alpha * mGravity[0] + (1 - alpha) * event.values[0]
            mGravity[1] = alpha * mGravity[1] + (1 - alpha) * event.values[1]
            mGravity[2] = alpha * mGravity[2] + (1 - alpha) * event.values[2]
       }
       if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
            mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha) * event.values[0]
            mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha) * event.values[1]
            mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha) * event.values[2]
        }
        val R = FloatArray(9)
        val L = FloatArray(9)
        val success = SensorManager.getRotationMatrix(R, L, mGravity, mGeomagnetic)
        if (success) {
            val orientation = FloatArray(3)
            SensorManager.getOrientation(R, orientation)
            azimuth = Math.toDegrees(orientation[0].toDouble()).toFloat()
            azimuth = (azimuth + 360) % 360
            val anim: Animation = RotateAnimation(
                    -currentAzimuth,
                    -azimuth,
                    Animation.RELATIVE_TO_SELF,
                    0.5f,
                    Animation.RELATIVE_TO_SELF,
                    0.5f
             )
             currentAzimuth = azimuth
             anim.duration = 500
             anim.repeatCount = 0
             anim.fillAfter = true
             compass.startAnimation(anim)
        }
     }
}

4.效果展示

發表迴響