Mapbox-gl-native: MapboxAccountManager not checking permission correctly onResume

Created on 15 Aug 2016  路  14Comments  路  Source: mapbox/mapbox-gl-native

Go into activity with mapview while user locations enabled, I then goto settings and disable location permission, switch back to the activity containing just the mapview and the app crashes.

ezgif com-video-to-gif

logcat output:

08-15 16:27:51.040 3953-3953/com.mapbox.mapboxandroiddemo E/OfflineManager: Failed to read the storage key: Attempt to invoke virtual method 'boolean android.os.BaseBundle.getBoolean(java.lang.String, boolean)' on a null object reference
08-15 16:27:51.071 3953-3953/com.mapbox.mapboxandroiddemo E/MapboxMap: Could not activate user location tracking: user did not accept the permission or permissions were not requested.
08-15 16:27:51.073 3953-3953/com.mapbox.mapboxandroiddemo D/AndroidRuntime: Shutting down VM


                                                                            --------- beginning of crash
08-15 16:27:51.080 3953-3953/com.mapbox.mapboxandroiddemo E/AndroidRuntime: FATAL EXCEPTION: main
                                                                            Process: com.mapbox.mapboxandroiddemo, PID: 3953
                                                                            java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mapbox.mapboxandroiddemo/com.mapbox.mapboxandroiddemo.examples.basics.SimpleMapViewActivity}: com.mapbox.mapboxsdk.exceptions.MapboxAccountManagerNotStartedException: 
                                                                            MapboxAccountManager was not started correctly. Use MapboxAccountManager#start(Context, String) to initialise. 
                                                                            More information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                                                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                                                                                at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                at android.os.Looper.loop(Looper.java:154)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
                                                                             Caused by: com.mapbox.mapboxsdk.exceptions.MapboxAccountManagerNotStartedException: 
                                                                            MapboxAccountManager was not started correctly. Use MapboxAccountManager#start(Context, String) to initialise. 
                                                                            More information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.
                                                                                at com.mapbox.mapboxsdk.MapboxAccountManager.getInstance(MapboxAccountManager.java:56)
                                                                                at com.mapbox.mapboxsdk.maps.MapView.onCreate(MapView.java:365)
                                                                                at com.mapbox.mapboxandroiddemo.examples.basics.SimpleMapViewActivity.onCreate(SimpleMapViewActivity.java:21)
                                                                                at android.app.Activity.performCreate(Activity.java:6664)
                                                                                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                                                                                    ... 9 more

cc: @zugaldia @bleege

Android bug

All 14 comments

Adding here that these types of checks will need to be moved to onStart/onStop. Android N introduces the focus principle with multi window. You want to be able to due above use-case in a multi window setup.

Capturing chat with @cammace where he confirmed that this is with the Demo App only (as of right now) and that his device is running the latest Android Nougat beta OS. Will still look into this issue, just documenting this as "stuff we know" before digging in.

Tried reproducing using the SDK TestApp running on Samsung S5 ( Android 5.0 / API 21) but was unable. Steps were:

  1. Launch SDK TestApp on device
  2. Open Location Picker activity
  3. Disable Location permission in Android UI

    • Makes SDK TestApp not longer visible on screen

  4. Make SDK TestApp visible on screen

This seems like the correct result as API 21 still uses App Install Time permissions strategy. I'll test this next on a Nexus 5x running Android 6.0 / API 23.

I repeated the test on the Nexus 5x running Android 6.0.1 / API 23 and it also did not crash. The only remaining differences that I can see at this point are:

  1. Running on Android Nougat device (API 24)
  2. Demo App calls MapboxAccountManager.start() in initial Activity.onCreate() and not in the app's Application object as the Test App does.

Next Steps

Let's try to rule out the Activity vs Application setup of MapboxAccountManager.start() option as it'll be the easiest. @cammace can you add a basic Application class to the Demo App and move the MapboxAccountManager.start() call there and then retest on your Nougat device? No need to make this a permanent addition to the code base (as the diversity of setups across our apps is useful) as we just want to rule this discrepancy out so that we know definitively if this is just a Nougat thing. Cool?

Just tested this by moving MapboxAccountManager to the application object and no crash occurred.

I'm picking this up again now that Android Nutella Nougat is officially out the door from Google and I've got it running on my Nexus 5x. The SDK TestApp should continue to work fine for testing as it's still using Activity.onCreate() to instantiate MapboxAccountManager.start(). We'll see if it still blows up running under this condition or if this was something that was ironed out by Google before the final release as @cammace's tests were on Nougat Beta releases.

While building (and waiting for) the Mapbox Android SDK TestApp, I retried the test scenario from the OP (see animated gif) using the latest Demo App from Google Play on my Nexus 5x running Android Nougat. It did not crash the app running on the final version of Android Nougat. According to the source code MapboxAccountManager.start() is still called from MainActivity.onCreate() in this version of the app.

Next steps are to verify again the Mapbox Android SDK TestApp to complete the testing that was previously done above on Android 5 and Android 6.

I was able to successfully test the same test scenario in the TestApp that was used on Android 5 and Android 6 with Android Nougat (see screenshot below).

