Android studio определить местоположение

Геолокация

2-й курс/Закрытая зона

Метки: LocationManager , getProvider() , Criteria , LocationListener

В настоящее время работа с геолокационными сервисами наиболее популярна в среде программистов. Android имеет широкую поддержку всех видов разработки, связанных с геолокацией.

Основные примеры использования геолокации — определить собственное местонахождение, определить координаты какого-нибудь объекта, а также связать эти координаты с другими задачами — показать соседние кафе и рестораны, город, страну и т.д.

Прежде чем приступить к разработке приложений, связанных с геолокационными сервисами, разработчик должен запомнить несколько важных правил. Самая главное правило — местонахождение пользователя является конфиденциальной информацией. Вы всегда должны явно указать пользователю, что собираетесь использовать эти данные и запросить согласие на подобное использование. Очень многие известные компании пренебрегли этим правилом и были оштрафованы на крупные суммы, а также подмочили свою репутацию.

Сами геолокационные сервисы очень ресурсоёмки как по части потребления энергии, так и по части передачи объемов информации. Поэтому нужно осторожно подходить к использованию этих функций и всегда предусматривать возможность отключения ненужных сервисов.

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

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

Источник

Полный список

— получаем данные о местоположении

Android устройства могут предоставить нам данные по нашему текущему местоположению. Это, конечно, очень удобно и вовсю используется для, например, пользования картой, получения актуальной для вашей местности информации (прогноз погоды), всевозможных чекинов и пр.

Реализация этого всего вполне проста. Мы вешаем слушателя на провайдера и получаем данные. На данный момент есть два провайдера: GPS и Network.

GPS – тут все понятно, это данные с GPS-спутников.

Network – это координаты, которые можно получить через сотовую связь или WiFi. Для этого провайдера нужен инет.

Напишем простое приложение, которое будет запрашивать и отображать координаты.

Project name: P1381_Location
Build Target: Android 2.3.3
Application name: Location
Package name: ru.startandroid.develop.p1381location
Create Activity: MainActivity

В strings.xml добавим строки:

Несколько TextView, в которые мы будем выводить данные, и кнопка для открытия настроек местоположения.

В onCreate определяем TextView-компоненты и получаем LocationManager, через который и будем работать.

В onResume вешаем слушателя с помощью метода requestLocationUpdates. На вход передаем:

— тип провайдера: GPS_PROVIDER или NETWORK_PROVIDER
— минимальное время (в миллисекундах) между получением данных. Я укажу здесь 10 секунд, мне этого вполне хватит. Если хотите получать координаты без задержек – передавайте 0. Но учитывайте, что это только минимальное время. Реальное ожидание может быть дольше.
— минимальное расстояние (в метрах). Т.е. если ваше местоположение изменилось на указанное кол-во метров, то вам придут новые координаты.
— слушатель, объект locationListener, который рассмотрим ниже

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

В onPause отключаем слушателя методом removeUpdates.

locationListener – слушатель, реализует интерфейс LocationListener с методами:

onLocationChanged – новые данные о местоположении, объект Location. Здесь мы вызываем свой метод showLocation, который на экране отобразит данные о местоположении.

onProviderDisabled – указанный провайдер был отключен юзером. В этом методе вызываем свой метод checkEnabled, который на экране обновит текущие статусы провайдеров.

onProviderEnabled – указанный провайдер был включен юзером. Тут также вызываем checkEnabled. Далее методом getLastKnownLocation (он может вернуть null) запрашиваем последнее доступное местоположение от включенного провайдера и отображаем его. Оно может быть вполне актуальным, если вы до этого использовали какое-либо приложение с определением местоположения.

onStatusChanged – изменился статус указанного провайдера. В поле status могут быть значения OUT_OF_SERVICE (данные будут недоступны долгое время), TEMPORARILY_UNAVAILABLE (данные временно недоступны), AVAILABLE (все ок, данные доступны). В этом методе мы просто выводим новый статус на экран.

