Skip to content

Navigation Activity crash when navigation start #1988

Description

@jeluchu

Navigation Activity · Kotlin for Android

import android.location.Location
import android.os.Bundle
import android.os.Environment
import android.preference.PreferenceManager
import android.text.SpannableString
import android.text.Spanned
import android.text.style.AbsoluteSizeSpan
import android.view.View
import android.widget.TextView
import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.jeluchu.laelipa.R
import com.mapbox.api.directions.v5.models.BannerInstructions
import com.mapbox.api.directions.v5.models.DirectionsResponse
import com.mapbox.api.directions.v5.models.DirectionsRoute
import com.mapbox.geojson.Point
import com.mapbox.mapboxsdk.Mapbox
import com.mapbox.mapboxsdk.camera.CameraPosition
import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.services.android.navigation.ui.v5.NavigationView
import com.mapbox.services.android.navigation.ui.v5.NavigationViewOptions
import com.mapbox.services.android.navigation.ui.v5.OnNavigationReadyCallback
import com.mapbox.services.android.navigation.ui.v5.listeners.BannerInstructionsListener
import com.mapbox.services.android.navigation.ui.v5.listeners.InstructionListListener
import com.mapbox.services.android.navigation.ui.v5.listeners.NavigationListener
import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import timber.log.Timber

