Livre de recettes sur les appareils dédiés

Ce livre de recettes aide les développeurs et les intégrateurs de systèmes à améliorer leurs Google Cloud. Suivez nos recettes pour trouver des solutions aux appareils comportements. Ce livre de recettes convient mieux aux développeurs qui ont déjà l'application d'un appareil. Si vous débutez, consultez la section Appareils dédiés présentation.

Applications Home personnalisées

Ces recettes sont utiles si vous développez une application pour remplacer Android Home l'écran et le lanceur d'applications.

Devenez l'appli d'accueil

Vous pouvez définir votre application comme application d'accueil de l'appareil pour qu'elle soit lancée automatiquement au démarrage de l'appareil. Vous pouvez également activer qui permet de verrouiller l'application que vous avez ajoutée à la liste d'autorisation au premier plan les tâches.

Toutes les applications d'accueil gèrent la catégorie d'intent CATEGORY_HOME : permet au système de reconnaître une application d'accueil. Définissez-en une pour devenir l'application d'accueil par défaut des activités de votre application comme gestionnaire privilégié d'intent Home, en appelant DevicePolicyManager.addPersistentPreferredActivity() comme illustré dans l'exemple suivant:

Kotlin

// Create an intent filter to specify the Home category.
val filter = IntentFilter(Intent.ACTION_MAIN)
filter.addCategory(Intent.CATEGORY_HOME)
filter.addCategory(Intent.CATEGORY_DEFAULT)

// Set the activity as the preferred option for the device.
val activity = ComponentName(context, KioskModeActivity::class.java)
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE)
        as DevicePolicyManager
dpm.addPersistentPreferredActivity(adminName, filter, activity)

Java

// Create an intent filter to specify the Home category.
IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);

