Расширенный Android в Kotlin 04.1: Android Google Maps

Эта лаборатория кода является частью курса Advanced Android in Kotlin. Вы получите максимальную пользу от этого курса, если будете последовательно работать с кодовыми таблицами, но это не обязательно. Все кодовые таблицы курсов перечислены на целевой странице Advanced Android in Kotlin codelabs .

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

В этом уроке вы создадите приложение Google Maps под названием Wander, которое отображает настроенные карты и показывает местоположение пользователя.

Предпосылки

Знание следующего:

  • Как создать базовое приложение для Android и запустить его с помощью Android Studio.
  • Как создавать ресурсы, например строки, и управлять ими.
  • Как провести рефакторинг кода и переименовать переменные с помощью Android Studio.
  • Как использовать карту Google в качестве пользователя.
  • Как установить разрешения на выполнение.

Что ты узнаешь

  • Как получить ключ API из консоли Google API и зарегистрировать ключ для своего приложения
  • Как интегрировать Google Map в ваше приложение
  • Как отображать разные типы карт
  • Как стилизовать карту Google
  • Как добавить маркеры на карту
  • Как разрешить пользователю ставить маркер на достопримечательность (POI)
  • Как включить отслеживание местоположения
  • Как создать приложение The Wander со встроенной картой Google
  • Как создавать собственные функции для вашего приложения, такие как маркеры и стили
  • Как включить отслеживание местоположения в вашем приложении

В этой кодовой лаборатории вы создаете приложение Wander , которое отображает карту Google с настраиваемым стилем. Приложение Wander позволяет ставить маркеры на местоположения, добавлять наложения и видеть свое местоположение в режиме реального времени.

5b12eda7f467bc2f.png

SDK Карт для Android требует ключа API. Чтобы получить ключ API, зарегистрируйте свой проект на странице API и сервисы . Ключ API привязан к цифровому сертификату, который связывает приложение с его автором. Дополнительные сведения об использовании цифровых сертификатов и подписи приложения см. В разделе Подписание приложения .

В этой кодовой таблице вы используете ключ API для сертификата отладки. Сертификат отладки небезопасен по конструкции, как описано в разделе Подписание отладочной сборки . Для опубликованных приложений Android, использующих Maps SDK для Android, требуется второй ключ API: ключ для сертификата выпуска. Дополнительные сведения о получении сертификата выпуска см. В разделе Получение ключа API .

Android Studio включает шаблон Google Maps Activity, который генерирует полезный код шаблона. Код шаблона включает файл google_maps_api.xml, содержащий ссылку, упрощающую получение ключа API.

Шаг 1. Создайте проект Wander с шаблоном карт.

  1. Создайте новый проект Android Studio.
  2. Выберите шаблон Google Maps Activity .

d6b874bb19ea68cd.png

  1. Назовите проект Wander .
  2. Установите минимальный уровень API на API 19 . Убедитесь, что язык - Kotlin .
  3. Щелкните Готово .
  4. Когда приложение будет построено, взгляните на свой проект и следующие файлы, связанные с картами, которые 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

  1. Откройте отладочную версию файла google_maps_api.xml .
  2. Найдите в файле комментарий с длинным URL-адресом. Параметры URL-адреса включают конкретную информацию о вашем приложении.
  3. Скопируйте и вставьте URL-адрес в браузер.
  4. Следуйте инструкциям по созданию проекта на странице API и службы . Из-за параметров в предоставленном URL-адресе страница знает, что нужно автоматически включить SDK Maps для Android.
  5. Щелкните Создать ключ API .
  6. На следующей странице перейдите в раздел Ключи API и щелкните только что созданный ключ.
  7. Нажмите Ограничить ключ и выберите Maps SDK для Android, чтобы ограничить использование ключа приложениями Android.
  8. Скопируйте сгенерированный ключ API. Начинается с « AIza" .
  9. В файле google_maps_api.xml вставьте ключ в строку google_maps_key где написано YOUR_KEY_HERE .
  10. Запустите ваше приложение. Вы должны увидеть встроенную карту своего занятия с маркером, установленным в Сиднее, Австралия. (Маркер Сиднея является частью шаблона, и вы измените его позже.)

34dc9dd877c90996.png

Шаг 3. Переименуйте mMap

MapsActivity имеет частный lateinit var под названием mMap , который имеет тип GoogleMap . Чтобы следовать соглашениям об именах Kotlin, измените имя mMap на map .

  1. В MapsActivity щелкните правой кнопкой мыши mMap и выберите Refactor > Rename ...

