Розробка програм для Windows Phone/Акселерометр

Матеріал з Вікіпідручника
Перейти до навігації Перейти до пошуку

Аппарат Windows Phones містить у собі акселерометр — це невеликий електромеханічний пристрій який безпосередньо вимірює силу, яка у фізиці має назву — сила прискорення.

Загальні відомості[ред.]

Коли телефон знаходиться у положенні спокою, акселерометр також фіксує силу тяжіння, отже акселерометр також може дати інформацію про положення телефону відносно землі. Акселерометр також реагує на рухи телефону, такі як струси і ривки, що може бути використане як інформативний сигнал для вашої гри чи програми.

Вимірювання акселерометра зручно представляти у вигляді тривимірного вектору (x, y, z), який вказує напрям прискорення у просторі і його величину. Значення довжини вектора можна отримати із тривимірного вектора за допомогою теореми Піфагора:

XNA має визначення типу для тривимірного вектору ; Silverlight - ні.

Використовується тривимірна система координат, така сама як використовується для створення ігор на основі XNA - це правостороння декартова система координат. При будь-якому розташуванні телефону, позитивний напрямок осі Y вказує на верх, вісь X направлена зліва направо у площині екрану телефону. Вісь Z буде направлено прямо на вас.

Якщо ви повернете телефон на 90° за годинниковою стрілкою вектор акселерометра матиме значення (–1, 0, 0), якщо ви перевернете низом до гори – отримаєте значення (0, 1, 0), якщо ви опустите руки вниз тримаючи телефон дисплеєм вверх до себе, отримаєте вектор (0, 0, –1).

Звичайно, значення вектору рідко будуть мати цілі значення, і його довжина буде різною.

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

Робота з акселерометром в програмі[ред.]

Для того щоб мати змогу працювати з акселерометром, вам необхідно підключити бібліотеку Microsoft.Devices.Sensors, і прописати дерективу using для простору імен Microsoft.Devices.Sensors. А у файлі WMAppManifest.xml, вам необхідно прописати наступне:

<Capability Name="ID_CAP_SENSORS" />


Це зроблено по замовченню у проекті.

Далі вам необхідно створити екземпляр класу Accelerometer, назначити обробник події для ReadingChanging і визвати метод Start.

public MainPage() 
{ 
   InitializeComponent(); 
   Accelerometer acc = new Accelerometer(); acc.ReadingChanged += OnAccelerometerReadingChanged; 
   try 
   { 
      acc.Start(); 
   } 
   catch (Exception exc) 
   { 
      txtblk.Text = exc.Message; 
   } 
}


Клас Accelerometer також має методи Stop і Dispose.

У Silvrlight програмі метод обробки події ReadingChanged отримує аргументи зібрані у класі AccelerometerReadingEventArgs. Об’єкт має поля X, Y, and Z типу double, які несуть в собі значення вектору і поле DateTimeOffset типу TimeStamp.

Для прикладу напишемо простий код для Silverlight програми, яка виконує прості дії по реєстрації інформації отриманої з акселерометру і відображенню її у текстовому полі TextBlock на екрані.

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

Для вирішення цієї задчі існує клас Dispatcher об’явлений у просторі System.Windows.Threading. За допомогою цього класу ви можете ставити в чергу задачі від іншого потоку, основному потоку в якому створено графічні елементи. Екземпляр класу Dispatcher, доступний як поле класу DependencyObject, від якого унаслідуються графічні компоненти.

Для того, щоб працювати з диспетчером вам необхідно створити делегат і метод який буде виконувати дії по зміні тексту і який відповідає формату описаному за допомогою делегату. Делегат і метод нічого не мають повертати.

delegate void SetTextBlockTextDelegate(TextBlock txtblk, string text);

void SetTextBlockText(TextBlock txtblk, string text) 
{ 
   txtblk.Text = text; 
}


У методі OnAccelerometerReadingChanged, перше що вам необхідно виконати метод CheckAccess, щоб перевірити можливість визову методу SetTextBlockText напряму, якщо ні то визвати метод диспетчера – BeginInvoke, першим аргументом якого буде екземпляр делегату для метода SetTextBlockText за яким слідують усі необхідні для цього методу параметри:

void OnAccelerometerReadingChanged(object sender, AccelerometerReadingEventArgs args) 
{ 
   string str = String.Format("X = {0:F2}\n" + 
                              "Y = {1:F2}\n" + 
                              "Z = {2:F2}\n\n" + 
                              "Magnitude = {3:F2}\n\n" + "{4}", 
                              args.X, args.Y, args.Z, 
                              Math.Sqrt(args.X * args.X + args.Y * args.Y + args.Z * args.Z), args.Timestamp); 

   if (txtblk.CheckAccess()) { 
      SetTextBlockText(txtblk, str); 
   } 
   else 
   { 
      txtblk.Dispatcher.BeginInvoke(new SetTextBlockTextDelegate(SetTextBlockText), txtblk, str); 
   } 
}


Література[ред.]