When a device supports multiple users, its apps must be made aware of these distinct users.
Certain apps need to have some components run as singletons and can accept requests from any user. Only system apps can currently use this feature.
This facility:
See the diagram below for a depiction of permissions flow with multiple users.
To identify an app as a singleton, Add android:singleUser=”true”
to your service or provider in the Android manifest.
The system will instantiate that component in the process running as user 0 only. Any requests to connect to that provider or service from any user will be routed to the process in user 0. If this is the only component in your app, only one instance of your app will run.
Activities in your package will still be launched in a separate process for each user, with the UID being in the UID range for that user (such as 1010034).
These permissions are required
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
Use the following APIs to make apps aware of multiple users.
int userHandle = UserHandle.getCallingUserId()
Context.startActivityAsUser(Intent, UserHandle)
Context.bindServiceAsUser(Intent, …, UserHandle)
Context.sendBroadcastAsUser(Intent, … , UserHandle)
Context.startServiceAsUser(Intent, …, UserHandle)
UserHandle
can be an explicit user or one of the special handles: UserHandle.CURRENT
or UserHandle.ALL
. CURRENT
indicates the user that is currently in the foreground. You can use ALL
when you want to send a broadcast to all users.
(INTERACT_ACROSS_USERS)
Or with components in other apps:
(INTERACT_ACROSS_USERS_FULL)
singleUser
component in user 0.
UserManager
system service:
UserManager.getUsers()
UserManager.getUserInfo()
UserManager.supportsMultipleUsers()
UserManager.getUserSerialNumber(int userHandle)
- a non-recycled number that corresponds to a user handle.
UserManager.getUserHandle(int serialNumber)
UserManager.getUserProfiles()
- returns the collection of self and managed profiles, if any.
Not all services need to run an instance in another user or work profile. If your system service only needs to run as user 0, disable the service's components when running under other users to help preserve resources. The following example shows how you might do this at your service's entry points:
// Add on all entry points such as boot_completed or other manifest-listed receivers and providers if (!UserManager.isSystemUser()) { // Disable the service ComponentName targetServiceName = new ComponentName(this, TargetService.class); context.getPackageManager().setComponentEnabledSetting( targetServiceName, COMPONENT_ENABLED_STATE_DISABLED, 0); }
The example could also use PackageManager.setApplicationEnabledSetting()
to disable
the entire app.