Quando un dispositivo supporta più utenti , le sue app devono essere informate di questi utenti distinti.
Alcune app devono avere alcuni componenti eseguiti come singleton e possono accettare richieste da qualsiasi utente. Solo le app di sistema possono attualmente utilizzare questa funzionalità.
Questa struttura:
- Conserva le risorse
- Arbitra una o più risorse condivise tra gli utenti
- Riduce il sovraccarico della rete utilizzando una singola connessione al server
Consulta il diagramma seguente per una rappresentazione del flusso di autorizzazioni con più utenti.
Abilitazione di un componente singleton
Per identificare un'app come singleton, aggiungi android:singleUser="true"
al tuo servizio, ricevitore o provider nel manifest Android.
Il sistema creerà un'istanza di quel componente nel processo in esecuzione solo come utente 0. Qualsiasi richiesta di connessione a quel provider o servizio o di trasmissione a quel ricevitore da parte di qualsiasi utente verrà instradata al processo nell'utente 0. Se questo è l'unico componente nella tua app, verrà eseguita solo un'istanza della tua app.
Le attività nel pacchetto verranno comunque avviate in un processo separato per ciascun utente, con l'UID compreso nell'intervallo UID per quell'utente (ad esempio 1010034).
Interagire con gli utenti
Imposta le autorizzazioni
Queste autorizzazioni sono necessarie
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
Utilizza le API
Utilizza le seguenti API per rendere le app consapevoli di più utenti.
- Estrai l'handle utente dalle chiamate Binder in entrata:
-
int userHandle = UserHandle.getCallingUserId()
-
- Utilizza API nuove e protette per avviare servizi, attività, trasmissioni su un utente specifico:
-
Context.startActivityAsUser(Intent, UserHandle)
-
Context.bindServiceAsUser(Intent, …, UserHandle)
-
Context.sendBroadcastAsUser(Intent, … , UserHandle)
-
Context.startServiceAsUser(Intent, …, UserHandle)
UserHandle
può essere un utente esplicito o uno degli handle speciali:UserHandle.CURRENT
oUserHandle.ALL
.CURRENT
indica l'utente attualmente in primo piano. UtilizzaALL
quando desideri inviare una trasmissione a tutti gli utenti. -
- Comunica con i componenti nella tua app:
(INTERACT_ACROSS_USERS)
O con i componenti in altre app:(INTERACT_ACROSS_USERS_FULL)
- Potrebbe essere necessario creare componenti proxy eseguiti nel processo dell'utente che quindi accedono al componente
singleUser
nell'utente 0. - Interroga gli utenti e i loro handle con il nuovo servizio di sistema
UserManager
:-
UserManager.getUsers()
-
UserManager.getUserInfo()
-
UserManager.supportsMultipleUsers()
-
UserManager.getUserSerialNumber(int userHandle)
- un numero non riciclato che corrisponde a un handle utente. -
UserManager.getUserHandle(int serialNumber)
-
UserManager.getUserProfiles()
- restituisce la raccolta di profili personali e gestiti, se presenti.
-
- Registrati per ascoltare utenti specifici o tutti e le richiamate con le nuove API su ContentObserver, PackageMonitor, BroadcastReceiver che forniscono informazioni aggiuntive su quale utente ha causato la richiamata.
Servizi in più utenti o profili
Non tutti i servizi devono eseguire un'istanza in un altro utente o profilo di lavoro. Se il servizio di sistema deve essere eseguito solo come utente 0, disabilita i componenti del servizio quando viene eseguito con altri utenti per preservare le risorse. L'esempio seguente mostra come potresti eseguire questa operazione nei punti di ingresso del tuo servizio:
// 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); }
L'esempio potrebbe anche utilizzare PackageManager.setApplicationEnabledSetting()
per disabilitare l'intera app.