Windows 7 Sensor & Location Platformを使ってみよう!! - その2

さて、2回目です。今回は、Windows 7 PCに接続されたセンサーを取り出すコードを紹介します。

接続されたセンサーを取り出すには、Windows 7 API Code PackのSensorManagerクラスを使います。SensorManagerには以下の5個のスタティックメソッドが用意されています。

  • SensorList<Sensor> GetAllSensors()
  • SensorList<Sensor> GetSensorByCategorId(Guid category)
  • SensorList<Sensor> GetSensorsByTypeId(Guid typeId)
  • SensorList<S> GetSensorsByTypeId<S>()
  • S GetSensorBySensorId<S>(Guid sensorId)

戻り値のSensorListクラスは、個々のセンサーを表現するSensorクラスのコンテナです。最後のメソッドを除き、該当するセンサーコンテナを返します。SensorList<S>の部分は、Sensorクラス、及び、Sensorクラスの派生クラスを表します。
1番目のメソッドは、Windows 7 PCに接続された全てのセンサーを格納したコンテナを返します。
Sensor & Location Platformのヘッダーファイルsensorsapi.hを覗くと、センサーはカテゴリー分けされ、カテゴリーの下に複数のセンサー種別が定義されています。別のヘッダーファイルsensors.hには、カテゴリー、種別毎に一意のGUIDが定義されています。二番目のメソッドは、カテゴリーのGUIDを指定して、指定されたカテゴリーに属するセンサーのみを取り出すことができます。三番目のメソッドは、種別のGUID(TypeId)を指定して、その種別に属するセンサーのみを取り出すメソッドです。四番目のメソッドは、<S>で指定した種別のセンサーのみを取り出せます。Windows 7 API Code Packでは、Sensorクラスの派生クラスとして、AmbientLightSensor(照度センサー)、BooleanSwitchArray(タッチアレイ)、Accelerometer3D(3軸加速度センサー)が用意されていて、親クラスを含む、これら4種類のクラスをSとして指定できます。
個々のセンサーは、それぞれを一意に特定する識別子を持つことを推奨されています。五番目のメソッドは、センサー識別子を指定して、そのセンサーの種別のクラスオブジェクトで、接続されたセンサー(1個)を取り出します。

自分が使いたいセンサー(例えば温度センサー等)に対応したクラスが無い場合は、既存のクラス定義(Code PackのSensorsプロジェクトのSensorsの下にある)を参照して、sensors.hに定義されたGuidを使って、独自に作成すればよいでしょう。

では、以下に幾つかのサンプルコードを紹介しましょう。最初にusingを加えて…

using Microsoft.WindowsAPICodePack.Sensors;

全てのセンサーを取り出すには

SensorList<Sensor> sensors =     SensorManager.GetAllSensors(); foreach (Sensor sensor in sensors) {     …. }

特定のセンサー(例えば照度センサー)を取り出したい場合は、

SensorList<AmbientLightSensor> sensors =     SensorManager.GetSensorsByTypeId<AmbientLightSensor>(); foreach (AmbientLightSensor sensor in sensors) {     …. }

取得したいセンサーのIDを知っている場合は、

Guid sensorId = new Guid(“{….}”); AmbientLightSensor sensor =     SensorManager.GetSensorBySensorId(sensorId);

となります。

さて、Windows PCの周辺デバイスは、かなり昔から、PC実行中に抜き差しできる、いわゆる、Plug & Playに対応しています。センサーも当然ながら、Plug & Playができる可能性があります。ということは、アプリケーションが実行中に接続されたり、抜かれたりするセンサーデバイスもありうるわけです。Sensor & Location PlatformはPCに直接接続されているセンサーだけでなく、無線やLANで接続されたセンサーデバイスを扱うことも可能です。アプリケーションで、センサーの抜き差しを検知するには、SensorManagerクラスに定義されているイベントにハンドラーを登録しておき、センサーデバイスの抜き差しを監視します。

SensorManager.SensorsChanged +=     new SensorsChangedEventHandler(SensorChanged); …… void SensorChanged(SensorsChangedEventArgs e) {     if (e.Change == SensorAvailabilityChange.Addition)     {         Sensor addedSensor =             SensorManager.GetSensorBySensorId<Sensor>(e.SensorId);         ……      }     else if (e.Change == SensorAvailabilityChange.Removal)     {         Guid removedSensorId = e.SensorId;         ……      } }

センサーが接続されると、イベント引数のChangeにAdditionの値がセットされます。センサーが切り離されると、ChangeにRemovalがセットされます。特に接続されていたセンサーが切り離されるとそのセンサーの値を定期的にポーリングしているスレッドなどがあると、Exceptionが発生してしまうので、後始末をちゃんとしましょうね。

それから、Sensor & Location Platformでは、各センサーごとにUser Access Controlを行うことができます。センサーデバイスをつないだら、コントロールパネル→ハードウェアとサウンド→位置センサーとその他のセンサーの有効化で、ユーザーに対して実行権限を付与しておくか、以下のコードでアプリケーション実行時毎に、ユーザーに対してセンサーを利用して良いかを問い合わせることができます。メソッドは、

RequestPermission(IntPtr parentWindowsHandle, bool model, SensorList<Sensor> sensors)

です。このメソッドの最初の引数には、Win32時代からおなじみのWindowのHandleを指定する必要があります。これは.NETのInterop機能を利用して取得します。二番目の引数をtrueで指定すると、ダイアログが表示されてOK、NGを選択させることができます。コードは以下のようになります。

using System.Windows.Interop; …… WindowInteropHelper wiHelper =     new WindowsInteropHelper(MyWindow); // WPFのウィンドウクラス SensorList<Sensor> sensors = new SensorList<Sensor>(); sensors.Add(…); // パーミッションを得たいセンサーのリスト RequestPermission(wiHelper.Handle, true, sensors);

これで、センサーの取得、センサーの接続・切り離し、使用許可の処理ができるようになりました。

今日はこれまで。

その3へ 目次へ