Android Google Map в Kotlin: Фиксированное и текущее местоположение

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

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

Kotlin Android Google Map Выбор действия

Чтобы реализовать Google Map, нам нужно сгенерировать ключ API Google Map и интегрировать его в наше приложение.

Скопируйте URL-адрес из файла res/values/google_map_api.xml и вставьте его в браузер, или можно напрямую посетить консоль Google Developer, чтобы сгенерировать ключ Google Map API.

Копирование URL-адрес из файла
Сгенерировать ключ Google Map API

Нажмите «Создать ключ API», чтобы сгенерировать ключ API.

Создать ключ API

После нажатия на «Создать ключ API» будет сгенерирован наш ключ API, отображающий следующий экран.

API ключ создан

Вставьте сгенерированный ключ API в наш файл res/values/google_map_api.xml.

Вставка сгенерированного ключа

activity_maps.xml

Добавьте следующий код в файл макета activity_maps.xml.

<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="example.javatpoint.com.kotlingooglemap.MapsActivity" /> 

build.gradle

Добавьте зависимости Google Map Service и Google Location Service в файл build.gradle.

 
dependencies { 
    implementation fileTree(include: ['*.jar'], dir: 'libs') 
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 
    implementation 'com.android.support:appcompat-v7:26.1.0' 
    implementation 'com.google.android.gms:play-services-maps:11.8.0' 
    implementation 'com.google.android.gms:play-services-location:11.8.0' 
    testImplementation 'junit:junit:4.12' 
} 

strings.xml

<resources>  
    <string name="app_name">Kotlin Google Map</string>  
    <string name="title_activity_maps">Map Fixed Location</string>  
</resources>

google_map_api.xml

Поместите ключ Google Map API в файл res/values/google_map_api.xml.

<resources>  
    <!--  
     Follow the directions here:  
  
    https://developers.google.com/maps/documentation/android/signup  
  
    Once you have your key (it starts with "AIza"), replace the "google_maps_key"  
    string in this file.  
    -->  
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyCmTF-n-REPLACE-WITH-YOUR-KEY</string>  
</resources>

MapsActivity.kt

Чтобы получить объект GoogleMap в нашем классе MapsActivity.kt, нам нужно реализовать интерфейс OnMapReadyCallback и переопределить метод обратного вызова onMapReady(). Чтобы отобразить местоположение исправления на карте, поместите точку широты и долготы в LatLng(широта, долгота).

GoogleMap.addMarker() указывает местоположение данного объекта.

 
package example.javatpoint.com.kotlingooglemap 
 
import android.os.Bundle 
import android.support.v7.app.AppCompatActivity 
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.Marker 
import com.google.android.gms.maps.model.MarkerOptions 
 
class MapsActivity : AppCompatActivity(), OnMapReadyCallback,  GoogleMap.OnMarkerClickListener { 
 
    private lateinit var mMap: GoogleMap 
 
    override fun onCreate(savedInstanceState: Bundle?) { 
        super.onCreate(savedInstanceState) 
        setContentView(R.layout.activity_maps) 
        // 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 India and move the camera 
        val myLocation = LatLng(20.5937, 78.9629) 
        mMap.addMarker(MarkerOptions().position(myLocation).title("Marker in India")) 
        mMap.moveCamera(CameraUpdateFactory.newLatLng(myLocation)) 
        mMap.uiSettings.isZoomControlsEnabled = true 
    } 
    override fun onMarkerClick(p0: Marker?) = false 
 
} 

AndroidManifest.xml

Добавьте в файл AndroidManifest.xml.

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="example.javatpoint.com.kotlingooglemap">  
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
  
    <application  
        android:allowBackup="true"  
        android:icon="@mipmap/ic_launcher"  
        android:label="@string/app_name"  
        android:roundIcon="@mipmap/ic_launcher_round"  
        android:supportsRtl="true"  
        android:theme="@style/AppTheme">  
  
        <meta-data  
            android:name="com.google.android.geo.API_KEY"  
            android:value="@string/google_maps_key" />  
  
        <activity  
            android:name=".MapsActivity"  
            android:label="@string/title_activity_maps">  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  
  
                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
        </activity>  
    </application>  
  
</manifest>

Выход:

Вывод фиксированного местоположения

MapsActivity.kt

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

 
package example.javatpoint.com.kotlingooglemap 
 
import android.Manifest 
import android.content.pm.PackageManager 
import android.os.Build 
import android.os.Bundle 
import android.support.v4.app.ActivityCompat 
import android.support.v4.app.FragmentActivity 
import android.widget.Toast 
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.Marker 
import com.google.android.gms.maps.model.MarkerOptions 
 
