| | |
| | | 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 |
| | |
| | | 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) |
| | |
| | | */ |
| | | @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 |
| | |
| | | // 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() |
| | | } |
| | | |
| | | /** |
| | |
| | | * @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") |
| | | } |
| | | } |
| | | |
| | |
| | | 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() |
| | | ) |
| | |
| | | |
| | | 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()) |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | 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 |
| | | } |
| | | |
| | | //初始化定位监听 |