At this point now that I have successfully tested Android Nougat Final with both Activity and Application scenarios I'm thinking the next thing to do would be to have @cammace re-test the scenario from the OP on his device to see if it's still exhibiting the same crash behavior. If it is then I can continue to look into this issue, and if not then we can close.

screen shot 2016-09-19 at 6 29 24 pm

Checked using the demo app and the SNAPSHOT and was still able to reproduce. The crash was produced using a Nexus 5x running Nougat latest release. The activity only needs a mapview in it for the bug to occur but I tested mainly using the SimpleMapViewActivity.

Ah ha! I was finally able to recreate the issue locally on a Nexus 5x running Android Nougat Release with @cammace updated instructions with the latest SDK SNAPSHOT (4.2.0-SNAPSHOT Number 68). The issue seems to only occur when Settings | App Permissions | Mapbox Dev Preview | Location is toggled rather than Location Services for the entire device.

Next step will be to try to recreate the crash in the TestApp so that it can be fixed there and then publish a new SNAPSHOT so that it can be verified against the DemoApp.

09-20 10:51:20.947 10373-10373/com.mapbox.mapboxandroiddemo E/AndroidRuntime: FATAL EXCEPTION: main
                                                                              Process: com.mapbox.mapboxandroiddemo, PID: 10373
                                                                              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mapbox.mapboxandroiddemo/com.mapbox.mapboxandroiddemo.examples.basics.SimpleMapViewActivity}: com.mapbox.mapboxsdk.exceptions.MapboxAccountManagerNotStartedException: 
                                                                              MapboxAccountManager was not started correctly. Use MapboxAccountManager#start(Context, String) to initialise. 
                                                                              More information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.
                                                                                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                                                                                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                                                                                  at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                                                                                  at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                  at android.os.Looper.loop(Looper.java:154)
                                                                                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                                                  at java.lang.reflect.Method.invoke(Native Method)
                                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
                                                                               Caused by: com.mapbox.mapboxsdk.exceptions.MapboxAccountManagerNotStartedException: 
                                                                              MapboxAccountManager was not started correctly. Use MapboxAccountManager#start(Context, String) to initialise. 
                                                                              More information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.
                                                                                  at com.mapbox.mapboxsdk.MapboxAccountManager.getInstance(MapboxAccountManager.java:59)
                                                                                  at com.mapbox.mapboxsdk.maps.MapView.onCreate(MapView.java:370)
                                                                                  at com.mapbox.mapboxandroiddemo.examples.basics.SimpleMapViewActivity.onCreate(SimpleMapViewActivity.java:21)
                                                                                  at android.app.Activity.performCreate(Activity.java:6664)
                                                                                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                                                                                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                                                                                    ... 9 more

I started the debug work with TestApp by using the MyLocationDrawableActivity example so that Location permissions would be triggered. The TestApp configures MapboxAccountManager.start() in MapboxApplication so the first thing I did was re-verify that the it does not crash by using the same Settings | App Permissions | Mapbox TestApp | Location settings test case that I was able to get the DemoApp to crash with earlier today (see previous comment). Good news is that I confirmed that it DOES NOT crash in this scenario. This gives this issue a workaround in the short term.

Next up is to move the MapboxAccountManager.start() to MyLocationDrawableActivity and repeat the Settings | App Permissions | Mapbox TestApp | Location settings test case with hopes that it will crash as the DemoApp did.

Hrm... I just tried moving MapboxAccountManager.start() to MyLocationDrawableActivity to mirror the DemoApp setup and it did not crash as expected. I even commented out the line in MyLocationDrawableActivity.onCreate() that set the access token via MapboxMapOptions so that MapboxAccountManager would be the only way for the access token to be set and it still did no crash. This is puzzling.

I think the next thing to try will be to further isolate things by creating a simple app that just loads a MapView using the latest SDK SNAPSHOT and then run the Settings | App Permissions | Mapbox TestApp | Location settings test case on it using both Application and Activity methods. This will help shed light on if the TestApp is giving false positives by not crashing or if maybe there's something specific with the DemoApp code that is causing it to crash.

I created a project called SimpleMap (see link below) using the SDK SNAPSHOT to isolate things further. This app loads a MapView into the MainActivity and centers it over a location manually without requesting Location Services. I setup MapboxAccountManager.start() in the MainActivity.create() method and ran the app on the Nexus 5x with Android Nougat through the Settings | App Permissions | Mapbox TestApp | Location settings test case. It did not crash.

https://github.com/bleege/SimpleMap

Next step is to compare the DemoApp code with the SimpleMap code and see where the differences are, if any.

ezgif com-video-to-gif

Thanks for putting this project together @bleege, I loaded it up and wasn't able to produce the issue at first. I then created a new launcher activity and placed the account manager inside that activity instead (doesn't have a mapview). The made the issue reproducible (shown in GIF above). The reason this occurred is because I'm leaving the app to toggle the location permission, the launcher activity (one with the account manager) is destroyed making the account manager null.

Moving forward this can be fixed in the documentation by explicitly stating that the account manager can either go in the application object (preferred) or must go in the same activity the mapview's in. Ticket to fix in demo app can be found here

Was this page helpful?
0 / 5 - 0 ratings