e713ccb3384450c6.png

  1. Измените имя переменной на map .

Обратите внимание, как все ссылки на mMap в функции onMapReady() также меняются на map .

Карты Google включают в себя несколько типов карт: обычные, гибридные, спутниковые, рельефные и «нет» (для отсутствия карты вообще).

Карта нормалей

Спутниковая карта

Гибридная карта

Карта местности

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

В этом задании вы:

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

Добавить меню для типов карт

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

  1. Чтобы создать новый XML-файл меню, щелкните правой кнопкой мыши каталог res и выберите « Создать» > « Файл ресурсов Android» .
  2. В диалоговом окне назовите файл map_options .
  3. Выберите Меню для типа ресурса.
  4. Щелкните ОК .
  5. На вкладке « Код » замените код в новом файле следующим кодом, чтобы создать параметры меню карты. Тип карты «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>
  1. В 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>
  1. В MapsActivity переопределите метод onCreateOptionsMenu() и map_options меню из map_options ресурсов map_options .
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. В 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)
}
  1. Запустите приложение.
  2. Нажмите 428da163b831115b.png для изменения типа карты. Обратите внимание, как внешний вид карты меняется в разных режимах.

6fa42970d87f5dc7.png

По умолчанию обратный вызов onMapReady() включает код, который помещает маркер в Сидней, Австралия, где были созданы Карты Google. Обратный вызов по умолчанию также анимирует карту для панорамирования в Сидней.

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

Шаг 1. Увеличьте масштаб до своего дома и добавьте маркер

  1. В файле MapsActivity.kt найдите метод onMapReady() . Удалите из него код, который помещает маркер в Сидней и перемещает камеру. Вот как должен выглядеть ваш метод сейчас.
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. Определите широту и долготу вашего дома, следуя этим инструкциям .
  2. Создайте значение для широты и значение для долготы и введите их значения с плавающей запятой.
val latitude = 37.422160
val longitude = -122.084270
  1. Создайте новый объект LatLng именем homeLatLng . В объекте homeLatLng передайте только что созданные значения.
val homeLatLng = LatLng(latitude, longitude)
  1. Создание val для того, как увеличено вы хотите быть на карте. Используйте уровень масштабирования 15f.
val zoomLevel = 15f

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

  • 1 : Мир
  • 5 : Земля / континент
  • 10 : Город
  • 15 : Улицы
  • 20 : Здания
  1. Переместить камеру в homeLatLng , вызвав moveCamera() функцию на map объекта и передать в CameraUpdate объекта с помощью CameraUpdateFactory.newLatLngZoom() . Передайте объект homeLatLng и zoomLevel .
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. Добавьте маркер на карту дома 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))
}
  1. Запустите ваше приложение. Карта должна перемещаться по вашему дому, увеличиваться до желаемого уровня и ставить отметку на вашем доме.

fc939024778ee76.png

Шаг 2. Разрешите пользователям добавлять маркер с помощью длительного щелчка

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

  1. Создайте в MapsActivity заглушку MapsActivity именем setMapLongClick() который принимает GoogleMap в качестве аргумента.
  2. Прикрепите прослушиватель setOnMapLongClickListener к объекту карты.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. В setOnMapLongClickListener() вызовите метод addMarker() . Передайте новый объект MarkerOptions с позицией, установленной на переданный LatLng .
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. В конце метода onMapReady() вызовите setMapLongClick() с map .
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. Запустите ваше приложение.
  2. Коснитесь карты и удерживайте ее, чтобы установить маркер в месте.
  3. Коснитесь маркера, который центрирует его на экране.

4ff8d1c1db3bca9e.png

Шаг 3. Добавьте информационное окно для маркера

На этом этапе вы добавляете InfoWindow которое отображает координаты маркера при InfoWindow маркера.

  1. В setMapLongClick()setOnMapLongClickListener() создайте val для 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)
       )
   }
}
  1. В addMarker() установите title маркера на Dropped Pin с помощью R.string. dropped_pin строковый ресурс.
  2. Установите 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)
              
       )
   }
}
  1. Запустите ваше приложение.
  2. Коснитесь и удерживайте карту, чтобы поставить маркер местоположения.
  3. Коснитесь маркера, чтобы открыть информационное окно.

63f210e6e47dfa29.png

Шаг 4. Добавьте прослушиватель POI