// Set the activity as the preferred option for the device.
ComponentName activity = new ComponentName(context, KioskModeActivity.class);
DevicePolicyManager dpm =
    (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.addPersistentPreferredActivity(adminName, filter, activity);

Vous devez toujours déclarer le filtre d'intent dans le fichier manifeste de votre application, comme indiqué dans l'extrait de code XML suivant:

<activity
        android:name=".KioskModeActivity"
        android:label="@string/kiosk_mode"
        android:launchMode="singleInstance"
        android:excludeFromRecents="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.HOME"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

En règle générale, il est préférable que votre application de lancement ne s'affiche pas sur l'écran "Aperçu". Toutefois, vous n'avez pas besoin d'ajouter excludeFromRecents à la déclaration d'activité, car le lanceur d'applications d'Android masque lorsque le système s'exécute en mode tâches verrouillées.

Afficher des tâches distinctes

FLAG_ACTIVITY_NEW_TASK peut être un indicateur utile pour de type lanceur d'applications, car chaque nouvelle tâche apparaît comme un élément distinct dans Écran "Aperçu". Pour en savoir plus sur les tâches dans l'écran "Aperçu", consultez la section Récents Écran.

Kiosques publics

Ces recettes sont idéales pour les appareils non surveillés dans les espaces publics, aident de nombreux utilisateurs d’appareils dédiés à se concentrer sur leurs tâches.

Verrouiller l'appareil

Pour vous assurer que les appareils sont utilisés à bon escient, vous pouvez ajouter les restrictions utilisateur présentées dans le tableau 1.

Tableau 1. Restrictions utilisateur pour les appareils en mode kiosque
Restriction utilisateur Description
DISALLOW_FACTORY_RESET Empêche l'utilisateur de rétablir la configuration d'usine de l'appareil. Les administrateurs d'appareils entièrement gérés et l'utilisateur principal peuvent définir ce paramètre. ou d'une restriction d'accès.
DISALLOW_SAFE_BOOT Empêche l'utilisateur de démarrer l'appareil dans mode sans échec lorsque le système ne lancera pas automatiquement votre application. Les administrateurs de comptes appareils gérés et l'utilisateur principal peut définir cette restriction.
DISALLOW_MOUNT_PHYSICAL_MEDIA Empêche l'utilisateur de l'appareil d'installer les volumes de stockage à l'appareil. Administrateurs d'appareils entièrement gérés et utilisateur principal vous pouvez définir cette restriction.
DISALLOW_ADJUST_VOLUME Coupe le son de l'appareil et empêche l'utilisateur de modifier le son les paramètres de volume et du vibreur. Vérifier que votre kiosque n'a pas besoin d'audio pour la lecture de contenus multimédias ou les fonctionnalités d'accessibilité. Les administrateurs de comptes l'utilisateur principal, les utilisateurs secondaires et les profils professionnels ou d'une restriction d'accès.
DISALLOW_ADD_USER Empêche l'utilisateur de l'appareil d'ajouter des utilisateurs, comme des utilisateurs secondaires ou à des utilisateurs restreints. Le système ajoute automatiquement cette restriction utilisateur des appareils entièrement gérés, mais il a peut-être été effacé. Les administrateurs de comptes appareils gérés et l'utilisateur principal peut définir cette restriction.

L'extrait de code suivant montre comment définir ces restrictions:

Kotlin

// If the system is running in lock task mode, set the user restrictions
// for a kiosk after launching the activity.
arrayOf(
        UserManager.DISALLOW_FACTORY_RESET,
        UserManager.DISALLOW_SAFE_BOOT,
        UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
        UserManager.DISALLOW_ADJUST_VOLUME,
        UserManager.DISALLOW_ADD_USER).forEach { dpm.addUserRestriction(adminName, it) }

Java

// If the system is running in lock task mode, set the user restrictions
// for a kiosk after launching the activity.
String[] restrictions = {
    UserManager.DISALLOW_FACTORY_RESET,
    UserManager.DISALLOW_SAFE_BOOT,
    UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
    UserManager.DISALLOW_ADJUST_VOLUME,
    UserManager.DISALLOW_ADD_USER};

for (String restriction: restrictions) dpm.addUserRestriction(adminName, restriction);

Vous pouvez supprimer ces restrictions lorsque votre application est en mode administrateur afin de qu'un administrateur informatique puisse toujours utiliser ces fonctionnalités pour la maintenance des appareils. Pour effacer la restriction, appeler DevicePolicyManager.clearUserRestriction()

Supprimer les boîtes de dialogue d'erreur

Dans certains environnements, tels que les démonstrations en magasin ou l'information publique s'affiche, vous ne souhaitez peut-être pas présenter de boîtes de dialogue d'erreur aux utilisateurs. Dans Android 9.0 (API niveau 28) ou supérieur, vous pouvez supprimer les boîtes de dialogue d'erreur système en cas de plantage les applications qui ne répondent pas en ajoutant le paramètre Utilisateur DISALLOW_SYSTEM_ERROR_DIALOGS ou d'une restriction d'accès. Le système redémarre les applications qui ne répondent pas, comme si l'utilisateur avait fermé l'appareil. l'application depuis la boîte de dialogue. L'exemple suivant montre comment procéder:

Kotlin

override fun onEnabled(context: Context, intent: Intent) {
    val dpm = getManager(context)
    val adminName = getWho(context)

    dpm.addUserRestriction(adminName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS)
}

Java

public void onEnabled(Context context, Intent intent) {
  DevicePolicyManager dpm = getManager(context);
  ComponentName adminName = getWho(context);

  dpm.addUserRestriction(adminName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS);
}

Si un administrateur de l'utilisateur principal ou secondaire définit cette restriction, le système supprime les boîtes de dialogue d'erreur uniquement pour cet utilisateur. Si l'administrateur d'un compte appareil définit cette restriction, le système supprime les boîtes de dialogue pour tous les utilisateurs.

Gardez l'écran allumé

Si vous créez un kiosque, vous pouvez empêcher un appareil de se rendre veille lorsque l'activité de votre application est exécutée. Ajouter l'indicateur de mise en page FLAG_KEEP_SCREEN_ON à l'élément comme illustré dans l'exemple suivant:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Keep the screen on and bright while this kiosk activity is running.
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  // Keep the screen on and bright while this kiosk activity is running.
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

Nous vous conseillons de vérifier que l'appareil est branché à un secteur, à un port USB ou à un réseau sans fil. le chargeur. S'inscrire pour recevoir des annonces sur les changements de batterie et utiliser BatteryManager pour connaître l'état de charge. Vous pouvez même envoyer à distance des alertes administrateur si l'appareil est débranché. Pour obtenir des instructions détaillées, consultez Contrôler le niveau de la batterie et le niveau de charge État.

Vous pouvez également définir le STAY_ON_WHILE_PLUGGED_IN paramètre global pour maintenir l'appareil activé lorsqu'il est branché à une source d'alimentation. Les administrateurs d'appareils entièrement gérés équipés d'Android 6.0 (niveau d'API 23) ou version ultérieure peuvent : appelez DevicePolicyManager.setGlobalSetting() comme indiqué dans l'exemple suivant:

