androidenterprisemdmandroid-restrictions

Enterprise Android App Config - Application Restrictions - Not working as expected


Really could use some guidance on how to debug / troubleshoot this issue I'm having.

I built my first app designed to be configured by an Enterprise MDM / EMM service. I created the app_restrictions.xml file, and I setup my Bundle for restrictions to be read in from that file.

When running in debug on a device connected to my computer, I can successfully read in all the values from the XML file

However the problem occurs once I roll it into production.

I've published the app to the play store, and added the app to the EMM/MDM.

I can see the managed configuration settings all appear inside the EMM/MDM - so I've got everything right up to this point.

However once the app is pushed with an alternate configuration to a device, the values being read in are not the custom values from the EMM/MDM - they are my default values inside of the XML that I developed.

I cannot find any good resources on troubleshooting this part of the process.

Anyone done this before have any ideas?


Solution

  • I've been creating a lot of B2B applications lately, and providing the customer with the ability to customize the app on a per-device or per-deployment basis is critical.

    Here's my guide to adding App Config settings into your application for any MDM to be able to leverage these via the Managed Google Play Store:

    Manifest: you must have this inside the section:

            <meta-data android:name="android.content.APP_RESTRICTIONS"
            android:resource="@xml/app_restrictions" />
    

    app_restrictions.xml This file will hold your app restrictions. There are only a few options for app restrictions but you can make this work in all kinds of different creative ways. here's a basic set of restrictions:

    <restrictions xmlns:android="http://schemas.android.com/apk/res/android">
    
        <restriction
        android:key="LicenseKey"
        android:title="@string/LicenseKey"
        android:restrictionType="string"
        android:description="@string/LicenseKey_Description"
        android:defaultValue="" />
    
        <restriction
        android:key="Section1"
        android:title="Settings"
        android:restrictionType="bundle">
    
            <restriction
            android:key="Setting1"
            android:title="Setting 1"
            android:description="More descriptive description here"
            android:restrictionType="choice"
            android:entryValues="@array/setting_1_array_values"
            android:entries="@array/setting_1_array_choices"
            android:defaultValue="@string/setting_1"/>
    
            <restriction
            android:key="Setting2"
            android:title="Setting 2"
            android:description="More descriptive description here"
            android:restrictionType="string"
            android:defaultValue="Some default string value here" />
    
            <restriction
            android:key="Setting3"
            android:title="Setting 3"
            android:description="More descriptive description here"
            android:restrictionType="integer"
            android:defaultValue="20" />
    
    </restriction>
    
    <restriction
        android:key="Section 2"
        android:title="Group things in more sections to make it easier to manage if you have lots of settings"
        android:restrictionType="bundle">
    
            <restriction
            android:key="Setting4"
            android:title="Setting 4"
            android:description="More descriptive description here"
            android:restrictionType="integer"
            android:defaultValue="20" />
    
            <restriction
            android:key="Setting5"
            android:title="Setting 5"
            android:description="More descriptive description here"
            android:restrictionType="integer"
            android:defaultValue="20" />
    
    </restriction>
    

    For some of your restrictions you may want a pre-defined list of items in a drop down style selector - as shown above you can use an array for this and put the following into your Strings.xml

    Strings.xml:

    <string-array name="setting_1_array_choices">
        <item>"Choose This for Option A"</item>
        <item>"Choose This for Option B"</item>
    </string-array>
    <string-array name="setting_1_array_values">
        <item>option_a</item>
        <item>option_b</item>
    </string-array>
    

    Now - loading these restrictions into your app:

        RestrictionsManager manager = (RestrictionsManager) getSystemService(this.RESTRICTIONS_SERVICE);
        Bundle restrictions = manager.getApplicationRestrictions();
        loadRestrictions(restrictions);
    

    To load them I created this loadRestrictions sample:

    private void loadRestrictions (Bundle bundle) {
        Set<String> keys = bundle.keySet();
        if (keys.isEmpty()) {
            //empty key set here
            //nothing sent via MDM App Config
        } else {
            //we've got keys to process
            for (String k : keys) {
                Object value = bundle.get(k);
                String valueString = "";
                if (value != null) {
                    valueString = value.toString();
                }
                switch (k) {
                    case "Section1":
                        if (value != null) {
                            loadRestrictions((Bundle) value);
                        }
                        break;
                    case "Section2":
                        if (value != null) {
                            loadRestrictions((Bundle) value);
                        }
                        break;
                    case "Setting1":
                        //Setting 1
                        // this is an array of choices
                        String optionChoice = "";
                        if(valueString.equals("option_a")) {
                            optionChoice = "Option A Was Chosen";
                        } else if (valueString.equals("option_b")) {
                            optionChoice = "Option B Was Chosen";
                        } else {
                            //we should not ever get here?
                            optionChoice = "ERROR?";
                        }                        
                        break;
                    case "Setting2":
                        //Setting 1
                        // value for this key is in valueString
                        String setting2 = (String) valueString;
                        break;
                    case "Setting3":
                        //Setting 3
                        // INTEGER value for this key is in value
                        int setting3 = (int) value;
                        break;
                    case "Setting4":
                        //Setting 4
                        // INTEGER value for this key is in value
                        int setting4 = (int) value;
                        break;
                    case "Setting5":
                        //Setting 5
                        // INTEGER value for this key is in value
                        int setting5 = (int) value;
                        break;
                    default:
                        //another odd error occurred here
                        break;
                } //switch
            } //for keys
        }
    }//load restrictions
    

    Enjoy!!!