class MapsActivity : FragmentActivity(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener  { 
 
    private lateinit var mMap: GoogleMap 
 
    companion object { 
        private val MY_PERMISSION_FINE_LOCATION = 101 
    } 
    override fun onCreate(savedInstanceState: Bundle?) { 
        super.onCreate(savedInstanceState) 
        setContentView(R.layout.activity_maps) 
        // 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) 
    } 
 
    override fun onMapReady(googleMap: GoogleMap) { 
        mMap = googleMap 
 
        // Add a marker in India and move the camera 
        val india = LatLng(20.5937, 78.9629) 
        mMap.addMarker(MarkerOptions().position(india).title("Marker in India")) 
        mMap.moveCamera(CameraUpdateFactory.newLatLng(india)) 
 
        if(ActivityCompat.checkSelfPermission(this, 
                        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
                 mMap.isMyLocationEnabled = true 
        } 
        else {//condition for Marshmello and above 
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
                requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), MY_PERMISSION_FINE_LOCATION) 
            } 
        } 
        mMap.setOnMarkerClickListener(this) 
    } 
    override fun onMarkerClick(p0: Marker?) = false 
     
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { 
        super.onRequestPermissionsResult(requestCode, permissions, grantResults) 
        when(requestCode) { 
            MY_PERMISSION_FINE_LOCATION -> if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {//permission to access location grant 
                if(ActivityCompat.checkSelfPermission(this, 
                                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
                    mMap.isMyLocationEnabled = true 
                } 
            } 
            //permission to access location denied 
            else { 
                Toast.makeText(applicationContext, "This app requires location permissions to be granted", Toast.LENGTH_LONG).show() 
                finish() 
            } 
        } 
    } 
 
} 

Вывод:

Вывод 1
Вывод 2

Текущее местоположение

Чтобы внедрить Google Map в приложение для Android, нам нужно сгенерировать ключ Google Map API. Процесс создания ключа Google Map API описан в разделе по фиксированному местоположению Google Map выше.

Теперь в этом уроке мы будем отображать и размещать маркер в текущем местоположении пользователя. Чтобы просмотреть текущее местоположение пользователя, нам нужно реализовать некоторые интерфейсы Google Map и вызвать там методы обратного вызова.

API-интерфейс карт Google

  1. OnMapRreadyCallback: этот интерфейс вызывается, когда его экземпляр установлен в объекте MapFragment. Метод onMapReady(GoogleMap) интерфейса OnMapReadyCallback вызывается, когда карта готова к использованию. В методе onMapReady(GoogleMap) мы можем добавить маркеры, прослушиватели и другие атрибуты.
  2. LocationListener: этот интерфейс используется для получения уведомления об изменении местоположения устройства. Абстрактный метод onLocationChanged(Location) интерфейса LocationListener вызывается при изменении местоположения.
  3. GoogleApiClient.ConnectionCallbacks: этот интерфейс предоставляет методы обратных вызовов onConnected(Bundle) и onConnectionSuspended(int), которые вызываются при подключении и отключении устройства соответственно.
  4. GoogleApiClient.OnConnectionFailedListener: этот интерфейс предоставляет метод обратных вызовов onConnectionFailed(ConnectionResult), который вызывается при возникновении ошибки при подключении устройства к службе.

Свойство isLocationEnabled GoogleMap используется для включения слоя местоположения, который позволяет устройству взаимодействовать с текущим местоположением.

Учебное пособие с использованием Java для отображения текущего местоположения пользователя Google Map описано в Android Google Map Displaying Current Location.

Типы карт Google

В Map API доступны четыре различных типа карт Google. Каждый из них имеет различный вид карты. Эти типы: Нормальный, Гибридный, Спутниковый и Ландшафтный.

  • googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
  • googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
  • googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
  • googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);

Используя синтаксис Kotlin, мы будем использовать указанные выше типы карт Google как:

  • googleMap.mapType = MAP_TYPE_NONE
  • googleMap.mapType = MAP_TYPE_HYBRID
  • googleMap.mapType = MAP_TYPE_SATELLITE
  • googleMap.mapType = MAP_TYPE_TERRAIN

Подробности об этих типах карт объясняются здесь.

activity_maps.xml

Добавьте следующий код в файл макета activity_maps.xml.

 <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="example.javatpoint.com.kotlingooglemapcurrentlocation.MapsActivity" />
 

strings.xml

<resources>  
    <string name="app_name">Kotlin Google Map Current Location</string>  
    <string name="title_activity_maps">Map Current Location</string>  
</resources> 

build.gradle

Добавьте зависимости Google Map Service и Google Location Service в файл build.gradle.

 
dependencies { 
    implementation fileTree(dir: 'libs', include: ['*.jar']) 
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 
    implementation 'com.android.support:appcompat-v7:26.1.0' 
    implementation 'com.google.android.gms:play-services-maps:11.8.0' 
    compile 'com.google.android.gms:play-services-location:11.8.0' 
    testImplementation 'junit:junit:4.12' 
} 

google_maps_api.xml

Поместите ключ Google Map API в файл res/values/google_map_api.xml.

<resources>  
    <!--  
     https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=20:0B:71:3B:B2:46:75:A1:87:78:2E:4C:49:3F:E3:B6:FD:2D:76:D3%3Bexample.javatpoint.com.kotlingooglemapcurrentlocation  
  
    Alternatively, follow the directions here:  
    https://developers.google.com/maps/documentation/android/start#get-key  
    -->  
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyCuxsZ0D73o-REPLACE-WITH-YOUR-API</string>  
</resources> 

