Quando um dispositivo oferece suporte a vários usuários, os apps precisam ser informados sobre esses usuários distintos.
Alguns apps precisam executar alguns componentes como singletons e podem aceitar solicitações de qualquer usuário. No momento, apenas apps do sistema podem usar esse recurso.
Esta instalação:
- Conservar 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 conferir uma representação do fluxo de permissões com vários usuários.
Figura 1. Permissões para vários usuários
Ativar um componente singleton
Para identificar um app como um singleton, adicione android:singleUser="true"
ao serviço,
receptor ou provedor no manifesto do Android.
O sistema instancia esse componente no processo executado apenas como usuário 0. Todas as solicitações de conexão com esse provedor ou serviço ou de transmissão para esse receptor de qualquer usuário são roteadas para o processo no usuário 0. Se esse for o único componente no app, apenas uma instância dele será executada.
As atividades no pacote ainda são iniciadas em um processo separado para cada usuário, com o UID no intervalo de UID desse usuário (como 1010034).
Interagir com os usuários
Definir permissões
Estas permissões são obrigatórias:
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
Usar APIs
Use as APIs abaixo para informar aos apps a presença de vários usuários.
- Extraia o identificador do usuário de chamadas de Binder recebidas:
int userHandle = UserHandle.getCallingUserId()
- Use novas APIs protegidas para iniciar serviços, atividades e 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á em primeiro plano. UseALL
quando quiser enviar uma transmissão para todos os usuários. - Comunicar com componentes no seu próprio app:
(INTERACT_ACROSS_USERS)
Ou com componentes em outros apps:(INTERACT_ACROSS_USERS_FULL)
- Talvez seja necessário criar componentes proxy que sejam executados no processo do usuário e
acessem o componente
singleUser
no usuário 0. - Consultar usuários e os identificadores deles com o novo serviço do 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.
- Registro para ouvir usuários específicos ou todos e os callbacks com novas APIs no ContentObserver, PackageMonitor e BroadcastReceiver que fornecem informações adicionais sobre qual usuário causou o callback.
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 precisa ser executado apenas como usuário 0, desative os componentes do serviço quando ele for executado por outros usuários para preservar os recursos. O exemplo abaixo mostra como fazer isso nos pontos de entrada do 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 desativar
todo o app.