本文概述
要在Android应用程序中实现Google Map, 我们需要生成Google Map API密钥。 Google Map Fixed Location教程中介绍了创建Google Map API密钥的过程。
在Kotlin Android Google Map固定位置的上一教程中, 我们显示了Google固定位置。
现在, 在本教程中, 我们将显示标记并将其放置在用户的当前位置。要查看用户的当前位置, 我们需要实现一些Google Map接口并在其中调用回调方法。
Google Map API介面
- OnMapRreadyCallback:当在MapFragment对象上设置其实例时, 调用此接口。准备使用地图时, 将调用OnMapReadyCallback接口的onMapReady(GoogleMap)方法。在onMapReady(GoogleMap)方法中, 我们可以添加标记, 侦听器和其他属性。
- LocationListener:当设备位置更改时, 此接口用于接收通知。位置更改后, 将调用LocationListener接口的onLocationChanged(Location)抽象方法。
- GoogleApiClient.ConnectionCallbacks:此接口提供了分别在设备连接和断开连接时调用的onConnected(Bundle)和onConnectionSuspended(int)回调方法。
- GoogleApiClient.OnConnectionFailedListener:此接口提供了回调方法onConnectionFailed(ConnectionResult), 当将设备连接到服务时发生错误时将调用该方法。
GoogleMap的isLocationEnabled属性用于启用位置图层, 该图层允许设备与当前位置进行交互。
Android用Java Map显示当前位置介绍了使用Java显示Google Map用户当前位置的教程。
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.srcmini02.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
在build.gradle文件中添加Google Map Service和Google Location Service依赖项。
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.srcmini02.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.srcmini02.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.srcmini02.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>
输出:
评论前必须登录!
注册