По умолчанию достопримечательности (POI) отображаются на карте вместе с соответствующими значками. POI включают парки, школы, правительственные здания и многое другое. Если для типа карты задано значение « normal , на карте также отображаются бизнес-объекты. Деловые точки интереса представляют собой предприятия, такие как магазины, рестораны и отели.

На этом этапе вы добавляете на карту GoogleMap.OnPoiClickListener . Этот прослушиватель кликов помещает маркер на карту сразу же, когда пользователь щелкает POI. Слушатель щелчков также отображает информационное окно, содержащее имя точки интереса.

  1. Создайте в MapsActivity заглушку MapsActivity именем setPoiClick() который принимает GoogleMap в качестве аргумента.
  2. В setPoiClick() установите OnPoiClickListener для переданного GoogleMap .
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. В setOnPoiClickListener() создайте val poiMarker для маркера.
  2. Установите его на маркер, используя map.addMarker() с MarkerOptions устанавливая title на имя POI.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. В функции 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()
   }
}
  1. В конце onMapReady() вызовите setPoiClick() и передайте map .
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. Запустите приложение и найдите POI, например парк или кафе.
  2. Коснитесь POI, чтобы поставить на него маркер и отобразить имя POI в информационном окне.

f4b0972c75d5fa5f.png

Вы можете настроить Карты Google разными способами, придав своей карте уникальный вид.

Вы можете настроить объект MapFragment используя доступные атрибуты XML , как если бы вы настраивали любой другой фрагмент. Однако на этом этапе вы настраиваете внешний вид содержимого MapFragment , используя методы объекта GoogleMap .

Чтобы создать индивидуальный стиль для вашей карты, вы создаете файл JSON, который определяет, как отображаются объекты на карте. Вам не нужно создавать этот файл JSON вручную. Google предоставляет мастер стилей платформы Maps , который генерирует JSON для вас после того, как вы визуально стилизуете свою карту. В этой задаче вы стилизуете карту в ретро-стиле, что означает, что карта использует винтажные цвета и вы добавляете цветные дороги.

Шаг 1. Создайте стиль для своей карты

  1. Перейдите на страницу https://mapstyle.withgoogle.com/ в своем браузере.
  2. Выберите « Создать стиль» .
  3. Выберите Ретро .

208b3d3aeab0d9b6.png

  1. Щелкните Дополнительные параметры .

4a35faaf9535ee82.png

  1. Выберите Дорога > Заливка .
  2. Измените цвет дорог на любой по вашему выбору (например, розовый).

92c3293749293a4c.png

  1. Щелкните Готово .

f1bfe8585eb69480.png

  1. Скопируйте код JSON из появившегося диалогового окна и, если хотите, поместите его в текстовую заметку для использования на следующем шаге.

3c32168b299d6420.png

Шаг 2. Добавьте стиль на карту

  1. В Android Studio в каталоге res создайте каталог ресурсов и назовите его raw . Вы используете raw ресурсы каталога, такие как код JSON.
  2. Создайте в res/raw файл с именем map_style.json .
  3. Вставьте сохраненный код JSON в новый файл ресурсов.
  4. В MapsActivity создайте переменную класса TAG над onCreate() . Это используется для целей регистрации.
private val TAG = MapsActivity::class.java.simpleName
  1. Также в MapsActivity создайте функцию setMapStyle() которая принимает GoogleMap .
  2. В setMapStyle() добавьте блок try{} .
  3. В блоке try{} создайте val success для успеха стилизации. (Вы добавляете следующий блок catch.)
  4. В блоке try{} установите стиль JSON для карты, вызовите setMapStyle() для объекта GoogleMap . Передайте объект MapStyleOptions , который загружает файл JSON.
  5. Назначьте результат на 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
           )
       )
   }
}
  1. Добавьте оператор if, если success будет ложным. Если стилизация не удалась, распечатайте журнал о том, что синтаксический анализ не удался.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. Добавьте блок 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)
   }
}
  1. Наконец, вызовите метод setMapStyle() методе onMapReady() передав его в ваш объект GoogleMap .
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. Запустите ваше приложение.
  2. Установите карту в normal режим, и новый стиль должен быть виден с ретро-темой и дорогами выбранного вами цвета.

b59d6cb81f02a14f.png

Шаг 3. Создайте стиль для маркера

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

  1. В 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))
   )
}
  1. Запустите приложение. Маркеры, появляющиеся после долгого щелчка, теперь окрашены в синий цвет. Обратите внимание, что маркеры POI по-прежнему красные, потому что вы не добавили стиль в метод onPoiClick() .

b9916bca3c367e3.png

Один из способов настроить карту Google - нарисовать поверх нее. Этот метод полезен, если вы хотите выделить определенный тип местности, например, популярные места для рыбалки.

  • Фигуры: на карту можно добавлять полилинии , многоугольники и круги .
  • Объекты GroundOverlay : наложение на землю - это изображение, прикрепленное к карте. В отличие от маркеров, наложения на землю ориентированы на поверхность Земли, а не на экран. Поворот, наклон или масштабирование карты изменяет ориентацию изображения. Наложения на землю полезны, когда вы хотите зафиксировать одно изображение в одной области на карте.

Шаг: Добавьте наложение земли

В этой задаче вы добавляете наложение земли в форме Android в свое домашнее местоположение.

  1. Загрузите этот образ Android и сохраните его в папке res/drawable . (Убедитесь, что имя файла - android.png .)

61fabd56a0841b44.png

  1. В onMapReady() после вызова перемещения камеры в исходное положение создайте объект GroundOverlayOptions .
  2. Назначьте объект переменной с именем androidOverlay .
val androidOverlay = GroundOverlayOptions()
  1. Используйте метод BitmapDescriptorFactory.fromResource() для создания объекта BitmapDescriptor из загруженного ресурса изображения.
  2. Передайте полученный объект BitmapDescriptor в метод image() объекта GroundOverlayOptions .
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. Создайте float overlaySize для ширины в метрах желаемого наложения. Для этого примера хорошо 100f ширина 100f .

Задайте свойство position для объекта GroundOverlayOptions , вызвав метод position() , и homeLatLng объект homeLatLng и overlaySize .

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. Вызовите addGroundOverlay() для объекта GoogleMap и передайте свой объект GroundOverlayOptions .
map.addGroundOverlay(androidOverlay)
  1. Запустите приложение.
  2. Измените значение zoomLevel на zoomLevel чтобы изображение Android отображалось как наложение.

b1b25b0acd6a9807.png

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

Слой данных о местоположении добавляет на карту значок « Мое местоположение» .

f317f84dcb3ac3a1.png

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

В этой задаче вы включаете уровень данных о местоположении.

Шаг: запросить разрешения на местоположение

Для включения отслеживания местоположения в Google Maps требуется одна строка кода. Однако вы должны убедиться, что пользователь предоставил разрешения на местоположение (с использованием модели разрешений времени выполнения).

На этом этапе вы запрашиваете разрешения на определение местоположения и включаете отслеживание местоположения.

  1. В файле AndroidManifest.xml убедитесь, что разрешение FINE_LOCATION уже присутствует. Android Studio вставила это разрешение, когда вы выбрали шаблон Google Maps.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. В MapsActivity создайте переменную класса REQUEST_LOCATION_PERMISSION .
private val REQUEST_LOCATION_PERMISSION = 1
  1. Чтобы проверить, предоставлены ли разрешения, создайте метод в MapsActivity именем isPermissionGranted() . В этом методе проверьте, предоставил ли пользователь разрешение.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. Чтобы включить отслеживание местоположения в вашем приложении, создайте в MapsActivity метод с MapsActivity enableMyLocation() который не принимает аргументов и ничего не возвращает. Внутри проверьте разрешение 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
       )
   }
}
  1. Вызовите enableMyLocation() из обратного вызова onMapReady() чтобы включить уровень местоположения.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Переопределите метод 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()
       }
   }
}
  1. Запустите ваше приложение. Должно появиться диалоговое окно с запросом доступа к местоположению устройства. Давай, дай разрешение.

da7e23e00ec762c1.png

На карте теперь отображается текущее местоположение устройства с помощью синей точки. Обратите внимание, что есть кнопка местоположения. Если вы отодвинете карту от своего местоположения и нажмете эту кнопку, она центрирует карту обратно относительно местоположения устройства.

5b12eda7f467bc2f.png

Загрузите код готовой кодовой лаборатории.

$  git clone https://github.com/googlecodelabs/android-kotlin-geo-maps

Кроме того, вы можете загрузить репозиторий в виде zip-файла, распаковать его и открыть в Android Studio.

Скачать zip-архив

Поздравляю! Вы добавили карту Google в приложение Android Kotlin и применили для нее стиль.

Документация разработчика Android:

Справочная документация:

Ссылки на другие кодовые лаборатории в этом курсе см. На целевой странице Advanced Android in Kotlin codelabs .