Search code examples
kotlinmapboxmapbox-android

Location Permissions and LocationComponent crashing app on first install


Beginner with MapBox and Kotlin. On first install of my APK after enabling location permission, my LocationComponent will not activate, nor show on map. The app will crash and location component will appear without issue and app works as it should.

Can anyone provide some assistance to get my LocationComponent to activate and display after enabling location permissions?

Cheers!

2020-01-17 14:38:16.768 16702-16702/com.example.carparker E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.carparker, PID: 16702
com.mapbox.mapboxsdk.location.LocationComponentNotInitializedException: The LocationComponent has to be activated with one of the LocationComponent#activateLocationComponent overloads before any other methods are invoked.
    at com.mapbox.mapboxsdk.location.LocationComponent.checkActivationState(LocationComponent.java:1606)
    at com.mapbox.mapboxsdk.location.LocationComponent.getLastKnownLocation(LocationComponent.java:1030)
    at com.example.carparker.MainActivity.centreCamera(MainActivity.kt:176)
    at com.example.carparker.MainActivity$onCreate$4.onClick(MainActivity.kt:125)
    at android.view.View.performClick(View.java:6294)
    at android.view.View$PerformClick.run(View.java:24770)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

fun onCreate() {
       mapView = findViewById(R.id.mapView)
        parkButton = findViewById(R.id.parkBtn)
    mapView.onCreate(savedInstanceState)
    mapView?.getMapAsync {mapboxMap ->
        map = mapboxMap
        map.setStyle(Style.MAPBOX_STREETS) {
            Log.d(TAG, "Enable location component")

                enableLocation()
                enableLocationComponent(it)
        }


    /**
 * Enables permissions for location
 */
fun enableLocation()  {
    if (PermissionsManager.areLocationPermissionsGranted(this)) {


    } else {
        permissionManager = PermissionsManager(this)
        permissionManager.requestLocationPermissions(this)
    }

}

   /**
     * Actions enable location again
     */
override fun onPermissionResult(granted: Boolean) {
    if (granted) {

        enableLocation()

    }
}

/**
 * Enables user tracking and displaying the location puck.
 */
private fun enableLocationComponent(loadedMapStyle: Style) {
        // Check if permissions are enabled and if not request
        if (PermissionsManager.areLocationPermissionsGranted(this)) {

            // Create and customize the LocationComponent's options
            val customLocationComponentOptions = LocationComponentOptions.builder(this)
                .trackingGesturesManagement(true)
                .accuracyColor(ContextCompat.getColor(this, R.color.mapbox_blue))

                .build()

            val locationComponentActivationOptions = LocationComponentActivationOptions.builder(this, loadedMapStyle)
                .locationComponentOptions(customLocationComponentOptions)
                .build()



                // Get an instance of the LocationComponent and then adjust its settings
            map.locationComponent.apply {

                    // Activate the LocationComponent with options
                    activateLocationComponent(locationComponentActivationOptions)

                    // Enable to make the LocationComponent visible
                    isLocationComponentEnabled = true

                    // Set the LocationComponent's camera mode
                    cameraMode = CameraMode.TRACKING


                    // Set the LocationComponent's render mode
                    renderMode = RenderMode.COMPASS


                }

        } else {
            permissionManager = PermissionsManager(this)
            permissionManager.requestLocationPermissions(this)
        }
    }

Solution

  • You're duplicating a lot of permissions checking and initialization.

    See https://github.com/mapbox/mapbox-android-demo/blob/master/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/location/KotlinLocationComponentActivity.kt for a barebones Kotlin example of how to do a basic LocationComponent setup.