class NavigationActivity: AppCompatActivity(), OnNavigationReadyCallback, NavigationListener,
ProgressChangeListener, InstructionListListener, BannerInstructionsListener {

    private var navigationView: NavigationView? = null
    private var spacer: View? = null
    private var speedWidget: TextView? = null

    private var bottomSheetVisible = true
    private var instructionListShown = false

    var latshop: Double = 0.0
    var longshop: Double = 0.0
    var currentlat: Double = 0.0
    var currentlong: Double = 0.0

    override fun onCreate(savedInstanceState: Bundle?) {
        Mapbox.getInstance(this, getString(R.string.acces_token))
        setTheme(R.style.Theme_AppCompat_Light_NoActionBar)
        initNightMode()
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_navigation)
        navigationView = findViewById(R.id.navigationView)
        speedWidget = findViewById(R.id.speed_limit)
        spacer = findViewById(R.id.spacer)
        setSpeedWidgetAnchor(R.id.summaryBottomSheet)

        val intent = intent
        latshop = intent.extras!!.getDouble("latshop")
        longshop = intent.extras!!.getDouble("longshop")
        currentlat = intent.extras!!.getDouble("currentlat")
        currentlong = intent.extras!!.getDouble("currentlong")

        val initialPosition = CameraPosition.Builder().target(LatLng(currentlat, currentlong))
            .zoom(INITIAL_ZOOM.toDouble())
            .build()
        navigationView!!.onCreate(savedInstanceState)
        navigationView!!.initialize(this, initialPosition)
    }

    override fun onNavigationReady(isRunning: Boolean) { fetchRoute() }
    override fun onCancelNavigation() { finish() }
    override fun onNavigationFinished() {}
    override fun onNavigationRunning() {}
    override fun onProgressChange(location: Location?, routeProgress: RouteProgress?) {
        location?.let { setSpeed(it) }
    }

    override fun onInstructionListVisibilityChanged(show: Boolean) {
        instructionListShown = show
        speedWidget!!.visibility = if (show) View.GONE else View.VISIBLE
    }

    override fun willDisplay(instructions: BannerInstructions?): BannerInstructions = instructions!!

    override fun onSaveInstanceState(outState: Bundle) {
        navigationView!!.onSaveInstanceState(outState)
        super.onSaveInstanceState(outState)
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)
        navigationView!!.onRestoreInstanceState(savedInstanceState)
    }

    private fun startNavigation(directionsRoute: DirectionsRoute) {
        val options = NavigationViewOptions.builder()
            .navigationListener(this)
            .directionsRoute(directionsRoute)
            .shouldSimulateRoute(false)
            .progressChangeListener(this)
            .instructionListListener(this)
            .bannerInstructionsListener(this)
            .offlineRoutingTilesPath(obtainOfflineDirectory())
            .offlineRoutingTilesVersion(obtainOfflineTileVersion())
        setBottomSheetCallback(options)

        navigationView!!.startNavigation(options.build())
    }

    private fun obtainOfflineDirectory(): String {
        val offline = Environment.getExternalStoragePublicDirectory("Offline")
        if (!offline.exists()) {
            Timber.d("Offline directory does not exist")
            offline.mkdirs()
        }
        return offline.absolutePath
    }

    private fun obtainOfflineTileVersion(): String? = PreferenceManager.getDefaultSharedPreferences(this).getString(getString(R.string.offline_version_key), "")

    private fun fetchRoute() {
        NavigationRoute.builder(this)
            .accessToken(getString(R.string.acces_token))
            .origin(Point.fromLngLat(currentlat, currentlong))
            .destination(Point.fromLngLat(latshop, longshop))
            .alternatives(true)
            .build()
            .getRoute(object : Callback<DirectionsResponse> {
                override fun onFailure(call: Call<DirectionsResponse>, throwable: Throwable) {
                    Timber.e("Error: %s", throwable.message)
                }

                override fun onResponse(call: Call<DirectionsResponse>, response: Response<DirectionsResponse>) {
                    startNavigation(response.body()!!.routes()[0])
                }
            })
    }

    private fun setSpeedWidgetAnchor(@IdRes res: Int) {
        val layoutParams = spacer!!.layoutParams as CoordinatorLayout.LayoutParams
        layoutParams.anchorId = res
        spacer!!.layoutParams = layoutParams
    }

    private fun setBottomSheetCallback(options: NavigationViewOptions.Builder) {
        options.bottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
            override fun onStateChanged(bottomSheet: View, newState: Int) {
                when (newState) {
                    BottomSheetBehavior.STATE_HIDDEN -> {
                        bottomSheetVisible = false
                        setSpeedWidgetAnchor(R.id.recenterBtn)
                    }
                    BottomSheetBehavior.STATE_EXPANDED -> bottomSheetVisible = true
                    BottomSheetBehavior.STATE_SETTLING -> if (!bottomSheetVisible) { setSpeedWidgetAnchor(R.id.summaryBottomSheet) }
                    else -> return
                }
            }

            override fun onSlide(bottomSheet: View, slideOffset: Float) {}
        })
    }


    private fun initNightMode() {
        val nightMode = retrieveNightModeFromPreferences()
        AppCompatDelegate.setDefaultNightMode(nightMode)
    }

    private fun retrieveNightModeFromPreferences(): Int {
        val preferences = PreferenceManager.getDefaultSharedPreferences(this)
        return preferences.getInt(getString(R.string.current_night_mode), AppCompatDelegate.MODE_NIGHT_AUTO)
    }

    private fun saveNightModeToPreferences(nightMode: Int) {
        val preferences = PreferenceManager.getDefaultSharedPreferences(this)
        val editor = preferences.edit()
        editor.putInt(getString(R.string.current_night_mode), nightMode)
        editor.apply()
    }

    private fun setSpeed(location: Location) {
        val string = String.format("%d\nKPH", (location.speed * 1.609344).toInt())
        val mphTextSize = resources.getDimensionPixelSize(R.dimen.mph_text_size)
        val speedTextSize = resources.getDimensionPixelSize(R.dimen.speed_text_size)

        val spannableString = SpannableString(string)
        spannableString.setSpan(
            AbsoluteSizeSpan(mphTextSize),
            string.length - 4, string.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE
        )

        spannableString.setSpan(
            AbsoluteSizeSpan(speedTextSize),
            0, string.length - 3, Spanned.SPAN_INCLUSIVE_INCLUSIVE
        )

        speedWidget!!.text = spannableString
        if (!instructionListShown) {
            speedWidget!!.visibility = View.VISIBLE
        }
    }


    public override fun onStart() {
        super.onStart()
        navigationView!!.onStart()
    }

    public override fun onResume() {
        super.onResume()
        navigationView!!.onResume()
    }

    override fun onLowMemory() {
        super.onLowMemory()
        navigationView!!.onLowMemory()
    }

    override fun onBackPressed() {
        if (!navigationView!!.onBackPressed()) {
            super.onBackPressed()
        }
    }

    public override fun onPause() {
        super.onPause()
        navigationView!!.onPause()
    }

    public override fun onStop() {
        super.onStop()
        navigationView!!.onStop()
    }

    override fun onDestroy() {
        super.onDestroy()
        navigationView!!.onDestroy()
        if (isFinishing) {
            saveNightModeToPreferences(AppCompatDelegate.MODE_NIGHT_AUTO)
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO)
        }
    }

    companion object {

        private const val INITIAL_ZOOM = 16
    }


}

