18034727885
2026-08-18 dab2f54542d151c92dcba04bd9833280e9728e2d
修复问题
2个文件已修改
127 ■■■■■ 已修改文件
app/src/main/java/com/driver/igotrip/base/gaode/AMapKit.kt 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/base/gaode/NaviGoogleActivity.kt 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/base/gaode/AMapKit.kt
@@ -18,6 +18,7 @@
import android.util.Log
import android.view.View
import androidx.core.content.ContextCompat
import cn.sinata.rxnetty.LogHelper
import cn.sinata.xldutils.utils.SPUtils
import com.driver.igotrip.R
import com.driver.igotrip.base.Const
@@ -44,6 +45,9 @@
import com.google.android.gms.maps.model.PolylineOptions
import com.google.gson.Gson
import com.tbruyelle.rxpermissions2.RxPermissions
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
@@ -439,25 +443,34 @@
        return false
    }
    fun getClient(url: String, function: (String) -> Unit) {
    fun getClient(url: String, retryCount: Int = 3, function: (String) -> Unit) {
        val client = OkHttpClient().newBuilder().build()
        val mediaType = "text/plain".toMediaTypeOrNull()
        val body = RequestBody.create(mediaType, "")
        val request: Request = Request.Builder()
            .url(url)
            .method("GET", null)
            .build()
        Thread {
        LogHelper.logRecord("请求谷歌服务器 $url")
        val subscribe = Observable.just(request)
            .map { request -> client.newCall(request).execute().body?.string() ?: "" }
            .retry(retryCount.toLong())   // 最多额外重试 3 次(加上首次共 4 次尝试)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
            try {
                val response = client.newCall(request).execute()
                Handler(Looper.getMainLooper()).post {
                    function(response.body?.string() ?: "")
                    if (it.isEmpty()) {
                        LogHelper.logRecord("请求谷歌服务器成功 获取结果异常为空")
                        return@subscribe
                }
                    function(it)
                    LogHelper.logRecord("请求谷歌服务器成功")
            } catch (e: Exception) {
                e.printStackTrace()
                    LogHelper.logRecord("请求谷歌服务器成功,获取结果异常报错 message:${e.message},stackTrace:${e.stackTraceToString()}")
            }
        }.start()
            }, { throwable ->
                throwable.printStackTrace()
                LogHelper.logRecord("请求谷歌服务器异常报错 message:${throwable.message},stackTrace:${throwable.stackTraceToString()}")
            })
    }
    /***
app/src/main/java/com/driver/igotrip/base/gaode/NaviGoogleActivity.kt
@@ -11,7 +11,7 @@
import com.driver.igotrip.base.MyApplication
import com.driver.igotrip.base.MyBaseActivity
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.LatLng
import com.google.android.libraries.navigation.ListenableResultFuture
import com.google.android.libraries.navigation.NavigationApi
import com.google.android.libraries.navigation.NavigationApi.NavigatorListener
import com.google.android.libraries.navigation.Navigator
@@ -22,19 +22,26 @@
import com.google.android.libraries.navigation.SupportNavigationFragment
import com.google.android.libraries.navigation.Waypoint
import com.google.android.libraries.navigation.Waypoint.UnsupportedPlaceIdException
import java.lang.ref.WeakReference
class NaviGoogleActivity : MyBaseActivity() {
    override fun setContentView() {
        setContentView(R.layout.activity_navgoogle)
    }
    // 使用弱引用避免匿名内部类泄漏
    private val activityWeakRef = WeakReference(this)
    private var mNavigator: Navigator? = null
    private var mNavFragment: SupportNavigationFragment? = null
    private var mRoutingOptions: RoutingOptions? = null
    private var pendingRoute: ListenableResultFuture<RouteStatus>? = null
    private var arrivalListener: Navigator.ArrivalListener? = null
    private var roadSnappedLocationProvider: RoadSnappedLocationProvider? = null
    private val lat by lazy { intent.getDoubleExtra("lat", 0.0) }
    private val lon by lazy { intent.getDoubleExtra("lon", 0.0) }
    override fun setContentView() {
        setContentView(R.layout.activity_navgoogle)
    }
    override fun initView() {
        showTitle(false)
@@ -58,9 +65,10 @@
             */
            @SuppressLint("MissingPermission")
            override fun onNavigatorReady(navigator: Navigator) {
                val activity = activityWeakRef.get() ?: return
                Log.e(Const.GoogleDriver.TAG, "Navigator ready.")
                mNavigator = navigator
                mNavFragment =
                activity.mNavigator = navigator
                activity.mNavFragment =
                    supportFragmentManager.findFragmentById(R.id.navigation_fragment) as SupportNavigationFragment
                // Set the last digit of the car's license plate to get route restrictions
@@ -68,23 +76,22 @@
                // mNavigator.setLicensePlateRestrictionInfo(getLastDigit(), "BZ");
                // Set the camera to follow the device location with 'TILTED' driving view.
                mNavFragment?.getMapAsync {
                activity.mNavFragment?.getMapAsync {
                    it.followMyLocation(GoogleMap.CameraPerspective.TILTED)
                }
                mNavFragment
                // Set the travel mode (DRIVING, WALKING, CYCLING, or TWO_WHEELER).
                mRoutingOptions = RoutingOptions()
                mRoutingOptions?.travelMode(RoutingOptions.TravelMode.DRIVING)
                navigator.addArrivalListener {
                    finish()
                activity.mRoutingOptions = RoutingOptions()
                activity.mRoutingOptions?.travelMode(RoutingOptions.TravelMode.DRIVING)
                // 保存 ArrivalListener 以便后续移除
                activity.arrivalListener = Navigator.ArrivalListener {
                    activity.finish()
                }
                navigator.addArrivalListener(activity.arrivalListener!!)
                // Navigate to a place
                navigateToPlace(lat, lon)
                activity.navigateToPlace(lat, lon)
                initLocationListener()
                activity.initLocationListener()
            }
            /**
@@ -92,24 +99,25 @@
             * @param errorCode The error code returned by the navigator.
             */
            override fun onError(@NavigationApi.ErrorCode errorCode: Int) {
                val activity = activityWeakRef.get() ?: return
                when (errorCode) {
                    NavigationApi.ErrorCode.NOT_AUTHORIZED -> displayMessage(
                    NavigationApi.ErrorCode.NOT_AUTHORIZED -> activity.displayMessage(
                        "Error loading Navigation SDK: Your API key is "
                                + "invalid or not authorized to use the Navigation SDK."
                    )
                    NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED -> displayMessage(
                    NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED -> activity.displayMessage(
                        ("Error loading Navigation SDK: User did not accept "
                                + "the Navigation Terms of Use.")
                    )
                    NavigationApi.ErrorCode.NETWORK_ERROR -> displayMessage("Error loading Navigation SDK: Network error.")
                    NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING -> displayMessage(
                    NavigationApi.ErrorCode.NETWORK_ERROR -> activity.displayMessage("Error loading Navigation SDK: Network error.")
                    NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING -> activity.displayMessage(
                        ("Error loading Navigation SDK: Location permission "
                                + "is missing.")
                    )
                    else -> displayMessage("Error loading Navigation SDK: $errorCode")
                    else -> activity.displayMessage("Error loading Navigation SDK: $errorCode")
                }
            }
@@ -121,42 +129,45 @@
        val destination: Waypoint = try {
            Waypoint.builder().setLatLng(lat, lon).build()
        } catch (e: UnsupportedPlaceIdException) {
            e.printStackTrace()
            displayMessage("Error starting navigation: Place ID is not supported.")
            return
        }
        // Create a future to await the result of the asynchronous navigator task.
        val pendingRoute = mNavigator!!.setDestination(destination, mRoutingOptions)
        pendingRoute = mNavigator?.setDestination(destination, mRoutingOptions)
        // Define the action to perform when the SDK has determined the route.
        pendingRoute.setOnResultListener { code ->
        pendingRoute?.setOnResultListener { code ->
            // 使用弱引用避免 Activity 泄漏
            val activity = activityWeakRef.get() ?: return@setOnResultListener
            when (code) {
                RouteStatus.OK -> {
                    // Hide the toolbar to maximize the navigation UI.
                    if (actionBar != null) {
                        actionBar!!.hide()
                    if (activity.actionBar != null) {
                        activity.actionBar!!.hide()
                    }
                    // Enable voice audio guidance (through the device speaker).
                    mNavigator!!.setAudioGuidance(
                    activity.mNavigator?.setAudioGuidance(
                        Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE
                    )
                    // Simulate vehicle progress along the route for demo/debug builds.
                    if (BuildConfig.DEBUG) {
                        mNavigator!!.simulator.simulateLocationsAlongExistingRoute(
                        activity.mNavigator?.simulator?.simulateLocationsAlongExistingRoute(
                            SimulationOptions().speedMultiplier(5f)
                        )
                    }
                    // Start turn-by-turn guidance along the current route.
                    mNavigator!!.startGuidance()
                    activity.mNavigator?.startGuidance()
                }
                RouteStatus.NO_ROUTE_FOUND -> displayMessage("Error starting navigation: No route found.")
                RouteStatus.NETWORK_ERROR -> displayMessage("Error starting navigation: Network error.")
                RouteStatus.ROUTE_CANCELED -> displayMessage("Error starting navigation: Route canceled.")
                else -> displayMessage(
                RouteStatus.NO_ROUTE_FOUND -> activity.displayMessage("Error starting navigation: No route found.")
                RouteStatus.NETWORK_ERROR -> activity.displayMessage("Error starting navigation: Network error.")
                RouteStatus.ROUTE_CANCELED -> activity.displayMessage("Error starting navigation: Route canceled.")
                else -> activity.displayMessage(
                    "Error starting navigation: "
                            + code.toString()
                )
@@ -166,7 +177,7 @@
    override fun onEventMainThread(event: BaseEvent?) {
        if (event?.code == BaseEvent.RELOAD_NAVI) {
            navigateToPlace(event!!.msg.toDouble(), event.msgTwo.toDouble())
            navigateToPlace(event.msg.toDouble(), event.msgTwo.toDouble())
        }
    }
@@ -196,8 +207,27 @@
    override fun onDestroy() {
        super.onDestroy()
        // 1. 停止导航
        mNavigator?.stopGuidance()
        // 2. 移除 ArrivalListener
        arrivalListener?.let { mNavigator?.removeArrivalListener(it) }
        // 3. 取消待定路由请求
        pendingRoute?.cancel(true)
        // 4. 移除位置监听
        removeLocationListener()
        // 5. 释放 Navigator(如果有 shutdown 方法)
        // mNavigator?.shutdown()
        // 清空引用
        mNavigator = null
        mNavFragment = null
        mRoutingOptions = null
        pendingRoute = null
        arrivalListener = null
    }
    //初始化定位监听