本サイトからスピンオフした姉妹サイトです。Plugin」プラグインを紹介。今回は、Accelerometer(加速度)センサー、Gyroscope(ジャイロスコープ)センサーの機能を使う方法を説明する。前回はGPSを簡単に使用できるGeolocatorを紹介した。Pluginを2回に分けて紹介していく。Studioの最新版を使用している。8.1の6つのプロジェクトが作成されるが、本連載ではAndroid/iOS/UWPでのスクリーンショットを使用している。最新版にアップデートしてUWPアプリの作成も試してもらいたい。Studioの場合は[ソリューション]ビューの各プロジェクト項目からNuGetパッケージを追加できる)。Motionを[インストール]する。Pluginの概要CrossDeviceMotionクラス(DeviceMotion.Plugin名前空間)のCurrentプロパティを使用して、Accelerometer(加速度)センサー、Gyroscope(ジャイロスコープ)センサー、Magnetometer(磁気)センサー、Compass(コンパス)にアクセスできる。センサーの種類を表すMotionSensorType列挙体にAccelerometer、Gyroscope、Magnetometer、Compassが含まれており、センサーの応答間隔を表すMotionSensorDelay列挙体には以下が含まれている。200戻り値の型であるMotionSensorValueType列挙体にはSingleとVectorがあり、Accelerometer、Gyroscope、MagnetometerがVector値を、CompassがSingle値を返す。APIの詳細はGitHubのReadme(英語)を参照してほしい。今回は「Accelerometer」と「Gyroscope」を紹介する。Accelerometer(加速度)センサーAccelerometerは、デバイスの傾きを取得するセンサーだ。使い道としては、例えばドライビングゲームでスマホの傾きを検出して、それに応じてハンドルを切る操作などが想像できるだろう。簡単なサンプルコードはGitHubにアップした。サンプルの中の「BI_Accelerometer」と「BI_Gyroscope」というフォルダーの中身がXamarin.Formsのプロジェクトで、「X_Accelerometer」と「X_Gyroscope」がXamarinネイティブのプロジェクトだ。次のコードで傾きを取得できる。CurrentメソッドでCrossDeviceMotionクラスのインスタンスを取得する。そのインスタンスをメンバー変数に代入して保持しておかないと、ガベージコレクションによりオブジェクトが自動削除されることがあるので注意してほしい。Startメソッドに、引数としてMotionSensorType(センサーの種類)とMotionSensorDelay(センサー値の取得間隔)を与えて、センサー値の取得を開始する。sensorType)メソッドでセンサーがアクティブなことを確認し、SensorValueChangedイベントのイベントハンドラーで、デバイスの傾きが変化した際の処理を記述すればよいだろう。SensorValueChangedイベントハンドラーの引数として渡されたSensorValueChangedEventArgsのValueプロパティ値は、2で指定したMotionSensorTypeに基づき、適切な型にキャストしてほしい。リスト1では、X/Y/Z軸の値を取得するためにMotionVector型にキャストしている。センサー値の取得は、バックグラウンドのスレッドで動作している。}でくくる必要があるので注意してほしい(※上記のコードでは、Viewが動作するメインスレッドにアクセスする必要がないのでコメントアウトしている)。BeginInvokeOnMainThreadメソッドは、名前のとおりだが、メインスレッド上のコードを呼び出すためのものである。注意点Accelerometerセンサーで得られるX値・Y値・Z値だが、OSにより取得できる値が異なるので注意してほしい。以下の数値の説明に誤りがありましたので修正しました。詳しくは末尾の更新履歴をご参照ください)。[+]側が上になる場合、加速度の値(単位はm/s2=メートル毎秒毎秒)が戻り値として取得できる。9.8m/s2)で9.8になる。共に、1G(=重力加速度)を1とした値が戻り値として取得できる。加速度の値(X/Y/Z軸のイメージ)まずスマートフォンの表面の横軸がX軸、縦軸がY軸、スマートフォンの裏面から表面に突き刺さるような形でZ軸をイメージしてほしい。Accelerometerは傾きなので、「X/Y/Z軸のどのベクトルが、重力に対して上になっているか?」が数値に反映される。スマートフォンを地面に対して水平に保持すると(=机の上にスマホを置いているのと同じ状態で)、重力に反するベクトルがZ軸のプラス方向に1Gとなるので、Z軸のみがAndroidでは9.8、iOS/UWPでは-1となる(X軸とY軸は0)。スマートフォンを縦に持って地面に向かって垂直の状態を保持すると(=机の上にスマホの下側を付けて立てている状態で)、重力に反するベクトルがY軸のプラス方向に1Gとなるので、Y軸のみがAndroidでは9.8、iOS/UWPでは-1となる(X軸とZ軸は0)。ここまでくればX軸についても理解できるだろうが、スマートフォンの左側面を下にして横に持って垂直の状態を保持すると(=机の上にスマホの左側を付けて立てている状態で)、重力に反するベクトルがX軸のプラス方向に1Gとなるので、X軸のみがAndroidでは9.8、iOS/UWPでは-1となる(Y軸とZ軸は0)。理解がより深まるように、もう少し複雑な事例を示しておこう。端末の右上が上になるようにいい感じに斜めに持った例(左:Android、中:iPhone、右:UWP)これは図1で行ったX軸、Y軸、Z軸に対しての各プラス方向への傾けを全て半分ずつ(=45度ずつ)行った状態だ。コツとしては、机に置いた状態から下を付けた状態で45度傾け、さらに左側が下になる形で45度分横に回転させることだ。これによりX/Yの値が、Androidではそれぞれ5、iOS/UWPでは-0.5となり、Zの値がAndroidでは7前後、iOS/UWPでは-0.7前後となる(Z値はセンサーの位置によって多少数値が異なるようだ)。Xamarin.iOSでのAccelerometerの取得方法Xamarin.iOSでAccelerometerセンサーの値を取得するには、CMMotionManagerクラスを使用する。説明すると、CMMotionManagerオブジェクトのStartAccelerometerUpdatesメソッドでセンサー値の取得を開始する。同メソッドの第2引数にはCMAccelerometerHandlerデリゲートを指定するが、そのデリゲートメソッドの第1引数に渡されるCMAccelerometerDataオブジェクトのAcceleration.XプロパティでX値、Acceleration.YプロパティでY値、Acceleration.ZプロパティでZ値を取得すればよい。日本語情報」を参照してほしい。Xamarin(英語)」と、そのサンプルアプリも参照するとより理解が深まるだろう。Xamarin.Androidでセンサー値を取得するには、SensorManagerクラスを使用する。説明すると、ActivityにISensorEventListenerインターフェースの実装を追加し、SensorManagerオブジェクトのRegisterListenerメソッドを使用してセンサー監視を登録する。その後は、先ほどのインターフェースにより実装したOnSensorChangedメソッド内で、その引数として渡されたSensorEventオブジェクトのValuesプロパティ値(=IList<float>型で、Values[0]がX値、Values[1]がY値、Values[2]がZ値を表す)を使用すればよい。日本語情報」を参照してほしい。Xamarin(英語)」と、そのサンプルアプリも参照するとより理解が深まるだろう。Gyroscope(ジャイロスコープ)センサーGyroscopeは、デバイスの動きを検知するセンサーだ。使い道としては、例えばLINEユーザーであれば「ふるふる」の機能を思い浮かべてほしい。Googleマップにも「シェイクでフィードバックを送信」の機能がある。Gyroscopeのセンサー値を取得するコードは、先ほどのAccelerometerの場合と比較して、MotionSensorType列挙体でGyroscopeを指定する以外は変わらないため、ここでは詳しい説明を割愛する。ポイントは、MotionVectorオブジェクトのXプロパティ値で前後のひねりの速さ、Yで左右のひねりの速さを取得でき、Zでスマホ正面から見て左右の回転(=スライド)を取得できる。4-2が分かりやすいだろう。ひねりの速度の値(X/Y/Z軸のイメージ)まずスマートフォンの表面の横軸がX軸、縦軸がY軸、スマートフォンの裏面から表面に突き刺さるような形でZ軸をイメージしてほしい。Gyroscopeは「X/Y/Z軸の各軸に対するひねり」が数値に反映される。試す際には、それぞれの軸を中心として円状の矢印の方向に回転させるとプラスの値、逆方向に回転させるとマイナスの値が得られる。AndroidとiOS/UWPでは回転方向に対して数値の+と-が逆になるので注意してほしい。回転速度の単位はrad/s(ラジアン毎秒)となる。乱暴だが、サンプルアプリでは端末のシェイクを判定する次のロジックを用意した。SensorValueChangedイベントハンドラー内で判定しているが、通常は別途Modelを用意して判定するとよいだろう。その個数が3より大きい際に「シェイクした」と判定して、ダイアログを表示している。基本的なコードはAccelerometerと同じなので割愛する。違いは、CMMotionManagerクラスのStartGyroUpdatesメソッドでセンサー値の取得を開始することと、(先ほどはAcceleration.Xプロパティだった箇所が)RotationRate.xプロパティでX値、RotationRate.yプロパティでY値、RotationRate.zプロパティでZ値を取得することだ。Xamarin.AndroidでのGyroscopeの取得方法こちらも基本的なコードはAccelerometerと同じだ。違いは、SensorManager型のメンバー変数sensorManagerのRegisterListenerメソッドを呼び出す際に、その第2引数に(先ほどのAccelerometerではsensorManager.GetDefaultSensor(SensorType.Accelerometer)を指定したが)GyroscopeではsensorManager.GetDefaultSensor(SensorType.Gyroscope)を渡すことだ。Phoneなどで簡単に各種センサーの機能を使用することができる。皆さんのアプリに、タップ以外のモーションによる操作を追加したい場合にぜひ活用してほしい。次回はMagnetometer、Compassを紹介する。Xamarinネイティブでの各センサーの使い方もあらためて詳しく紹介したい。【更新履歴】2016/03/10Accelerometerセンサーで得られる値について、「Androidの最大値が10、iOSが1」と記載していましたが、「Androidは加速度の値(=単位はm/s2=メートル毎秒毎秒で、重力加速度は9.8m/s2)、iOSはG(=重力加速度)を1とした値」の誤りでした。お詫びして訂正させていただきます。※以下では、本稿の前後を合わせて5回分(第62回~第66回)のみ表示しています。INDEX]を参照してください。Xamarinを複数回にわたって紹介していく。Storage」プラグインを説明する。Xamarinを複数回にわたって紹介していく。今回は、GPSの機能を使える「Geolocator」プラグインを説明する。Plugin」プラグインを紹介。今回は、Accelerometer(加速度)センサー、Gyroscope(ジャイロスコープ)センサーの機能を使う方法を説明する。Plugin」プラグインを紹介。今回は、Magnetometer(磁気)センサー、Compass(コンパス)の機能を使う方法を説明する。Workbooksの基本的な使い方を解説。機械学習エンジニアを目指す人~初中級者のための技術情報サイトです。2023最適なビューへの切り替えを推奨します:スマートフォン用表示に。