Lorsqu'un appareil accepte plusieurs utilisateurs, ses applications doivent être au courant de ces différents utilisateurs.
Pour certaines applications, certains composants doivent s'exécuter en tant que singletons et accepter les requêtes de n'importe quel utilisateur. Actuellement, seules les applications système peuvent utiliser cette fonctionnalité.
Cette installation:
- Limite les ressources
- Arbite une ou plusieurs ressources partagées entre les utilisateurs
- Réduit la surcharge réseau en utilisant une seule connexion au serveur.
Le schéma ci-dessous illustre le flux d'autorisations avec plusieurs utilisateurs.
Activer un composant singleton
Pour identifier une application en tant que singleton, ajoutez android:singleUser="true"
à votre service :
récepteur ou fournisseur dans le fichier manifeste Android.
Le système instancie ce composant dans le processus s'exécutant en tant qu'utilisateur 0 uniquement. Toute demande de connexion à ce fournisseur ou de service, ou de diffusion à ce destinataire, tout utilisateur sera acheminé vers le processus de l'utilisateur 0. S'il s'agit du seul composant de votre application, une seule instance de votre application s'exécutera.
Les activités de votre package seront quand même lancées dans un processus distinct pour chaque utilisateur, l'UID se trouvant dans la plage d'UID de cet utilisateur (par exemple, 1010034).
Interagir avec les utilisateurs
Définir les autorisations
Ces autorisations sont requises
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
Utiliser des API
Utilisez les API suivantes pour que les applications puissent prendre en compte plusieurs utilisateurs.
- Extrayez le handle utilisateur des appels de liaison entrants:
<ph type="x-smartling-placeholder">
- </ph>
-
int userHandle = UserHandle.getCallingUserId()
-
- Utilisez de nouvelles API protégées pour démarrer des services, des activités et des diffusions sur une
utilisateur:
<ph type="x-smartling-placeholder">
- </ph>
Context.startActivityAsUser(Intent, UserHandle)
Context.bindServiceAsUser(Intent, …, UserHandle)
Context.sendBroadcastAsUser(Intent, … , UserHandle)
Context.startServiceAsUser(Intent, …, UserHandle)
UserHandle
peut être un utilisateur explicite ou l'un des identifiants spéciaux:UserHandle.CURRENT
ouUserHandle.ALL
.CURRENT
indique l'utilisateur qui est actuellement au premier plan. UtilisezALL
lorsque vous le souhaitez envoyer une diffusion à tous les utilisateurs. - Communiquer avec les composants de votre propre application:
(INTERACT_ACROSS_USERS)
Ou avec des composants d'autres applications:(INTERACT_ACROSS_USERS_FULL)
- Vous devrez peut-être créer des composants de proxy
qui s'exécutent dans le processus de l'utilisateur et
Accédez ensuite au composant
singleUser
de l'utilisateur 0. - Interrogez les utilisateurs et leurs identifiants avec le nouveau service système
UserManager
: <ph type="x-smartling-placeholder">- </ph>
UserManager.getUsers()
UserManager.getUserInfo()
UserManager.supportsMultipleUsers()
UserManager.getUserSerialNumber(int userHandle)
: numéro non recyclé correspondant à l'identifiant d'un utilisateur.UserManager.getUserHandle(int serialNumber)
UserManager.getUserProfiles()
: renvoie la collection des profils internes et gérés, le cas échéant.
- Inscrivez-vous pour écouter des utilisateurs spécifiques ou tous, ainsi que les rappels avec les nouvelles API activées. ContentObserver, PackageMonitor, BroadcastReceiver, qui fournissent des informations sur l'utilisateur à l'origine du rappel.
Services pour plusieurs utilisateurs ou profils
Tous les services n'ont pas besoin d'exécuter une instance dans un autre profil utilisateur ou profil professionnel. Si votre service système ne doit s'exécuter qu'en tant qu'utilisateur 0, désactivez les composants du service lorsque vous l'exécutez sous d'autres utilisateurs pour pour préserver les ressources. L'exemple suivant montre comment procéder au niveau de l'entrée de votre service points:
// 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'exemple peut également utiliser PackageManager.setApplicationEnabledSetting()
pour désactiver
l'ensemble de l'application.