Android使用GoogleMap实现定位与路径检索功能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ww897532167/article/details/80455534

本文是作者在学习使用Google Map 时的学习笔记,采用的是Kotlin语言编写。


1. Google Map定位

1.1 API KEY创建

1.1.1 手动创建

  1. 打开网址:https://cloud.google.com/maps-platform/ 登陆后点击右上角 控制台 按钮
    这里写图片描述
  2. 进入控制台后 点击顶部左侧按钮 选择项目 按钮
    这里写图片描述
  3. 有项目则选择项目打开,跳至第5步,无项目则新建项目后继续第4步
    这里写图片描述
  4. 新建项目Map Project Test
    这里写图片描述
  5. 管理项目支持的API与服务,选择左侧 API与服务 然后点击 按钮
    这里写图片描述
  6. 地图API与服务列表,可以全部开启,在本文中用到了Maps SDK for Android,Maps JavaScript API
    在上文Android使用Google定位服务定位并将经纬度转换为详细地址信息 会用到 Places API
    这里写图片描述
  7. 点击 Maps SDK for Android 然后启用开服务
    这里写图片描述
  8. 项目API与服务的凭据,选择左侧 API与服务 然后点击 凭据 按钮,在点击新建凭据,选择API密钥
    这里写图片描述
  9. 生成API KEY
    这里写图片描述
    Google Map 所需要的密钥就生成了,如果想要限制密钥的使用,点击限制密钥按钮即可进行设置,在此我不进行设置,这个API KEY AIzaSyBAQIaEYapcR4kCFPt4735cM-Z0ZQDCv14所有人所有项目都可以使用。
  10. 限制密钥,在生成密钥的时候可以点击限制密钥按钮,在 API和服务 凭据栏 可以编辑密钥 进行限制密钥操作。
    这里写图片描述

1.1.2 Android Studio创建

如果嫌弃上面步骤繁琐,可以在创建项目的时候,直接创建Google Maps Activity 然后找到
app\src\debug\res\values\google_maps_api.xml 打开XML文件中列出的URL链接,即可自动创建一个仅供当前APP使用的API KEY。
这里写图片描述
这里写图片描述

1.2 基础地图展示

在创建API KEY的时候,采用方式二创建,然后将生成的API KEY 填入
debug\res\values\google_maps_api.xmlrelease\res\values\google_maps_api.xml 文件中。
运行App即可展示基础地图,代码就不贴了,简单说下几个地方的变化
1 app的 build.gradle 添加了依赖

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

2 debug 与 release文件
3 AndroidManifest.xml 文件中添加了以下内容

 <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />
  <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

1.3 定位功能

查看上一篇文章:Android使用Google定位服务定位并将经纬度转换为详细地址信息
在上文的基础上,进行简单的修改。地图初始化后开始获取位置信息,得到位置信息后,将地图中心移动到当前位置即可

class MapLocationActivity : AppCompatActivity() {
    private var googleMap: GoogleMap? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this::onMapReady)
    }

    private fun onMapReady(map: GoogleMap) {
        googleMap = map
        //此处进行权限申请,位置信息获取 调用 自己编写的 requestLocationPermission() 方法
    }
}

修改上文中的handleLocation(location: Location)方法

    @SuppressLint("MissingPermission")
    private fun handleLocation(location: Location) {
        val map = googleMap ?: return
        map.isMyLocationEnabled = true
        map.uiSettings.isMyLocationButtonEnabled = true
        val latLng = LatLng(location.latitude, location.longitude)
        //地图中心位置移动到定位位置,并设置地图缩放等级15
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f))
        //定位成功后可停止获取位置更新
        stopLocationUpdates()
    }

详细代码:MapLocationActivity

2. Google Map路线规划

2.1 路径信息获取

Google Map 并没有直接给出路径规划的方法,但可以使用Polyline绘制折线。
官方文档:https://developers.google.com/maps/documentation/android-sdk/shapes
然后路线信息获取可以通过HTTP请求Google Map Web Sevice 下的 Directions API
获取到。
URL示例:https://maps.googleapis.com/maps/api/directions/json?origin=成都&destination=深圳&language=zh-CN
或者采用经纬度做参数
https://maps.googleapis.com/maps/api/directions/json?origin=30.5702000000,104.0647600000&destination=22.5428600000,114.0595600000&language=zh-CN
更多参数以及数据字段信息请查看API官方文档
官方文档:https://developers.google.com/maps/documentation/directions/intro
JSON示例(数据为成都到深圳,使用mode = driving的路线规划):
这里写图片描述
JSON 数据中 routes 对应路线信息,legssteps字段对应整个行程路线的步骤 json如下
这里写图片描述
但如果只是绘制路线,我们可以获取 overview_polyline 中的内容,可以发现这个字段 与地图路线相关的类 Polyline 对应。

2.2 Map绘制路径

在这里网络请求以及JSON解析就不写了,HTTP 请求2.1中给出的示例URL,获取到返回的JSON 然后解析我们需要的字段 overview_polyline 对应的的数据来绘制路线。
此处需要介绍一个库 Google Maps Android API Utility Library,在此 需要库中的提供的方法将我们获取的路径信息 解码 路线绘制代码如下:

class MapLocationActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this::onMapReady)
    }

    private fun onMapReady(map: GoogleMap) {
        val line = "agryDundzRnXibE~yM{lBlyXaM|}O{y@`_SgrIb_OamDnpOmkA`bSseJ" +
                "jyTe|MlqHsgKpfBw|If`F}kBpiFefCp}EgeDdpO{uHjsIe`QnnHcy_@nmKk}Et`NsaMlsQisVbqJq" +
                "iTreNciY~eKcmSxkI{vOlnKonHtmZqwNr{PwtJ~pK_vDlfI}sQvwB}sLzeHodLvhEboBdbCcUzmApl" +
                "CniDaUr}CoyDzyCtDxmFkxDzi@kpJfgC_~EtcApt@hbA}fDuy@ycEpnAwgDkcC}lBjqDgsKpdDmqIx" +
                "d@_iIlbCawB`}AqoD|nBw`DjcGebAxnGjyA~jOv|@vpCyoB~oJcJf_InaAfcCl~BriInj@flAklCtk" +
                "GuxD`lHsqBxhDu~D~~Em{Nx_@gtH_`BkzVll@}eIomBy`GzaDemDdsD~rBnmOd}HxrMvjD~wGbVtuEe" +
                "hBjkLx`DhkKflDlwE`A`zBtfCd_KuWz_Jrj@ptDnqA|mMkVnsL}iAvkL`|AnyJ{LvdBd_@nyB{rHjzG" +
                "ijC~tDsm@dkFwzAbrHi_D~uAjqC||C{pFxkEg|SdpDgoZjmIikPleFo~LlmEqjN~eBm~VxnJk~OvcFo" +
                "dJjWwdKxoFae`@~yEe~Hfo@ckMxyG_nSnrLii_@r_CmxOtzGaoRlxBauJ`LifN~`D}uE_ZuyHmr@o|I" +
                "mfCsh\\giEmuIkeAkyLhmC_u\nwAkd\ti@ugSxqG{uf@npD_jFsvAkhMsvCkuIlyAehFqt@wlMzvEs_G" +
                "h`EiePr`DgcLbiCmfExgJ|lAtlk@upH~gRo`C`jGuoCnmFolCnvEhpExpFd{@fgDyt@xqJ{rRjqE}xD" +
                "`xIosB|hQktGzbQa{EnxG_|FfuJwdG|qFsvBye@}fFhkBqaM~fGulPwZe_\\dt@g`IzfDsrFx`FmpCf|A" +
                "qyEhxE{eJ`_BwjGpbIuzF`cHm`Ixz@yfEbwCarDcnBuzNbgFolk@uIooW`pLouAd`L{`B`dP}rEfyK}x" +
                "Bx~FinFx{D{cKxc@amGfzA_qHnbBghSlk@_gN`gHyfFbbN{jJnvKafKv_OkgA~bFefBlrDgvGbdHipFr}" +
                "CuiH~pIs~Ip~JqtKndIidR~`@kgKrcDgqHpfRcnMrrCeoDlnG{|@|eD_`K|rBoeK|uAom\\wpFwlO``@wsO" +
                "ocAyeG~pBw|G_k@cvJbcFw|UfnNesNblGorHtwEam@vsLpuDppLqnErkBeaLpzCkuD~fImkHz|KnqBn" +
                "`Dyw@ryBcnDvoHmdI~gAywG~wBadOuRgp@"

        val decodedPath = PolyUtil.decode(line)  //来源Google Map Util
        val lineOptions = PolylineOptions().apply {
            addAll(decodedPath) //添加路线
            color(Color.GREEN)  //线条设置
            jointType(JointType.ROUND)
            width(15f)
        }
        map.addPolyline(lineOptions)
    }
}

效果图:
这里写图片描述
Google Maps Android API Utility 还有其他方便的工具,此处附上官方地址:
https://developers.google.com/maps/documentation/android-sdk/utility/
路径规划的线条设置也还有很多样式,此处附上介绍文档:
https://developers.google.com/maps/documentation/android-sdk/shapes#customizing_appearances

2.3 启用外部浏览器或地图APP实现路径规划与导航

很多时候我们自己的APP 内嵌地图只是需要获取定位信息,以及目的地信息,比较复杂路线规划以及导航功能,可以通过外部浏览器或Google地图APP来实现。
实现代码:

class MapLocationActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)
        startOtherMap.setOnClickListener {
            val url = Uri.parse(
                "https://www.google.com/maps/dir/?api=1&origin=" +
                        "30.5702000000,104.0647600000&destination=22.5428600000,114.0595600000"
            )
            val intent = Intent().apply {
                action = "android.intent.action.VIEW"
                data = url
            }
            startActivity(intent)
        }
    }
}

实现效果(在内嵌的地图的APP中,打开外部地图,并传递起始点):
这里写图片描述
附上启动外部浏览器或地图相关的官方文档链接:
https://developers.google.com/maps/documentation/urls/guide
附上代码链接:
https://github.com/897532167/GoogleMapDemo/blob/master/app/src/main/java/cn/xhuww/googlemapdemo/MapLocationActivity.kt

猜你喜欢

转载自blog.csdn.net/ww897532167/article/details/80455534