Провайдеры включаются и отключаются в настройках системы. Тем самым, просто определяется доступен ли провайдер для получения от него координат. Чуть позже увидим, как можно отправить юзера в эти настройки. Программное включение/выключение провайдеров через стандартные методы недоступно.

Читайте также:  Звуки нажатия кнопок для андроид

Далее идут свои методы.

showLocation на вход берет Location, определяет его провайдера методом getProvider и отображает координаты в соответствующем текстовом поле.

formatLocation на вход берет Location, читает из него данные и форматирует из них строку. Какие данные он берет: getLatitude – широта, getLongitude – долгота, getTime – время определения.

checkEnabled определяет включены или выключены провайдеры методом isProviderEnabled и отображает эту инфу на экране.

Метод onClickLocationSettings срабатывает по нажатию кнопки Location settings и открывает настройки, чтобы пользователь мог включить или выключить провайдер. Для этого используется Intent с action = ACTION_LOCATION_SOURCE_SETTINGS.

Осталось в манифесте прописать разрешение на определение координат — ACCESS_FINE_LOCATION, которое позволит нам использовать и Network и GPS. Также существует разрешение ACCESS_COARSE_LOCATION, но оно дает доступ только к Network-провайдеру.

С кодом все, давайте смотреть, что получилось. Все сохраняем и запускаем приложение.

У меня на планшете сейчас выключен GPS, выключен WiFi, вставлена симка и выключен мобильный интернет.

Запускаю приложение и вижу такую картину:

GPS выключен, Network включен. Но инета нет, поэтому Network мне ничего не дает. Надо включить либо мобильный инет, либо WiFi.

Я включаю WiFi. Проходит секунд 15-20 и инфа с Network пошла

Видим широту, долготу и время.

Напомню, что мы ставили минимальную скорость обновления – 10 сек. Но у меня провайдер Network выдает данные не чаще, чем раз в минуту.

Теперь давайте включим GPS. Для этого мы специально повесили кнопку Location settings, которую надо будет нажать пользователю, чтобы перейти в настройки. Жмем кнопку.

Видим, что GPS выключен, а Network включен. Наше приложение показывало все верно.

Разумеется, GPS можно включать и выключать через быстрые настройки системы (справа сверху). Но не все пользователи об этом знают. А тут мы их точно направим.

Включаем GPS и жмем Назад, чтобы вернуться в приложение.

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

В итоге сигнал пойман и получен результат.

У GPS через какое-то время включился статус 2 (AVAILABLE).

А у Network тишина со статусом. Не знаю, нормально это или нет.

Если с GPS сигналом все ок, то каждые 10 сек вы будете получать инфу о вашем местоположении. Если убрать планшет от окна, получим плохой сигнал: данные могут приходить реже и статус у меня иногда меняется на 1 (TEMPORARILY_UNAVAILABLE).

Прочее

Есть еще третий тип провайдера — PASSIVE_PROVIDER. Сам по себе этот провайдер никакие данные не вернет. Но повесив на него слушателя, вы сможете получать данные о местоположении, когда кто-то еще в системе пытается определить местоположение через обычные провайдеры. Система будет дублировать результаты и вам.

Метод getAllProviders вернет вам список всех доступных провайдеров. Метод getProviders(boolean enabledOnly) вернет либо все, либо только включенные.

Объект Location кроме координат, времени и провайдера имеет еще несколько атрибутов, которые могут прийти и пустыми:

getAccuracy – точность показания в метрах

getAltitude – высота над уровнем моря в метрах

getSpeed – скорость движения в м/с

getBearing – насколько я понял, это угол, на который текущая траектория движения отклоняется от траектории на север. Он же азимут.

Местоположение можно протестировать и через AVD эмулятор. Для этого надо в Eclipse открыть DDMS (Window > Open Perspective > DDMS) и выбрать вкладку Emulator Control. Внизу будет вкладка Manual, на которой есть поля для ввода координат и кнопка отправки.

На следующем уроке:

— создаем приложение с картой
— настраиваем карту и обрабатываем ее события
— программно меняем положение камеры

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Читайте также:  Мобильный офис рнкб для андроид

Источник

Простой способ добавить геолокацию в свой проект для Android

