Определение доступности GPS в Android
Эта статья, надеюсь, станет хорошим подспорьем начинающим в области программирования под Android. А может даже и матерые профи что-нибудь почерпнут.
Итак, понадобилось мне как-то определять, доступен ли в настоящее время GPS-фикс. Казалось бы, LBS (location-based service) — вещь перспективная и популярная, и Google, прекрасно это понимая, предоставит простой в обращении инструмент для их разработки. Ага, разбежался… Не так-то все и просто, поэтому приходится в определенной мере изощряться.
Ну и в чем тут у нас собственно проблема? Проблема в определении текущего местоположения пользователя. Видов существует несколько, но ТЗ велит использовать GPS и позиционирование по сотовым вышкам. Задача — определить текущие координаты с максимальной точностью, т.е. в идеале по GPS. Если он недоступен, то по вышкам. Если есть сигнал GPS, то все легко и просто — берем со спутника координаты и делаем с ними что угодно. Если сигнала нет, то при обработке координат вы рискуете нарваться на null, в чем очень мало хорошего, а при недолжной обработке исключений может быть еще и что-нибудь с печальными последствиями. Значит, надо как-то определить, а есть ли у нас фикс?
Ну что ж, проблема видна — будем решать!
Начнем с ковыряния LocationManager. Есть в нем занятное свойство isProviderEnabled(), возвращающее булево значение. Ура? Рано… Это значение всего лишь характеризует, включен GPS-приемник вашего телефона или нет (собственно, можно было и по названию догадаться). Первый блин получился как всегда, идем дальше.
Залезем во внутренности LocationListener. Что мы видим? Ба, да это обработчик onStatusChanged()! В идеале реагирует на изменение статуса провайдера, выставляя соответствующие значения. В идеале… Не реагирует он ни на что начиная с андроида версии 2.1! С грустью проходим мимо.
Продолжим? Конечно продолжим! Очевидным выглядит следующий финт ушами — сравнение времени последнего пришедшего фикса с текущим системным временем. Казалось бы, логично — раз фикс старый, то GPS недоступен. Не совсем так: фиксы приходят только при движении, соответственно можно перепутать недоступность спутников с простым сидением на месте. Согласитесь, будет не совсем приятно, если вы сидите себе сидите, и тут вдруг — оппа! — и ваш телефон решил, что вы телепортнулись метров на 400-500. Снова не то, но приемчик запомним — пригодится.
Теперь посмотрим в сторону GpsStatus.Listener, реализующий метод onGpsStatusChanged(int event). Переменная event может принимать несколько значений, нас же интересует GPS_EVENT_SATELLITE_STATUS. Возникновение такого события говорит о том, что ваш приемник анализирует GPS-спутники. Вот это-то нам и надо! Дальше все просто и понятно — берем текущий статус GPS и вытаскиваем из него доступные спутники. В самом простом случае нас просто интересует их количество.
Небольшое отступление для начинающих в области навигации. Для определения текущей координаты нам в общем-то необходимо три спутника (для трехмерной координаты). Но это если у вас есть атомные часы, что очень-очень редко в случае мобильных девайсов. Поэтому для синхронизации времени нам потребуется еще один спутник.
Выглядеть обработчик статуса будет примерно так:
В переменной status лежит информация о всех доступных спутниках
Итак, дальше все ну совсем замечательно — смотрим количество спутников, если их меньше четырех, то фикса никакого нет и быть не может, значит используем другие методы позиционирования (уж извините, но конкретную реализацию описывать не буду). Этот метод можно скрестить с сопоставлением времен, описанным на пару абзацев выше. Так можно выставить определенный период «доверия» фиксу
Подобьем баланс. Все выше приведенное не дает вам точных гарантий определения доступности фикса. На самом деле просто отсекаются ситуации, в которых фикса уж точно нет. Это, конечно, не совсем то, что хотелось, но уже что-то!
UPD: Похоже, решение найдено! Свершилось это благодаря r_ii.
Итак, ваш GPS-приемник, будучи во включенном состоянии, постоянно принимает сигналы в соответствии с протоколом NMEA. Вот его-то нам и надо!
Для просмотра этих сигналов добавляем в код следующее:
За этот код спасибо вот этому топику 2m0nd. Полное описание протокола здесь (pdf, англ).
Собственно, дело за малым — парсить полученную строку. В данном случае нас интересует строки с ключевым (первым) полем $GPGGA, а в них параметр №6, по умному называемый GPS Quality Indicator. Он принимает следующие значения:
- 0-фикс не доступен
- 1-GPS-фикс
- 2-дифференциальный фикс
Бинго!
Источник
Полный список
— получаем данные о местоположении
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 для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Лучшие приложения для поиска gps координат на Android и iOS
Илья – главный редактор сайта softdroid.net. Является автором нескольких сотен руководств и статей по настройке Android. Около 15 лет занимается ремонтом техники и решением технических проблем iOS и Android. Имел дело практически со всеми более-менее популярными марками мобильных смартфонов и планшетов Samsung, HTC, Xiaomi и др. Для тестирования используется iPhone 12 и Samsung Galaxy S21 с последней версией прошивки.
Утилиты-навигаторы, содержащие в себе карты различных городов, являются одними из самых популярных и востребованных в магазинах приложений.
По большей части, все приложения с картами работают по одному принципу и имеют одну цель: помочь пользователю в ориентировании по незнакомой местности и прокладывании оптимальных маршрутов. Большая часть из них имеет дополнительный – иногда и платный – функционал, который может заметно облегчить и упростить взаимодействие пользователя с приложением.
Сегодня мы рассмотрим пять приложений для поиска GPS-координат, расскажем об их работе, преимуществах и платных функциях.
GPS Coordinates
Первое из рассматриваемых нами приложений – GPS Coordinates. Один из самых простых и незатейливых навигаторов с интересными возможностями.
Разработчики позволяют юзерам, скачавшим данную утилиту, загружать, делиться и сохранять координаты для того, чтобы использовать их в дальнейшем. Также предусмотрена стандартная функция нахождения координат пользователя по введённому адресу и изменения вида карты. Возможно отображение обычной карты-схемы и вид со спутника.
Базовые функции функции приложения:
- конвертация любого адреса в gps-координаты и наоборот (широта и долгота);
- быстрая отправка координат в социальные сети или на email;
- локальное сохранение и загрузка gps-координат на мобильное устройство.
В целом, GPS Coordinates представляет собой обычное приложения без наворотов. Оно будет полезно тем, кому нужны самые простые карты, чтобы не потеряться в незнакомом городе.
GPS/Glonass координаты
Утилита с картами, функционирующая на основе известной навигационной системы «Глонасс». Имеет ряд полезных функций, о которых мы расскажем далее.
Во-первых, что крайне положительно отличает его на фоне остальных GPS-навигаторов – возможность сделать фотографию, привязав её к координатам на карте. Таким образом интуитивно и удобно отмечать важные координаты на карте. Можно сравнить эту функцию с приложением Инстаграм, где фото также привязывается к определенной локации.
Ещё один безусловный плюс – возможность загрузки офлайн-карт и вычисление координат без подключения к интернету. Наравне с предыдущей функцией, “GPS/Glonass координаты” становится одним из наиболее предпочитаемых приложений в походах или длительных путешествиях вдали от цивилизации.
Однако не всё так радужно. Пользователи Play Market отмечают навязчивую интернет-рекламу при работе с приложением. Данная реклама очень долго грузится при слабой сети и не даёт узнать своё местоположение до её просмотра. От рекламы можно избавиться путём покупки полной версии приложения.
My Location — GPS Coordinates
Ещё один простой и незатейливый навигатор. В отличии от GPS Coordinates, имеет более широкий функционал:
- Определение координат указанной точки на карте в виде Latitude/Longitude
- Копирование, публикация, печать и сохранение координат в социальных сетях
- Преобразование координат в адрес и наоборот
На главном экране приложения имеются три раздела: «Мои координаты», «Сохранённые локации» и «Настройки». Первая кнопка отвечает за то, чтобы найти и показать на экране ваше текущее местоположение через спутник. Координаты, которыми вы будете пользоваться в дальнейшем, можно сохранить и перейти к их списку с помощью второй кнопки. Настройки позволят указать конкретную страну, город, адрес или почтовый индекс.
Приложение My Location бесплатно, на экране отображается реклама.
GPS & Maps: Track Coordinates, Compass + Waypoints
Главное отличие данного навигатора от предыдущих – наличие компаса. Это не является чем-то необычным, особенно учитывая тот факт, что на iPhone, например, компас является встроенным приложением. Однако использовать компас в приложении-навигаторе несомненно удобнее. В остальном, функционал приложения GPS & Maps стандартен.
Интерфейс вполне удобный. Переключаясь между пунктами меню внизу экрана, пользователь может:
- узнать собственное месторасположение,
- свериться с компасом,
- открыть карту местности
- докупить дополнительный функционал во внутреннем магазине.
За дополнительную плату можно отмечать своё местоположение маркерами, а компас будет отображаться поверх карты в виде виджета. Также докупаются и другие виджеты: показатели скорости, координат и другое.
Данное приложение, на наш взгляд, хоть и является довольно удобным, всё-таки проигрывает другим навигаторам, в том числе, упомянутым ранее, поскольку там большая часть функций работала точно так же, но не требовала доплаты.
Кроме того, пользователи жалуются на то, что фотографии со спутника в некоторых областях давно устарели. Поэтому рекомендовать конкретно это приложение мы поостережёмся.
Скачать GPS & Maps на iOS
Coordinates — GPS Formatter
Приложение “GPS Formatter” бесплатно и обладает основным функционалом простейшего навигатора, как и предыдущие. От рекламы можно избавиться приобретя подписку ($3 в месяц).
Отличительной фишкой навигатора является возможность выбора из огромного количества форматов координат – например Georef или военная координатная сетка системы МГРС.
Также приложение может конвертировать входящие данные в координаты и отмечать их на карте или выводить уже имеющиеся данные через Airdrop в формате .txt для дальнейшей работы с ними на персональном компьютере.
Ещё один бонус для владельцев техники Apple — поддержка умных часов Apple Watch с выводом текущих координат пользователя на дисплей.
Встроенный в приложение калькулятор помогает вычислять значения геомагнитного поля: декларацию, напряжённость и другие.
Единственным минусом можно назвать громоздкий пользовательский интерфейс.
Мы считаем, что данное приложение является одним из лучших в категории GPS-навигаторов за счёт своего действительно широкого и интересного набора функций, бесплатности и невысокой цены за избавление от рекламы.
Источник