Ноу Інти, лекція, датчики і служби

Датчики і сервіси

Мета лекції: навчитися працювати з координатами, акселерометром. картами та іншими, службами та датчиками.

Пристрій Windows Phone 7 повинна мати ряд апаратних можливостей - іноді званих датчиками - і надавати деякі програмні сервіси, можливо, з апаратною підтримкою. Розглянемо ті з них, які найбільш цікаві розробникам:

акселерометр

Вихідні дані акселерометра зручно представити у вигляді тривимірного вектора. Зазвичай вектори записуються напівжирним шрифтом, тому вектор прискорення може бути позначений так:. У XNA є тип тривимірний вектор. в Silverlight немає.

Тоді як три координати точно визначають точку в просторі, вектор позначає напрямок і величину. Очевидно, що точка і вектор взаємопов'язані. Напрямок вектора - це промінь з точки в точку. Але вектор це зовсім не відрізок. з'єднує і. Цей напрямок цього відрізка.

Для обчислення модуля вектора використовується тривимірна форма теореми Піфагора:

Ноу Інти, лекція, датчики і служби


Мал. 8.1. Тривимірна система координат

Це традиційна тривимірна система координат. така ж використовується при створенні 3D-графіки на XNA. Її називають правою системою координат. Розмістіть вказівний палець правої руки вздовж позитивного спрямування, середній палець - уздовж позитивного напрямку, і великий палець буде вказувати на позитивний напрямок.

При вільному падінні модуль вектора прискорення, теоретично, повинен прагнути до нуля.

Для роботи з акселерометром використовується бібліотека Microsoft.Devices.Sensors і простір імен Microsoft.Devices.Sensors. У файлі WMAppManifest.xml необхідно вказати:

Це задається за замовчуванням.

У додатку створюється екземпляр класу Accelerometer (Акселерометр), задається обробник події ReadingChanging (Зміна показань приладу) і викликається метод Start.

Розглянемо проект SilverlightAccelerometer. project. який просто забезпечує виведення на екран поточних показань. Центрований TextBlock описується в файлі XAML.

Проект Silverlight: SilverlightAccelerometer Файл. MainPage. xaml (фрагмент)

Щоб додати бібліотеку Microsoft.Devices.Sensors в проект потрібно:

  1. натиснути правою кнопкою на вузол SilverlightAccelerometer / References у вікні Solution Explorer і виберіть Add Reference. На вкладці .NET вікна, що з'явилося для вибору бібліотек виберіть пункт Microsoft.Devices.Sensors і натиснути OK;

Ноу Інти, лекція, датчики і служби


Мал. 8.2. Додавання бібліотеки Microsoft.Devices.Sensors

  • додати рядок using Microsoft.Devices.Sensors; в MainPage.xaml.cs
  • Ця програма буде забезпечувати висновок на екран вектора акселерометра протягом усього часу його виконання, тому створення класу Accelerometer і виклик методу Start відбувається в конструкторі:

    Проект Silverlight: SilverlightAccelerometer Файл. MainPage. xaml .cs (фрагмент)

    Документація попереджає, що виклик Start може привести до формування виключення, тому додаток захищає себе від цього. Клас Accelerometer також підтримує методи Stop (Зупинити) і Dispose (Видалити), але в даній програмі вони не використовуються. Для забезпечення відомості про доступність акселерометра і його стані надається властивість State.

    Подія ReadingChanged забезпечується класом аргументів події AccelerometerReadingEventArgs. Цей об'єкт має властивості, і типу double і властивість TimeStamp типу DateTimeOffset (Зсув дати-часу). У додатку SilverlightAccelerometer завдання обробника події - форматувати ці дані в рядок і задати її як значення властивості Text об'єкта TextBlock.

    Заковика тут в тому, що обробник події (в даному випадку, OnAccelerometerReadingChanged (При зміні показань акселерометра)) викликається в іншому потоці виконання. Це означає, що він повинен оброблятися особливим чином.

    Трохи теорії. Створення та доступ до всіх елементів і об'єктів користувальницького інтерфейсу в додатку на Silverlight виконується в основному потоці виконання, який часто називають потоком користувальницького інтерфейсу або UI-потоком. Ці об'єкти користувальницького інтерфейсу не є потокобезпечна; для них не передбачено одночасний доступ з безлічі потоків. Тому Silverlight не допустить доступу до об'єкта призначеного для користувача інтерфейсу з потоку, який не є UI-потоком.

    Це означає, що метод OnAccelerometerReadingChanged не може безпосередньо звернутися до елементу TextBlock, щоб задати нове значення його властивості Text.

    На щастя в просторі імен System.Windows.Threading описаний клас Dispatcher (Диспетчер), який забезпечує вирішення цієї проблеми. Через клас Dispatcher можна направляти завдання з потоку, який не є UI-потоком, в чергу. яка пізніше буде оброблена UI-потоком. Все це звучить досить заплутано, але з точки зору розробника все досить просто, тому що ці завдання набувають форми простих викликів методів.

    Примірник Dispatcher вже доступний. Клас DependencyObject (Залежність) описує властивість Dispatcher типу Dispatcher. і від DependencyObject успадковується безліч класів Silverlight. З екземплярами всіх цих класів можна працювати з потоків, які не є UI-потоками, тому що всі вони мають властивості Dispatcher. З будь-якого похідного від DependencyObject класу, створеного в UI-потоці, може використовуватися будь-який об'єкт Dispatcher. Вони всі однакові.

    Клас Dispatcher визначає метод CheckAccess (Перевірити можливість доступу), який повертає true. якщо поточний потік має доступ до конкретного об'єкта призначеного для користувача інтерфейсу. (Метод CheckAccess також дублюється самим DependencyObject.) Для випадків, коли доступ до об'єкта з поточного потоку неможливий, Dispatcher надає дві версії методу Invoke (Викликати), за допомогою яких виконується відправка завдань для UI-потоку.

    У проекті SilverlightAccelerometer реалізована версія коду, досконала з точки зору синтаксису.

    У розгорнутій версії потрібно делегат і метод, що відповідає цьому делегату. Делегат (і метод) не повинен мати значення, що повертається, але у нього має бути така кількість аргументів, якого буде достатньо для виконання завдання. В даному випадку це завдання полягає в привласненні рядки в якості значення властивості Text об'єкта TextBlock.

    Проект: SilverlightAccelerometer Файл. MainPage. xaml .cs (фрагмент)

    OnAccelerometerReadingChanged відповідає за виклик SetTextBlockText (Задати текст блоку тексту). Він вперше використовує CheckAccess. щоб визначити можливість виклику методу SetTextBlockText безпосередньо. Якщо це неможливо, обробник викликає метод BeginInvoke (Почати виклик). Його першим аргументом є екземпляр делегата з методом SetTextBlockText. За ним слідують всі необхідні SetTextBlockText аргументи:

    Проект: SilverlightAccelerometer Файл. MainPage. xaml .cs (фрагмент)

    Це не найгірший варіант, але необхідність перестрибувати з потоку в потік спричинила за собою застосування додаткового методу і делегата.

    Ноу Інти, лекція, датчики і служби


    Мал. 8.3. результат програми

    Схожі статті