Android接入google地图
1.注册一个Google 帐号2.需要一个可以美元扣款的信用卡3.登录Google帐号,访问Google Cloud谷歌云的网站 cloud.google.com,之后点击蓝色按钮 免费开始使用,按提示注册即可。
Android接入google地图
- 创建谷歌云结算账户
1.注册一个Google 帐号
2.需要一个可以美元扣款的信用卡
3.登录Google帐号,访问Google Cloud谷歌云的网站 cloud.google.com,之后点击蓝色按钮 免费开始使用,按提示注册即可。
示例源代码:
git@github.com:sueleeyu/android-maps.git
二、控制台创建Project
1.进入谷歌云控制台,创建项目:
https://console.cloud.google.com/projectselector2/home/dashboard
2.创建凭证:选择创建的项目,点击左上角图标,创建该项目凭据
3.输入包名和证书指纹
在android studio控制台输入:
keytool -list -printcert -jarfile F:\...\app-release.apk //apk位置
可以获取指纹
4.选择api库
5.选择android sdk
6.启用:
三、创建android studio项目
1.新建空白android工程
2.添加google play service:File-Setting-Google Play service。
3.在app的build.gradle的dependencies添加:
implementation 'com.google.android.gms:play-services-maps:18.0.2'
implementation 'com.google.android.gms:play-services-location:19.0.1'
4.strings.xml中添加谷歌云控制台生成的appKey:
<string name="google_map_key">AIzaSyBY…gLc</string>
5.在AndroidManifest.xml中添加meta-data:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_map_key" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
6. 在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
7.添加如下fragment到activity_main.xml,运行demo。
<fragment
android:id="@+id/mapview"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
四、定位功能接入
1.MainActivity实现OnMapReadyCallback接口
2. onCreate中添加代码getMapAsync
3. onMapReady回调中动态申请权限,然后调用定位,显示地图
package com.suelee.maps
import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.location.Location
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Looper
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.location.*
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.*
class MainActivity : AppCompatActivity(), OnMapReadyCallback {
//定位client
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
private var map:GoogleMap? = null
private var currentLocation : Location? = null
//当前定位marker点
private var currentMarker: Marker? = null
val REQUEST_PHOTO_CODE = 3002 //获取权限
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
val mapFragment : SupportMapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
@SuppressLint("MissingPermission")
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
googleMap.mapType = GoogleMap.MAP_TYPE_HYBRID
val permission = arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
requestPermission(permission, REQUEST_PHOTO_CODE)
googleMap.isIndoorEnabled = true
}
@SuppressLint("MissingPermission")
private fun startLocationUpdates(){
fusedLocationProviderClient.requestLocationUpdates(
LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)//设置高精度
.setInterval(3000), //3秒一次定位请求
locationCallback,
Looper.getMainLooper())
}
//定位回调
private val locationCallback = object : LocationCallback(){
override fun onLocationResult(locationResult: LocationResult) {
for (location in locationResult.locations){
drawLocationMarker(location, LatLng(location.latitude,location.longitude))
}
}
}
@SuppressLint("NewApi")
private fun drawLocationMarker(location: Location, latLng: LatLng) {
if (currentLocation == null){//第一次定位画定位marker
currentMarker = map?.addMarker(
MarkerOptions()
.position( latLng).title("Marker")
//.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_vehicle_location))
)
map?.moveCamera(
CameraUpdateFactory.newLatLngZoom(
latLng,14f
))
}else{
val deltaTime = location.time - currentLocation!!.time
//有方位精度
if (location.hasBearingAccuracy()){
if (deltaTime <= 0){
map?.animateCamera(CameraUpdateFactory.newCameraPosition(
CameraPosition.Builder()
.target(latLng)
.zoom(map?.cameraPosition!!.zoom)
.bearing(location.bearing)
.build()
))
}else{
map?.animateCamera(CameraUpdateFactory.newCameraPosition(
CameraPosition.Builder()
.target(latLng)
.zoom(map?.cameraPosition!!.zoom)
.bearing(location.bearing)
.build()
), deltaTime.toInt(),null)
}
currentMarker?.rotation = 0f
}else{
if (deltaTime <= 0){
map?.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,map?.cameraPosition!!.zoom))
}else{
map?.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,map?.cameraPosition!!.zoom), deltaTime.toInt(), null)
}
//设置marker的指针方向
currentMarker?.rotation = location.bearing - (map?.cameraPosition?.bearing ?:0f)
}
}
currentLocation = location
}
private fun stopLocationUpdates(){
fusedLocationProviderClient.removeLocationUpdates(locationCallback)
}
override fun onDestroy() {
super.onDestroy()
stopLocationUpdates()
}
///----------
/**
* 动态获权
* */
/**
* 动态获权请求值
*/
private var REQUEST_CODE_PERMISSION = 0x00099
protected val TAG = this.javaClass.simpleName
/**
* 请求权限
* 动态获权
* @param permissions 请求的权限
* @param requestCode 请求权限的请求码
*/
open fun requestPermission(
permissions: Array<String>,
requestCode: Int
) {
REQUEST_CODE_PERMISSION = requestCode
if (checkPermissions(permissions)) {
permissionSuccess(REQUEST_CODE_PERMISSION)
} else {
try {
val needPermissions =
getDeniedPermissions(permissions)
ActivityCompat.requestPermissions(
this,
needPermissions.toTypedArray(),
REQUEST_CODE_PERMISSION
)
} catch (e: Exception) {
Log.e("BaseActivity", "获取权限失败 Exception = $e")
}
}
}
/**
* 检测所有的权限是否都已授权
*/
fun checkPermissions(permissions: Array<String>): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true
}
for (permission in permissions) {
if (ContextCompat.checkSelfPermission(
this,
permission
) != PackageManager.PERMISSION_GRANTED
) {
return false
}
}
return true
}
/**
* 获取权限集中需要申请权限的列表
*/
fun getDeniedPermissions(permissions: Array<String>): List<String> {
val needRequestPermissionList: MutableList<String> =
ArrayList()
for (permission in permissions) {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED ||
ActivityCompat.shouldShowRequestPermissionRationale(this, permission)
) {
needRequestPermissionList.add(permission)
}
}
return needRequestPermissionList
}
/**
* 系统请求权限回调
*/
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_CODE_PERMISSION) {
if (verifyPermissions(grantResults)) {
permissionSuccess(REQUEST_CODE_PERMISSION)
} else {
permissionFail(REQUEST_CODE_PERMISSION)
}
}
}
/**
* 确认所有的权限是否都已授权
*/
fun verifyPermissions(grantResults: IntArray): Boolean {
for (grantResult in grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
return false
}
}
return true
}
/**
* 获取权限成功
*/
open fun permissionSuccess(requestCode: Int) {
Log.e(TAG, "获取权限成功=$requestCode")
startLocationUpdates()
}
/**
* 权限获取失败
*/
open fun permissionFail(requestCode: Int) {
Log.e(TAG, "获取权限失败=$requestCode")
}
}
4.运行,真机需要安装google 服务才可以,国内手机基本不行。
五、常见问题
1.manifest merger faild:Apps targeting Android 12 and higher are required to specify an explicit…
解决:根据提示在AndroidManifest.xml文件中给activity添加: android:exported="true"
六、参考文献
1. Google官方文档:
https://developers.google.com/maps/documentation/android-api/map?hl=zh-cn
2. Google官方文档
https://developers.google.com/maps/documentation/android-sdk/config?hl=zh-cn
3. Android使用GoogleMap实现定位及定位回正_Tobey_r1的博客-CSDN博客_google map 定位
4. https://blog.51cto.com/u_15360378/3808483
5. 示例源代码:
git@github.com:sueleeyu/android-maps.git
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)