【Google Maps – DirectionsSDK-Integration】

Ich habe einige Informationen im Internet überprüft und festgestellt, dass es immer noch viele Artikel über die Google Maps SDK-Integration gibt, die jedoch nicht systematisch sind. Hier sind einige systematische Anordnungen, die hauptsächlich in die folgenden Abschnitte unterteilt sind, und ich hoffe, es wird Ihnen hilfreich sein, die die ersten Google Maps sind:

  1. 【Google Maps – Integrationsvorbereitung】
  2. [Google Maps – MapsSDK-Integration]
  3. [Google Maps – DirectionsSDK-Integration]
  4. [Google Maps – PlacesSDK-Integration]

Beginnen wir mit dem Text:

Aus bekannten Gründen müssen Ihr PC und Ihre mobilen Endgeräte vor der Integration des Google Maps SDK zunächst die Wand umgehen, da Sie sonst einige nachfolgende Funktionen nicht bedienen können.

Google Maps – DirectionsSDK-Integration

Bevor wir mit dem Text beginnen, hier eine Erklärung: Bei der Integration der Anfahrtsfunktion müssen Sie die Abrechnungsfunktion mit Ihrem Google Maps-Entwicklerkonto aktivieren. Um die Abrechnungsfunktion zu aktivieren, müssen Sie eine internationale Kreditkarte binden. Was! Ich habe keine internationale Kreditkarte, nur inländische funktionieren, die Antwort ist nein. Sofort fühlte ich mich 10.000 verärgert und integrierte die heimische Karte, es ist nicht so lästig! Aber keine Sorge, für Studenten, die die Abrechnungsfunktion nicht aktivieren können, werde ich Ihnen später eine Lösung zur Verfügung stellen, los geht's!
Bildschirmfoto:
Bildbeschreibung hier einfügen

Routenplanung

Reden wir nicht zu viel Quatsch, fangen wir mit den Renderings an:
Bildbeschreibung hier einfügen
Zunächst einmal ist klar, dass die Beschaffung dieser Streckeninformationen nicht mit der Einbindung heimischer Karten vergleichbar ist. Google Maps ist stattdessen eine HTTP-Get-Anfrage. Der Link ist wie folgt:

https://maps.googleapis.com/maps/api/directions/json?origin=Toronto&destination=Montreal&avoid=highways&mode=bicycling&key=your_api_kay

Sie können die offizielle Dokumentation sorgfältig lesen , um die Bedeutung der Übergabe von Parametern zu erfahren.Hier poste ich auch den Schlüsselcode:

 /**
     * 获取线路信息
     *
     * origin,destination :可是以下几种:位置ID,地址,字符串经纬度
     *
     * mode: driving  (默认)表示使用道路网络的标准行车路线。
     *       walking
     *       bicycling
     *       transit  通过公共交通路线(如果有)请求路线。如果将模式设置为transit,则可以选择指定departure_time或 arrival_time。
     *       如果未指定任何时间,则 departure_time默认为现在(即,出发时间默认为当前时间)。
     *       您还可以选择包含 transit_mode和和/或 transit_routing_preference。
     *
     * arrival_time:指定公交路线的理想到达时间
     * departure_time:指定所需的出发时间。
     *
     * waypoints:指定要在起点和终点之间的路径上包括的直通或中途停留位置的中间位置数组。航点通过将路线引导通过指定位置来更改路线
     * API支持以下行驶模式的航点:驾驶,步行和骑车;不中转。
     *
     * alternatives:如果设置为 true,则指定“方向”服务可以在响应中提供多个路线选择。
     * 请注意,提供路由选择可能会增加服务器的响应时间。这仅适用于没有中间航路点的请求。
     *
     * avoid: 表示计算出的路线应避开所指示的特征。highways 表示计算出的路线应避开高速公路。
     *
     * units:指定显示结果时要使用的单位制。有效值在下面的“单位系统”中指定 。
     *
     */
    private fun getLineInfo() {
    
    

        ViseHttp.GET("directions/json")
            .tag("tag1")
            .addParam("origin", strOrigin)
            .addParam("destination", strDestination)
            //.addParam("mode", "driving")

            .addParam(
                "waypoints",
                "$strWaypoints2"
            ) //航路点,最大允许数量 waypoints为25,加上起点和终点  $strWaypoints1|$strWaypoints2
            //.addParam("alternatives", "true") //如果设置为 true,这仅适用于没有中间航路点的请求。
            //.addParam("avoid", "tolls|highways|ferries")

            .addParam("key", Config.API_KAY)
            .request(object : ACallback<LineModule?>() {
    
    
                override fun onSuccess(mBean: LineModule?) {
    
    
                    //请求成功,AuthorModel为解析服务器返回数据的对象,可以是String,按需定义即可
                    dealWithData(mBean)
                }

                override fun onFail(errCode: Int, errMsg: String) {
    
    
                    //请求失败,errCode为错误码,errMsg为错误描述
                    Log.i(TAG, " errCode=${
      
      errCode} errMsg=$errMsg")
                }
            })
    }

