Полный список
— получаем данные о местоположении
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 на Java
Мобильные устройства часто используются для решения различных задач связанных с определением географических координат. Транспорт, строительство, путешественники, так или иначе, нуждаются в определении своего местоположения или других объектов.
На сегодняшний день самым простым решением для этого является использование портативных приёмников спутниковых навигационных систем, в частности встраиваемых в устройства на базе Android. При этом наиболее распространёнными являются устройства с поддержкой системы GPS.
В Android SDK весь функционал по работе с навигационными системами объединён в пакет android.location. Ключевые компоненты данного пакета:
- LocationManager – (класс) обеспечивает доступ к системной службе определения местоположения Android;
- LocationListener — (интерфейс) регламентирует обработку приложение событий службы определения местоположения Android;
- Location – (класс) представляет географические координаты полученные от навигационной системы.
Подготовка к работе
При написании Android приложения работающего с навигационными системами на Java с помощью Android SDK вначале необходимо выполнить ряд подготовительных операций.
Это связано с тем, что в отличие от Delphi, здесь отсутствуют какие-либо разрешения, предоставляемые по умолчанию и нет готовых компонентов, которые полностью брали бы на себя всю работу по взаимодействию с GPS приёмником.
Все необходимые действия потребуется выполнить самостоятельно.
Первым делом предоставляем приложению необходимые разрешения в файле манифеста.
Далее создаём в коде приложения объект LocationListener для обработки событий службы определения местоположения Android.
Назначение его методов – обработка соответствующих событий. Конкретно:
- onLocationChanged – изменение местоположения. Именно он используется для определения текущих географических координат;
- onStatusChanged – изменение состояния поставщика данных о местоположении. В частности приёмника GPS;
- onProviderEnabled – получение доступа к поставщику данных о местоположении;
- onProviderDisabled – потеря доступа к поставщику данных о местоположении.
В завершение зарегистрируем созданный нами объект LocationListener для работы с приёмником GPS.
Для этого создаём экземпляр класса LocationManager.
И выполняем регистрацию при помощи метода requestLocationUpdates.
Перед вызовом метода requestLocationUpdates обязательно необходимо проверить наличие соответствующих разрешений (оператор if). Если они отсутствуют перед оператором return можно выполнить некоторые действия. Например, записать сообщение об ошибке в журнал. Однако в любом случае при отсутствии необходимых разрешений работа с навигационной системой должна быть завершена до регистрации объекта LocationListener.
Метод requestLocationUpdates имеет несколько перегрузок. Наиболее часто используемая из них принимает четыре параметра. Именно она использована в примере выше.
- Поставщик данных о местоположении.
В данном примере используется GPS; - Минимальный интервал обновления данных о местоположения в миллисекундах.
Значение «0» соответствует использованию минимально возможного интервала времени для данного устройства; - Минимальное расстояние для обновления данных о местоположении в метрах.
Значение «0» соответствует использованию минимально возможного расстояния для данного устройства; - Регистрируемый объект LocationListener.
После регистрации приложение сможет получать информацию о местоположении устройства по мере его изменения.
Если необходимо получить её единовременно, необходимо вместо метода requestLocationUpdates использовать метод requestSingleUpdate, который также имеет несколько перегрузок.
Наиболее востребованная из них принимает три параметра:
- Поставщик данных о местоположении.
В данном примере используется GPS; - Регистрируемый объект LocationListener;
- Объект, реализующий обратный вызов.
Необязательный параметр.
Пример использования метода requestSingleUpdate:
Источник
Находки программиста
Решения конкретных задач программирования. Java, Android, JavaScript, Flex и прочее. Настройка софта под Linux, методики разработки и просто размышления.
воскресенье, 13 мая 2012 г.
Работа с GPS и Google Maps в Android
Продолжаем осваивать аппаратные возможности Android-смартфонов. В предыдущих постах мы изучили, как использовать в наших приложениях микрофон и камеру. Теперь возьмёмся за более сложную тему: GPS. Сложность, конечно же, относительная. В сети есть масса примеров кода, с помощью которого можно получить координаты клиента, поэтому чтобы сделать наш пример интереснее, соединим получение координат с их использованием. В этой статье вы узнаете как получить доступ к Google Maps API, отобразить карту с различными её «плюшками» и вывести на неё наши координаты, полученные различными способами: по спутникам, данным мобильной сети или wifi.
Итак, приступим:
Получаем ключ к Google Maps API
Чтобы иметь возможность использовать Google Maps в своём Android-приложении, нужно получить ключ. Ключ приложения генерируется на этой странице на основании сертификата, которым будет в дальнейшем подписано ваше приложение. Обычно готовое приложение подписывается отдельным сертификатом, а в процессе разработки используется другой из хранилища debug.keystore, которое находится в каталоге .android вашей домашней директории. В этом случае вам потребуется сгенерировать два ключа и не забыть заменить отладочный ключ на «боевой», перед финальной сборкой приложения. Для генерации ключа вам потребуется получить «сertificate fingerprint» командой
keytool -list -keystore
/.android/debug.keystore
Пароль от debug.keystore обычно — пустая строка.
Доступы и библиотеки
Google Maps API в состав Android SDK входит как отдельная библиотека, поэтому её нужно отдельно подключить в AndroidManifest.xml вашего приложения командой
Эта строка должна находиться внутри тега «application».
Также не забудем попросить разрешения на получение координат и доступ в интернет:
android.permission.ACCESS_FINE_LOCATION
android.permission.INTERNET
android.permission.ACCESS_WIFI_STATE
Последнее из разрешений, нужно нам для отслеживания состояния wifi-подключения. Это позволит нам выбрать подходящий способ получения приблизительных координат, пока наше устройство будет искать спутники и получать от них точные координаты.
Рисуем гуглокарту
Карту нам нарисует MapView, в конструктор которого мы передаём ключ, полученный на первом шаге. Сразу после создания желательно установить zoom level карты (1 — весь мир на экране, больше — детальнее) , а также методом setCenter(new GeoPoint(latitude, longitude)) спозиционировать карту куда-нибудь. Обе операции выполняем при помощи MapController-а, который получаем из экземпляра MapView методом getController(). Чтобы показать кнопки изменения масштаба вызовем метод setBuiltInZoomControls(true). И, главное, не забудьте сделать карту кликабельной методом setClickable(true).
Далее «вставляем» MapView в RelativeLayout вместе с остальными компонентами. В нашем случае это будет панель с двумя элементами управления: переключателем режима спутниковых фотографий и пиктограммой для возврата карты к текущему местоположению.
В целом картинка должна быть примерно такой, как на иллюстрации слева.
Все картинки возьмём из android.R.drawable, чтобы не морочить себе голову подготовкой своей графики.
Получаем текущие координаты
Вот мы и подошли к самому интересному. Весь код нашего приложения помещается в одном файле главного Activity:
Координаты текущего местоположения тут мы получаем дважды: перед отрисовкой карты (последние известные с прошлого поиска) и после обновления.
Первое получение координат мы делаем в методе getLastCopords(). Эта операция выполняется достаточно быстро, чтобы не тормозить нам построение интерфейса. Она может завершиться неудачно, и в этом случае мы устанавливаем карту в точку new GeoPoint(0, 0). В случае успеха устанавливаем карту в нужное место и устанавливаем маркер текущего местоположения методом map.getOverlays().add(new MarkerOverlay(p)).
Важно учесть, что в нашем устройстве есть три источника получения координат.
Первый: GPS — даёт самые точные координаты, но работает медленнее всех и может ничего не найти. Второй: сеть wifi — отвечает быстро, относительно точно и всегда, когда wifi вообще есть в наличии. Третий: (с версии Android 2.2): PASSIVE_PROVIDER — сигнал соты оператора. Даёт координаты с точностью до нескольких кварталов, медленно, но практически всегда. Для получения данных с прошлого поиска скорость не имеет значения, поэтому опрашиваем провайдеров по очереди, начиная с самого точного.
Чтобы обновить координаты, подписываемся на результат обновления лучшего в данный момент провайдера в методе requestNewCoordinates(). При этом проверяем, разрешено ли использование спутников (может быть выключено пользователем ради экономии заряда батареи), есть ли сеть wifi и т.п.
При запуске обновления передаём выбранному провайдеру экземпляр LocationListener-а, в методе onLocationChanged которого мы получим новые координаты, передвинем на них карту и поставим маркер.
При выходе из приложения (в onPause()) нужно не забыть остановить обновление координат у выбранного ранее провайдера методом removeUpdates(listener), чтобы не разряжать пользователю батарею напрасно.
Несколько слов о отладке «координатного» приложения. Есть одна проблема, которая может попить кровушки у вас при отладке приложения на реальном устройстве. Различные провайдеры могут не давать события locationChanged очень долго или совсем. Например, PASSIVE_PROVIDER у меня вернул координаты только при отключении и повторном включении передачи данных. Спутники вообще могут быть недоступны в помещении. Поэтому мой совет: выполняйте отладку на эмуляторе, а событие locationChanged тут можно вызвать очень просто:
path/to/android-sdk/platform-tools/adb emu geo fix -121.45356 46.51119
Эта команда в консоли переместит вас в уютное заснеженое ущелье где-то в северной америке 🙂
Источник