0
1

More than 1 year has passed since last update.

【Android】端末の位置を測定する

Last updated at Posted at 2023-03-01

はじめに

Android端末の位置(Azimuth/Pitch/Roll)を測定する方法について解説。
加速度センサーと地磁気センサーを組み合わせることで、端末の位置を測定。

Azimuth/Pitch/Rollについて

上記の図の通り。地面と水平に、北向きに端末を置いた場合、Azimuth/Pitch/Rollともに0となる。

コード

  • センサーイベントリスナー(SensorEventListener)インターフェースを継承。
  • センサーマネージャー(sensorManager)を定義し、onResume時にリスナーを登録、onPause時にリスナーを解除する。
  • onSensorChangedメソッド内で端末の位置を測定。
MainActivity.kt
class MainActivity : AppCompatActivity(), SensorEventListener {
	/** ViewBinding */
	private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }

	/** センサーマネージャー */
	private val sensorManager by lazy { getSystemService(SENSOR_SERVICE) as SensorManager }

	private val accelerometerReading = FloatArray(3)
	private val magnetometerReading = FloatArray(3)

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(binding.root)
	}

	override fun onResume() {
		super.onResume()

		//加速度センサー
		val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
		if (accelerometer != null) sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)

		//地磁気センサー
		val magneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)
		if (magneticField != null) sensorManager.registerListener(this, magneticField, SensorManager.SENSOR_DELAY_NORMAL)
	}

	override fun onPause() {
		super.onPause()
		sensorManager.unregisterListener(this)
	}

	override fun onSensorChanged(event: SensorEvent) {
		//加速度センサー
		if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
			System.arraycopy(event.values, 0, accelerometerReading, 0, accelerometerReading.size)
		}

		//地磁気センサー
		if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
			System.arraycopy(event.values, 0, magnetometerReading, 0, magnetometerReading.size)
		}

		val rotationMatrix = FloatArray(9)
		val orientationAngles = FloatArray(3)

		SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerReading, magnetometerReading)
		SensorManager.getOrientation(rotationMatrix, orientationAngles)

		val azimuth = Math.toDegrees(orientationAngles[0].toDouble())
		val pitch = Math.toDegrees(orientationAngles[1].toDouble())
		val roll = Math.toDegrees(orientationAngles[2].toDouble())
		//TODO ここに処理を記載
	}

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1