Quando um dispositivo oferece suporte a vários usuários , seus aplicativos devem estar cientes desses usuários distintos.
Certos aplicativos precisam ter alguns componentes executados como singletons e podem aceitar solicitações de qualquer usuário. Atualmente, apenas aplicativos do sistema podem usar esse recurso.
Esta facilidade:
- Conserva recursos
- Arbitra um ou mais recursos compartilhados entre usuários
- Reduz a sobrecarga de rede usando uma única conexão de servidor
Consulte o diagrama abaixo para obter uma representação do fluxo de permissões com vários usuários.
Figura 1. Permissões de vários usuários
Habilitando um componente singleton
Para identificar um aplicativo como singleton, adicione android:singleUser=”true”
ao seu serviço, receptor ou provedor no manifesto do Android.
O sistema instanciará esse componente no processo executado apenas como usuário 0. Quaisquer solicitações para se conectar a esse provedor ou serviço, ou para transmitir para esse receptor, de qualquer usuário serão roteadas para o processo no usuário 0. Se este for o único componente em seu aplicativo, apenas uma instância de seu aplicativo será executada.
As atividades em seu pacote ainda serão iniciadas em um processo separado para cada usuário, com o UID no intervalo de UID desse usuário (como 1010034).
Interagindo com os usuários
Definir permissões
Essas permissões são necessárias
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
Empregar APIs
Use as APIs a seguir para tornar os aplicativos cientes de vários usuários.
- Extraia o identificador do usuário das chamadas recebidas do Binder:
-
int userHandle = UserHandle.getCallingUserId()
-
- Use APIs novas e protegidas para iniciar serviços, atividades, transmissões em um usuário específico:
-
Context.startActivityAsUser(Intent, UserHandle)
-
Context.bindServiceAsUser(Intent, …, UserHandle)
-
Context.sendBroadcastAsUser(Intent, … , UserHandle)
-
Context.startServiceAsUser(Intent, …, UserHandle)
UserHandle
pode ser um usuário explícito ou um dos identificadores especiais:UserHandle.CURRENT
ouUserHandle.ALL
.CURRENT
indica o usuário que está atualmente em primeiro plano. UseALL
quando quiser enviar uma transmissão para todos os usuários. -
- Comunique-se com componentes em seu próprio aplicativo:
(INTERACT_ACROSS_USERS)
Ou com componentes em outros aplicativos:(INTERACT_ACROSS_USERS_FULL)
- Pode ser necessário criar componentes de proxy que são executados no processo do usuário que acessam o componente
singleUser
no usuário 0. - Consulte usuários e seus handles com o novo serviço de sistema
UserManager
:-
UserManager.getUsers()
-
UserManager.getUserInfo()
-
UserManager.supportsMultipleUsers()
-
UserManager.getUserSerialNumber(int userHandle)
- um número não reciclado que corresponde a um identificador de usuário. -
UserManager.getUserHandle(int serialNumber)
-
UserManager.getUserProfiles()
- retorna a coleção de perfis próprios e gerenciados, se houver.
-
- Registre-se para ouvir usuários específicos ou todos e os retornos de chamada com novas APIs no ContentObserver, PackageMonitor, BroadcastReceiver que fornecem informações adicionais sobre qual usuário causou o retorno de chamada.
Serviços em vários usuários ou perfis
Nem todos os serviços precisam executar uma instância em outro usuário ou perfil de trabalho. Se o serviço do sistema precisar ser executado apenas como usuário 0, desative os componentes do serviço ao executar com outros usuários para ajudar a preservar os recursos. O exemplo a seguir mostra como você pode fazer isso nos pontos de entrada do seu serviço:
// 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); }
O exemplo também pode usar PackageManager.setApplicationEnabledSetting()
para desabilitar o aplicativo inteiro.