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へ 目次へ

Comments (0)

Skip to main content