MapsActivity.kt

Добавьте следующий код в файл класса MapsActivity.kt.

 
package example.javatpoint.com.kotlingooglemapcurrentlocation 
 
import android.content.pm.PackageManager 
import android.location.Location 
import android.os.Build 
import android.os.Bundle 
import android.support.v4.app.FragmentActivity 
import android.support.v4.content.ContextCompat 
import com.google.android.gms.common.ConnectionResult 
import com.google.android.gms.common.api.GoogleApiClient 
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.BitmapDescriptorFactory 
import com.google.android.gms.maps.model.LatLng 
import com.google.android.gms.maps.model.Marker 
import com.google.android.gms.maps.model.MarkerOptions 
import android.Manifest 
import android.os.Looper 
import android.widget.Toast 
import com.google.android.gms.location.* 
import com.google.android.gms.location.FusedLocationProviderClient 
import com.google.android.gms.location.LocationCallback 
import com.google.android.gms.location.LocationRequest 
import com.google.android.gms.location.LocationServices 
 
 
class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener, 
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { 
 
    private var mMap: GoogleMap? = null 
    internal lateinit var mLastLocation: Location 
    internal lateinit var mLocationResult: LocationRequest 
    internal lateinit var mLocationCallback: LocationCallback 
    internal var mCurrLocationMarker: Marker? = null 
    internal var mGoogleApiClient: GoogleApiClient? = null 
    internal lateinit var mLocationRequest: LocationRequest 
    internal var mFusedLocationClient: FusedLocationProviderClient? = null 
 
 
    override fun onCreate(savedInstanceState: Bundle?) { 
        super.onCreate(savedInstanceState) 
        setContentView(R.layout.activity_maps) 
        // 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) 
 
    } 
 
    override fun onMapReady(googleMap: GoogleMap) { 
        mMap = googleMap 
 
        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
            if(ContextCompat.checkSelfPermission(this, 
                            Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
                buildGoogleApiClient() 
                mMap!!.isMyLocationEnabled = true 
            } 
        } else { 
            buildGoogleApiClient() 
            mMap!!.isMyLocationEnabled = true 
        } 
 
    } 
 
    @Synchronized 
    protected fun buildGoogleApiClient() { 
        mGoogleApiClient = GoogleApiClient.Builder(this) 
                .addConnectionCallbacks(this) 
                .addOnConnectionFailedListener(this) 
                .addApi(LocationServices.API).build() 
        mGoogleApiClient!!.connect() 
    } 
 
    override fun onConnected(bundle: Bundle?) { 
 
        mLocationRequest = LocationRequest() 
        mLocationRequest.interval = 1000 
        mLocationRequest.fastestInterval = 1000 
        mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY 
        if(ContextCompat.checkSelfPermission(this, 
                        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this) 
            mFusedLocationClient?.requestLocationUpdates(mLocationRequest,mLocationCallback, Looper.myLooper()) 
        } 
    } 
 
 
    override fun onLocationChanged(location: Location) { 
 
        mLastLocation = location 
        if(mCurrLocationMarker != null) { 
            mCurrLocationMarker!!.remove() 
        } 
        //Place current location marker 
        val latLng = LatLng(location.latitude, location.longitude) 
        val markerOptions = MarkerOptions() 
        markerOptions.position(latLng) 
        markerOptions.title("Current Position") 
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)) 
        mCurrLocationMarker = mMap!!.addMarker(markerOptions) 
 
        //move map camera 
        mMap!!.moveCamera(CameraUpdateFactory.newLatLng(latLng)) 
        mMap!!.animateCamera(CameraUpdateFactory.zoomTo(11f)) 
 
        //stop location updates 
        if(mGoogleApiClient != null) { 
            mFusedLocationClient?.removeLocationUpdates(mLocationCallback) 
        } 
    } 
 
    override fun onConnectionFailed(connectionResult: ConnectionResult) { 
        Toast.makeText(applicationContext,"connection failed", Toast.LENGTH_SHORT).show() 
    } 
 
    override fun onConnectionSuspended(p0: Int) { 
        Toast.makeText(applicationContext,"connection suspended", Toast.LENGTH_SHORT).show() 
    } 
}   

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="example.javatpoint.com.kotlingooglemapcurrentlocation">  
  
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
  
    <application  
        android:allowBackup="true"  
        android:icon="@mipmap/ic_launcher"  
        android:label="@string/app_name"  
        android:roundIcon="@mipmap/ic_launcher_round"  
        android:supportsRtl="true"  
        android:theme="@style/AppTheme">  
   
        <meta-data  
            android:name="com.google.android.geo.API_KEY"  
            android:value="@string/google_maps_key" />  
  
        <activity  
            android:name=".MapsActivity"  
            android:label="@string/title_activity_maps">  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  
  
                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
        </activity>  
    </application>  
  
</manifest> 

Вывод:

Примечание. Проверьте это на реальном устройстве Android для получения наилучшего результата вывода.

Текущее местоположение - вывод

Оцените статью