Kotlin

val pluggedInto = BatteryManager.BATTERY_PLUGGED_AC or
        BatteryManager.BATTERY_PLUGGED_USB or
        BatteryManager.BATTERY_PLUGGED_WIRELESS
dpm.setGlobalSetting(adminName,
        Settings.Global.STAY_ON_WHILE_PLUGGED_IN, pluggedInto.toString())

Java

int pluggedInto = BatteryManager.BATTERY_PLUGGED_AC |
    BatteryManager.BATTERY_PLUGGED_USB |
    BatteryManager.BATTERY_PLUGGED_WIRELESS;
dpm.setGlobalSetting( adminName,
    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, String.valueOf(pluggedInto));

Packages d'applis

Cette section contient des recettes pour installer efficacement des applications sur des appareils dédiés.

Mettre en cache les packages d'applications

Si les utilisateurs d'un appareil partagé partagent un ensemble commun d'applications, qu'il est judicieux d'éviter de télécharger des applications autant que possible. Pour simplifier la navigation sur des appareils partagés avec un ensemble fixe d'utilisateurs, comme des appareils les travailleurs postés, sous Android 9.0 (niveau d'API 28) ou version ultérieure, vous pouvez mettre en cache des applications (APK) requis pour les sessions multi-utilisateurs.

L'installation d'un APK mis en cache (déjà installé sur l'appareil) s'effectue dans en deux étapes:

  1. Le composant "admin" d'un appareil entièrement géré (ou d'un délégué) qui suit) définit la liste des APK à conserver sur l'appareil.
  2. Les composants d'administration des utilisateurs secondaires affiliés (ou de leurs délégués) peuvent installer l'APK mis en cache pour le compte de l'utilisateur. Les administrateurs de comptes appareil, l'utilisateur principal ou un profil professionnel affilié (ou son délégué) peuvent également installer l'application mise en cache, si nécessaire.

Pour définir la liste des APK à conserver sur l'appareil, l'administrateur appelle DevicePolicyManager.setKeepUninstalledPackages() Cette méthode ne vérifie pas que l'APK est installé sur l'appareil. Elle est utile si vous voulez installer une application juste avant que vous en ayez besoin pour un utilisateur. Pour obtenir une liste précédemment définis, vous pouvez appeler DevicePolicyManager.getKeepUninstalledPackages() Après avoir appelé setKeepUninstalledPackages() avec les modifications ou lorsqu'un serveur secondaire utilisateur est supprimé, le système supprime tous les APK mis en cache qui ne sont plus nécessaires.

Pour installer un APK mis en cache, appelez DevicePolicyManager.installExistingPackage() Avec cette méthode, vous ne pouvez installer qu'une application déjà mise en cache par le système : votre solution pour appareil dédié (ou l'utilisateur d'un appareil) doit d'abord installer l'application sur l'appareil avant de pouvoir appeler cette méthode.

L'exemple suivant montre comment utiliser ces appels d'API dans l'interface d'administration un appareil entièrement géré et un utilisateur secondaire:

Kotlin

// Set the package to keep. This method assumes that the package is already
// installed on the device by managed Google Play.
val cachedAppPackageName = "com.example.android.myapp"
dpm.setKeepUninstalledPackages(adminName, listOf(cachedAppPackageName))

// ...

// The admin of a secondary user installs the app.
val success = dpm.installExistingPackage(adminName, cachedAppPackageName)

Java

// Set the package to keep. This method assumes that the package is already
// installed on the device by managed Google Play.
String cachedAppPackageName = "com.example.android.myapp";
List<String> packages = new ArrayList<String>();
packages.add(cachedAppPackageName);
dpm.setKeepUninstalledPackages(adminName, packages);

// ...

// The admin of a secondary user installs the app.
boolean success = dpm.installExistingPackage(adminName, cachedAppPackageName);

Déléguer des applications

