Xamarin.Android 方位の取得(傾きセンサー)
1 方位の取得方法
Androidで方位を取得する方法は、次の2つがあります。(1) TYPE_ORIENTATION(傾きセンサー)による方法
(2) TYPE_MAGNETIC_FIELD(磁界センサー)とTYPE_ACCELEROMETER(加速度センサー)による方法
今回は、(1)の傾きセンサーを使用してみます。
針の指している方向がちょっと?となりますが・・・
磁北は、真北(地図の真上)より、左(西)に少しずれています。(偏角)
2 傾きセンサー(TYPE_ORIENTATION)

まずは、OnCreate()で、SensorManagerのインスタンスや、表示のための初期化を行っています。
リスナー(ISensorEventListener)は、自分自身として実装し、登録及び解除は、OnResume()及びOnPause()で行っています。
OnSensorChanged()で取得できるのは、「方位角」「傾斜角」「回転角」の3つですが、
この方位角は、現在の角度(0〜360の左回り)です。
サンプルでは、この値(角度)を1回分保存し、前回との差分で画像を回転させています。
[Activity(Label = "AndroidApplication1", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : Activity,ISensorEventListener{ private SensorManager _senseManager; private ImageView _imageView; private TextView _textView; private Matrix _matrix; private float _centerX; //回転の中心座標 private float _centerY; //回転の中心座標 protected override void OnCreate(Bundle bundle){ base.OnCreate(bundle); SetContentView(Resource.Layout.Main); _senseManager = (SensorManager) GetSystemService(SensorService); _imageView = FindViewById<ImageView>(Resource.Id.image); _textView = FindViewById<TextView>(Resource.Id.textView); _matrix = new Matrix(); //ディスプレイのサイズ取得 var display = WindowManager.DefaultDisplay; var dispWidth = display.Width; var dispHeight = display.Height; //画像のサイズ取得 var d = Resources.GetDrawable(Resource.Drawable.magnet); var imageWidth = d.IntrinsicWidth; var imageHeight = d.IntrinsicHeight; //画像を画面の中央に移動する _matrix.PostTranslate((dispWidth - imageWidth) / 2, (dispHeight - imageHeight) / 2); //回転させる際の中心座標を保存しておく _centerX = dispWidth/2; _centerY = dispHeight/2; } protected override void OnResume(){ base.OnResume(); //傾きセンサー取得 var list = _senseManager.GetSensorList(SensorType.Orientation); //取得に成功した場合のみ処理 if (list.Count > 0){ //リスナーに登録(第3引数は感度) _senseManager.RegisterListener(this,list[0], SensorDelay.Normal); } } protected override void OnPause(){ base.OnPause(); //リスナー解除 _senseManager.UnregisterListener(this); } //ISensorEventListenerで必須 public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy){ } private float _keepValue;//前回の角度 public void OnSensorChanged(SensorEvent e) { //傾きセンサーのみ処理 if (e.Sensor.Type == SensorType.Orientation){ //e.Values[0] 方位角 //e.Values[1] 傾斜角 //e.Values[2] 回転角 //現在の角度を取得 var value = e.Values[0]; //中心座標と回転角(前回角度ー現在角度)をセットする _matrix.PostRotate(_keepValue - value, _centerX, _centerY); //画像を回転させる _imageView.ImageMatrix = _matrix; //テキスト表示 _textView.Text = string.Format("{0} - {1} = {2}", _keepValue,value,_keepValue - value); //次回用に角度を保存する _keepValue = value; } } }