Créer des applications multi-utilisateurs

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.

Flux d'autorisations pour plusieurs utilisateurs

Figure 1 : Autorisations pour 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.

  1. Extrayez le handle utilisateur des appels de liaison entrants: <ph type="x-smartling-placeholder">
      </ph>
    • int userHandle = UserHandle.getCallingUserId()
  2. 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 ou UserHandle.ALL. CURRENT indique l'utilisateur qui est actuellement au premier plan. Utilisez ALL lorsque vous le souhaitez envoyer une diffusion à tous les utilisateurs.
  3. Communiquer avec les composants de votre propre application: (INTERACT_ACROSS_USERS) Ou avec des composants d'autres applications: (INTERACT_ACROSS_USERS_FULL)
  4. 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.
  5. 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.
  6. 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.