Android API: 28
Mapbox Navigation SDK version: 8.1.0

2019-07-04 19:51:31.700 7161-7731/com.jeluchu.laelipa E/AndroidRuntime: FATAL EXCEPTION: mapbox_navigation_thread
    Process: com.jeluchu.laelipa, PID: 7161
    java.lang.Error: Any tile edge can only be used once as part of the geometry
        at com.mapbox.navigator.Navigator.getRouteBufferGeoJson(Native Method)
        at com.mapbox.services.android.navigation.v5.navigation.MapboxNavigator.retrieveRouteGeometryWithBuffer(MapboxNavigator.java:110)
        at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.updateRoute(NavigationRouteProcessor.java:75)
        at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.buildNewRouteProgress(NavigationRouteProcessor.java:53)
        at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorRunnable.process(RouteProcessorRunnable.java:63)
        at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorRunnable.run(RouteProcessorRunnable.java:46)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.os.HandlerThread.run(HandlerThread.java:61)
java.lang.Error: Any tile edge can only be used once as part of the geometry at com.mapbox.navigator.Navigator.getRouteBufferGeoJson(Native Method) at com.mapbox.services.android.navigation.v5.navigation.MapboxNavigator.retrieveRouteGeometryWithBuffer(MapboxNavigator.java:110) at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.updateRoute(NavigationRouteProcessor.java:75) at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.buildNewRouteProgress(NavigationRouteProcessor.java:53) at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorRunnable.process(RouteProcessorRunnable.java:63) at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorRunnable.run(RouteProcessorRunnable.java:46) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.os.HandlerThread.run(HandlerThread.java:61)

Crashlytics Reports

