How to Use Namespaces for Advanced Android Configuration

Today, we would like to introduce a feature that we call Custom Configuration. With Custom Config, Esper customers can more effectively finetune Android devices in every way possible. A custom config uses JSON to define changes or actions. These are categorized into sections we like to call Namespaces. Each namespace serves a special purpose.

Recently, we introduced 3 new namespaces, the “settings,” “dpcParams,” and “scripts” namespaces:

  • The “settings” namespace allows you to make over-the-air changes to nearly all Android settings 
  • The “dpcParams” exposes certain tunable parameters within the Esper device Agent. 
  • The “scripts” namespace allows you to perform arbitrary launch actions on the device – whether that be an explicit/implicit intent, a service or a broadcast.

To use these namespaces, you will need to perform a POST request using Curl, Postman, or a similar tool to an API.

POST <endpoint>-api.esper.cloud/api/v0/enterprise/<enterprise-id>/command/

e.g:

POST
https://develop-api.esper.cloud/api/v0/enterprise/ff871e3a-1800-43c6-aab3-c81f8b1f435c/command/

Add an Authorization token and Content-Type header to call this API.

Authorization: Bearer  <your-token-here>

Content-Type: application/json

Please follow the instructions here to generate an access token.

Now, let’s look at  the individual namespaces to understand which BODY needs to be sent with this POST request.

The ‘settings’ namespace:

Android supports three major categories of Settings –  System Settings, Global Settings and Secure Settings. These categories collectively comprise over 500 total settings for single-purpose Android experiences.

Most of the important System Settings can be controlled seamlessly through Esper’s cloud console UI. But, modifying any of the Secure Settings requires an enabled Supervisor plugin for your devices. Modifying global settings also generally requires a Supervisor plugin, with a few exceptions that can now be modified using JSON. 

You’ll need to send the following POST body in order to make use of this namespace.

{
    "command_type": "DEVICE",
    "command": "UPDATE_DEVICE_CONFIG",
    "command_args": {
        "custom_settings_config": {
            "settings": {
                 "global": [
                   {
                          "key": "data_roaming",
                           "value": "1"
                    }
                   ],
                 "secure": [
                      { 
                          "key": "doze_enabled",
                           "value": "0"  
                      }
                 ],
                 "system": [
                      {
                           "key": "screen_off_timeout",
                           "value": "60000"
                      }
                 ]
              }
    },
    "devices": [
        "<device-uuid-here>"
    ],
    "device_type": "all"
    }
}

You’ll need to substitute the device’s UUID to which you need to send the command:

devices": [
      "<device-uuid-here>"
  ],

The UUID of the device can be found out in your browser’s address bar when you view a device. See the screenshot below:

Here 77204919-2f56-40df-85c8-f7740bff93ca is the UUID.

The area of focus in the above mentioned POST body is:

"settings": {
                 "global": [
                   {
                          "key": "data_roaming",
                           "value": "1"
                    }
                   ],
                 "secure": [
                      { 
                          "key": "doze_enabled",
                           "value": "0"  
                      }
                 ],
                 "system": [
                      {
                           "key": "screen_off_timeout",
                           "value": "60000"
                      }
                 ]
              }

In the code example above, we have specified three different settings in three different categories. The “global”, “secure” and “system” sub namespaces accept arrays, which means you can send multiple settings across all three categories in a single payload. All settings that require secure access, including global settings, will require a supervisor plugin. 

After navigating to the official Android documentation page, there are a few things to note: 

  • Most of the Settings have been deprecated
  • The majority of the Secure settings are undocumented, including the settings used in the example above
  • To explore more Settings you can update, navigate to the AOSP code for the Settings Provider

If you need any help finding a particular setting, please don’t hesitate to contact us.

It is also important to note that Secure & Global Settings must be used with extreme caution as these can cause unexpected issues if not handled properly.

Once you POST this request, you can go and check the ‘Event Feed’ of your device to know the status of the operation.

The ‘dpcParams’ namespace:

Now that we’ve seen how we can practically tune any Android Settings, it’s time to talk about some other settings which determine how Esper can work  best for you. We introduced the dpcParams namespace to allow you to control how the Esper Agent’s different parameters can be optimized to your business needs.

We currently support five different DPC parameters and we are actively working to bring more tunable settings for you. Let us look at what these Fabulous Five can do!

Sr. NoDPC ParamDescription
1wifiRevertTimeoutSpecifies the timeout value (of type Long) for the wifi to be turned on automatically after it is turned off.

Default: 10000ms

When and Why to Use This?
On the Esper Console, we allow the ability to turn off the WiFI of your device. Sometimes, an admin can accidentally turn off the WiFi or you may need to turn it off for some reason, but turning it off can disconnect the internet of the device resulting in the device going offline. The timeout automatically turns the WiFI back on when it expires.
2multipleLauncherActivitiesEnables support for apps with multiple launcher icons. Certain apps have multiple home screen icons, this parameter enables the support for that.

Default: false
3bluetoothAutoEnableTimeOutThis parameter works the same as the wifiRevertTimeout parameter, and is used for bluetooth.

Default: -1 (Disabled)
4nonSuspendableLaunchersListWhen you onboard a device, Esper will suspend all the launcher apps on your device. If you need to exempt a launcher app from this auto-suspension, you will need to add your launcher’s packageName to this list
5uploadAllPackagesThis is a boolean parameter that, if enabled, will upload the full app list to the Esper Console.

When and Why to Use This?
Currently, if you view the ‘Apps’ tab in Esper Console, you might only see a list of apps which have launchable home screen icons. However, in some circumstances you might need to load all apps on the device in this list.

Now that we know what all the five parameters can do, let’s look at a few examples on how to utilize these. The POST body for the above namespace would be as follows:

{
  "command_type": "DEVICE",
  "command": "UPDATE_DEVICE_CONFIG",
  "command_args": {
    "custom_settings_config": {
      "dpcParams": [
        {
          "key": "wifiRevertTimeout",
          "value": "150000"
        }
      ]
    },
    "devices": [
      "<device-uuid-here>"
    ],
    "device_type": "all"
  }
}

The point of focus is:

 "dpcParams": [
                {
                    "key": "wifiRevertTimeout",
                     "value": "150000"
                }
            ]

The namespace accepts an array, hence you can specify multiple parameters in a single payload. It’s important to note that, no matter the data type of the parameter, the value of the parameter must always be a String e.g  “value”: “false”,  “value”: “true”

Here’s an example of how you might use the nonSuspendableLaunchersList 

"dpcParams": [
                {
                    "key": "nonSuspendableLaunchersList",
                     "value": "com.android.launcher2"
                }
            ]

Note that you can specify multiple launchers separated by a comma.

The ‘scripts’ namespace:

The scripts namespace enables the  execution  of arbitrary components within or outside the DPC. A script, as the name suggests, is a snippet which defines an action.  Here’s a preview of how this namespace appears: 

{
    "command_type": "DEVICE",
    "command": "UPDATE_DEVICE_CONFIG",
    "command_args": {
        "custom_settings_config": {
            "scripts": [
                {
                    "action": "LAUNCH",
                    "actionParams": {
                        "intentAction": "android.settings.SETTINGS",
                        "extras": {
                            "test1": 12,
                            "test2": "Hello"
                        }
                    }
                }
            ]
        }
    },
    "devices": [
        "<device-uuid-here>"
    ],
    "device_type": "all"
}

The point of focus is:

{
  "scripts": [
    {
      "action": "LAUNCH",
      "actionParams": {
        "intentAction": "android.settings.SETTINGS",
        "extras": {
          "test1": 12,
          "test2": "Hello"
        }
      }
    }
  ]
}

The namespace accepts an array, which means you can enter in multiple scripts to execute. The “actionParams”  host the dictionary of parameters needed to define what kind of launch this is.

An intent, as Android defines it, “is an abstract description of an operation to be performed”. An intent can be used to launch an activity, start a service, or send a broadcast. 

Let us look at the different actionParams that we support and what their purpose is.

ParameterDescriptionExample
intentActionDefines an action to be performed. Usually used to implicitly launch an activity“intentAction”: “android.settings.SETTINGS”.

This launches the Settings app.
componentNameDefines the name of the component towards which the intent is directed. Usually used to start a service or explicitly launch an activity.“componentName”: “io.esper.example/io.esper.example.TestActivity”
flagsSet special flags controlling how this intent is handled. Most values here depend on the type of component being executed by the Intent, specifically the FLAG_ACTIVITY_* flags are all for use with Context#startActivity More info: https://developer.android.com/reference/android/content/Intent#setFlags(int)“flags”: 536870912The flag 536870912

indicates FLAG_ACTIVITY_SINGLE_TOP.

If you need to combine multiple flags, Android suggests to do a bitwise OR. You’ll need to do this yourself and then set the resultant value.
serviceTypeOnly to be used when launching a service. This parameter defines the type of service to be started. BACKGROUND and FOREGROUND are valid values.“serviceType”:
“BACKGROUND”
extrasThis defines a bundle of extras that needs to be attached to the intent. The bundle can host integers, Strings, boolean etc.“extras”: {          
“test1”: 12,          
“test2”: “Hello”
}
launchTypeOptional parameter which specifies what type of component to launch. Valid values are ACTIVITY, SERVICE, or BROADCAST.If this parameter is not specified, the script will start a service if the serviceType parameter is included, otherwise it will launch an explicit activity if componentName parameter is defined, implicit otherwise.“launchType” :
“BROADCAST”


Tells the device to send a broadcast with the specified intent.


You can access all testing materials from the Esper device sample Applications repository. In this repository, you’ll find example JSONs to perform different kinds of launches.

To learn more about Esper’s developer tools, sign up and start using Esper free up to 100 Android devices today

0