Эта практическая работа входит в курс «Advanced Android in Kotlin». Вы получите максимальную пользу от этого курса, выполняя задания последовательно, но это не обязательно. Все практическая работа курса перечислены на целевой странице практической работы «Advanced Android in Kotlin» .
Создание приложений с помощью Google Карт позволяет добавлять в них новые функции, такие как спутниковые снимки, удобный пользовательский интерфейс для управления картами, отслеживание местоположения и маркеры местоположения. Вы можете расширить возможности стандартных Google Карт, отображая информацию из собственного набора данных, например, местоположение популярных мест для рыбалки или скалолазания. Вы также можете создавать игры, в которых игрок исследует физический мир, например, в поисках сокровищ или даже в играх с дополненной реальностью.
На этом уроке вы создадите приложение Google Maps под названием Wander, которое отображает настроенные карты и показывает местоположение пользователя.
Предпосылки
Знание следующего:
- Как создать простое приложение для Android и запустить его с помощью Android Studio.
- Как создавать и управлять ресурсами, такими как строки.
- Как рефакторить код и переименовать переменные с помощью Android Studio.
- Как пользоваться картой Google как пользователь.
- Как установить разрешения времени выполнения.
Чему вы научитесь
- Как получить ключ API из Google API Console и зарегистрировать ключ в своем приложении
- Как интегрировать Google Maps в ваше приложение
- Как отображать различные типы карт
- Как стилизовать карту Google
- Как добавить маркеры на карту
- Как предоставить пользователю возможность разместить маркер на точке интереса (POI)
- Как включить отслеживание местоположения
- Как создать приложение The
Wander
со встроенной картой Google - Как создавать пользовательские функции для вашего приложения, такие как маркеры и стили
- Как включить отслеживание местоположения в вашем приложении
В этой лабораторной работе вы создадите приложение Wander
, которое отображает карту Google с пользовательским стилем. Приложение Wander позволяет вам отмечать места на карте маркерами, добавлять наложения и видеть своё местоположение в режиме реального времени.
Для Maps SDK для Android требуется ключ API. Чтобы получить ключ API, зарегистрируйте свой проект на странице API и сервисы . Ключ API привязан к цифровому сертификату, который связывает приложение с его автором. Подробнее об использовании цифровых сертификатов и подписи приложения см. в разделе «Подпись приложения» .
В этой лабораторной работе вы используете ключ API для отладочного сертификата. Отладочный сертификат изначально небезопасен, как описано в разделе «Подписание отладочной сборки» . Для опубликованных приложений Android, использующих Maps SDK для Android, требуется второй ключ API: ключ для сертификата выпуска. Подробнее о получении сертификата выпуска см. в разделе «Получение ключа API» .
В Android Studio есть шаблон активности Google Карт, который генерирует полезный код шаблона. Этот код включает файл google_maps_api.xml , содержащий ссылку, упрощающую получение ключа API.
Шаг 1: Создайте проект Wander с помощью шаблона карт
- Создайте новый проект Android Studio.
- Выберите шаблон «Действия Google Карт» .
- Назовите проект
Wander
. - Установите минимальный уровень API на API 19. Убедитесь, что выбран язык Kotlin .
- Нажмите кнопку Готово .
- После завершения сборки приложения взгляните на свой проект и следующие файлы, связанные с картами, которые Android Studio создает для вас:
google_maps_api.xml — этот файл конфигурации используется для хранения вашего ключа API. Шаблон генерирует два файла google_maps_api.xml : один для отладки и один для выпуска. Файл ключа API для сертификата отладки находится в папке src/debug/res/values . Файл ключа API для сертификата выпуска находится в папке src/release/res/values . В этой лабораторной работе используется только сертификат отладки.
activity_maps.xml — этот файл макета содержит один фрагмент, заполняющий весь экран. Класс SupportMapFragment
является подклассом класса Fragment
. SupportMapFragment
— это самый простой способ разместить карту в приложении. Это оболочка для представления карты, которая автоматически обрабатывает необходимые требования жизненного цикла.
Вы можете включить SupportMapFragment
в файл макета, используя тег <fragment>
в любой ViewGroup
с дополнительным атрибутом name
.
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java — файл MapsActivity.kt создаёт экземпляр SupportMapFragment
в методе onCreate()
и использует метод getMapAsync
()
класса для автоматической инициализации системы карт и представления. Активность, содержащая SupportMapFragment
, должна реализовывать интерфейс OnMapReadyCallback
и метод onMapReady()
этого интерфейса. Метод onMapReady()
вызывается при загрузке карты.
Шаг 2: Получите ключ API
- Откройте отладочную версию файла google_maps_api.xml .
- В файле найдите комментарий с длинным URL-адресом. Параметры URL-адреса включают конкретную информацию о вашем приложении.
- Скопируйте и вставьте URL-адрес в браузер.
- Следуйте инструкциям по созданию проекта на странице «API и сервисы» . Благодаря параметрам в указанном URL-адресе страница автоматически включает Maps SDK для Android.
- Нажмите «Создать ключ API» .
- На следующей странице перейдите в раздел «Ключи API» и нажмите на ключ, который вы только что создали.
- Нажмите «Ограничить ключ» и выберите Maps SDK для Android, чтобы ограничить использование ключа приложениями Android.
- Скопируйте сгенерированный API-ключ. Он начинается с «
AIza"
. - В файле
google_maps_api.xml
вставьте ключ в строкуgoogle_maps_key
там, где указаноYOUR_KEY_HERE
. - Запустите приложение. В вашей активности должна появиться встроенная карта с маркером Сиднея, Австралия. (Маркер Сиднея является частью шаблона, и вы сможете изменить его позже.)
Шаг 3: Переименуйте mMap
У MapsActivity
есть приватная var
lateinit
mMap
, которая имеет тип GoogleMap
. Чтобы соответствовать правилам именования Kotlin, измените имя mMap
на map
.
- В
MapsActivity
щелкните правой кнопкой мышиmMap
и выберите Рефакторинг > Переименовать...
- Измените имя переменной на
map
.
Обратите внимание, что все ссылки на mMap
в функции onMapReady()
также изменяются на map
.
Google Maps включает в себя несколько типов карт: обычные, гибридные, спутниковые, карты рельефа и «отсутствуют» (карта вообще отсутствует).
Нормальная карта | Спутниковая карта | Гибридная карта | Карта местности |
Каждый тип карты предоставляет различную информацию. Например, при использовании карт для навигации в автомобиле удобно видеть названия улиц, поэтому можно использовать стандартный вариант. В пешем походе карта рельефа может помочь определить, какой подъём вам ещё предстоит пройти, чтобы добраться до вершины.
В этом задании вы:
- Добавьте панель приложения с меню параметров, позволяющим пользователю изменять тип карты.
- Переместите начальную точку карты в свое домашнее местоположение.
- Добавить поддержку маркеров, которые обозначают отдельные местоположения на карте и могут включать метку.
Добавить меню для типов карт
На этом этапе вы добавляете панель приложения с меню параметров, которое позволяет пользователю изменять тип карты.
- Чтобы создать новый XML-файл меню, щелкните правой кнопкой мыши по каталогу res и выберите «Создать» > «Файл ресурсов Android» .
- В диалоговом окне назовите файл
map_options
. - Выберите Меню для типа ресурса.
- Нажмите ОК .
- На вкладке «Код» замените код в новом файле следующим кодом, чтобы создать пункты меню карты. Тип карты «none» опущен, поскольку «none» приводит к полному отсутствию карты. Этот шаг приводит к ошибке, но она будет устранена на следующем шаге.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/normal_map"
android:title="@string/normal_map"
app:showAsAction="never" />
<item
android:id="@+id/hybrid_map"
android:title="@string/hybrid_map"
app:showAsAction="never" />
<item
android:id="@+id/satellite_map"
android:title="@string/satellite_map"
app:showAsAction="never" />
<item
android:id="@+id/terrain_map"
android:title="@string/terrain_map"
app:showAsAction="never" />
</menu>
- В
strings.xml
добавьте ресурсы для атрибутовtitle
, чтобы устранить ошибки.
<resources>
...
<string name="normal_map">Normal Map</string>
<string name="hybrid_map">Hybrid Map</string>
<string name="satellite_map">Satellite Map</string>
<string name="terrain_map">Terrain Map</string>
<string name="lat_long_snippet">Lat: %1$.5f, Long: %2$.5f</string>
<string name="dropped_pin">Dropped Pin</string>
<string name="poi">poi</string>
</resources>
- В
MapsActivity
переопределите методonCreateOptionsMenu()
и добавьте меню из файла ресурсовmap_options
.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.map_options, menu)
return true
}
- В
MapsActivity.kt
переопределите методonOptionsItemSelected()
. Измените тип карты, используя константы типа карты, чтобы отразить выбор пользователя.
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
// Change the map type based on the user's selection.
R.id.normal_map -> {
map.mapType = GoogleMap.MAP_TYPE_NORMAL
true
}
R.id.hybrid_map -> {
map.mapType = GoogleMap.MAP_TYPE_HYBRID
true
}
R.id.satellite_map -> {
map.mapType = GoogleMap.MAP_TYPE_SATELLITE
true
}
R.id.terrain_map -> {
map.mapType = GoogleMap.MAP_TYPE_TERRAIN
true
}
else -> super.onOptionsItemSelected(item)
}
- Запустите приложение.
- Щелкните
Чтобы изменить тип карты, обратите внимание на то, как меняется внешний вид карты в разных режимах.
По умолчанию функция обратного вызова onMapReady()
включает код, который устанавливает маркер в Сиднее (Австралия), где были созданы Google Карты. Функция обратного вызова по умолчанию также анимирует карту, перемещаясь в сторону Сиднея.
В этом задании вы перемещаете камеру карты к своему дому, масштабируете ее до указанного уровня и размещаете там маркер.
Шаг 1: Увеличьте масштаб изображения до своего дома и добавьте маркер.
- В файле
MapsActivity.kt
найдите методonMapReady()
. Удалите из него код, который устанавливает маркер в Сиднее и перемещает камеру. Вот как должен выглядеть ваш метод.
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
}
- Найдите широту и долготу вашего дома, следуя этим инструкциям .
- Создайте значение широты и значение долготы и введите их значения с плавающей точкой.
val latitude = 37.422160
val longitude = -122.084270
- Создайте новый объект
LatLng
с именемhomeLatLng
. В объектhomeLatLng
передайте только что созданные вами значения.
val homeLatLng = LatLng(latitude, longitude)
- Создайте
val
масштаба карты. Используйте уровень масштабирования 15f.
val zoomLevel = 15f
Уровень масштабирования управляет степенью приближения карты. Следующий список даёт представление о том, какой уровень детализации отображается на каждом уровне масштабирования:
-
1
: Мир -
5
: Суша/континент -
10
: Город -
15
: Улицы -
20
: Здания
- Переместите камеру в
homeLatLng
, вызвав функциюmoveCamera()
объектаmap
и передайте объектCameraUpdate
с помощьюCameraUpdateFactory.newLatLngZoom()
. Передайте объектhomeLatLng
иzoomLevel
.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
- Добавьте маркер на карту в
homeLatLng
.
map.addMarker(MarkerOptions().position(homeLatLng))
Ваш окончательный метод должен выглядеть так:
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
//These coordinates represent the latitude and longitude of the Googleplex.
val latitude = 37.422160
val longitude = -122.084270
val zoomLevel = 15f
val homeLatLng = LatLng(latitude, longitude)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
map.addMarker(MarkerOptions().position(homeLatLng))
}
- Запустите приложение. Карта должна переместиться к вашему дому, увеличиться до нужного уровня и отметить его маркером.
Шаг 2: Разрешите пользователям добавлять маркер с помощью долгого нажатия
На этом этапе вы добавляете маркер, когда пользователь касается и удерживает местоположение на карте.
- Создайте заглушку метода в
MapsActivity
с именемsetMapLongClick()
, который принимаетGoogleMap
в качестве аргумента. - Присоедините прослушиватель
setOnMapLongClickListener
к объекту карты.
private fun setMapLongClick(map:GoogleMap) {
map.setOnMapLongClickListener { }
}
- В методе
setOnMapLongClickListener()
вызовите методaddMarker()
. Передайте новый объектMarkerOptions
с позицией, заданной переданным значениемLatLng
.
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
map.addMarker(
MarkerOptions()
.position(latLng)
)
}
}
- В конце метода
onMapReady()
вызовитеsetMapLongClick()
сmap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapLongClick(map)
}
- Запустите приложение.
- Нажмите и удерживайте карту, чтобы разместить маркер в определенном месте.
- Коснитесь маркера, и он окажется в центре экрана.
Шаг 3: Добавьте информационное окно для маркера.
На этом этапе вы добавляете InfoWindow
, которое отображает координаты маркера при касании маркера.
- В
setMapLongClick()setOnMapLongClickListener()
создайтеval
дляsnippet
. Snippet — это дополнительный текст, отображаемый после заголовка. Ваш snippet отображает широту и долготу маркера.
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
// A snippet is additional text that's displayed after the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
)
}
}
- В
addMarker()
задайтеtitle
маркера как Dropped Pindropped_pin
используя строковый ресурсR.string.
. - Установите для маркера
snippet
значениеsnippet
.
Готовая функция выглядит так:
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
// A Snippet is Additional text that's displayed below the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet)
)
}
}
- Запустите приложение.
- Нажмите и удерживайте карту, чтобы установить маркер местоположения.
- Нажмите на маркер, чтобы открыть информационное окно.
Шаг 4: Добавьте прослушиватель POI
По умолчанию точки интереса (POI) отображаются на карте вместе с соответствующими значками. К ним относятся парки, школы, правительственные здания и многое другое. Если выбран normal
тип карты, на карте также отображаются деловые объекты интереса (POI). Такие объекты представляют собой предприятия, такие как магазины, рестораны и отели.
На этом этапе вы добавляете на карту слушатель GoogleMap.OnPoiClickListener
. Этот прослушиватель щелчков мгновенно размещает маркер на карте, когда пользователь нажимает на точку интереса (POI). Он также отображает информационное окно с названием точки интереса.
- Создайте заглушку метода в
MapsActivity
с именемsetPoiClick()
, который принимаетGoogleMap
в качестве аргумента. - В методе
setPoiClick()
установитеOnPoiClickListener
для переданного объектаGoogleMap
.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- В
setOnPoiClickListener()
создайтеval poiMarker
для маркера. - Установите его в качестве маркера с помощью
map.addMarker()
аMarkerOptions
задайте в качествеtitle
имя точки интереса.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
}
}
- В функции
setOnPoiClickListener()
вызовитеshowInfoWindow()
дляpoiMarker
, чтобы немедленно отобразить информационное окно.
poiMarker.showInfoWindow()
Ваш окончательный код для функции setPoiClick()
должен выглядеть следующим образом.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
poiMarker.showInfoWindow()
}
}
- В конце
onMapReady()
вызовитеsetPoiClick()
и передайтеmap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setPoiClick(map)
}
- Запустите приложение и найдите точку интереса, например парк или кофейню.
- Нажмите на точку интереса, чтобы поместить на нее маркер и отобразить название точки интереса в информационном окне.
Вы можете настраивать Google Maps различными способами, придавая своей карте уникальный вид.
Вы можете настроить объект MapFragment
, используя доступные атрибуты XML , как и любой другой фрагмент. Однако на этом этапе вы настраиваете внешний вид и содержание MapFragment
, используя методы объекта GoogleMap
.
Чтобы создать индивидуальный стиль для вашей карты, вы генерируете JSON-файл, определяющий, как отображаются объекты на карте. Вам не нужно создавать этот JSON-файл вручную. Google предоставляет мастер стилей Maps Platform , который генерирует JSON-файл после того, как вы визуально стилизуете карту. В этом задании вы оформляете карту в ретро-стиле, то есть используете винтажные цвета и добавляете цветные дороги.
Шаг 1: Создайте стиль для вашей карты
- Перейдите по адресу https://mapstyle.withgoogle.com/ в вашем браузере.
- Выберите Создать стиль .
- Выберите Ретро .
- Нажмите Дополнительные параметры .
- В списке Тип объекта выберите Дорога > Насыпь .
- Измените цвет дорог на любой выбранный вами (например, розовый).
- Нажмите кнопку Готово .
- Скопируйте JSON-код из полученного диалогового окна и, если хотите, сохраните его в виде текстовой заметки для использования на следующем шаге.
Шаг 2: Добавьте стиль к вашей карте.
- В Android Studio, в разделе
res
В каталоге создайте каталог ресурсов и назовите егоraw
. Ресурсы каталогаraw
используются как JSON-код. - Создайте файл в
res/raw
с именемmap_style.json
. - Вставьте сохранённый JSON-код в новый файл ресурсов.
- В
MapsActivity
создайте переменную классаTAG
над методомonCreate()
. Она будет использоваться для ведения журнала.
private val TAG = MapsActivity::class.java.simpleName
- Также в
MapsActivity
создайте функциюsetMapStyle()
, которая принимаетGoogleMap
. - В
setMapStyle()
добавьте блокtry{}
. - В блоке
try{}
создайтеval success
для успешного выполнения стилизации. (Вы добавляете следующий блок catch.) - В блоке
try{}
задайте стиль JSON для карты, вызовитеsetMapStyle()
для объектаGoogleMap
. Передайте объектMapStyleOptions
, который загрузит JSON-файл. - Присвойте результат параметру
success
. МетодsetMapStyle()
возвращает логическое значение, указывающее на успешность анализа файла стилей и установки стиля.
private fun setMapStyle(map: GoogleMap) {
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
val success = map.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this,
R.raw.map_style
)
)
}
}
- Добавьте оператор if, устанавливающий значение false для
success
. Если стилизация не удалась, выведите в журнал сообщение о том, что разбор не удался.
private fun setMapStyle(map: GoogleMap) {
try {
...
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
}
}
- Добавьте блок
catch{}
для обработки ситуации с отсутствующим файлом стилей. В блокеcatch
, если файл не удаётся загрузить, генерируется исключениеResources.NotFoundException
.
private fun setMapStyle(map: GoogleMap) {
try {
...
} catch (e: Resources.NotFoundException) {
Log.e(TAG, "Can't find style. Error: ", e)
}
}
Готовый метод должен выглядеть как следующий фрагмент кода:
private fun setMapStyle(map: GoogleMap) {
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
val success = map.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this,
R.raw.map_style
)
)
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
} catch (e: Resources.NotFoundException) {
Log.e(TAG, "Can't find style. Error: ", e)
}
}
- Наконец, вызовите метод
setMapStyle()
в методеonMapReady()
передав ему объектGoogleMap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapStyle(map)
}
- Запустите приложение.
- Переведите карту в
normal
режим, и новый стиль с ретро-темой и дорогами выбранного вами цвета должен быть заметен.
Шаг 3: Выберите стиль маркера
Вы можете ещё больше персонализировать свою карту, стилизовав маркеры. На этом этапе вы измените стандартные красные маркеры на что-то более стильное.
- В методе
onMapLongClick()
добавьте следующую строку кода вMarkerOptions()
конструктора, чтобы использовать маркер по умолчанию, но изменить цвет на синий.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
Теперь onMapLongClickListener()
выглядит так:
map.setOnMapLongClickListener { latLng ->
// A snippet is additional text that's displayed after the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
)
}
- Запустите приложение. Маркеры, появляющиеся после долгого нажатия, теперь окрашены в синий цвет. Обратите внимание, что маркеры точек интереса (POI) по-прежнему красные, поскольку вы не добавили стили к методу
onPoiClick()
.
Один из способов персонализировать карту Google — рисовать поверх неё. Этот приём полезен, если вы хотите выделить определённый тип местоположения, например, популярные места для рыбалки.
- Фигуры: на карту можно добавлять полилинии , многоугольники и круги .
- Объекты
GroundOverlay
: Наземное наложение — это изображение, закреплённое на карте. В отличие от маркеров, наземные наложения ориентированы на поверхность Земли, а не на экран. Поворот, наклон или масштабирование карты изменяют ориентацию изображения. Наземные наложения полезны, когда требуется закрепить отдельное изображение в определённой области карты.
Шаг: Добавьте наложение земли
В этом задании вы добавите наземную накладку в форме Android к своему домашнему местоположению.
- Загрузите это изображение Android и сохраните его в папке
res/drawable
. (Убедитесь, что имя файла —android.png
.)
- В
onMapReady()
после вызова перемещения камеры в положение вашего дома создайте объектGroundOverlayOptions
. - Назначьте объект переменной
androidOverlay
.
val androidOverlay = GroundOverlayOptions()
- Используйте метод
BitmapDescriptorFactory.fromResource()
для создания объектаBitmapDescriptor
из загруженного ресурса изображения. - Передайте полученный объект
BitmapDescriptor
в методimage()
объектаGroundOverlayOptions
.
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
- Создайте
float overlaySize
указывающий ширину нужного наложения в метрах. В этом примере хорошо подойдёт ширина100f
.
Задайте свойство position
для объекта GroundOverlayOptions
, вызвав метод position()
, и передайте объект homeLatLng
и overlaySize
.
val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(homeLatLng, overlaySize)
- Вызовите
addGroundOverlay()
для объектаGoogleMap
и передайте ему объектGroundOverlayOptions
.
map.addGroundOverlay(androidOverlay)
- Запустите приложение.
- Измените значение
zoomLevel
на 18f, чтобы увидеть изображение Android в виде наложения.
Пользователи часто используют Google Карты, чтобы увидеть своё текущее местоположение. Чтобы отобразить местоположение устройства на карте, можно использовать слой данных о местоположении .
Слой данных о местоположении добавляет «Моё местоположение» на карту. При нажатии кнопки карта центрируется на местоположении устройства. Местоположение отображается синей точкой, если устройство неподвижно, и синим шевроном, если устройство движется.
В этой задаче вы включите слой данных о местоположении.
Шаг: Запросите разрешение на определение местоположения
Для включения отслеживания местоположения в Google Картах требуется всего одна строка кода. Однако необходимо убедиться, что пользователь предоставил разрешения на определение местоположения (используя модель разрешений времени выполнения).
На этом этапе вы запрашиваете разрешения на определение местоположения и включаете отслеживание местоположения.
- Убедитесь, что в файле
AndroidManifest.xml
уже присутствует разрешениеFINE_LOCATION
. Android Studio добавила это разрешение при выборе шаблона Google Maps.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- В
MapsActivity
создайте переменную классаREQUEST_LOCATION_PERMISSION
.
private val REQUEST_LOCATION_PERMISSION = 1
- Чтобы проверить, предоставлены ли разрешения, создайте метод
isPermissionGranted()
вMapsActivity
. В этом методе проверяется, предоставил ли пользователь разрешение.
private fun isPermissionGranted() : Boolean {
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
- Чтобы включить отслеживание местоположения в приложении, создайте метод
enableMyLocation()
вMapsActivity
, который не принимает аргументов и ничего не возвращает. Внутри него проверьте наличие разрешенияACCESS_FINE_LOCATION
. Если разрешение предоставлено, включите слой местоположения. В противном случае запросите разрешение.
private fun enableMyLocation() {
if (isPermissionGranted()) {
map.isMyLocationEnabled = true
}
else {
ActivityCompat.requestPermissions(
this,
arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION_PERMISSION
)
}
}
- Вызовите
enableMyLocation()
из обратного вызоваonMapReady()
, чтобы включить слой местоположения.
override fun onMapReady(googleMap: GoogleMap) {
...
enableMyLocation()
}
- Переопределите метод
onRequestPermissionsResult()
. ЕслиrequestCode
равенREQUEST_LOCATION_PERMISSION
, разрешение предоставляется, а массивgrantResults
непустой и в его первом слоте указаноPackageManager.PERMISSION_GRANTED
, вызовитеenableMyLocation()
.
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
enableMyLocation()
}
}
}
- Запустите приложение. Должно появиться диалоговое окно с запросом на доступ к данным о местоположении устройства. Дайте разрешение.
Текущее местоположение устройства теперь отображается на карте синей точкой. Обратите внимание на кнопку определения местоположения. Если вы переместите карту от своего местоположения и нажмете эту кнопку, она снова центрируется относительно местоположения устройства.
Загрузите код для готовой лабораторной работы.
$ git clone https://github.com/googlecodelabs/android-kotlin-geo-maps
Кроме того, вы можете загрузить репозиторий в виде zip-файла, распаковать его и открыть в Android Studio.
- Для использования API Карт вам понадобится ключ API из консоли API Google .
- В Android Studio использование шаблона Activity Google Maps генерирует
Activity
с одним фрагментомSupportMapFragment
в макете приложения. Шаблон также добавляетACCESS_FINE_PERMISSION
в манифест приложения, реализуетOnMapReadyCallback
в вашей Activity и переопределяет требуемый методonMapReady()
.
Чтобы изменить тип карты GoogleMap
во время выполнения, используйте метод GoogleMap.setMapType()
. Карта Google может быть одного из следующих типов:
- Обычная : Типичная дорожная карта. Показаны дороги, некоторые объекты, созданные человеком, и важные природные объекты, такие как реки. Также видны обозначения дорог и объектов.
- Гибрид : данные спутниковых снимков с добавлением дорожных карт. Также видны обозначения дорог и объектов.
- Спутник : Данные фотографии. Обозначения дорог и объектов не видны.
- Рельеф : топографические данные. Карта включает цвета, контурные линии и подписи, а также перспективную штриховку. Также видны некоторые дороги и подписи.
- Нет : нет фрагментов базовой карты.
О Google Картах:
- Маркер — это указатель определенного географического местоположения.
- При нажатии на маркер по умолчанию отображается информационное окно с данными о местоположении.
- По умолчанию точки интереса (POI) отображаются на базовой карте вместе с соответствующими значками. К ним относятся парки, школы, правительственные здания и многое другое.
- Кроме того, на
normal
карте по умолчанию отображаются деловые объекты (магазины, рестораны, гостиницы и т. д.). - Вы можете фиксировать клики по POI с помощью
OnPoiClickListener
. - Вы можете изменить внешний вид практически любого элемента карты Google с помощью мастера стилей . Мастер стилей генерирует JSON-файл, который вы передаёте в карту Google с помощью метода
setMapStyle()
. - Вы можете настроить маркеры, изменив цвет по умолчанию или заменив значок маркера по умолчанию на пользовательское изображение.
Другая важная информация:
- Используйте наложение земной поверхности , чтобы привязать изображение к географическому положению.
- Используйте объект
GroundOverlayOptions
для указания изображения, его размера в метрах и положения. Передайте этот объект методуGoogleMap.addGroundOverlay()
, чтобы установить наложение на карту. - Если у вашего приложения есть разрешение
ACCESS_FINE_LOCATION
, вы можете включить отслеживание местоположения, установивmap.isMyLocationEnabled = true
. - Это не рассматривается в данной практической работе, но вы можете предоставить дополнительную информацию о местоположении с помощью Google Street View , который представляет собой панорамную фотографию заданного места с возможностью навигации.
Документация для разработчиков Android:
- Начать
- Добавление карты с маркером
- Объекты карты
- Добавление стилизованной карты
- Просмотр улиц
- Наземные наложения
Справочная документация:
Ссылки на другие практические занятия по этому курсу см. на целевой странице практических занятий по курсу Advanced Android in Kotlin .