Приводится решение по реализации класса, предоставляющего возможность получить данные о местоположении пользователя, используя GPSили Networkпровайдера.
Ключевые слова:Android, геолокация, программирование.
Устройства на Android позволяют получить данные о текущем местоположении. Добавить геолокацию в проект возможно при применение Google Maps Android API и классов пакета android.location.
Первый вариант использует сервера Google Maps и даёт возможность добавить карты в приложение с помощью MapView, отображающего карту с данными, полученными от службы Google Maps.
Второй вариант использует системную службу LocationManager. И именно этот вариант будет описан далее.
Классы пакета android.location
Android даёт доступ к службе для определения местоположения, поддерживаемую устройством через классы пакета android.location.
Всего в пакет входит 9 классов:
1) Address представляет собой набор строк, описывающих местоположение, является упрощённой версией xAL (eXtensible Address Language). С использованием этого класса возможно получить такие данные, как номер телефона, почтовый индекс, город, страну, код страны, улицу, номер дома и т.д.
2) Criteria позволяет задать границы для работы с провайдером. Например, должен ли он возвращать информацию о широте и долготе, точность этих данных и прочее.
3) Класс Geocoder для прямого геокодирования и обратного. Трансформирует адрес или другую информацию о местоположении в широту и долготу и наоборот.
4) GpsSatellite предоставляет информацию о текущём состоянии спутника (высоту, азимут, отношение сигнал / помеха).
5) GpsStatus возвращает максимальное количество спутников, их список и время для получения последнего исправления с момента перезапуска GPS.
6) Location даёт доступ к данным о географическом местоположении (широта, долгота, время определения координат, точность, скорость, пеленг и т.д.).
7) LocationManager предоставляет права на пользование одноимённой системной службой. Та, в свою очередь, – права на использование трёх провайдеров: GPS_PROVIDER, NETWORK_PROVIDER и PASSIVE_PROVIDER. GPS_PROVIDER – это данные с GPS спутников. NETWORK_PROVIDER – координаты, которые можно получить через сотовую связь или WiFi. PASSIVE_PROVIDER возвращает данные, когда кто-то в системе пытается определить местоположение через GPS или NETWORK провайдеров.
8) LocationProvider – абстрактынй класс для провайдеров. Каждый провайдер имеет набор требований, при которых он может быть использован, например, количество спутников, GPS оборудование, доступ к сети конкретного оператора и прочее. При использовании методов этого класса возможно получить все эти требования.
9) SettingInjectorService динамически формирует резюме и активирует статус предпочтений введённых в списке настроек приложений. Настройки геолокации, которые применяются в приложении, должны быть показаны в рамках только этого приложения.
Добавляем геолокацию в проект
Чтобы получать информацию о местонахождении, в файле AndroidManifest.xml необходимо прописать соответствующее разрешение. В нашем случае, это ACCESS_FINE_LOCATION, т.к. это разрешение позволяет использовать оба провайдера. Когда ACCESS_COARSE_LOCATION даёт разрешение только
NETWORK провайдеру.
Создаём класс и добавляем ему слушателя LocationListener. Описываем в этом классе одноимённый метод принимающий два параметра: тип провайдера и контекст (Листинг 1).
public class ActivateLocation implements LocationListener {
private Location location;
private LocationManager locationManager;
public static final int GPS = 0; /** LocationManager.GPS_PROVIDER **/
public static final int NETWORK = 1; /** LocationManager.NETWORK_PROVIDER **/
public static final int PASSIVE = 2; /** LocationManager.PASSIVE_PROVIDER **/
/**
* Register location listener.
* @param context
* @param PROVIDER GPS, NETWORK or PASSIVE.
*/
public ActivateLocation(int PROVIDER, Context context) {
locationManager = context.getSystemService(Context.LOCATION_SERVICE);
switch (PROVIDER) {
case GPS: {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
break;
}
case NETWORK: {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
0, 0, this);
location = locationManager.getLastKnownLocation(
LocationManager.NETWORK_PROVIDER);
break;
}
case PASSIVE: {
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
0, 0, this);
location = locationManager.getLastKnownLocation(LocationManager.
PASSIVE_PROVIDER);
break;
}
}
…
}
Листинг 1. Присвоение слушателя
Наиболее точные данные приходят от GPS провайдера, но они приходят с задержкой, и заряд аккумулятора расходуется быстрее. NETWORK провайдер возвращает менее точные данные чем GPS, но данные приходят быстрее и заряд аккумулятора расходуется медленнее.
Добавляем возможность удалить слушателя и получать данные вызовом метода getLocation() (Листинг 2).
/**
* Unregister location listener.
*/
public void unregisterLocationListener(){ locationManager.removeUpdates(this); };
/**
* Return location.
*/
public Location getLocation(){ return location; };
@Override
public void onLocationChanged(Location loc) {
location = loc;
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) { }
@Override
public void onProviderEnabled(String s) { }
@Override
public void onProviderDisabled(String s) { }
Листинг 2. Продолжение класса ActivateLocation
Интерфейс LocationListener позволяет описать следующие методы: onLocationChanged, onProviderDisabled, onProviderEnabled и onStatusChanged.
onStatusChanged возвращает статус провайдера.
onProviderEnabled и onProviderDisabled вызываются когда провайдер был включен или выключен пользователем.
onLocationChanged возвращает данные о местоположении.
Используем только последний метод. К глобальной переменной location приравниваем последнюю информацию о местоположении. И значение этой переменной возвращаем в методе getLocation(). Таким образом самые последнии данные будут доступны пользователю.
Создание экземпляра класса ActivateLocation
Использование класса ActivateLocation, позволяет добавить геолокацию в проект. Метод getLocation() вернёт последнее местоположение пользователя и множество дополнительной информации (точность, скорость, время, пеленг и т.д.) (Листинг 3).
ActivateLocation aloc = new ActivateLocation(ActivateLocation.GPS, this);
Location location = aloc.getLocation();
Листинг 3. Получение данных о местоположении через класс ActivateLocation.
Создавать экземпляр класса ActivateLocation, т.е. регистрировать слушателя, лучше в onResume() и в onPause() удалять слушателя вызовом метода aLoc.unregisterLocationListener(). Тогда, Activity находясь в состоянии, когда его не видно пользователю, не будет взаимодействовать со службой LocationManager (получать данные от провайдера) и, соответственно, не будет тратить ресурсы (заряд аккумулятора).
Заключение
Представленный класс будет полезен в таких областях, как социальные сервисы, основанные на геолокации, дополненная реальность или даже простые приложения в которых учитывается пространственное расположение пользователя.
Литература:
1. Android Developers. Location and Maps. [Электронный ресурс]. URL: http://developer.android.com/guide/topics/location/index.html#maps (21.05.2014).
2. Android Developers. Google Play services. [Электронный ресурс]. URL: http://developer.android.com/google/play-services/maps.html (21.05.2014).
3. Android Developers. Location Strategies. [Электронный ресурс]. URL: http://developer.android.com/guide/topics/location/strategies.html (21.05.2014).
4. Android Developers. Location. [Электронный ресурс]. URL: http://developer.android.com/reference/android/location/package-summary.html (21.05.2014).