Я рассказал о том, как можно использовать Sensor and Location platform в своих приложениях. Мы увидели, что использование этого набора компонент может быть очень удобным для приложения и не требует много усилий. Также мы получаем возможность работы с множеством устройств в унифицированном виде. Единственной проблемой использования этой платформы остается наличие драйверов для Windows 7 и наличие оберток для Sensor API. Разработка драйвера для устройства – задача производителя, в первую очередь. А вот реализацию поддержки в Sensor API вполне можно сделать собственными силами. Здесь мы и займемся этим.
Как я уже говорил точкой входа является класс SensorManager
. С помощью этого класса можно получить доступ к нужным сенсорам и поработать с ними. Этот класс имеет такие методы как получение списка всех сенсоров, получение сенсора по ID или по типу, запрос на использование сенсора, а также событие изменения количества сенсоров в системе.

Каждый сенсор имеет два основных типа идентификаторов – SensorId
и TypeId
. TypeId
идентифицирует отдельный класс устройств. Например, по нему можно получить все датчики света в системе, или какие-то другие типы устройств. SensorId
присваивается уникально каждому устройству. Например, если в системе три однотипных датчика движений, то каждый будет иметь уникальный идентификатор. Есть еще также CategoryId
, который объединяет сенсоры в категории.
Каждый идентификатор представляет собой GUID
. Они задаются производителями при разработке устройства и драйверов. Таким образом, можно получить конкретный сенсор только зная его ID
. Каждый сенсор представлен классом Sensor. Он имеет общую информацию о сенсоре и методы, которые позволяют получить данные из обобщенных коллекций в нетипизированном виде. Понятно, что такое представление данных не очень удобно для наших приложений. Поэтому для каждого сенсора принято реализовывать класс-обертку в рамках Sensor API
. Реализуется она путем наследования от общего класса Sensor
. В демонстрационных примерах уже есть две такие реализации – для акселерометра и для датчика света. Однако, в устройстве, которое мы рассматривали ранее присутствуют также сенсорные кнопки, которые также можно использовать. Поэтому давайте реализуем такой класс для этого датчика.
Мы определим новый класс, который будет наследником класса Sensor
. Для того, чтобы он распознавался в Sensor API его нужно пометить атрибутом SensorDescription
, в котором указать TypeId
для этого типа сенсоров. В базовом классе Sensor существуют две важные вещи для нас – свойство DataReport
и событие DataReportChanged
. Это свойство содержит данные от сенсора, а событие срабатывает при их изменении. Задача нашего класса – воспользоваться этими данными и доставить их пользователю нашего класса в удобном виде. Для этого создадим еще один небольшой класс, который будет заниматься разбором информации из DataReport.
Экспериментальным путем мы выясним, что при нажатии кнопки 1 генерируется код 1, при нажатии 2 – генерируется код 2, при нажатии 3 – генерируется код 4, а при нажатии 4 – генерируется код 8. Видно, что здесь используются просто двоичные разряды. Также генерируется код 0 в случае отпускания всех кнопок. Таким образом, мы можем написать следующий код.
[SensorDescription("545C8BA5-B143-4545-868F-CA7FD986B4F6")]
public class SwitchArraySensor : Sensor
{
public class SwitchArraySensorData
{
private static Guid KeyStateProperyId = new Guid(@"38564a7c-f2f2-49bb-9b2b-ba60f66a58df");
public SwitchArraySensorData(SensorReport report)
{
uint state = (uint) report.Values[KeyStateProperyId][0];
Button1Pressed = (state & 0x01) != 0;
Button2Pressed = (state & 0x02) != 0;
Button3Pressed = (state & 0x04) != 0;
Button4Pressed = (state & 0x08) != 0;
}
public bool Button1Pressed { get; private set; }
public bool Button2Pressed { get; private set; }
public bool Button3Pressed { get; private set; }
public bool Button4Pressed { get; private set; }
}
public SwitchArraySensorData Current
{
get { return new SwitchArraySensorData(DataReport); }
}
public event EventHandler StateChanged;
public SwitchArraySensor()
{
DataReportChanged += SwitchArraySensor_DataReportChanged;
}
void SwitchArraySensor_DataReportChanged(Sensor sender, EventArgs e)
{
if (StateChanged != null)
{
StateChanged.Invoke(sender, e);
}
}
}
Фактически, этот класс является оберткой в Sensor API для нужного нам сенсора. Для его использования я должен подписаться на событие StateChanged
и получать информацию через свойство Current
.
Для получения списка доступных сенсоров заданного типа можно использовать метод GetSensorsByTypeId
класса SensorManager
. При этом TypeId
этих сенсоров будет определяться исходя из заданного атрибута SensorDescription
. Теперь, используя эти сенсоры мы можем подписаться на нужные событие и получать данные в удобном для приложения виде. Например, можем отображать на форме состояние нажатия кнопок.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var sensors = SensorManager.GetSensorsByTypeId<SwitchArraySensor>();
foreach (SwitchArraySensor sensor in sensors)
{
switch (sensor.FriendlyName)
{
case "Left Switch Array Sensor":
sensor.StateChanged += delegate(object leftSensor, EventArgs arg)
{
var buttons = ((SwitchArraySensor)leftSensor).Current;
SwitchState(LeftButton1, buttons.Button1Pressed);
SwitchState(LeftButton2, buttons.Button2Pressed);
SwitchState(LeftButton3, buttons.Button3Pressed);
SwitchState(LeftButton4, buttons.Button4Pressed);
};
break;
case "Right Switch Array Sensor":
sensor.StateChanged += delegate(object rightSensor, EventArgs arg)
{
var buttons = ((SwitchArraySensor)rightSensor).Current;
SwitchState(RightButton1, buttons.Button1Pressed);
SwitchState(RightButton2, buttons.Button2Pressed);
SwitchState(RightButton3, buttons.Button3Pressed);
SwitchState(RightButton4, buttons.Button4Pressed);
};
break;
}
}
}
В итоге получим приложение, которое выглядит следующим образом.

Конечно, пример с реализацией подобного сенсора достаточно синтетический. Однако, он явно демонстрирует процесс подключения датчика к Sensor API.
Также, если вам необходимо реализовать собственный драйвер для устройства с целью подключения к Windows 7 Sensor and Location platform, рекомендую вам обратиться на официальный ресурс.