Welche Art von Daten bekommen wir also? Hier poste ich die vollständigen JSON-Daten hier, damit jeder sie verwenden kann. Studenten, denen es unangenehm ist, die Abrechnungsfunktion zu aktivieren, können die JSON-Daten vollständig in ihre eigenen Projekte kopieren, die lokalen JSON-Daten lesen, die Datenanforderung simulieren und dann analysieren und die nachfolgende Anzeigeverarbeitung durchführen. Zur Bedeutung der einzelnen Rückgabeparameter siehe auch die offizielle Dokumentation .

JSON-Daten:

{
    
    
   "geocoded_waypoints" : [
      {
    
    
         "geocoder_status" : "OK",
         "place_id" : "ChIJy-z5i18alTURP4V2gaGOgZY",
         "types" : [ "establishment", "point_of_interest", "transit_station" ]
      },
      {
    
    
         "geocoder_status" : "OK",
         "place_id" : "ChIJyXsMpF0alTURAOY_NJyY1U8",
         "types" : [ "establishment", "point_of_interest" ]
      }
   ],
   "routes" : [
      {
    
    
         "bounds" : {
    
    
            "northeast" : {
    
    
               "lat" : 36.7065579,
               "lng" : 119.1854509
            },
            "southwest" : {
    
    
               "lat" : 36.7023932,
               "lng" : 119.1759237
            }
         },
         "copyrights" : "Map data ©2020",
         "legs" : [
            {
    
    
               "distance" : {
    
    
                  "text" : "1.5 公里",
                  "value" : 1515
               },
               "duration" : {
    
    
                  "text" : "4分钟",
                  "value" : 241
               },
               "end_address" : "中国山东省潍坊市奎文区胜利东街华都鲁成大厦",
               "end_location" : {
    
    
                  "lat" : 36.7065579,
                  "lng" : 119.1772408
               },
               "start_address" : "中国潍坊市奎文区健康街潍县中路口",
               "start_location" : {
    
    
                  "lat" : 36.7045897,
                  "lng" : 119.1854509
               },
               "steps" : [
                  {
    
    
                     "distance" : {
    
    
                        "text" : "37 米",
                        "value" : 37
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 7
                     },
                     "end_location" : {
    
    
                        "lat" : 36.7047135,
                        "lng" : 119.1851888
                     },
                     "html_instructions" : "向\u003cb\u003e北\u003c/b\u003e行驶",
                     "polyline" : {
    
    
                        "points" : "uz__FalmvUMBSHDVBL"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.7045897,
                        "lng" : 119.1854509
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "52 米",
                        "value" : 52
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 15
                     },
                     "end_location" : {
    
    
                        "lat" : 36.70426399999999,
                        "lng" : 119.1853314
                     },
                     "html_instructions" : "向\u003cb\u003e左\u003c/b\u003e转,前往\u003cb\u003e804省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e健康东街\u003c/b\u003e",
                     "maneuver" : "turn-left",
                     "polyline" : {
    
    
                        "points" : "m{__FmjmvUxA["
                     },
                     "start_location" : {
    
    
                        "lat" : 36.7047135,
                        "lng" : 119.1851888
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "0.8 公里",
                        "value" : 850
                     },
                     "duration" : {
    
    
                        "text" : "2分钟",
                        "value" : 127
                     },
                     "end_location" : {
    
    
                        "lat" : 36.7023932,
                        "lng" : 119.1760839
                     },
                     "html_instructions" : "向\u003cb\u003e右\u003c/b\u003e转,进入\u003cb\u003e804省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e健康东街\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003e继续沿健康东街前行\u003c/div\u003e",
                     "maneuver" : "turn-right",
                     "polyline" : {
    
    
                        "points" : "sx__FikmvULlAVtBHp@VtB@NTlBJv@fCzSn@lFf@`ERbBTfB"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.70426399999999,
                        "lng" : 119.1853314
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "0.5 公里",
                        "value" : 458
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 64
                     },
                     "end_location" : {
    
    
                        "lat" : 36.7065083,
                        "lng" : 119.1759237
                     },
                     "html_instructions" : "向\u003cb\u003e右\u003c/b\u003e转,进入\u003cb\u003e金马路\u003c/b\u003e",
                     "maneuver" : "turn-right",
                     "polyline" : {
    
    
                        "points" : "}l__FoqkvUoA@[@sHJ}ABoCBgABc@@}@@"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.7023932,
                        "lng" : 119.1760839
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "0.1 公里",
                        "value" : 118
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 28
                     },
                     "end_location" : {
    
    
                        "lat" : 36.7065579,
                        "lng" : 119.1772408
                     },
                     "html_instructions" : "向\u003cb\u003e右\u003c/b\u003e转,进入\u003cb\u003e胜利东街\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003e目的地在左侧\u003c/div\u003e",
                     "maneuver" : "turn-right",
                     "polyline" : {
    
    
                        "points" : "uf`_FopkvUCgBEsC?K"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.7065083,
                        "lng" : 119.1759237
                     },
                     "travel_mode" : "DRIVING"
                  }
               ],
               "traffic_speed_entry" : [],
               "via_waypoint" : []
            }
         ],
         "overview_polyline" : {
    
    
            "points" : "uz__FalmvUa@LHd@xA[LlA`@fDz@jHrFnd@TfBoA@oILyIL}@@CgBE_D"
         },
         "summary" : "健康东街和金马路",
         "warnings" : [],
         "waypoint_order" : []
      },
      {
    
    
         "bounds" : {
    
    
            "northeast" : {
    
    
               "lat" : 36.7069392,
               "lng" : 119.1854509
            },
            "southwest" : {
    
    
               "lat" : 36.7039003,
               "lng" : 119.1764395
            }
         },
         "copyrights" : "Map data ©2020",
         "legs" : [
            {
    
    
               "distance" : {
    
    
                  "text" : "1.4 公里",
                  "value" : 1357
               },
               "duration" : {
    
    
                  "text" : "5分钟",
                  "value" : 279
               },
               "end_address" : "中国山东省潍坊市奎文区胜利东街华都鲁成大厦",
               "end_location" : {
    
    
                  "lat" : 36.7065579,
                  "lng" : 119.1772408
               },
               "start_address" : "中国潍坊市奎文区健康街潍县中路口",
               "start_location" : {
    
    
                  "lat" : 36.7045897,
                  "lng" : 119.1854509
               },
               "steps" : [
                  {
    
    
                     "distance" : {
    
    
                        "text" : "37 米",
                        "value" : 37
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 7
                     },
                     "end_location" : {
    
    
                        "lat" : 36.7047135,
                        "lng" : 119.1851888
                     },
                     "html_instructions" : "向\u003cb\u003e北\u003c/b\u003e行驶",
                     "polyline" : {
    
    
                        "points" : "uz__FalmvUMBSHDVBL"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.7045897,
                        "lng" : 119.1854509
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "52 米",
                        "value" : 52
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 15
                     },
                     "end_location" : {
    
    
                        "lat" : 36.70426399999999,
                        "lng" : 119.1853314
                     },
                     "html_instructions" : "向\u003cb\u003e左\u003c/b\u003e转,前往\u003cb\u003e804省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e健康东街\u003c/b\u003e",
                     "maneuver" : "turn-left",
                     "polyline" : {
    
    
                        "points" : "m{__FmjmvUxA["
                     },
                     "start_location" : {
    
    
                        "lat" : 36.7047135,
                        "lng" : 119.1851888
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "0.2 公里",
                        "value" : 167
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 41
                     },
                     "end_location" : {
    
    
                        "lat" : 36.7039003,
                        "lng" : 119.1835148
                     },
                     "html_instructions" : "向\u003cb\u003e右\u003c/b\u003e转,进入\u003cb\u003e804省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e健康东街\u003c/b\u003e",
                     "maneuver" : "turn-right",
                     "polyline" : {
    
    
                        "points" : "sx__FikmvULlAVtBHp@VtB"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.70426399999999,
                        "lng" : 119.1853314
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "0.3 公里",
                        "value" : 340
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 52
                     },
                     "end_location" : {
    
    
                        "lat" : 36.7069392,
                        "lng" : 119.1839711
                     },
                     "html_instructions" : "向\u003cb\u003e右\u003c/b\u003e转,进入\u003cb\u003e222省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e潍县中路\u003c/b\u003e",
                     "maneuver" : "turn-right",
                     "polyline" : {
    
    
                        "points" : "kv__F}_mvUgBOYCoBQkBMSAwAMa@E_AIOAEA]C"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.7039003,
                        "lng" : 119.1835148
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "0.7 公里",
                        "value" : 672
                     },
                     "duration" : {
    
    
                        "text" : "2分钟",
                        "value" : 118
                     },
                     "end_location" : {
    
    
                        "lat" : 36.70669,
                        "lng" : 119.1764407
                     },
                     "html_instructions" : "向\u003cb\u003e左\u003c/b\u003e转,进入\u003cb\u003e胜利东街\u003c/b\u003e",
                     "maneuver" : "turn-left",
                     "polyline" : {
    
    
                        "points" : "ki`_FybmvU?PFrD@|AB|AFjGBpBDxDFbFD|DBdC"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.7069392,
                        "lng" : 119.1839711
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
    
    
                     "distance" : {
    
    
                        "text" : "89 米",
                        "value" : 89
                     },
                     "duration" : {
    
    
                        "text" : "1分钟",
                        "value" : 46
                     },
                     "end_location" : {
    
    
                        "lat" : 36.7065579,
                        "lng" : 119.1772408
                     },
                     "html_instructions" : "\u003cb\u003e调头\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003e目的地在左侧\u003c/div\u003e",
                     "maneuver" : "uturn-left",
                     "polyline" : {
    
    
                        "points" : "yg`_FwskvU^?EsC?K"
                     },
                     "start_location" : {
    
    
                        "lat" : 36.70669,
                        "lng" : 119.1764407
                     },
                     "travel_mode" : "DRIVING"
                  }
               ],
               "traffic_speed_entry" : [],
               "via_waypoint" : []
            }
         ],
         "overview_polyline" : {
    
    
            "points" : "uz__FalmvUa@LHd@xA[LlA`@fDVtBgBOiCUyFc@sBQL`KXzWHbI^?EsC?K"
         },
         "summary" : "222省道/潍县中路和胜利东街",
         "warnings" : [],
         "waypoint_order" : []
      }
   ],
   "status" : "OK"
}

Der Schlüsselcode zum Parsen und Verarbeiten:

private fun dealWithData(mBean: LineModule?) {
    
    
        val status = mBean!!.status
        if (status == "OK") {
    
    

            //包含一个数组,其中包含有关起点,目的地和航点的地理编码的详细信息。
            val geocodedWaypoints = mBean!!.geocoded_waypoints
            Log.i(TAG, "geocodedWaypoints.size=${
      
      geocodedWaypoints.size}")


            val routes = mBean!!.routes //路线 测试发现:第一条数据就是最优的线路
            if (routes != null && routes.size > 0) {
    
    
                Log.i(TAG, "routes.size=${
      
      routes.size}")

                var routesNumber = 0;

                routes.forEach {
    
    
                    routesNumber++;

                    //包含的视口边界框 overview_polyline。
                    val bounds = it.bounds

                    routesGlobalPreview(bounds);


                    //包含一个points 对象,该对象保存路线的编码折线表示。该折线是结果方向的近似(平滑)路径。
                    val overviewPolyline = it.overview_polyline

                    val points = overviewPolyline.points
                    Log.i(TAG, "points=$points")


                    // val mLatLngList: MutableList<LatLng> = decodePoly(points) as MutableList<LatLng>

                    val mLatLngList: MutableList<LatLng> = PolyUtil.decode(points)
                    Log.i(TAG, " mLatLngList.size=${
      
      mLatLngList.size}")

                    showLine(mLatLngList, routesNumber);


                    //包含一个数组,该数组包含有关给定路线内两个位置之间路线段的信息。对于指定的每个航点或目的地,将显示一条单独的航段。
                    // (没有航路点的路线将在legs阵列中仅包含一条腿。)每条腿由一系列组成steps。(请参见下面的“ 指导腿”。)
                    val legs = it.legs
                    Log.i(TAG, "legs.size=${
      
      legs.size}")
                    //总时间显示处理
                    calculateTotalTime(legs)


                    // 包含该路线的简短文字说明,适用于对路线进行命名和消除歧义。
                    val summary = it.summary


                    //包含显示这些方向时要显示的警告数组。您必须自己处理并显示这些警告。
                    val warnings = it.warnings


                    //包含要为此路线显示的版权文本。您必须自己处理和显示此信息。
                    val copyrights = it.copyrights


                    //包含一个数组,该数组指示计算出的路线中任何路标的顺序。如果请求是optimize:true在其waypoints参数内 传递的,则此路点可能会重新排序。
                    val waypointOrder = it.waypoint_order


                }
            } else {
    
    
                Log.i(TAG, " routes is null")
            }


        } else {
    
    
            if (status == "ZERO_RESULTS") {
    
    
                Log.i(TAG, " status 在起点和终点之间找不到路由")
            } else {
    
    
                Log.i(TAG, " status=${
      
      status}")
            }


        }
    }

Verwirklichen Sie die Navigationsfunktion

Am Ende dieses Artikels zur Google diese beiden Fragen hinterlassen:

  1. Was soll ich tun, wenn ich das blaue Punktsymbol im Screenshot durch mein eigenes ersetzen möchte?
  2. Wie gehen Sie nach dem Wechsel zu Ihrem eigenen Symbol mit der Richtungsänderung des blauen Punkts um?

Hier ist also die Antwort.

blauen Punkt ersetzen

Schlüsselcode:

 private fun getDeviceLocation() {
    
    

        val selfPermission4 =
            ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        if (selfPermission4 != PackageManager.PERMISSION_GRANTED) {
    
    
            ActivityCompat.requestPermissions(
                this,
                arrayOf(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_BACKGROUND_LOCATION
                ),
                12
            )
            return
        } else {
    
    
            Log.i(TAG, "getDeviceLocation: 已有权限")
        }

        //就可以去掉官方自带的定位按钮。
        mGoogleMap.isMyLocationEnabled = false
        
        mGoogleMap.uiSettings?.isMyLocationButtonEnabled = true

        //这行代码,就能发起定位请求
        val locationResult = fusedLocationProviderClient.lastLocation

        locationResult.addOnCompleteListener(this) {
    
     task ->
            if (task.isSuccessful) {
    
    
                // Set the map's camera position to the current location of the device.
                val lastKnownLocation = task.result
                if (lastKnownLocation != null) {
    
    
                    Log.i(TAG, "getDeviceLocation:  locationResult if")

                    val currentLocation =
                        LatLng(lastKnownLocation!!.latitude, lastKnownLocation!!.longitude)

                    mGoogleMap.animateCamera(
                        CameraUpdateFactory.newLatLngZoom(
                            currentLocation,
                            17.3f
                        )
                    )

                    if (isFirstLocation) {
    
    
                        val fbearin = lastKnownLocation.bearing //和道路一个方向
                        println("MainActivity.getDeviceLocation fbearin=" + fbearin)
                        //添加自定义定位蓝点
                        mPositionMarker = mGoogleMap!!.addMarker(
                            MarkerOptions()
                                .position(currentLocation)
                                .title("我的位置")
                                .rotation(fbearin)
                                .anchor(0.5f, 0.5f)
                                .icon(BitmapDescriptorFactory.fromResource(R.drawable.baseline_arrow_circle_up_red_900_24dp))
                        )
                    }
                    mPositionMarker!!.position = currentLocation;

                    //添加自定义蓝点范围
                    val circle: Circle = mGoogleMap!!.addCircle(
                        CircleOptions().apply {
    
    
                            center(currentLocation)
                            if (isFirstLocation) {
    
    
                                radius(100.00)
                                strokeWidth(3f)
                                strokeColor(
                                    ContextCompat.getColor(
                                        this@MainActivity,
                                        R.color.purple
                                    )
                                )
                                fillColor(
                                    ContextCompat.getColor(
                                        this@MainActivity,
                                        R.color.blue_100
                                    )
                                )
                                clickable(true)
                                strokePattern(getSelectedPattern(0))
                                isFirstLocation = false
                            }

                        })


                } else {
    
    
                    Log.i(TAG, "getDeviceLocation:  locationResult else")
                }
            } else {
    
    
                Log.e(TAG, "Exception: %s", task.exception)
            }
        }

        
    }

ps: Bitte schau dir die Kommentare im Code an, die Kommentare sind klar gesagt.

blaue Punktrichtung

Für die Richtungsänderung des blauen Punktes müssen wir uns hier auf den Sensor des Mobilgeräts verlassen. Stellen Sie die Richtung des blauen Punktes ein, indem Sie die Daten im Sensor lesen.
Schlüsselcode:
Holen Sie sich zuerst den Sensormanager

 mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager;

Implementieren Sie dann die SensorEventListener-Schnittstelle

    /加速度传感器数据
    private val accelerometerReading = FloatArray(3)

    //地磁传感器数据
    private val magnetometerReading = FloatArray(3)

    //旋转矩阵,用来保存磁场和加速度的数据
    private val rotationMatrix = FloatArray(9)

    //方向数据
    private val orientationAngles = FloatArray(3)


    class MainActivity : AppCompatActivity(), OnMapReadyCallback, SensorEventListener {
    
    }

Dann registrieren Sie sich für die Überwachung

 override fun onResume() {
    
    
        super.onResume()
        //加速度传感器
        val accelerometer: Sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
        if (accelerometer != null) {
    
    
            mSensorManager.registerListener(
                this,
                accelerometer,
                SensorManager.SENSOR_DELAY_NORMAL,
                SensorManager.SENSOR_DELAY_UI
            )
        }
        //地磁传感器
        val magneticField: Sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)
        if (magneticField != null) {
    
    
            mSensorManager.registerListener(
                this,
                magneticField,
                SensorManager.SENSOR_DELAY_NORMAL,
                SensorManager.SENSOR_DELAY_UI
            )
        }

    }

    override fun onPause() {
    
    
        super.onPause()
        mSensorManager.unregisterListener(this);
    }

