Опубликован: 10.04.2013 | Доступ: свободный | Студентов: 482 / 15 | Длительность: 16:52:00
Специальности: Программист
Лекция 4:

Многоточечные жесты

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >

Географическое расположение

Прежде чем мы рассмотрим датчики в целом, я хочу отдельно рассмотреть возможности определения географического расположения в приложениях для Магазина Windows, так как это API устроено не так, как у других датчиков. Мы уже использовали эту возможность, начиная с Главы 2 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", в приложении "Here My Am!", но нам нужен более полной обзор этой крайне полезной возможности.

В отличие от других датчиков, только определение местоположения имеет выделенную возможность, которую вы должны объявить в манифесте. То, где вы находитесь на Земле, это абсолютные данные, которые являются частью личной информации. Таким образом, пользователи должны дать согласие, прежде чем приложение сможет получить эти сведения, и ваше приложение так же должно предоставлять "Соглашение о конфиденциальности" в Магазине Windows. Другие датчики, в отличие от этого, предоставляют относительную информацию – вы не можете, например, узнать что-либо о человеке из данных о наклоне устройства, о его перемещении или из сведений о том, насколько яркий свет его освещает. Соответственно, вы можете использовать другие датчики без объявления каких-либо особых возможностей.

Как вы можете знать, данные о географическом местоположении могут быть получены двумя различными путями. Первый, и наиболее точный, конечно, это получение данных с GPS-приемника, который получает информацию от геостационарных спутников, расположенных на орбитах в несколько сотен миль. Другим, достаточно полезным, хотя и не всегда точным средством является попытка узнать местоположение на основе IP-адреса проводного сетевого соединения или триангуляция на основе расположения доступных точек доступа WiFi. В любом случае, WinRT делает все возможное для того, чтобы дать вам достойные показатели.