Долго я прочёсывал интернет в поисках простого решения, как мне в проект добавить 1 только класс и больше не беспокоиться о проблемах геолокации.
Критерии были такие:
1) решить всё в 1 классе, как можно меньше используя внешний код.
2) у пользователя должна быть всегда под рукой 1 static переменная в которой указанно его местоположение и больше ни о чём он знать не должен.

Большинство постов не отвечало на поставленный вопрос: конечно сначала нужно обратиться к сервису, потом нужно установить listner, потом вы можете посмотреть на трёхстраничный краткий пример как это делать.
В итоге я написал свой класс, с которым и хочу вас познакомить: он прост в использовании и с ним сможет справиться любой: просто добавьте его в проект и будет вам счастье.

Итак, что же здесь есть?

Класс разделен на 3 части:
1) imHere — переменная типа Location, в которой будет всегда доступна самая последняя информация о местоположении пользователя.
2) функция SetUpLocationListener — в любом случае нам нужна будет начальная установка для того, чтобы система начала сама без нашего участия выполнять обновление переменной imHere.
3) все остальные обязательные части LocationListener, которые можно переделать по собственному желанию.

Итак, как это работает?

1) создаем класс MyLocationListener
2) копируем в него код написанный выше
3) в основной функции (например MainActivity) ближе к началу запускаем:

или для любителей потоков

4) теперь у нас всегда и в любой части нашего проекта есть переменная MyLocationListener.imHere типа Location, в которой хранится самое последнее местоположение пользователя и множество дополнительной информации, как например скорость или точность определения местоположения.

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

(!) Не забудьте: в зависимости от выбранного провайдера нужно добавить в манифест соответствующее разрешение. Например используемый выше GPS_PROVIDER требует добавления следующей строчки в манифест:

Источник

Глубокое погружение в определение местоположения

Этот пост является переводом топика из блога android-developers. Далее повествование ведется от Рето Майера, автора книги Professional Android 2 Application Development. Он пишет о том, как можно улучшить приложения, использующие местоположение, в смысле кэширования результатов, скорости работы и так далее.

Без разницы, ищете ли вы место, где бы поесть, или ближайшее место велосипедов Boris Bike, всегда есть задержка при получении данных местоположения от GPS и заполнении абстрактного списка результатов в вакууме. Когда вы находитесь в месте, где хотели бы получить контекстную информацию, то часто вы сталкиваетесь с отсутствием подключения к данным.

Вместо того, чтобы грозить кулаком в небо, я написал open-source приложение, которое включает в себя советы и рекомендации по сокращению времени между открытием приложения и просмотром актуальной информации о близлежащих местах, вкупе с разумным обеспечением offline режима работы. И всё это, сохраняя использование аккумулятора на возможном минимуме.

Покажи мне код!

Вы можете проверить мой проект Android Protips for Location. Не забудьте прочесть Readme.txt, чтобы успешно скомпилировать и запустить приложение.

Что оно делает на самом деле?

Оно использует Google Places API для реализации базовой функциональности приложений, которые которые используют местоположение для определения списка близлежащих достопримечательностей (точек на карте), позволяют просмотреть их детали, а также проверить или оценить.

Код реализует многие из лучших практик, о которых я подробно рассказал на своей сессии на Google I/O 2011, Android Protips: Advanced Topics for Expert Android Developers (видео). В том числе использование Intent’ов для получения обновлений о местоположении, используя Passive Location Provider, наблюдение за состоянием устройства для изменения частоты обновлений, переключение Receiver’ов во время исполнения приложения, и также используя Cursor Loader.

Приложение написано для Honeycomb, но также может работать и на версия 1.6 и выше.

Теперь у вас есть код, давайте подробнее рассмотрим его

Мой главный приоритет — свежесть: минимизация задержек между открытием приложения и возможностью проверить нужные места, и в то же время минимизировать использование аккумулятора.

Читайте также:  Стоковый плеер для андроид

