Istruzioni sui dispositivi dedicati

Questo libro di ricette aiuta sviluppatori e integratori di sistemi a migliorare soluzione di dispositivo. Segui le nostre ricette per trovare soluzioni per i dispositivi i comportamenti dei modelli, Questo libro di ricette è più adatto agli sviluppatori che hanno già un dell'app del dispositivo: se hai appena iniziato, leggi l'articolo Dispositivi dedicati Panoramica.

App Home personalizzate

Queste ricette sono utili se stai sviluppando un'app che sostituisca Android Home schermata e Avvio app.

Diventa l'app Home

Puoi impostare la tua app come app Home del dispositivo in modo che venga lanciata automaticamente all'avvio del dispositivo. Puoi anche attivare la home page pulsante che porta la tua app inclusa nella lista consentita in primo piano nella schermata di blocco modalità attività.

Tutte le app per la casa gestiscono la categoria di intent CATEGORY_HOME, che è il modo in cui il sistema riconosce un'app Home. Per diventare l'app Home predefinita, impostane una delle attività della tua app come gestore di intent preferito, chiamando DevicePolicyManager.addPersistentPreferredActivity() come mostrato nell'esempio seguente:

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);

Devi comunque dichiarare il filtro di intent nel file manifest dell'app, come mostrato nel seguente snippet XML:

<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>

In genere non vuoi che l'app Avvio app venga visualizzata nella schermata Panoramica. Tuttavia, non è necessario aggiungere excludeFromRecents a la dichiarazione dell'attività perché Avvio app di Android nasconde la versione attività quando il sistema è in esecuzione in modalità di blocco attività.

Mostra attività separate

FLAG_ACTIVITY_NEW_TASK può essere un indicatore utile di tipo Avvio app perché ogni nuova attività viene visualizzata come elemento separato nella Schermata Panoramica. Per scoprire di più sulle attività nella schermata Panoramica, leggi Recenti. Schermo.

Chioschi pubblici

Queste ricette sono perfette per i dispositivi automatici negli spazi pubblici, ma possono anche per aiutare molti utenti di dispositivi dedicati a concentrarsi sulle proprie attività.

Blocca il dispositivo

Per assicurarti che i dispositivi vengano utilizzati per la finalità prevista, puoi aggiungere le limitazioni relative all'utente elencate nella tabella 1.

Tabella 1. Limitazioni per gli utenti relative ai dispositivi kiosk
Limitazione utente Descrizione
DISALLOW_FACTORY_RESET Impedisce all'utente di ripristinare le impostazioni di fabbrica del dispositivo. Gli amministratori di dispositivi completamente gestiti e l'utente principale possono impostare questa opzione delle risorse.
DISALLOW_SAFE_BOOT Impedisce all'utente di avviare il dispositivo in modalità provvisoria in cui il sistema non avvierà automaticamente l'app. Amministratori di dispositivi gestiti e l'utente principale può impostare questa limitazione.
DISALLOW_MOUNT_PHYSICAL_MEDIA Impedisce all'utente del dispositivo di montare qualsiasi volume di archiviazione che potrebbe collega al dispositivo. Amministratori di dispositivi completamente gestiti e utente principale possono impostare questa restrizione.
DISALLOW_ADJUST_VOLUME Disattiva l'audio del dispositivo e impedisce all'utente del dispositivo di modificare il suono. impostazioni volume e vibrazione. Verifica che il kiosk non abbia bisogno di audio per la riproduzione di contenuti multimediali o le funzioni di accessibilità. Amministratori di app completamente gestite dispositivi mobili, l'utente principale, gli utenti secondari e i profili di lavoro possono impostare questa delle risorse.
DISALLOW_ADD_USER Impedisce all'utente del dispositivo di aggiungere nuovi utenti, ad esempio utenti secondari o utenti con limitazioni. Il sistema aggiunge automaticamente questa limitazione utente a dispositivi completamente gestiti, ma potrebbe essere stato cancellato. Amministratori di dispositivi gestiti e l'utente principale può impostare questa limitazione.

Il seguente snippet mostra come impostare le limitazioni:

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);

Ti consigliamo di rimuovere queste limitazioni quando la tua app è in modalità amministratore. che un amministratore IT potesse comunque usare queste funzionalità per la manutenzione del dispositivo. Per cancellare la restrizione, chiama DevicePolicyManager.clearUserRestriction()

Elimina finestre di dialogo di errore

In alcuni ambienti, ad esempio dimostrazioni di vendita al dettaglio o informazioni pubbliche potrebbe essere utile non mostrare agli utenti finestre di dialogo di errore. In Android 9.0 (API livello 28) o superiore, puoi eliminare le finestre di dialogo degli errori di sistema per che non risponde alle app aggiungendo Utente di DISALLOW_SYSTEM_ERROR_DIALOGS delle risorse. Il sistema si riavvia con le app che non rispondono come se l'utente del dispositivo fosse chiuso l'app dalla finestra di dialogo. L'esempio seguente mostra come eseguire questa operazione:

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);
}

Se un amministratore dell'utente principale o secondario imposta questa limitazione, il sistema elimina le finestre di dialogo di errore solo per quell'utente. Se un amministratore di un account dispositivo imposta questa limitazione, il sistema elimina le finestre di dialogo per tutti gli utenti.

Mantieni lo schermo acceso

Se stai costruendo un kiosk, puoi interrompere l'accesso di un dispositivo dormire quando è in corso l'attività della tua app. Aggiungi il flag di layout FLAG_KEEP_SCREEN_ON allo sfondo come mostrato nell'esempio seguente:

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);
}

È consigliabile controllare che il dispositivo sia collegato a una presa CA, USB o wireless caricabatterie. Registrati per le trasmissioni con sostituzione della batteria e usa BatteryManager per scoprire lo stato di ricarica. Puoi anche inviare avvisi remoti a un amministratore se il dispositivo viene scollegato dall'alimentazione. Per istruzioni passo passo, leggi Monitorare il livello della batteria e la ricarica Stato.

Puoi anche impostare STAY_ON_WHILE_PLUGGED_IN impostazione globale per mantenere attivo il dispositivo mentre è collegato a una fonte di alimentazione. Gli amministratori di dispositivi completamente gestiti in Android 6.0 (livello API 23) o versioni successive possono chiama DevicePolicyManager.setGlobalSetting() come mostrato nel seguente esempio:

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));

Pacchetti di app

Questa sezione contiene ricette per installare in modo efficiente le app sui dispositivi dedicati.

Memorizza nella cache i pacchetti dell'app

Se gli utenti di un dispositivo condiviso condividono tutti un insieme di app, evitare di scaricare app quando è possibile. Per semplificare l'esperienza su dispositivi condivisi con un insieme fisso di utenti, come i dispositivi per turni, in Android 9.0 (livello API 28) o versioni successive, puoi memorizzare nella cache pacchetti (APK) necessari per le sessioni multiutente.

L'installazione di un APK memorizzato nella cache (già installato sul dispositivo) avviene in in due fasi:

  1. Il componente Amministratore di un dispositivo completamente gestito (o un delegato: vedi seguente) consente di impostare l'elenco di APK da conservare sul dispositivo.
  2. I componenti amministrativi degli utenti secondari affiliati (o dei loro delegati) possono installare l'APK memorizzato nella cache per conto dell'utente. Amministratori della piattaforma dispositivo, l'utente principale o un profilo di lavoro affiliato (o possono anche installare l'app memorizzata nella cache, se necessario.

Per impostare l'elenco di APK da conservare sul dispositivo, l'amministratore chiama DevicePolicyManager.setKeepUninstalledPackages() Questo metodo non controlla che l'APK sia installato sul dispositivo. È utile se vuoi installare un'app appena prima di averne bisogno per un utente. Per ottenere un elenco impostati in precedenza, puoi richiamare DevicePolicyManager.getKeepUninstalledPackages() Dopo aver chiamato setKeepUninstalledPackages() con modifiche o quando un indirizzo un utente, il sistema elimina tutti gli APK memorizzati nella cache che non sono più necessari.

Per installare un APK memorizzato nella cache, chiama DevicePolicyManager.installExistingPackage() Questo metodo consente di installare soltanto un'app che il sistema ha già memorizzato nella cache: (o l'utente di un dispositivo) deve prima installare l'app il dispositivo prima di poter chiamare questo metodo.

L'esempio seguente mostra come utilizzare queste chiamate API nell'amministratore un dispositivo completamente gestito e un utente secondario:

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);

Delegare le app

Puoi delegare un'altra app a gestire la memorizzazione nella cache dell'app. Puoi eseguire questa operazione per separare le funzionalità della soluzione o offrire agli amministratori IT la possibilità di utilizzarle le proprie app. L'app delegata riceve le stesse autorizzazioni dell'amministratore di strumento di authoring. Ad esempio, un delegato di un'app dell'amministratore di un utente secondario può chiamare installExistingPackage() ma non può chiamare setKeepUninstalledPackages().

Per effettuare una chiamata delegata DevicePolicyManager.setDelegatedScopes() e includi DELEGATION_KEEP_UNINSTALLED_PACKAGES nell'argomento scope. L'esempio seguente mostra come creare un'altra app Il delegato:

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 ...
}

Se tutto funziona correttamente, l'app delegata riceve ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED per la trasmissione e diventa il delegato. L'app può chiamare i metodi in questa guida come se fosse il proprietario del dispositivo o del profilo. Durante la chiamata DevicePolicyManager metodi, il delegato supera null per l'amministratore dell'oggetto componente.

Installa pacchetti dell'app

A volte è utile installare un'app personalizzata memorizzata nella cache locale su un dispositivo. Ad esempio, viene spesso eseguito il deployment di dispositivi dedicati ambienti con larghezza di banda limitata o aree senza connettività a internet. Il tuo deve tenere conto della larghezza di banda dei clienti. Il tuo può avviare l'installazione di un altro pacchetto dell'app (APK) utilizzando PackageInstaller corsi.

Sebbene qualsiasi app possa installare APK, gli amministratori sui dispositivi completamente gestiti possono installare (o disinstallare) pacchetti senza interazione da parte dell'utente. L'amministratore potrebbe gestire dispositivo, un utente secondario affiliato o un profilo di lavoro affiliato. Dopo il giorno terminando l'installazione, il sistema pubblica una notifica che informa che tutti gli utenti del dispositivo vedere. La notifica informa gli utenti dei dispositivi che l'app è stata installata (oppure aggiornato) dal suo amministratore.

Tabella 2. Versioni di Android che supportano l'installazione dei pacchetti senza interazione dell'utente
Versione di Android Componente amministrativo per l'installazione e la disinstallazione
Android 9.0 (livello API 28) o versioni successive Utenti secondari affiliati e profili di lavoro, entrambi su dispositivi completamente gestiti dispositivi
Android 6.0 (livello API 23) o versioni successive Dispositivi completamente gestiti

Le modalità di distribuzione di una o più copie dell'APK ai dispositivi dedicati dipendono da quanto sono remoti i dispositivi e possibilmente dalla loro distanza sono tra loro. La tua soluzione deve seguire le best practice per la sicurezza prima di installare APK su dispositivi dedicati.

Puoi utilizzare PackageInstaller.Session per creare una sessione che metta in coda una sessione o più APK per l'installazione. Nel seguente esempio riceviamo lo stato feedback nella nostra attività (modalità singleTop), ma puoi utilizzare un o 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 sessione invia un feedback sullo stato dell'installazione utilizzando gli intent. Controllo campo EXTRA_STATUS di ogni intent per ottenere stato. Ricorda che gli amministratori non ricevono Aggiornamento dello stato di STATUS_PENDING_USER_ACTION perché l'utente del dispositivo non deve approvare l'installazione.

Per disinstallare le app, puoi chiamare il numero PackageInstaller.uninstall. Gli amministratori di dispositivi, utenti e profili di lavoro completamente gestiti possono disinstallare i pacchetti senza interazione dell'utente con versioni di Android supportate (vedi tabella 2).

Bloccare gli aggiornamenti di sistema

I dispositivi Android ricevono aggiornamenti over-the-air (OTA) del sistema e dell'applicazione software. Bloccare la versione del sistema operativo in periodi critici, come festività o in altri momenti di punta, i dispositivi dedicati possono sospendere gli aggiornamenti di sistema OTA giorni. Per scoprire di più, vedi Gestire gli aggiornamenti di sistema.

Configurazione remota

Le configurazioni gestite di Android consentono agli amministratori IT di configurare da remoto la tua app. Potresti voler esporre impostazioni come liste consentite, host di rete o URL di contenuti per rendere la tua app più utile per l'IT Google Workspace for Education.

Se la tua app espone la propria configurazione, ricordati di includere le impostazioni nel documentazione. Per scoprire di più su come esporre la configurazione dell'app e reagire alle modifiche nelle impostazioni, consulta Impostare le configurazioni gestite.

Configurazione dello sviluppo

Durante lo sviluppo della soluzione per i dispositivi dedicati, a volte è necessario utile per impostare l'app come amministratore di un dispositivo completamente gestito senza dati di fabbrica resettare. Per impostare l'amministratore di un dispositivo completamente gestito, segui questi passaggi:

  1. Crea e installa l'app controller dei criteri dei dispositivi (DPC) sul dispositivo.
  2. Verifica che non siano presenti account sul dispositivo.
  3. Esegui questo comando nella shell Android Debug Bridge (adb). Tu devi sostituire com.example.dpc/.MyDeviceAdminReceiver nell'esempio con nome del componente di amministrazione dell'app:

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

Per aiutare i clienti a eseguire il deployment della tua soluzione, dovrai esaminare altre richieste di registrazione metodi. Consigliamo la registrazione del codice QR per dispositivi dedicati.

Risorse aggiuntive

Per scoprire di più sui dispositivi dedicati, leggi i seguenti documenti: