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.
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.