Androidにおけるセンサーの利用
続いて、現在値を表わすイメージを端末の向いている方向に合わせて回転させ、方位が分かるようにしましょう。なお、今回利用するのは方位センサーのみですが、Androidでは下記のセンサーに対応しています(Android1.5以降)。また、ソフトウェアとしては対応していますが、端末がセンサーを持っていなければ利用できません。
| 定数名 | 種類 |
|---|---|
| Sensor.TYPE_ACCELEROMETER | 加速度センサー |
| Sensor.TYPE_GYROSCOPE | ジャイロセンサー |
| Sensor.TYPE_LIGHT | 明るさセンサー |
| Sensor.TYPE_MAGNETIC_FIELD | 地磁気センサー |
| Sensor.TYPE_ORIENTATION | 方位センサー |
| Sensor.TYPE_PRESSURE | 圧力センサー |
| Sensor.TYPE_PROXIMITY | 近傍センサー |
| Sensor.TYPE_TEMPERATURE | 温度センサー |
実装のイメージはLocationManagerと同様で、管理クラス(android.hardware.SensorManager)にリスナ(android.hardware.SensorEventListener)を登録する事で、センサーからの通知を受け取ることができます。
// センサー管理クラス
protected SensorManager sensorManager = null;
protected OrientationSensorAdaptor sensorAdaptor = null;
@Override
protected void onResume() {
:
:中略
:
// センサー管理クラスの取得
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorAdaptor = new OrientationSensorAdaptor();
// センサー管理クラスから方位センサーのリストを取得する。
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if (sensors.size() > 0) {
Sensor sensor = sensors.get(0);
// センサーにリスナ登録する
sensorManager.registerListener(sensorAdaptor, sensor, SensorManager.SENSOR_DELAY_UI);
}
super.onResume();
}
@Override
protected void onPause() {
:
:中略
:
// センサーのリスナから削除する
sensorManager.unregisterListener( sensorAdaptor);
sensorAdaptor = null;
super.onPause();
}
/**
* センサーの値通知を受け取るリスナ
*/
private class OrientationSensorAdaptor implements SensorEventListener{
/**
* センサーの正確さに変化があったタイミングで通知される
* @param sensor センサー
* @param accuracy 正確さ
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
// 方位から回転角を設定
float[] values = event.values;
currentLocationOverlay.setOrientation( values[SensorManager.DATA_X]);
// 再描画
map.invalidate();
}
}
}

上記のサンプルでは複雑になるのを防ぐために意識していませんが、方位センサーを利用したアプリケーションを作成する場合には、磁北と真北の違いを考慮する必要があります。
磁北とは、文字どおり方位磁石の指す北で、Androidの方位センサーの指す北も磁北です。一方、真北とは自転軸の北端を表わすもので、両者の間には国内でおよそ3度~9度、海外では地域によっては40度もズレ(磁気偏角)が生じます。
Googleマップを含め一般的な地図は真北で書かれており、センサーから取得した方位(磁北)で見ると、ズレ(磁気偏角)が発生してしまいます。そのような場合には磁気偏角を取得して、センサーから取得した磁北を真北へと調整する必要があります。
// 引数は緯度、経度、標高、時間
GeomagneticField geomagnetic = new GeomagneticField(
latitude, longitude, altitude, System.currentTimeMillis());
// 磁気偏角を取得する
geomagnetic.getDeclination();
まとめ
今回の作業で、一通りの機能の実装が完了しました。次回は公開に向けた準備をします。
