方位センサー
以前、センサーを使ってどうこうという話を書きました。
このときは1.6前提での話だったのでTYPE_ORIENTATIONを利用するという話を書いていたのですが、その後この定数はdeprecatedということで廃止予定だから、なるべく使わないでくださいねってことになっていました。
そこで代返の機能を調べてみることにしました。
それから、2012/2のAndroidの会横浜支部定例会で方位センサーに関する話をしまして、そこで発表した内容などをgithubに載せています。
https://github.com/sato-c/sensorcheck
「よくわかるAndroidアプリ開発の教科書」のライブ壁紙で使っている方位磁針が元ネタですが、それを1つのViewにまとめて表示していますので、見てみてください。解像度違っていても同じ比率で表示するようにもしてあります。
まずは、TYPE_ORIENTATIONがダメになったと言うことでどうするかという話は、SensorManager.getOrientation()を使えということだそうで、2つのセンサーの値を使って、このgetOrientationメソッドにて変換、方位は出せるようになりました。そのときに参考にしたサイトはUsing getRotationMatrix and getOrientation in Android 2.1など。
とりあえう、この2つのメソッドで検索すると他にもいくつか出てきます。
地磁気センサーと加速度センサーで取ってきたデータをgetOrientationで変換しろってことですが、これ画面の向きが変わると値変わるから気をつけてねっていう仕様でした。
SDKのマニュアルなど読んでいると、remapCoordinateSystemを使って回転行列を使う環境に合わせて回転しないとダメ的な話が書いてあるんですが、ちょっとこれがよくわからない。
試しに画面の向きを都度確認しながら変換してみたりとか、そんな無駄なことを繰り返してみたんですけど、あんまりいい感じにならなかったので困ってました。
さて困った。というときは、SDKのソースを見てみるといいことあるかも。
ということで、早速探してみます。
まず、TYPE_ORIENTATIONが使えなくなるとはいえ、後方互換性のために残してあるはずと予想を立て、SensorManager.javaを見てみるとLegacyなセンサーのリスナーがーみたいなことが書いてあります。
なんかありそう。なので、追っていくと、TYPE_ORIENTATION(とTYPE_ORIENTATION_RAW)では、画面の向きによって補正してました。
画面の向きの取得は、Display.getRotation()で見ることができます。
Surface.ROTATION_0~Surface.ROTATION_270で向きが返ってきますので、これに応じて向き(角度)を補正してあげれば必要な角度を求めることができます。
SensorManager.getRotationMatrix→SensorManager.getOrientationで戻ってくる値はラジアンなので必要に応じて角度に変換する必要があります。角度に変換してから補正した方がわかりやすいかもしれません。
Displayを取得するには、WindowManagerサービスを利用しますので、Context.getSystemServiceを使います。
せっかくだから、載せておこう。
mWindow = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
そんなわけで無事目的の形を実装できましたので、先に進むことができるというわけでした。よかったよかった。