Требования:

  • Текущее местоположение должно находиться так быстро, как это возможно
  • Список мест должен обновляться при изменение местоположения
  • Список близлежащих мест должен быть доступен (в деталях) в автономном режиме
  • Отметки также должны быть доступны в автономном режиме
  • Данные о местоположении и другие данные пользователя должны быть правильно обработаны (см. более ранний пост с лучшими практиками )

Свежесть — значит никогда не ждать

Можно значительно сократить время ожидания получения первого приближения к местоположению, путём выбора последнего известного из Location Manager’a каждый раз, когда приложение переходит в активный режим.

В этом примере из GingerbreadLastLocationFinder, мы перебираем все провайдеры местоположения на устройстве, даже те, которые на данный момент недоступны, чтобы найти наиболее точное последнее местоположение.

Если есть координаты одного или более местоположений, то выбирается самое точное. Иначе, просто возвращается самый недавний результат.

Во втором случае (когда определено, что последнее обновление местоположения недостаточно недавнее), значение так или иначе возвращается, но мы запрашиваем одно обновление местоположения, используя самый быстрый провайдер.

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

Отметим также, что этот фрагмент кода показывает GingerbreadLastLocationFinder, который использует метод requestSingleUpdate для получения единоразового обновления местоположения. Эта функциональность не была доступна до Gingerbread — проверьте LegacyLastLocationFinder, посмотрите как я реализовал такую же функциональность для более ранних версий Android.

singleUpdateReceiver передает полученное обновление назад к вызывающему классу через слушателя Location Listener.

Используйте Intent’ы для получения обновлений местоположения

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

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

Следующий шаг — запросить обновление местоположения от Location Manager. В следующем фрагменте кода, взятом из GingerbreadLocationUpdateRequester мы можем передать критерии, используемые для определения — какой Location Manager будет запрашивать обновления напрямую в вызове метода requestLocationUpdates.

Обратите внимание, что мы передаём Pending Intent, а не Location Listener.

Вообще, я предпочитаю использовать Location Listener’ов, потому что они предоставляют гибкость в регистрации приёмников в нескольких Activity или Сервисах, или напрямую в манифесте.

В этом приложении, новое местоположение означает обновленный список близлежащих мест. Это происходит через сервисы, которые отправляют запросы к серверу и обновляют Контент-провайдер, который заполняет список мест.

Так как изменение местоположения напрямую не обновляет UI, то имеет смысл создавать и регистрировать связанный LocationChangedReceiver в манифесте, а не в Activity.

LocationChangedReceiver извлекает местоположение из каждого обновления и запускает сервис PlaceUpdateService, чтобы обновить базу близлежащих мест.

Получение данных во время автономной работы

Чтобы добавить поддержку режима offline, мы начнём с кэширования результатов поиска по PlacesContentProvider и PlaceDetailsContentProvider.

Также, при определенный обстоятельствах нужно проводить выборку сведений о местоположении. Этот фрагмент кода из сервиса PlacesUpdateService демонстрирует, как предварительная выборка включается для ограниченного количества мест.

Обратите внимание на то, что предварительная выборка данных потенциально выключается при низком заряде аккумулятора.

Похожая техника используется для реализации offline отметок.

Оптимизация времени работы аккумулятора: умные сервисы и использование состояния устройства для переключения ресиверов

Нет смысла запускать сервис обновления, когда устройство находится в автономном режиме. Сервис PlaceUpdateService проверяет возможность соединения, прежде чем пытаться получить обновление.

Если соединения нет, то ActiveLocationChangedReceiver и PassiveLocationChangedReceiver выключаются, а ConnectivityChangedReceiver включается.

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

Мониторинг состояния аккумулятора для уменьшения функциональности и экономии энергии

Когда телефон на последних 15%, то большинство приложений не работает, для того чтобы сохранить заряд. Мы можем зарегистрировать ресиверов в манифесте, чтобы выдавать предупреждение, когда устройство входит или выходит из состояния низкой батареи.

Этот фрагмент из PowerStateChangedReceiver выключает PassiveLocationChangedReceiver всякий раз, когда устройство переходит в состояние низкого аккумулятора и включает его, когда заряд в порядке.

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

Источник

Оцените статью