Использование сенсоров в приложении: реализация в managed-коде (ч.1)

Автор: Topol Четверг, Май 3rd, 2012 Нет комментариев

Рубрика: Операционные системы

До сего момента мы охватили архитектуру платформы Sensor and Location в Windows 7 ([url=http://www.thevista.ru/page.php?id=12383]Я тебя чувствую: использование платформы Sensor в Windows 7  [/url]) и Использование сенсоров в приложении: реализация в native-коде (ч.1). В сегодняшней статье я расскажу об управляемом API для использования сенсоров. В следующих публикациях я продолжу рассказ о нативных API.

До сих пор вы видели примеры использования платформы с помощью C++ и COM. Теперь давайте рассмотрим, как разработчики управляемого кода смогут использовать платформу с помощью [url=http://code.msdn.microsoft.com/WindowsAPICodePack]Windows API Code Pack для .NET  Framework[/url].

Обнаружение сенсоров с помощью управляемого кода
При использовании управляемого кода следуйте тем же рекомендациям, что и для нативного кода: для начала необходимо обнаружить сенсоры, проверить их состояние и при необходимости права, а затем прочитать данные с сенсора. Давайте начнем с обнаружения сенсора.

Основное пространство имен для сенсоров для сенсоров в Windows API Code Pack — это Microsoft.WindowsAPICodePack.Sensors из сборки Microsoft.WindowsAPICodePack.Sensors.dll. Это пространство имен содержит класс SensorManager, управляющий сенсорными устройствами, подключенными к ПК. Этот класс предоставляет набор методов, схожих с методами из нативного интерфейса ISensorManager. Эти методы включают GetSensorsByCategoryId, GetSensorsByTypeId и GetSensorsBySensorId, последний из которых получает в качестве входного параметра GUID, который представляет категорию сенсора, тип или идентификатор сенсора. Кроме того, вы также найдете метод GetAllSensors, который возвращает все сенсоры, подключенные к системе, независимо от типа или категории, как показано в следующем фрагменте кода.

Код:
private void PrintAllSensors()
{
SensorList<Sensor> sensorList =  SensorManager.GetAllSensors();
foreach (var sensor in sensorList)
{
StringBuilder sb = new  StringBuilder();
sb.Append(«Sensor Information:»);
sb.Append(Environment.NewLine);
sb.Append(sensor.FriendlyName);
sb.Append(Environment.NewLine);
sb.Append(sensor.CategoryId);
sb.Append(Environment.NewLine);
sb.Append(sensor.State);
sb.Append(Environment.NewLine);

Console.WriteLine(sb.ToString());
}
}

Запуск вышеприведенного фрагмента кода на моей локальной машине дает следующий результат: отображает сенсоры, подключенные к моей локальной машине. Обратите внимание, что лишь виртуальный датчик освещения находится в состоянии Ready, а остальные показывают AccessDenied, означая, что они не доступны.

      Sensor Information:

 

      Legacy GPS Driver

 

      bfa794e4-f964-4fdb-90f6-51056bfe4b44

 

      AccessDenied
      Sensor Information:

 

      Skyhook Wireless XPS Location Sensor

 

      bfa794e4-f964-4fdb-90f6-51056bfe4b44

 

      AccessDenied
      Sensor Information:

 

      Ambient Light Sensor

 

      17a665c0-9063-4216-b202-5c7a255e18ce

 

    Ready

Так как Windows API Code Pack включает строготипизированный класс сенсоров Sensor, получить список сенсоров и вывести их свойства достаточно просто. Нативный API имеет интерфейс Sensor, через который вы и будете работать с сенсорами, но помимо интерфейса ISensor требуется использовать GUID. В Windows API Code Pack присутствует список всех GUID, которые доступны в Sensors.h. Классы SensorPropertyKeys и SensorCategories содержат публичное свойство «только для чтения» для объектов GUID, которые соответствуют тем же самым значениям в файле Sensors.h. Однако, это не самая используемая и предпочтительная модель программирования, к которой привыкли .NET-разработчики, и в основном потому, что нативные объекты сенсора в определены не строго и вы вынуждены использовать более универсальную систему GUID для обращения к данным сенсора. Это не позволяет использовать весь спектр возможностей .NET, например, привязку данных, безопасность типов и свойства. Таким образом, пространство имен Microsoft.WindowsAPICodePack.Sensors, структура которого приведена на изображении ниже, включает несколько строготипизированных классов сенсора, позволяющих осуществлять привязку к их свойствам. Например, AmbientLightSensor, у которого одно публичное свойство, CurrentLuminousIntensity, отображающее текущее количество света (яркость), измеренное сенсором. Пространство имен также включает уровень совместимости, который охватывает нативный интерфейс, всю информацию о метаданных и объектную модель, с которой работают разработчики.

Обратите внимание, что пространство имен the Microsoft.WindowsAPICodePack.Sensors предлагает модель расширения, позволяющую создавать любой строготипизированный сенсор. Вместе с возможностями расширения, предлагаемыми нативным API, вы можете создать любой тип сенсора, какой только захотите, с любыми значениями данных. Дополнительную информацию о модуле расширения платформы Sensor and Location вы можете найти на веб-узле платформы: http://www.microsoft.com/whdc/device/sensors/.

Со строготипизированным классом сенсора Windows API Code Pack может определить версию .NET Generics методов Get. Например, GetSensorsByTypeId<S>, где S — производный тип от базового класса Sensor. Прототип выглядит следующим образом:

public static SensorList<S> GetSensorsByTypeId<S>( ) where S: Sensor

При использовании данной функции вы должны предопределить SensorList <> желаемого типа сенсора, (в нашем примере AmbientLightSensor), а затем вызвать метод, запрашивающий у менеджера сенсора возврат сенсоров типа AmbientLightSensor. Следующий фрагмент кода показывает этот процесс:

Код:
// Строготипизированный SensorList типа AmbientLightSensor
SensorList<AmbientLightSensor> alsList = null;
try
{
alsList = SensorManager.GetSensorsByTypeId<AmbientLightSensor>();
}
catch (SensorPlatformException)
{
//Обработка ошибки, когда отсутствует доступ к сенсорному устройству
}

Класс SensorManager содержит одно событие, называемое SensorChanged, эквивалентное нативному событию ISensorManager:: OnSensorEnter. Единственным различием между реализациями на нативном и управляемом коде является то, что реализация на управляемом коде в дополнение к получению события при подключении нового устройства генерирует событие при отключении сенсора. Таким образом, SensorsChangedEventArgs, параметры которого переданы обработчику события SensorManager.SensorChanged, включает SensorAvailabilityChange, определяющий тип изменения для каждого сенсора, который может стать Addition для вновь подключенных сенсоров и Removal при отключении сенсоров от ПК.

SensorManager_SensorsChanged представляет собой функцию, которая обрабатывает событие SensorsChanged в нашем приложении и это выглядит следующим образом:

Код:
void SensorManager_SensorsChanged( SensorsChangedEventArgs change )
{
// Событие SensorsChanged происходит в потоке, отличном от потока приложения.
// Анонимный делегат осуществляет обновление интерфейса приложения.
BeginInvoke( new MethodInvoker( delegate
{
PopulatePanel( );
} ) );
}

Событие SensorsChanged обрабатывается в ином потоке, отличном от основного потока приложения (UI). Windows Forms не позволяют обновлять интерфейс приложения из таких потоков. Поэтому для любого Windows-приложения с оконным интерфейсом мы настоятельно рекомендуем использовать поток, отличный от основного потока UI, для выполнения сложных вычислений или любого процесса ввода/вывода (также, как в нашем примере синхронного чтения данных сенсора). Для того, чтобы правильно осуществлять обработку обновлений для не-UI потоков, следует использовать BeginInvoke, позволяющий выполнить определенный делегат асинхронно в потоке, в котором был создан основной обработчик формы. Это также верно для любого приложения WPF. Метод PopulatePanel выполняет итерации через все сенсоры и обновляет интерфейс приложения по мере проверки состояния сенсора и чтения его данных. Об этом мы расскажем в следующих статьях.

Источник: thevista.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты