Cuando un dispositivo admite varios usuarios, sus apps deben de estos usuarios distintos.
Ciertas apps deben tener algunos componentes ejecutarse como singleton y pueden aceptar de cualquier usuario. Solo las apps del sistema pueden usar esta función actualmente.
Este centro tiene las siguientes características:
- Conserva los recursos
- Arbitra uno o más recursos compartidos entre usuarios.
- Reduce la sobrecarga de red mediante una única conexión de servidor.
Consulta el siguiente diagrama para ver una descripción del flujo de permisos con varios usuarios.
Cómo habilitar un componente singleton
Para identificar una app como un singleton, agrega android:singleUser="true"
a tu servicio.
receptor o proveedor en el manifiesto de Android.
El sistema creará una instancia de ese componente mientras se ejecuta como usuario 0. solamente. Cualquier solicitud para conectarse a ese proveedor o servicio, o para hacer transmisiones a ese receptor, desde cualquier usuario será enrutado al proceso en el usuario 0. Si este es el único componente de tu aplicación, solo se ejecutará una instancia de tu app.
Las actividades de tu paquete se seguirán iniciando en un proceso separado para por cada usuario, y el UID se encuentra en el rango de UID para ese usuario (como 1010034).
Cómo interactuar con los usuarios
Configurar permisos
Estos permisos son obligatorios
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
Usa APIs
Usa las siguientes APIs para que las apps conozcan varios usuarios.
- Extrae el identificador de usuario de las llamadas entrantes de Binder:
-
int userHandle = UserHandle.getCallingUserId()
-
- Usa APIs nuevas y protegidas para iniciar servicios, actividades y transmisiones en un
usuario:
Context.startActivityAsUser(Intent, UserHandle)
Context.bindServiceAsUser(Intent, …, UserHandle)
Context.sendBroadcastAsUser(Intent, … , UserHandle)
Context.startServiceAsUser(Intent, …, UserHandle)
UserHandle
puede ser un usuario explícito o uno de los identificadores especiales:UserHandle.CURRENT
oUserHandle.ALL
.CURRENT
indica el usuario que está actualmente en primer plano. UsaALL
cuando quieras enviar una transmisión a todos los usuarios. - Cómo comunicarte con los componentes de tu propia app:
(INTERACT_ACROSS_USERS)
O con componentes de otras apps:(INTERACT_ACROSS_USERS_FULL)
- Puede que debas crear componentes proxy
que se ejecuten en el proceso del usuario
y, luego, accede al componente
singleUser
en el usuario 0. - Consulta usuarios y sus controladores con el nuevo servicio del sistema
UserManager
:UserManager.getUsers()
UserManager.getUserInfo()
UserManager.supportsMultipleUsers()
UserManager.getUserSerialNumber(int userHandle)
: Es un número no reciclado que corresponde a un identificador de usuario.UserManager.getUserHandle(int serialNumber)
UserManager.getUserProfiles()
: Muestra la colección de perfiles propios y administrados, si los hubiera.
- Regístrate para escuchar a usuarios específicos o a todos, y las devoluciones de llamada con las nuevas APIs activadas. ContentObserver, PackageMonitor y BroadcastReceiver que proporcionan acceso información sobre el usuario que causó la devolución de llamada.
Servicios en múltiples usuarios o perfiles
No todos los servicios necesitan ejecutar una instancia en otro usuario o perfil de trabajo. Si el servicio del sistema solo necesita ejecutarse como usuario 0, inhabilita los componentes del servicio cuando se ejecute bajo otros usuarios para ayudan a preservar los recursos. En el siguiente ejemplo, se muestra cómo podrías hacer esto en la entrada de tu servicio puntos:
// 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); }
En el ejemplo, también se puede usar PackageManager.setApplicationEnabledSetting()
para inhabilitar
toda la aplicación.