Для доступа к данным о географическом местоположении, вы должны сначала создать экземпляр средства определения местоположения WinRT, Windows.Devices.Geolocation.Geolocator (http://msdn.microsoft.com/library/windows/apps/windows.devices.geolocation.geolocator.aspx). Когда он у вас есть, вы затем можете вызвать его метод getGeopositionAsync, результаты работы которого (помещенные в обработчик завершения), представляют собой объект типа Geoposition (в том же пространстве имен Windows.Devices.Geolocation, если не указано иное). Вот код из "Here My Am!":

var gl = new Windows.Devices.Geolocation.Geolocator();

gl.getGeopositionAsync().done(function (position) {	
//Сохранить для целей общего доступа	
lastPosition = { latitude: position.coordinate.latitude,
longitude: position.coordinate.longitude };	
}
 

У метода getGeopositionAsync имеется вариант использования (http://msdn.microsoft.com/library/windows/apps/hh973537.aspx), применяя который вы можете указать два параметра: максимальную давность для кэшированных данных (то есть то, насколько свежими должны быть данные) и значение тайм-аута, в течение которого вы хотите ждать ответ. И то и другое значение измеряются в миллисекундах.

Объект Geoposition (http://msdn.microsoft.com/library/windows/apps/windows.devices.geolocation.geoposition.aspx) содержит два свойства. Первое, это свойство coordinate, объект Geocoodinate (http://msdn.microsoft.com/library/windows/apps/windows.devices.geolocation.geocoordinate.aspx), который предоставляет свойства accuracy (точность измерения, измеряется в метрах), altitude (высота, измеряется в метрах), altitudeAccuracy (точность измерения высоты, измеряется в метрах), heading (курс, в градусах по отношению к истинному северу), latitude (широта, измеряется в градусах), longitude (долгота, измеряется в градусах), speed (скорость, измеряется в метрах в секунду), и timestamp (отметка времени, значения типа Date). Вторая часть Geoposition это объект CivicAddress (http://msdn.microsoft.com/library/windows/apps/windows.devices.geolocation.civicaddress.aspx), который содержит свойство civicAddress, которое может содержать свойства city (город, строка), country (страна, стока, содержащая двухбуквенный код страны в формате ISO-3166), postalCode (почтовый индекс, строка), state (штат, строка), и timestamp (отметка времени, тип Date), если поставщик географических данных поддерживает подобные данные2Таким образом, civicAddress может быть недоступен или не содержать данных. В качестве альтернативного способа получения этих данных используйте API Bing Maps (http://www.microsoft.com/maps/developers/web.aspx), в частности – класс MapAddress (http://msdn.microsoft.com/library/jj663670.aspx) для того, чтобы узнать адрес по имеющимся координатам.

Вы можете задать желаемую точность измерений посредством свойства desiredAccuracy средства определения местоположения, которое может принимать значение PositionAccuracy.default или PositionAccuracy.high. Последнее, учтите, создаст большую нагрузку на аппаратное обеспечение. Это может привести к повышению стоимости использования лимитированного сетевого соединения и ускорить разряд батарей, поэтому устанавливайте этой свойство в значение high только тогда, когда это имеет ключевую важность для работы с приложением.

Средство определения местоположения так же предоставляет свойство locationStatus, которое является перечислением PositionStatus (http://msdn.microsoft.com/library/windows/apps/windows.devices.geolocation.positionstatus.aspx), содержащим такие члены, как ready, initializing, noData, disabled, notInitialized, и notAvailable. Должно быть очевидным, что вы не сможете получить данные от средства определения местоположения, которое находится в состоянии, отличном от ready (готово). Для того, чтобы отследить это, вы можете прослушивать событие средства определения местоположения statusChanged, свойство eventArgs.status которого в вашем обработчике будет содержать PositionStatus. Это полезно, когда вы обнаруживаете, что GPS-приемнику может понадобиться пара секунд на то, чтобы предоставить необходимые данные. Например, вот как используется данное событие в примере "Определение местопол ожения" (http://code.msdn.microsoft.com/windowsapps/Geolocation-2483de66) из Windows SDK:

geolocator = new Windows.Devices.Geolocation.Geolocator();
geolocator.addEventListener("statuschanged", onStatusChanged); //Позже не забудьте удалить

function onStatusChanged(e) {
switch (e.status) {
// ...
}
}
 

Обратите внимание на то, что PositionStatus и statusChanged отражают чтение данных с GPS-устройства, и на чтение не влияет разрешение на получение данных о местоположении в панели параметров. Как показано в "Here My Am!", приложению не нужно проверять разрешение, пытаясь получить значения параметров, что является особенностью получения данных от устройства.

Два других интересных свойства средства определения местоположения – это movementThreshold, расстояние в метрах, на которое может переместиться устройство, прежде чем будет вызвана следующая операция чтения данных (это может быть использовано в сценариях с установкой географических границ), и reportInterval, который задается в миллисекундах между попытками чтения данных. Используйте последний параметр умеренно, устанавливайте его в то значение, которое вам действительно нужно, так как следует стремиться к минимизации сетевой активности и активности GPS-датчика. В любом случае, когда средство определения местоположения получает новые данные и обнаруживает, что устройство переместилось за пределы movementThreshold, оно вызывает событие positionChanged, свойство которого eventArgs.position является новым объектом Geoposition. Это так же показано в Сценарии 1 примера об определении местоположения:

geolocator.addEventListener("positionchanged", onPositionChanged);

function onPositionChanged(e) {
var coord = e.position.coordinate;

document.getElementById("latitude").innerHTML = coord.latitude;
document.getElementById("longitude").innerHTML = coord.longitude;
document.getElementById("accuracy").innerHTML = coord.accuracy;
}
 

В случае с movementThreshold и reportInterval, рассматривайте их с позиций нужд приложения, основанных на точности и/или интервале обновления данных о местоположении, которые вы используете. Например, данные о погоде относятся к регионам и могут обновляться лишь раз в час. Поэтому movementThreshold может быть установлено в милях или километрах, reportInterval – на 15, 30, 60 минут или на более длительное время. Приложения работы с картами или предназначенные для автомобилистов, с другой стороны, работают с данными, весьма чувствительными к местоположению и, таким образом, будут иметь гораздо меньшие пороговые значения и более короткие интервалы обновления.

Когда имеет значение время жизни устройства от батарей, лучше всего просто получать новые данные, когда они нужны пользователю, вместо того, чтобы выполнять это через некоторые регулярные интервалы. Но это, опять же, зависит от сценария приложения, и вы можете так же предоставить параметр, который позволяет пользователю управлять активностью подсистемы определения местоположения.

Так же очень важно отметить, что приложения не получают события positionChanged или statusChanged, когда они приостановлены, если только вы не зарегистрировали для этой цели фоновую задачу, запускаемую по таймеру и пользователь не добавил приложение на экран блокировки. Мы поговорим об этом подробнее в лекции 2 курса "Программная логика приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript и их взаимодействие с системой", и вы так же сможете увидеть, как это работает в Сценарии 3 примера об определении местоположения. Если, однако, вы не используете фоновые задачи или пользователь не поместил приложение на экран блокировки, и вам все еще нужно отслеживать местоположение пользователя, обрабатывайте соответствующим образом событие resuming и обновляйте там эти данные.

С другой стороны, некоторые сценарии, исопользующие определение местоположения, такие, как навигация, нуждаются в том, чтобы экран устройства был активен (предотвращая автоматическое выключение экрана), даже если пользователь ничего не делает. Для этой цели вы можете использовать класс Windows.System.Display.DisplayRequest (http://msdn.microsoft.com/library/windows/apps/windows.system.display.displayrequest.aspx), в частности, его методы requestActive и requestRelease, которые вы можете вызывать в начале и в конце сеанса навигации. Конечно, поддержание экрана во включенном состоянии приводит к потреблению большей энергии батарей, используйте эту возможность только когда это необходимо – когда приложение используется для целей навигации – и не прибегайте к выполнению подобного запроса при запуске приложения. В противном случае ваше приложение, возможно, прослывет в Магазине Windows как неумеренный потребитель энергии!

Врезка: Определение местоположения в HTML5

Опытные разработчики HTML/JavaScript могут удивиться, почему WinRT предоставляет API для определения местоположения в то время, как в HTML5 оно уже есть: window.navigator.geolocation и его метод getCurrentPosition , который возвращает объект с координатами. Причина подобного заключается в том, что другие языки, такие, как C#, VisualBasic и C++ не имеют других API для получения подобных данных, что предоставляет выбор разработчикам на HTML/JavaScript. Если посмотреть глубже, то API HTML5 пользуется теми же данными, что и API WinRT, требует объявления той же возможности Расположение (Location) в манифесте, и нуждается в таком же разрешении пользователя, то есть, в основном, эти два API идентичны. Я дал бы API WinRT небольшое преимущество за счет опции movementThreshold , которая помогает приложению экономить электроэнергию и делает возможной простую постановку географических границ. Выполнение тех же действий в HTML5 потребует более частых запросов и приведет к большему потреблению энергии. Во многих сценариях, однако, вы можете использовать либо то, либо другое, с одинаковыми результатами. Однако, как и другие API WinRT, Windows.Devices.Geolocation доступно лишь страницам локального контекста приложений для Магазина Windows. На страницах веб-контекста вы можете пользоваться API HTML5.

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >