Fork us on GitHub

Switching on Android Marshmallow Permission Prompts

Moving to Android API level 23
Switching on Android Marshmallow Permission Prompts

Switching on Android Marshmallow Permission Prompts

Up until Marshmallow (version 6) Android used a rather obtuse permission system that very few end users understood. With API level 23 (Marshmallow) Android finally shifted to a structure that makes more sense similarly to iOS. Marshmallow asks a users permission the first time an API is used e.g. when accessing contacts the user will receive a prompt whether to allow contacts access.

Permission can be denied and a user can later on revoke/grant a permission via external settings UI

This is really great as it allows apps to be installed with a single click and no permission prompt during install which can increase conversion rates!

The Transition

Starting today all compilations will be done with SDK level 23 but not with target level 23!

This means that by default the new permission mode is still off and you won’t see any of the effects mentioned below.

We will probably change this to be the default in the future but at the moment the target SDK defaults to 21. To activate this functionality you will need to set the target SDK to level 23 by using the build hint android.targetSDKVersion=23.

How Does This Look?

To test this API I’ve created a simple contacts app:

Form f = new Form("Contacts", BoxLayout.y());
f.add(new InfiniteProgress());
Display.getInstance().invokeAndBlock(() -> {
    Contact[] ct = Display.getInstance().getAllContacts(true, true, false, true, true, false);
    Display.getInstance().callSerially(() -> {
        for(Contact c : ct) {
            MultiButton mb = new MultiButton(c.getDisplayName());

When I try to install it without changing anything on my Android 6 OPO device I see this UI:

Install UI when using the old permissions system
Figure 1. Install UI when using the old permissions system

When I set android.targetSDKVersion=23 in the build hints and try to install again the UI looks like this:

Install UI when using the new permissions system
Figure 2. Install UI when using the new permissions system

When I launch the UI under the old permissions system I got to the contacts instantly in the new system I’m presented with this UI:

Native permission prompt first time
Figure 3. Native permission prompt first time

If I accept and allow all is good and the app loads as usual but if I deny then Codename One gives the user another chance to request the permission. Notice that in this case you can customize the prompt string as explained below.

Codename One permission prompt
Figure 4. Codename One permission prompt

If I would select don’t ask then I will get a blank screen since the contacts will return as a 0 length array. This makes sense as the user is aware he denied permission and the app will still function as expected on a device where no contacts are available. However, if the user realizes his mistake he can double back and ask to re-prompt for permission in which case he will see this native prompt:

Native permission prompt second time
Figure 5. Native permission prompt second time

Notice that denying this second request will not trigger another Codename One prompt.

Code Changes

For native Android developers this transition was painful requiring developers to rewrite API access with callbacks to respect the cases where permission is denied or revoked. When adding the support to Codename One we chose to make this as seamless as we always strived to be. The respective API’s will work just like they always worked and will prompt the user seamlessly for permissions.

Some behaviors that never occurred on Android but were perfectly legal in the past might start occurring with the switch to the new API. E.g. the location manager might be null and your app must always be ready to deal with such a situation

When permission is requested a user will be seamlessly prompted/warned, we have builtin text to control such prompts but you might want to customize the text. You can customize permission text via the Display properties e.g. to customize the text of the contacts permission we can do something such as:

Display.getInstance().setProperty("android.permission.READ_CONTACTS", "MyCoolChatApp needs access to your contacts so we can show you which of your friends already have MyCoolChatApp installed");

This is optional as there is a default value defined. You can define this once in the init(Object) method but for some extreme cases permission might be needed for different things e.g. you might ask for this permission with one reason at one point in the app and with a different reason at another point in the app.

The following permission keys are supported: "android.permission.READ_PHONE_STATE" android.permission.WRITE_EXTERNAL_STORAGE, android.permission.ACCESS_FINE_LOCATION, android.permission.SEND_SMS, android.permission.READ_CONTACTS, android.permission.WRITE_CONTACTS, android.permission.RECORD_AUDIO.

Should you Switch?

We suggest you test target level 23 with your app and see how it performs. Verify that nothing breaks and that the app maintains usability.

You will need a Marshmallow level device to test this properly as the app will look the same on older devices

Testing this is crucial as we would flip the switch to make this the default in the near future. The timing when this is switched on might not be as convenient as trying this option now. Due to the way Android works it is very possible that Google will promote target level 23 apps more aggressively to encourage developers to update their apps so it is prudent to update now rather than later.

Share this Post:

Posted by Shai Almog

Shai is the co-founder of Codename One. He's been a professional programmer for over 25 years. During that time he has worked with dozens of companies including Sun Microsystems.
For more follow Shai on Twitter & github.