Vous pouvez déléguer la gestion de la mise en cache des applications à une autre application. Vous pourriez le faire pour séparer les fonctionnalités de votre solution ou permettre aux administrateurs informatiques d'utiliser leurs propres applications. L'application déléguée reçoit les mêmes autorisations que l'administrateur . Par exemple, le délégué d'application de l'administrateur d'un utilisateur secondaire peut appeler installExistingPackage(), mais impossible d'appeler setKeepUninstalledPackages().

Pour passer un appel délégué DevicePolicyManager.setDelegatedScopes() et inclure DELEGATION_KEEP_UNINSTALLED_PACKAGES dans l'argument "Scopes". L'exemple suivant montre comment créer une autre application le délégué:

Kotlin

var delegatePackageName = "com.example.tools.kept_app_assist"

// Check that the package is installed before delegating.
try {
    context.packageManager.getPackageInfo(delegatePackageName, 0)
    dpm.setDelegatedScopes(
            adminName,
            delegatePackageName,
            listOf(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES))
} catch (e: PackageManager.NameNotFoundException) {
    // The delegate app isn't installed. Send a report to the IT admin ...
}

Java

String delegatePackageName = "com.example.tools.kept_app_assist";

// Check that the package is installed before delegating.
try {
  context.getPackageManager().getPackageInfo(delegatePackageName, 0);
  dpm.setDelegatedScopes(
      adminName,
      delegatePackageName,
      Arrays.asList(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES));
} catch (PackageManager.NameNotFoundException e) {
  // The delegate app isn't installed. Send a report to the IT admin ...
}

Si tout se passe comme prévu, l'application déléguée reçoit la ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED diffuser et devient le délégué. L'application peut appeler les méthodes de ce guide comme s'il s'agissait du propriétaire de l'appareil ou du profil. Lors d'un appel DevicePolicyManager, le délégué transmet null pour l'administrateur composant.

Installer des packages d'applis

Il est parfois utile d'installer une application personnalisée mise en cache localement sur une appareil. Par exemple, des appareils dédiés sont souvent déployés pour les environnements à bande passante limitée ou les zones sans connexion Internet. Votre une solution dédiée doit être attentive à la bande passante de vos clients. Votre application peut lancer l'installation d'un autre package d'application (APK) à l'aide de la PackageInstaller.

Toutes les applications peuvent installer des APK. En revanche, les administrateurs d'appareils entièrement gérés peuvent installer (ou désinstaller) des packages sans intervention de l’utilisateur. L'administrateur peut gérer l'appareil, un utilisateur secondaire affilié ou un profil professionnel affilié. Après la fin de l'installation, le système publie une notification indiquant que tous les utilisateurs de l'appareil voir. La notification informe les utilisateurs de l'appareil que l'application a été installée (ou mis à jour) par son administrateur.

Tableau 2. Versions d'Android compatibles avec l'installation de packages sans intervention de l'utilisateur
Version d'Android Composant d'administration pour l'installation et la désinstallation
Android 9.0 (niveau d'API 28) ou version ultérieure Utilisateurs secondaires et profils professionnels affiliés, tous deux entièrement gérés appareils
Android 6.0 (niveau d'API 23) ou version ultérieure Appareils entièrement gérés

La façon dont vous distribuez une ou plusieurs copies du fichier APK sur des appareils dédiés dépend de la distance entre les appareils et, éventuellement, de la distance qui les sépare les uns des autres. Votre solution doit respecter les bonnes pratiques de sécurité avant d'installer des APK sur des appareils dédiés.

Vous pouvez utiliser PackageInstaller.Session pour créer une session qui met une session en file d'attente. ou plusieurs APK à installer. Dans l'exemple suivant, nous recevons des informations dans notre activité (mode singleTop), mais vous pouvez utiliser un ou broadcast receiver:

Kotlin

// First, create a package installer session.
val packageInstaller = context.packageManager.packageInstaller
val params = PackageInstaller.SessionParams(
        PackageInstaller.SessionParams.MODE_FULL_INSTALL)
val sessionId = packageInstaller.createSession(params)
val session = packageInstaller.openSession(sessionId)

// Add the APK binary to the session. The APK is included in our app binary
// and is read from res/raw but file storage is a more typical location.
// The I/O streams can't be open when installation begins.
session.openWrite("apk", 0, -1).use { output ->
    getContext().resources.openRawResource(R.raw.app).use { input ->
        input.copyTo(output, 2048)
    }
}

// Create a status receiver to report progress of the installation.
// We'll use the current activity.
// Here we're requesting status feedback to our Activity but this can be a
// service or broadcast receiver.
val intent = Intent(context, activity.javaClass)
intent.action = "com.android.example.APK_INSTALLATION_ACTION"
val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0)
val statusReceiver = pendingIntent.intentSender

// Start the installation. Because we're an admin of a fully managed device,
// there isn't any user interaction.
session.commit(statusReceiver)

Java

// First, create a package installer session.
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
    PackageInstaller.SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);

