- Находки программиста
- воскресенье, 13 мая 2012 г.
- Работа с GPS и Google Maps в Android
- Как получить координаты экрана с маркера в google maps v2 android
- ОТВЕТЫ
- Ответ 1
- Изменить
- Работа с интерфейсом в Google Maps SDK для Android
- Выбор текущего местоположения и просмотр подробных сведений на карте
- Как получить код
- Как настроить проект
- Как получить ключ API и активировать нужные API
- Как добавить ключ API в свое приложение
- Как создать сборку и запустить приложение
- Понимание кода
- Создание клиента Places API
- Kotlin
- Запрос доступа к данным о местоположении
- Kotlin
- Kotlin
- Добавление карты
- Kotlin
- Kotlin
- Kotlin
- Kotlin
- Как получить информацию о местоположении устройства Android и позиции карты
- Kotlin
- Как получить данные о текущем местоположении
- Kotlin
- Kotlin
- Kotlin
- Kotlin
- Сохранение состояния карты
- Kotlin
- Kotlin
- Kotlin
Находки программиста
Решения конкретных задач программирования. 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
Эта команда в консоли переместит вас в уютное заснеженое ущелье где-то в северной америке 🙂
Источник
Как получить координаты экрана с маркера в google maps v2 android
У меня небольшая проблема с Android (google maps v2 api)
Я пытаюсь найти способ получить текущие координаты экрана (x, y) для этого объекта маркера.
Возможно, у кого-то есть идея? Я попробовал getProjection, но он не работает. Благодарю!:)
ОТВЕТЫ
Ответ 1
Да, используйте класс Projection . Более конкретно:
Получите Projection карты:
Получить местоположение вашего маркера:
Перейдите к методу Projection.toScreenLocation() :
Это все. Теперь screenPosition будет содержать положение маркера относительно верхнего левого угла всего контейнера карты:)
Изменить
Помните, что объект Projection будет возвращать только допустимые значения после того, как карта прошла процесс компоновки (т.е. имеет действительный набор width и height ). Вероятно, вы получаете (0, 0) , потому что вы слишком быстро пытаетесь получить доступ к позиции маркеров, как в этом случае:
- Создайте карту из XML файла макета, раздувая его
- Инициализировать карту.
- Добавить маркеры на карту.
- Запрос Projection карты для позиций маркеров на экране.
Это не очень хорошая идея, так как карта не имеет действительной ширины и высоты. Вы должны подождать, пока эти значения не будут действительны. Одним из решений является привязка OnGlobalLayoutListener к виду карты и ожидание процесса компоновки. Сделайте это после раздувания макета и инициализации карты — например, в onCreate() :
Прочитайте комментарии для дополнительной информации.
Источник
Работа с интерфейсом в Google Maps SDK для Android
Данная статья будет полезна тем, кто ранее не использовал в своей работе Google Maps SDK.
Под катом описаны основные приемы работы с картой, такие как добавление и управление маркерами, способы перемещения камеры над картой, управление зумом, построение маршрута и геокодинг. А так же ограничения и способы их обхода.
Источник
На написание статьи меня сподвиг собственный опыт, который я извлек при написании приложения для курьеров использующего в своей работе гугл карты. Так что все скриншоты и возможное упоминание бизнес логики будут происходить в контексте построения интерфейса курьера.
К сожалению Google Maps SDK for Android не позволяет изменять положение кнопок управления, т.н. UI controls, к ним относятся: IndoorLevelPicker — показ поэтажного плана строений, Compass — компас, My Location button — перейти на карте к текущему местоположению, Map toolbar — кнопи построения маршрута и открытия карты, а так же ZoomControls — увеличения и уменьшения маштаба карты.
На примере Map toolbar и ZoomControls посмотрим какие сложности могут возникнуть из-за невозможности сменить положение контролов и как это обойти.
Проблемы с отображением UI controls из SDK (выделено оранжевым) и их кастомные аналоги (выделено зеленым)
В данном случае у нас в правом нижнем углу расположена кнопка (floating action button) перехода к списку адресов заказов на доставку, на картинке слева видно, что ZoomControls оказались под ней и практически недоступны для нажатия. На картинке справа, при нажатии на маркер, появляются кнопки из Map toolbar, они так же оказались под кнопкой перехода к списку заказов.
Первое что нам необходимо сделать — это скрыть отображение оригинальных кнопок. Сделать это можно переопределив метод onMapReady, он вызывается в тот момент, когда карта готова к использованию.
Добавляем в верстку фрагмента нужные кнопки, там где они должны быть в соответствии с нашим дизайном:
Расположение кастомных кнопок управления картой
Затем в методе onCreateView указываем действия, которые должны произойти при нажатии на наши кнопки:
Особенность метода animateCamera в том, что маштаб изменяется плавно, а не мгновенно и если нужно, например, отключить анимацию конкретной кнопки зума, по достижению максимального или минимального маштаба, то для этого нужно переопределить метод onCameraIdle, который вызывается в момент прекращения изменения маштаба карты.
Что бы выполнить какое либо действие с маркером(кроме перетаскивания), например, создать новый заказ, удалить случайно поставленный маркер, перейти в уже существующий заказ или позвонить по телефону казанному в заказе добавляем в верстку соответствующие кнопки управления и прописываем их обработчики.
Кнопки управления маркером
Еще одна особенность, это то что в SDK нет кнопки для удаления поставленного на карту маркера. Для этого тоже делаем свою кнопку:
При нажатии на маркер открывается его заголовок, нажатие на который так же можно использовать для совершения какого либо действия, я при нажатии на заголовок нового маркера создаю новый заказ на доставку курьеру, а на маркер уже существующего заказа — открываю подробную информацию о доставке, включающюю перечень товаров.
Процесс вывода нескольких маркеров (считай списка заказов) на карту ничем принципиально не отличается от вывода одного маркера. Маркер состоит из координат (position), заголовка (title), мелкого текста под заголовком (snippet) и тэга (setTag) — его можно использовать для идентификации множества маркеров на карте.
Несколько маркеров на карте
Пара слов о геокодере
Геокодер используется для получения адреса, на основании координат. Поставив маркер на карте и нажав кнопку добавить заказ, мы получаем географические координаты нужной точки, т.е. широту и долготу. Но для удобства пользователя неплохо будет показать адрес в человекочитаемом виде, т.е., например, страна, город, улица, дом.
Google Maps SDK содержит класс Geocoder, вызвав его метод getFromLocation можно получить массив адресов по указанным координатам.
Для того, что бы не блокировать UI thread долгими, особенно если медленный или недоступный интернет, вызовами — будем использовать RxJava:
Полученный адрес точки на карте на основании географических координат
Источник
Выбор текущего местоположения и просмотр подробных сведений на карте
В этом руководстве рассказывается, как определить текущее местоположение устройства Android и показать сведения об организации или другом объекте, который там находится. Следуйте руководству по созданию приложения для Android с помощью Maps SDK for Android, Places SDK for Android и поставщика геоданных из нескольких источников в Location API сервисов Google Play.
Как получить код
Версия на языке Java:
Версия на языке Kotlin:
Как настроить проект
Чтобы создать проект в Android Studio, выполните следующие действия:
Импортируйте обучающий проект:
- В Android Studio выберите Файл > Создать > Импортировать проект.
- Перейдите в каталог, где вы сохранили репозиторий с примерами Google Maps Android API версии 2 после его скачивания.
- Найдите проект CurrentPlaceDetailsOnMap. Он расположен в следующем каталоге:
PATH-TO-SAVED-REPO/android-samples/tutorials/java/CurrentPlaceDetailsOnMap (Java)
PATH-TO-SAVED-REPO/android-samples/tutorials/kotlin/CurrentPlaceDetailsOnMap (Kotlin) - Выберите каталог проекта и нажмите ОК. Теперь Android Studio создаст ваш проект с использованием инструмента сборки Gradle.
Как получить ключ API и активировать нужные API
Для выполнения этого учебного проекта вам понадобится ключ Google API, который авторизован для работы с Maps SDK for Android и Places SDK for Android.
Нажмите кнопку ниже, чтобы получить ключ и активировать API.
Более подробную информацию можно найти в полном руководстве по получению ключа API.
Как добавить ключ API в свое приложение
- Откройте файл local.properties проекта.
Добавьте приведенную ниже строку и укажите вместо YOUR_API_KEY ваш ключ API.
Плагин Secrets Gradle Plugin для Android копирует ключ API во время сборки приложения и делает его доступным в виде переменной сборки в манифесте Android.
Как создать сборку и запустить приложение
- Подключите устройство Android к компьютеру. Выполните инструкции по активации параметров для разработчиков на устройстве Android и настройте ваше приложение и систему для обнаружения этого устройства. Для настройки виртуального устройства вы также можете использовать Менеджер виртуального устройства Android (AVD). Выбирая эмулятор, убедитесь, что вы используете образ, который содержит интерфейсы Google API. Подробную информацию можно найти в руководстве по началу работы.
- В Android Studio выберите пункт меню Запустить или нажмите на значок воспроизведения, чтобы запустить свое приложение. В открывшемся окне выберите устройство.
Android Studio запустит Gradle для сборки приложения, а затем отобразит результаты на устройстве или в эмуляторе. Вы должны увидеть карту с набором маркеров, в центре которой будет ваше актуальное местоположение, как показано на иллюстрации на этой странице.
- Если карта не отображается, проверьте, получен ли ключ API и добавлен ли он в приложение как описано выше. Проверьте журнал Android Monitor в Android Studio на наличие сообщений об ошибках, касающихся ключа API.
- Если на карте отображается только один маркер, установленный на Сиднейском мосту (местоположение по умолчанию, указанное в приложении), проверьте, предоставили ли вы приложению доступ к данным о местоположении. Приложение запрашивает доступ в процессе запуска, используя шаблон, который приводится в руководстве с описанием разрешений Android. Обратите внимание, что разрешения можно также предоставить непосредственно на устройстве, выбрав Настройки > Приложения >название приложения > Разрешения > Местоположение. Подробную информацию о том, как указывать разрешения в коде, вы найдете ниже, в руководстве по запросу доступа к данным о местоположении.
- Используйте средства отладки Android Studio чтобы просмотреть журналы и выполнить отладку приложения.
Понимание кода
В этой части руководства описаны наиболее важные компоненты приложения CurrentPlaceDetailsOnMap, чтобы вы могли понять принципы создания подобного приложения.
Создание клиента Places API
Ниже указаны объекты, которые являются основными точками входа в Places SDK на платформе Android:
- Класс Places создает клиентов для Places SDK на платформе Android и управляет ими.
- Интерфейс PlaceDetectionClient устанавливает текущее местоположение устройства и мест рядом.
Интерфейс LocationServices – главная точка входа для сервисов геолокации на платформе Android.
Чтобы использовать API, выполните следующие действия в рамках метода onCreate() вашего фрагмента или действия:
- Инициализируйте объект Places .
- Создайте объект PlaceDetectionClient .
- Создайте объект FusedLocationProviderClient .
Kotlin
Запрос доступа к данным о местоположении
Чтобы в вашем приложении работали функции геолокации (в том числе кнопка Мое местоположение на карте), необходимо получить от пользователя разрешение на доступ к данным о местоположении.
Это руководство содержит код, позволяющий запросить доступ к точным данным о местоположении. Подробную информацию можно найти в руководстве по разрешениям Android.
Добавьте следующее разрешение в качестве дочернего для элемента в вашем манифесте Android:
Запросите разрешения при запуске приложения, чтобы пользователь мог принять или отклонить запрос доступа к данным о местоположении. Следующий код позволяет проверить, предоставил ли пользователь доступ к данным о точном местоположении. Если разрешение отсутствует, оно будет запрошено у пользователя.
Kotlin
Переопределите обратный вызов метода onRequestPermissionsResult() , чтобы обработать результат запроса доступа:
Kotlin
Метод updateLocationUI() мы рассмотрим ниже.
Добавление карты
Отобразите карту, используя Maps SDK для Android.
Добавьте элемент в файл макета для объекта activity, activity_maps.xml . Этот элемент указывает, что фрагмент SupportMapFragment должен выступать в роли контейнера для карты и предоставить доступ к объекту GoogleMap . В учебном проекте используется версия вспомогательной библиотеки Android для фрагмента карты, чтобы обеспечить обратную совместимость с более ранними версиями фреймворка Android.
В методе onCreate() своего объекта activity установите файл макета как представление контента.
Kotlin
Реализуйте интерфейс OnMapReadyCallback и переопределите метод onMapReady() , чтобы настроить карту, когда объект GoogleMap будет доступен:
Kotlin
В методе onCreate() своего объекта activity получите дескриптор для фрагмента карты путем вызова метода FragmentManager.findFragmentById() . Затем используйте метод getMapAsync() , чтобы зарегистрировать обратный вызов карты:
Kotlin
Разместите в коде метод updateLocationUI() , чтобы добавить на карту элементы управления. Если пользователь предоставил разрешение на использование данных о местоположении, активируйте слой «Мое местоположение» и соответствующий элемент управления на карте. В противном случае отключите их и установите для текущего местоположения значение null:
Kotlin
Как получить информацию о местоположении устройства Android и позиции карты
Обратитесь к поставщику геоданных из нескольких источников, чтобы определить последнее известное местоположение устройства. Затем используйте эти данные для позиционирования карты. В этом руководстве есть код, который вам понадобится. Дополнительную информацию о том, как определить местоположение устройства, можно найти в руководстве по работе с поставщиком геоданных из нескольких источников для Location API сервисов Google Play.
Kotlin
Как получить данные о текущем местоположении
Получить список мест, где с вероятностью может находиться устройство, можно с помощью Places SDK for Android. Место в данном случае – это компания или другой объект для посещения.
Выполните приведенные ниже инструкции, чтобы настроить показ места, когда пользователь нажимает кнопку Узнать место. Пользователь увидит список подходящих мест и сможет сделать выбор, а затем добавить на карту маркер, чтобы указать местоположение выбранного места. В этом руководстве вы найдете код для взаимодействия с Places SDK for Android. Дополнительную информацию можно найти в руководстве по получению информации о текущем месте.
- Создайте файл макета ( current_place_menu.xml ) для меню параметров и переопределите метод onCreateOptionsMenu() , чтобы настроить это меню. Ознакомьтесь с кодом в примере приложения.
- Переопределите метод onOptionsItemSelected() , чтобы получать актуальную информацию о месте, когда пользователь нажимает Узнать место:
Kotlin
Создайте метод showCurrentPlace() , чтобы получить список мест, где может находиться устройство:
Kotlin
Создайте метод openPlacesDialog() , чтобы показать форму, в которой пользователь может выбрать место из списка. Добавьте на карту маркер для выбранного места. Маркер должен содержать сведения о названии и адресе места, а также другие атрибуты, которые предоставляет API:
Kotlin
Создайте собственный макет для контента информационного окна. Это позволяет показывать в окне несколько строк. Сначала добавьте файл макета XML ( custom_info_contents.xml ), который содержит текстовое представление для заголовка информационного окна, и еще одно текстовое представление для фрагмента (иными словами, текстовый контент информационного окна).
Реализуйте интерфейс InfoWindowAdapter , чтобы развернуть макет и загрузить контент информационного окна:
Kotlin
Сохранение состояния карты
Сохраните информацию о положении камеры и местоположении устройства. Когда пользователь поворачивает устройство Android или изменяет параметры конфигурации, фреймворк Android останавливает и заново запускает объект activity для карты. Чтобы обеспечить удобство для пользователя, сохраните соответствующее состояние приложения и восстановите его при необходимости.
Это руководство содержит весь код, который необходим для сохранения состояния карты. Дополнительную информацию вы можете найти в руководстве по использованию пакета savedInstanceState .
В операции, работающей с картой, настройте основные значения для сохранения состояния объекта activity:
Kotlin
Реализуйте обратный вызов onSaveInstanceState() , чтобы сохранить состояние, когда операция будет приостановлена:
Kotlin
В методе onCreate() своей операции получите информацию о местоположении устройства и положении камеры карты, если это было ранее сохранено:
Kotlin
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Источник