Fatal Exception: java.lang.IllegalArgumentException: Non-null and non-empty location list required.
       at com.mapbox.services.android.navigation.v5.location.replay.ReplayLocationDispatcher.checkValidInput + 79(ReplayLocationDispatcher.java:79)
       at com.mapbox.services.android.navigation.v5.location.replay.ReplayLocationDispatcher.<init> + 22(ReplayLocationDispatcher.java:22)
       at com.mapbox.services.android.navigation.v5.location.replay.ReplayRouteLocationEngine.obtainDispatcher + 164(ReplayRouteLocationEngine.java:164)
       at com.mapbox.services.android.navigation.v5.location.replay.ReplayRouteLocationEngine.start + 154(ReplayRouteLocationEngine.java:154)
       at com.mapbox.services.android.navigation.v5.location.replay.ReplayRouteLocationEngine.beginReplayWith + 203(ReplayRouteLocationEngine.java:203)
       at com.mapbox.services.android.navigation.v5.location.replay.ReplayRouteLocationEngine.requestLocationUpdates + 113(ReplayRouteLocationEngine.java:113)
       at com.mapbox.services.android.navigation.v5.navigation.LocationUpdater.requestInitialLocationUpdates + 58(LocationUpdater.java:58)
       at com.mapbox.services.android.navigation.v5.navigation.LocationUpdater.<init> + 31(LocationUpdater.java:31)
       at com.mapbox.services.android.navigation.v5.navigation.NavigationService.initializeLocationUpdater + 124(NavigationService.java:124)
       at com.mapbox.services.android.navigation.v5.navigation.NavigationService.initialize + 95(NavigationService.java:95)
       at com.mapbox.services.android.navigation.v5.navigation.NavigationService.startNavigation + 66(NavigationService.java:66)
       at com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation.onServiceConnected + 810(MapboxNavigation.java:810)
       at android.app.LoadedApk$ServiceDispatcher.doConnected + 1453(LoadedApk.java:1453)
       at android.app.LoadedApk$ServiceDispatcher$RunConnection.run + 1481(LoadedApk.java:1481)
       at android.os.Handler.handleCallback + 751(Handler.java:751)
       at android.os.Handler.dispatchMessage + 95(Handler.java:95)
       at android.os.Looper.loop + 154(Looper.java:154)
       at android.app.ActivityThread.main + 6121(ActivityThread.java:6121)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run + 889(ZygoteInit.java:889)
       at com.android.internal.os.ZygoteInit.main + 779(ZygoteInit.java:779)
Fatal Exception: java.lang.Error: Any tile edge can only be used once as part of the geometry
       at com.mapbox.navigator.Navigator.getRouteBufferGeoJson(Navigator.java)
       at com.mapbox.services.android.navigation.v5.navigation.MapboxNavigator.retrieveRouteGeometryWithBuffer + 110(MapboxNavigator.java:110)
       at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.updateRoute + 75(NavigationRouteProcessor.java:75)
       at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.buildNewRouteProgress + 53(NavigationRouteProcessor.java:53)
       at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorRunnable.process + 63(RouteProcessorRunnable.java:63)
       at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorRunnable.run + 46(RouteProcessorRunnable.java:46)
       at android.os.Handler.handleCallback + 751(Handler.java:751)
       at android.os.Handler.dispatchMessage + 95(Handler.java:95)
       at android.os.Looper.loop + 154(Looper.java:154)
       at android.os.HandlerThread.run + 61(HandlerThread.java:61)
Fatal Exception: kotlin.KotlinNullPointerException
       at com.jeluchu.laelipa.activities.NavigationActivity$fetchRoute$1.onResponse + 139(NavigationActivity.kt:139)
       at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteCallback.onResponse + 30(NavigationRouteCallback.java:30)
       at com.mapbox.api.directions.v5.MapboxDirections$1.onResponse + 185(MapboxDirections.java:185)
       at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run + 71(ExecutorCallAdapterFactory.java:71)
       at android.os.Handler.handleCallback + 751(Handler.java:751)
       at android.os.Handler.dispatchMessage + 95(Handler.java:95)
       at android.os.Looper.loop + 154(Looper.java:154)
       at android.app.ActivityThread.main + 6121(ActivityThread.java:6121)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run + 889(ZygoteInit.java:889)
       at com.android.internal.os.ZygoteInit.main + 779(ZygoteInit.java:779)

I pick up both the current position and the destination from another activity (I have verified that I get them correctly)

But when starting the activity of navigation, it closes giving several errors, among them is that I show you. Another error that has come up is: Non-empty location list required

    implementation 'com.mapbox.mapboxsdk:mapbox-android-navigation:0.40.0'
    implementation 'com.mapbox.mapboxsdk:mapbox-android-navigation-ui:0.40.0'
    implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:8.1.0'
    implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-building-v7:0.5.0'
    implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v7:0.9.0'
    implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-locationlayer:0.11.0'
    implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-places:0.6.0'
    implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-geojson:0.3.0'

These are the libraries I use Mapbox, in addition to their plugins, if they help to find the solution to my problem. These errors come out randomly without changing any part of the activity

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions