Android接入google地图

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

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值