Die endgültige Schnittstellenimplementierung:

 var mPositionMarker: Marker? = null
    //var azimuth = 0f
    override fun onSensorChanged(event: SensorEvent?) {
    
    
        //判断sensor类型
        if (event!!.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
    
    
            System.arraycopy(
                event.values,
                0,
                accelerometerReading,
                0,
                accelerometerReading.size
            );
        } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
    
    
            System.arraycopy(
                event.values,
                0,
                magnetometerReading,
                0,
                magnetometerReading.size
            );
        }
        updateOrientationAngles();

    }
    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
    
    
    }

    fun updateOrientationAngles() {
    
    
        // 更新旋转矩阵.
        // 参数1:
        // 参数2 :将磁场数据转换进实际的重力坐标中,一般默认情况下可以设置为null
        // 参数3:加速度
        // 参数4:地磁
        SensorManager.getRotationMatrix(
            rotationMatrix,
            null,
            accelerometerReading,
            magnetometerReading
        )

        //根据旋转矩阵计算设备的方向
        //参数1:旋转数组
        //参数2:模拟方向传感器的数据
        SensorManager.getOrientation(rotationMatrix, orientationAngles)
        val sb = StringBuilder()
        if (orientationAngles.size >= 3) {
    
    
            sb.append("z轴:${
      
      orientationAngles[0]}\n")
            sb.append("x轴:${
      
      orientationAngles[1]}\n")
            sb.append("y轴:${
      
      orientationAngles[2]}\n")

            //Log.i(TAG, "updateOrientationAngles:sb=>> ${sb.toString()}")

            val azimuth = Math.toDegrees(orientationAngles[0].toDouble()).toFloat()
            if (mPositionMarker != null) {
    
    
                mPositionMarker!!.rotation = azimuth
            }

      
        }

    }

An dieser Stelle können Sie den blauen Punkt ersetzen und die Richtung des blauen Punkts festlegen, indem Sie die Daten vom Gerätesensor abrufen. In Kombination mit der Funktion der Echtzeitpositionierung öffnen Sie die Navigation.

Erläuterung: Der Platz ist begrenzt, und im Artikel werden nur die Schlüsselcodes veröffentlicht. Bitte klicken Sie hier für den vollständigen Quellcode des Projekts:

Quelladresse des Projekts


Referenzblog:

Offizielle Dokumentation:
https://developers.google.com/maps/documentation/directions/overview

Offizielle Demo:

Wählen Sie das Koordinatensystem

[Google Maps – Extra Story android-maps-utils use]

Supongo que te gusta

Origin blog.csdn.net/da_caoyuan/article/details/109729433
Recomendado
Clasificación