Se un dispositivo supporta più utenti, le relative app devono essere consapevoli di questi utenti distinti.
Alcune app devono avere alcuni componenti eseguiti come singleton e possono accettare richieste da parte di un qualsiasi utente. Al momento solo le app di sistema possono usare questa funzionalità.
Questa struttura:
- Risparmia risorse
- Arbita una o più risorse condivise tra gli utenti
- Riduce l'overhead della rete utilizzando una singola connessione al server
Consulta il diagramma seguente per una descrizione del flusso di autorizzazioni con più utenti.
Attivazione di un componente singleton
Per identificare un'app come singleton, aggiungi android:singleUser="true"
al tuo servizio,
ricevitore o provider nel file manifest di Android.
Il sistema creerà un'istanza del componente nel processo in esecuzione come utente 0. . Qualsiasi richiesta di connessione a quel fornitore o servizio o di trasmettere a quel destinatario, da qualsiasi utente verrà indirizzato al processo nell'utente 0. Se questo è l'unico componente della tua app, verrà eseguita una sola istanza dell'app.
Le attività incluse nel pacchetto verranno comunque lanciate in un processo separato per ogni utente, con l'UID compreso nell'intervallo di UID di quell'utente (ad esempio 1010034).
Interazione con gli utenti
Imposta autorizzazioni
Queste autorizzazioni sono obbligatorie
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
Utilizza le API
Utilizza le API riportate di seguito per segnalare alle app la presenza di più utenti.
- Estrai l'handle dell'utente dalle chiamate a Binder in arrivo:
-
int userHandle = UserHandle.getCallingUserId()
-
- Utilizza nuove API protette per avviare servizi, attività e trasmissioni su un
utente:
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. UsaALL
quando vuoi inviare un annuncio a tutti gli utenti. - Comunicare con i componenti nella tua app:
(INTERACT_ACROSS_USERS)
Oppure con i componenti in altre app:(INTERACT_ACROSS_USERS_FULL)
- Potrebbe essere necessario creare componenti proxy che vengono eseguiti nel processo dell'utente per
quindi accedi al componente
singleUser
nell'utente 0. - Esegui una query sugli utenti e sui 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 all'handle di un utente.UserManager.getUserHandle(int serialNumber)
UserManager.getUserProfiles()
: restituisce la raccolta degli eventuali profili personali e gestiti.
- Registrati per ascoltare utenti specifici o tutti e i callback con le nuove API su ContentObserver, PackageMonitor, BroadcastReceiver che forniscono informazioni su quale utente ha attivato 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, disattiva i componenti del servizio quando viene eseguito da altri utenti per preservare le risorse. L'esempio seguente mostra come eseguire questa operazione all'indirizzo del tuo servizio punti:
// 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); }
Nell'esempio potresti anche utilizzare PackageManager.setApplicationEnabledSetting()
per disattivare
dell'intera app.