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); |
これで、センサーの取得、センサーの接続・切り離し、使用許可の処理ができるようになりました。
今日はこれまで。