Roles

Android Q introduces a standard facility, roles, that allows the OS to grant apps elevated access to system functions based on well-understood use cases. Semantically, each role represents a common use case, such as playing music, viewing photos in a gallery, or sending SMS messages. If an app loses its role, this elevated access is also revoked.

Apps can declare their intended use cases through roles, and then request role-specific elevated access accordingly. However, apps must also satisfy the role requirements to be considered for a role.

Roles help provide users with a clearer association between a key device workflow and the app that's used for performing that workflow.

Roles defined in Android Q

As of Beta 1, Android Q pre-defines the following set of roles and associated privileges:

Name Purpose Role-specific privileges
ROLE_BROWSER Web browser Is the default intent handler for requests to view web content (ACTION_VIEW and CATEGORY_BROWSER)
ROLE_DIALER Phone dialer Is the default handler for outgoing calls and call logs; can send SMS messages
ROLE_SMS SMS messaging app Can send and receive SMS messages; can read contacts
ROLE_HOME Home screen app Is the default launcher
ROLE_MUSIC Music player Has full control over files in the Music media directory, even those that other apps have created
ROLE_GALLERY Photo gallery viewer Has full control over files in the Photos & Videos media directory, even those that other apps have created

Satisfy role requirements

In order for your app to become a role holder, your app must satisfy the requirements for obtaining the elevated access that the role protects.

For example, in order for your app to become the user's default music player, you must declare the following permissions and intent filter in your manifest:

AndroidManifest.xml

<manifest>
    <!-- Use the old permission for devices running Android 9 (API level 28) or
         lower. -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="28" />

    <!-- Use the new "read audio" permission for Android Q. -->
    <uses-permission
        android:name="android.permission.READ_MEDIA_AUDIO" />

    <application>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category
                   android:name="android.intent.category.LAUNCHER" />

                <!-- You must include these categories for your app
                     to be considered for the ROLE_MUSIC role. -->
                <category android:name="android.intent.category.APP_MUSIC" />
                <category android:name="android.intent.category.DEFAULT" />
           </intent-filter>
        </activity>
    </application>
</manifest>

To learn more about permission and intent filter declaration in your app's manifest file, see the Intents and intent filters guide, as well as the <uses-permission> reference.

Request role assignment to your app

To request that your app assume a particular device role, complete the following steps:

  1. Determine whether the role is defined.
  2. Determine whether the user has assigned the role to your app.
  3. Determine whether your app can assume the role.

An example of this workflow appears in the following code snippet:

Kotlin

val roleManager = getSystemService(RoleManager::class.java)
if (roleManager.isRoleAvailable(RoleManager.ROLE_MUSIC)) {
    if (roleManager.isRoleHeld(RoleManager.ROLE_MUSIC)) {
        // This app is the default music app.
     } else {
        // This app isn't the default music player, but the role is available,
        // so request it.
        val roleRequestIntent = roleManager.createRequestRoleIntent(
                RoleManager.ROLE_MUSIC)
        startActivityForResult(roleRequestIntent, ROLE_REQUEST_CODE)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int,
        data: Intent?) {
    if (requestCode == ROLE_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            // Your app has the role that you requested.
        }
    }
}

Java

RoleManager roleManager = getSystemService(RoleManager.class);
if (roleManager.isRoleAvailable(RoleManager.ROLE_MUSIC)) {
    if (roleManager.isRoleHeld(RoleManager.ROLE_MUSIC)) {
        // This app is the default music app.
     } else {
        // This app isn't the default music player, but the role is available,
        // so request it.
        Intent roleRequestIntent = roleManager.createRequestRoleIntent(
                RoleManager.ROLE_MUSIC)
        startActivityForResult(roleRequestIntent, ROLE_REQUEST_CODE)
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode,
                                @Nullable Intent data) {
    if (requestCode == ROLE_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            // Your app has the role that you requested.
        }
    }
}