Cuando un dispositivo admite varios usuarios , sus aplicaciones deben tener en cuenta estos distintos usuarios.
Ciertas aplicaciones necesitan que algunos componentes se ejecuten como singleton y puedan aceptar solicitudes de cualquier usuario. Actualmente, solo las aplicaciones del sistema pueden usar esta función.
Esta instalación:
- Conserva los recursos
- Arbitra uno o más recursos compartidos entre usuarios.
- Reduce la sobrecarga de la red mediante el uso de una única conexión de servidor
Consulte el diagrama siguiente para obtener una descripción del flujo de permisos con varios usuarios.
Habilitar un componente singleton
Para identificar una aplicación como singleton, agregue android:singleUser="true"
a su servicio, receptor o proveedor en el manifiesto de Android.
El sistema creará una instancia de ese componente en el proceso que se ejecuta solo como usuario 0. Cualquier solicitud para conectarse a ese proveedor o servicio, o para transmitir a ese receptor, desde cualquier usuario se enrutará al proceso en el usuario 0. Si este es el único componente de su aplicación, solo se ejecutará una instancia de su aplicación.
Las actividades de su paquete se seguirán iniciando en un proceso separado para cada usuario, con el UID dentro del rango de UID para ese usuario (como 1010034).
Interactuando con los usuarios
Establecer permisos
Estos permisos son necesarios
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
Emplear API
Utilice las siguientes API para que las aplicaciones reconozcan a varios usuarios.
- Extraiga el identificador de usuario de las llamadas entrantes de Binder:
-
int userHandle = UserHandle.getCallingUserId()
-
- Utilice API nuevas y protegidas para iniciar servicios, actividades y transmisiones para un usuario específico:
-
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 se encuentra actualmente en primer plano. UtiliceALL
cuando desee enviar una transmisión a todos los usuarios. -
- Comunicarse con componentes en su propia aplicación:
(INTERACT_ACROSS_USERS)
O con componentes en otras aplicaciones:(INTERACT_ACROSS_USERS_FULL)
- Es posible que necesite crear componentes proxy que se ejecuten en el proceso del usuario y que luego accedan al componente
singleUser
en el usuario 0. - Consulta a los usuarios y sus identificadores con el nuevo servicio del sistema
UserManager
:-
UserManager.getUsers()
-
UserManager.getUserInfo()
-
UserManager.supportsMultipleUsers()
-
UserManager.getUserSerialNumber(int userHandle)
: un número no reciclado que corresponde a un identificador de usuario. -
UserManager.getUserHandle(int serialNumber)
-
UserManager.getUserProfiles()
: devuelve la colección de perfiles propios y administrados, si los hay.
-
- Regístrese para escuchar a usuarios específicos o a todos y las devoluciones de llamada con nuevas API en ContentObserver, PackageMonitor, BroadcastReceiver que brindan información adicional sobre qué usuario provocó 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 de su sistema solo necesita ejecutarse como usuario 0, deshabilite los componentes del servicio cuando se ejecute con otros usuarios para ayudar a preservar los recursos. El siguiente ejemplo muestra cómo puede hacer esto en los puntos de entrada de su servicio:
// 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); }
El ejemplo también podría usar PackageManager.setApplicationEnabledSetting()
para deshabilitar toda la aplicación.