Расширенный 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 Console и зарегистрировать ключ в своем приложении
  • Как интегрировать карту Google в ваше приложение
  • Как отображать разные типы карт
  • Как оформить карту Google
  • Как добавить маркеры на карту
  • Как разрешить пользователю размещать маркер в точке интереса (POI)
  • Как включить отслеживание местоположения
  • Как создать приложение The Wander со встроенной картой Google
  • Как создавать пользовательские функции для вашего приложения, такие как маркеры и стили
  • Как включить отслеживание местоположения в вашем приложении

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

Maps SDK для Android требует ключ API. Чтобы получить ключ API, зарегистрируйте свой проект на странице API & Services . Ключ 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 .

  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. Следуйте инструкциям по созданию проекта на странице APIs & Services . Из-за параметров в указанном URL-адресе страница автоматически включает Maps SDK для 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. Запустите свое приложение. Вы должны увидеть встроенную карту в своей активности с маркером, установленным в Сиднее, Австралия. (Маркер Сиднея является частью шаблона, и вы измените его позже.)

Шаг 3: переименуйте mMap

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

  1. В MapsActivity щелкните правой кнопкой мыши mMap и выберите Рефакторинг > Переименовать...

  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 .
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. Нажмите изменить тип карты. Обратите внимание, как меняется внешний вид карты в разных режимах.

По умолчанию обратный вызов 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. Запустите свое приложение. Карта должна перемещаться к вашему дому, масштабироваться до нужного уровня и ставить маркер на ваш дом.

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

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

  1. Создайте заглушку метода в 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. Коснитесь маркера, который отцентрирует его на экране.

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

На этом шаге вы добавляете 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. Коснитесь маркера, чтобы открыть информационное окно.

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

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

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

  1. Создайте заглушку метода в 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 в информационном окне.

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

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

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

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

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

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

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

  1. Нажмите Готово .

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

Шаг 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 режим, и новый стиль должен быть виден в ретро-стиле и с дорогами выбранного вами цвета.

Шаг 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() .

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

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

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

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

  1. Загрузите этот образ Android и сохраните его в папке res/drawable . (Убедитесь, что имя файла — android.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 .

Задайте свойство position для объекта GroundOverlayOptions , вызвав метод position() , и передайте объект 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 на 18f, чтобы изображение Android отображалось как наложение.

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

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

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

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

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

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

  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 метод с именем 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. Запустите свое приложение. Должно появиться диалоговое окно с запросом доступа к местоположению устройства. Давай, дай разрешение.

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

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

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


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

Скачать zip

  • Чтобы использовать API Карт, вам нужен ключ API из Google API Console .
  • В Android Studio при использовании шаблона действий Google Maps создается действие с одним Activity в SupportMapFragment приложения. Шаблон также добавляет ACCESS_FINE_PERMISSION в манифест приложения, реализует OnMapReadyCallback в вашей деятельности и переопределяет требуемый onMapReady() .

Чтобы изменить тип карты GoogleMap во время выполнения, используйте метод GoogleMap.setMapType() . Карта Google может быть одним из следующих типов карт:

  • Обычный : типичная дорожная карта. Показаны дороги, некоторые объекты, построенные людьми, и важные природные объекты, такие как реки. Также видны метки дорог и объектов.
  • Гибрид : добавлены спутниковые фотографии с картами дорог. Также видны метки дорог и объектов.
  • Спутник : Данные фотографии. Надписи дорог и объектов не видны.
  • Рельеф : Топографические данные. Карта включает в себя цвета, контурные линии и метки, а также перспективное затенение. Также видны некоторые дороги и метки.
  • None : нет фрагментов базовой карты.

О картах Google:

  • Маркер — это индикатор для определенного географического местоположения.
  • При касании маркер по умолчанию отображает информационное окно с информацией о местоположении.
  • По умолчанию точки интереса (POI) отображаются на базовой карте вместе с соответствующими значками. 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 codelabs .