Освой Android играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Шаблон Google Maps Activity

Вместо предисловия

В Мурманске (очень красивое название города для кошачьего уха, мур-мур) открыли памятник коту Семёну – герою местной легенды. В бронзе увековечили домашнего кота, который шесть с половиной лет шёл на север из Москвы, где его потеряли хозяева-идиоты.

Кот Семён

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

В настоящее время API содержит векторные карты, которые быстрее загружаются, а также позволяют пользователям легко переключаться между 2D и 3D режимами, в которых карты можно вращать при помощи жестов.

С картами вообще происходят постоянные перемены. Сначала объявили устаревшими старые карты. Чтобы установить новые карты, требовалось написать отдельную статью, как скачать и установить библиотеку, как сгенерировать ключ в командной строке. К счастью, в Android Studio появился новый шаблон, который позволил избавиться от лишних слов и кода. Это уже пятое масштабное переписывание статьи.

Шаблон Google Maps Activity

Запускаем новый проект и в шаблонах выбираем Google Maps Activity.

В следующем шаге делаем необходимые настройки.

Для работы с картами нужен ключ. Раньше был сложный вариант создания и хранения ключа в xml-файле. Сейчас процесс немного упростился.

Откройте файл манифеста. В нём содержится инструкция для получения ключа. Перейдите по ссылке в комментариях файла и получите ключ. Он должен начинаться на AIza.

Откройте файл local.properties и добавьте новую строку.


MAPS_API_KEY=AIza...

Возвращаемся в манифест и редактируем блок .


<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="YOUR_API_KEY" />
    android:value="${MAPS_API_KEY}" />

В шаблоне в манифесте не прописаны разрешения. Но возможно для каких-то вещей добавлять разрешения придётся, например, ACCESS_FINE_LOCATION.


<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Ручная подготовка

Если вы использовали другой шаблон или готовый проект, то необходимо проделать некоторые операции вручную.

Сначала нужно поставить плагин Secrets Gradle Plugin for Android. Для установки плагина в файле build.gradle уровня проекта добавьте в элемент dependencies, принадлежащий элементу buildscript, следующее.


buildscript {
    dependencies {
        classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0"
    }
}

В build.gradle модуля прописываем идентификатор плагина.


plugins {
    ...
    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}

Там же прописываем зависимость для библиотеки для работы с картами:


implementation 'com.google.android.gms:play-services-maps:18.0.2'

После этого мы получаем ключ и добавляем его в local.properties, как это было описано выше.

Знакомство с проектом

На этом предварительная подготовка завершена. Можно запустить проект. Если версия Сервисы Google Play устарела, то на экране появится кнопка Обновить. Если на устройстве свежая версия, то запустится пример с картой.

В текущей версии шаблона указаны координаты Сиднея, Австралия. Нажав на маркер, вы увидите всплывающий текст Marker in Sydney. Карту можно увеличивать двойным щелчком, а также сдвигать/раздвигать пальцами.

Познакомимся поближе с проектом. Для разметки используется фрагмент с классом Для разметки используется фрагмент с классом com.google.android.gms.maps.SupportMapFragment.


<?xml version="1.0" encoding="utf-8"?>
<fragment 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapsActivity" />

Код активности.


import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import ru.alexanderklimov.googlemapskot.databinding.ActivityMapsBinding

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

    private lateinit var mMap: GoogleMap
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap

        // Add a marker in Sydney and move the camera
        val sydney = LatLng(-34.0, 151.0)
        mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
    }
}

Класс MapsActivity наследуется от AppCompatActivity и использует интерфейс OnMapReadyCallback.

В методе onCreate() получаем доступ к фрагменту и загружаем карту в асинхронном режиме через метод getMapAsync().

Метод onMapReady() является частью интерфейса OnMapReadyCallback. В этом методе можно писать код, когда карта готова к использованию. В примере добавляется маркер (метод addMarker()) в указанной точке (через объект LatLng) с указанием текста (метод title()). Метод moveCamera() перемещает карту в указанную позицию и мы можем видеть сразу нужное место.

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


mMap.addMarker(MarkerOptions()
    .position(sydney).title("Marker in Sydney")
    .snippet("В Сиднее много котов"))

Подсказка появляется под описанием маркера с другим цветом. Если на карте должно быть несколько маркеров, то просто вызываете методы addMarker() несколько раз с разными параметрами.

Sydney

Дополнительное чтение

Обсуждение урока на форуме

Google Maps. Другие настройки карты

Google Maps. Продвинутые приёмы

Документация по Google Map

Реклама