// Add the APK binary to the session. The APK is included in our app binary
// and is read from res/raw but file storage is a more typical location.
try (
    // These I/O streams can't be open when installation begins.
    OutputStream output = session.openWrite("apk", 0, -1);
    InputStream input = getContext().getResources().openRawResource(R.raw.app);
) {
  byte[] buffer = new byte[2048];
  int n;
  while ((n = input.read(buffer)) >= 0) {
    output.write(buffer, 0, n);
  }
}

// Create a status receiver to report progress of the installation.
// We'll use the current activity.
// Here we're requesting status feedback to our Activity but this can be a
// service or broadcast receiver.
Intent intent = new Intent(context, getActivity().getClass());
intent.setAction("com.android.example.APK_INSTALLATION_ACTION");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.getIntentSender();

// Start the installation. Because we're an admin of a fully managed device,
// there isn't any user interaction.
session.commit(statusReceiver);

La session envoie des commentaires sur l'état de l'installation à l'aide d'intents. Chèque le champ EXTRA_STATUS de chaque intent pour obtenir état. N'oubliez pas que les administrateurs ne reçoivent pas Mise à jour de l'état de STATUS_PENDING_USER_ACTION car l'utilisateur de l'appareil n'a pas besoin d'approuver l'installation.

Pour désinstaller des applications, vous pouvez appeler PackageInstaller.uninstall. Les administrateurs d'appareils entièrement gérés, d'utilisateurs et de profils professionnels peuvent désinstaller des packages. sans intervention de l'utilisateur, si vous exécutez une version d'Android compatible (consultez l'article tableau 2).

Geler les mises à jour du système

Les appareils Android reçoivent des mises à jour OTA du système et des applications. logiciels. Pour figer la version du système d'exploitation lors des périodes critiques, comme les jours fériés ou pendant les périodes d'affluence, les appareils dédiés peuvent suspendre les mises à jour du système OTA jusqu'à 90 jours. Pour en savoir plus, consultez Gérer les mises à jour du système.

Remote Config

Les configurations gérées d'Android permettent aux administrateurs informatiques configurer votre application à distance. Vous voudrez peut-être exposer des paramètres tels que des listes d'autorisation, des hôtes réseau ou des URL de contenu afin de rendre votre application plus utile pour les équipes informatiques pour les administrateurs.

Si votre application expose sa configuration, n'oubliez pas d'inclure les paramètres dans votre dans la documentation Google Cloud. Pour savoir comment exposer la configuration de votre application et réagir aux modifications apportées aux paramètres, consultez Définir des configurations gérées.

Configuration du développement

Lorsque vous développez une solution pour des appareils dédiés, utile de définir votre application comme administrateur d'un appareil entièrement géré sans configuration d'usine réinitialisés. Pour définir l'administrateur d'un appareil entièrement géré, procédez comme suit:

  1. Créez et installez votre application de contrôle des règles relatives aux appareils (DPC) sur l'appareil.
  2. Vérifiez qu'aucun compte n'est enregistré sur l'appareil.
  3. Exécutez la commande suivante dans le shell Android Debug Bridge (adb). Toi devez remplacer com.example.dpc/.MyDeviceAdminReceiver dans l'exemple par nom du composant d'administration de votre application:

    adb shell dpm set-device-owner com.example.dpc/.MyDeviceAdminReceiver

Pour aider les clients à déployer votre solution, vous devrez consulter d'autres méthodes d'enregistrement méthodes. Nous vous recommandons d'enregistrer un code QR dans les cas suivants : appareils dédiés.

Ressources supplémentaires

Pour en savoir plus sur les appareils dédiés, consultez les documents suivants: