Se stai sviluppando app per il mercato aziendale, potresti dover soddisfare requisiti particolari impostati dalle norme di un'organizzazione. Le configurazioni gestite, precedentemente note come limitazioni delle applicazioni, consentono all'amministratore IT dell'organizzazione di specificare da remoto le impostazioni per le app. Questa funzionalità è particolarmente utile per le app approvate dall'organizzazione di cui è stato eseguito il deployment in un profilo di lavoro.
Ad esempio, un'organizzazione potrebbe richiedere che le app approvate consentano all'amministratore IT di:
- Consentire o bloccare gli URL per un browser web
- Configurare se un'app è autorizzata a sincronizzare i contenuti tramite rete mobile o solo tramite Wi-Fi
- Configurare le impostazioni email dell'app
Questa guida mostra come implementare le impostazioni di configurazione gestita nella tua app. Per visualizzare app di esempio con una configurazione gestita, consulta ManagedConfigurations. Se sei uno sviluppatore di soluzioni EMM (Enterprise Mobility Management), consulta la guida all'API Android Management.
Nota: per motivi storici, queste impostazioni di configurazione sono note come limitazioni e vengono implementate con file e classi che utilizzano questo termine (ad esempio RestrictionsManager
). Tuttavia, queste limitazioni possono effettivamente implementare una vasta gamma di opzioni di configurazione, non solo limitazioni alla funzionalità delle app.
Panoramica della configurazione remota
Le app definiscono le opzioni di configurazione gestita che possono essere impostate da remoto da un amministratore IT. Si tratta di impostazioni arbitrarie che possono essere modificate da un provider di configurazione gestita. Se la tua app è in esecuzione in un profilo di lavoro, l'amministratore IT può modificare la configurazione gestita dell'app.
Il fornitore di configurazioni gestite è un'altra app in esecuzione sullo stesso dispositivo. In genere questa app è controllata dall'amministratore IT. L'amministratore IT comunica le modifiche alla configurazione all'app del fornitore di configurazioni gestite. L'app, a sua volta, modifica le configurazioni nella tua app.
Per fornire configurazioni gestite esternamente:
- Dichiara le configurazioni gestite nel file manifest dell'app. In questo modo, l'amministratore IT può leggere le configurazioni dell'app tramite le API Google Play.
- Ogni volta che l'app riprende, utilizza l'oggetto
RestrictionsManager
per controllare le configurazioni gestite correnti e modificare l'interfaccia utente e il comportamento dell'app in modo che siano conformi a queste configurazioni. - Ascolta l'intent
ACTION_APPLICATION_RESTRICTIONS_CHANGED
. Quando ricevi questo messaggio, controllaRestrictionsManager
per vedere quali sono le configurazioni gestite correnti e apporta le modifiche necessarie al comportamento della tua app.
Definire le configurazioni gestite
La tua app può supportare qualsiasi configurazione gestita che vuoi definire. Dichiari le configurazioni gestite dell'app in un file di configurazioni gestite e dichiari il file di configurazioni nel file manifest. La creazione di un file di configurazione consente ad altre app di esaminare le configurazioni gestite fornite dalla tua app. I partner EMM possono leggere le configurazioni della tua app utilizzando le API Google Play.
Per definire le opzioni di configurazione remota dell'app, inserisci il seguente elemento
nell'elemento
<application>
del manifest:
<meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions" />
Crea un file denominato app_restrictions.xml
nella directory res/xml
della tua app. La struttura di questo file è descritta nel riferimento per RestrictionsManager
. Il file contiene un singolo elemento <restrictions>
di primo livello, che contiene un elemento secondario <restriction>
per ogni opzione di configurazione dell'app.
Nota:non creare versioni localizzate del file di configurazione gestito. La tua app può avere un solo file di configurazioni gestite, pertanto le configurazioni saranno coerenti per l'app in tutte le lingue.
In un ambiente aziendale, in genere una soluzione EMM utilizza lo schema di configurazione gestita per generare una console remota per gli amministratori IT, in modo che possano configurare da remoto l'applicazione.
Il provider di configurazione gestita può eseguire query sull'app per trovare dettagli sulle configurazioni disponibili dell'app, incluso il testo della descrizione. Il fornitore di configurazioni e l'amministratore IT possono modificare le configurazioni gestite della tua app in qualsiasi momento, anche quando l'app non è in esecuzione.
Ad esempio, supponiamo che la tua app possa essere configurata da remoto per consentire o vietare il download di dati tramite una connessione di rete mobile. La tua app potrebbe avere un elemento <restriction>
come questo:
<?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android"> <restriction android:key="downloadOnCellular" android:title="@string/download_on_cell_title" android:restrictionType="bool" android:description="@string/download_on_cell_description" android:defaultValue="true" /> </restrictions>
Utilizza l'attributo android:key
di ogni configurazione per leggere il relativo valore da un bundle di configurazione gestito. Per questo motivo,
ogni configurazione deve avere una stringa di chiave univoca e la stringa
non può essere localizzata. Deve essere specificato con un valore letterale di stringa.
Nota: in un'app di produzione, android:title
e android:description
devono essere estratti da un file di risorse localizzate, come descritto in Localizzazione con le risorse.
Un'app definisce le restrizioni utilizzando i bundle all'interno di un bundle_array
.
Ad esempio, un'app con più opzioni di connessione VPN potrebbe definire ogni configurazione del server VPN in un bundle
, con più bundle raggruppati in un array di bundle:
<?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android" > <restriction android:key="vpn_configuration_list" android:restrictionType="bundle_array"> <restriction android:key="vpn_configuration" android:restrictionType="bundle"> <restriction android:key="vpn_server" android:restrictionType="string"/> <restriction android:key="vpn_username" android:restrictionType="string"/> <restriction android:key="vpn_password" android:restrictionType="string"/> </restriction> </restriction> </restrictions>
I tipi supportati per l'elemento android:restrictionType
sono elencati nella Tabella 1 e documentati nel
riferimento per RestrictionsManager
e
RestrictionEntry
.
Tabella 1. Tipi di voci di limitazione e utilizzo.
Digitazione | android:restrictionType | Utilizzo tipico |
---|---|---|
TYPE_BOOLEAN
|
"bool" |
Un valore booleano, vero o falso. |
TYPE_STRING
|
"string" |
Un valore di stringa, ad esempio un nome. |
TYPE_INTEGER
|
"integer" |
Un numero intero con un valore compreso tra
MIN_VALUE e
MAX_VALUE .
|
TYPE_CHOICE
|
"choice" |
Un valore di stringa selezionato da android:entryValues , solitamente presentato come un elenco a scelta singola.
|
TYPE_MULTI_SELECT
|
"multi-select" |
Un array di stringhe con valori selezionati da android:entryValues .
Utilizzalo per presentare un elenco con selezione multipla in cui è possibile selezionare più di una voce, ad esempio per scegliere titoli specifici da inserire nella lista consentita.
|
TYPE_NULL
|
"hidden" |
Tipo di restrizione nascosta. Utilizza questo tipo per le informazioni che devono essere trasferite, ma non devono essere presentate all'utente nell'interfaccia utente. Memorizza un singolo valore di stringa. |
TYPE_BUNDLE_ARRAY
|
"bundle_array" |
Utilizzalo per memorizzare array di limitazioni
bundles . Disponibile in Android 6.0 (livello API 23).
|
Nota:i valori android:entryValues
sono leggibili dalla macchina e non possono essere localizzati. Utilizza android:entries
per presentare valori leggibili che possono essere localizzati.
Ogni voce deve avere un indice corrispondente in android:entryValues
.
Controllare le configurazioni gestite
La tua app non riceve una notifica automatica quando altre app modificano le sue impostazioni di configurazione. Devi invece controllare quali sono le configurazioni gestite quando l'app si avvia o riprende e ascoltare un intento di sistema per scoprire se le configurazioni cambiano durante l'esecuzione dell'app.
Per scoprire le impostazioni di configurazione correnti, l'app utilizza un oggetto RestrictionsManager
. L'app deve controllare le configurazioni gestite correnti nei seguenti momenti:
- Quando l'app si avvia o riprende, nel metodo
onResume()
- Quando l'app riceve una notifica di una modifica alla configurazione, come descritto in Ascoltare le modifiche alla configurazione gestita
Per ottenere un oggetto RestrictionsManager
, recupera l'attività corrente con getActivity()
, quindi chiama il metodo Activity.getSystemService()
dell'attività:
Kotlin
var myRestrictionsMgr = activity?.getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager
Java
RestrictionsManager myRestrictionsMgr = (RestrictionsManager) getActivity() .getSystemService(Context.RESTRICTIONS_SERVICE);
Una volta creato un RestrictionsManager
, puoi recuperare le impostazioni di configurazione correnti chiamando il relativo metodo getApplicationRestrictions()
:
Kotlin
var appRestrictions: Bundle = myRestrictionsMgr.applicationRestrictions
Java
Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
Nota: per comodità, puoi anche recuperare le configurazioni correnti con un UserManager
chiamando UserManager.getApplicationRestrictions()
. Questo metodo si comporta esattamente come RestrictionsManager.getApplicationRestrictions()
.
Il metodo getApplicationRestrictions()
richiede la lettura dall'archiviazione dati, pertanto deve essere utilizzato con parsimonia. Non chiamare questo metodo ogni volta che devi conoscere la configurazione corrente. Devi invece chiamarlo una volta all'avvio o al ripristino dell'app e memorizzare nella cache il bundle di configurazioni gestite recuperate. Quindi, ascolta
l'intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
per scoprire se la configurazione
cambia mentre l'app è attiva, come descritto in
Rileva le modifiche alla configurazione gestita.
Lettura e applicazione delle configurazioni gestite
Il metodo getApplicationRestrictions()
restituisce un Bundle
contenente una coppia chiave-valore per ogni configurazione impostata. I valori sono tutti di tipo Boolean
, int
, String
e String[]
. Una volta ottenute le configurazioni gestite Bundle
, puoi controllare le impostazioni di configurazione correnti con i metodi Bundle
standard per questi tipi di dati, ad esempio getBoolean()
o getString()
.
Nota:le configurazioni gestite Bundle
contengono un elemento per ogni configurazione impostata esplicitamente da un fornitore di configurazioni gestite. Tuttavia, non puoi presumere che una configurazione sia presente nel bundle solo perché hai definito un valore predefinito nel file XML delle configurazioni gestite.
Spetta all'app intraprendere l'azione appropriata in base alle impostazioni di configurazione gestita correnti. Ad esempio, se la tua app ha una configurazione che specifica se può scaricare dati tramite una connessione di rete mobile e scopri che la configurazione è impostata su false
, devi disattivare il download dei dati, tranne quando il dispositivo ha una connessione Wi-Fi, come mostrato nel seguente codice di esempio:
Kotlin
val appCanUseCellular: Boolean = if (appRestrictions.containsKey("downloadOnCellular")) { appRestrictions.getBoolean("downloadOnCellular") } else { // cellularDefault is a boolean using the restriction's default value cellularDefault } if (!appCanUseCellular) { // ...turn off app's cellular-download functionality // ...show appropriate notices to user }
Java
boolean appCanUseCellular; if (appRestrictions.containsKey("downloadOnCellular")) { appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular"); } else { // cellularDefault is a boolean using the restriction's default value appCanUseCellular = cellularDefault; } if (!appCanUseCellular) { // ...turn off app's cellular-download functionality // ...show appropriate notices to user }
Per applicare più restrizioni nidificate, leggi la voce di restrizione bundle_array
come una raccolta di oggetti Parcelable
e esegui il casting come Bundle
. In questo esempio, i dati di configurazione di ogni VPN vengono analizzati e utilizzati per creare un elenco di opzioni di connessione al server:
Kotlin
// VpnConfig is a sample class used store config data, not defined val vpnConfigs = mutableListOf<VpnConfig>() val parcelables: Array<out Parcelable>? = appRestrictions.getParcelableArray("vpn_configuration_list") if (parcelables?.isNotEmpty() == true) { // iterate parcelables and cast as bundle parcelables.map { it as Bundle }.forEach { vpnConfigBundle -> // parse bundle data and store in VpnConfig array vpnConfigs.add(VpnConfig() .setServer(vpnConfigBundle.getString("vpn_server")) .setUsername(vpnConfigBundle.getString("vpn_username")) .setPassword(vpnConfigBundle.getString("vpn_password"))) } } if (vpnConfigs.isNotEmpty()) { // ...choose a VPN configuration or prompt user to select from list }
Java
// VpnConfig is a sample class used store config data, not defined List<VpnConfig> vpnConfigs = new ArrayList<>(); Parcelable[] parcelables = appRestrictions.getParcelableArray("vpn_configuration_list"); if (parcelables != null && parcelables.length > 0) { // iterate parcelables and cast as bundle for (int i = 0; i < parcelables.length; i++) { Bundle vpnConfigBundle = (Bundle) parcelables[i]; // parse bundle data and store in VpnConfig array vpnConfigs.add(new VpnConfig() .setServer(vpnConfigBundle.getString("vpn_server")) .setUsername(vpnConfigBundle.getString("vpn_username")) .setPassword(vpnConfigBundle.getString("vpn_password"))); } } if (!vpnConfigs.isEmpty()) { // ...choose a VPN configuration or prompt user to select from list }
Ascolta le modifiche alla configurazione gestita
Ogni volta che le configurazioni gestite di un'app vengono modificate, il sistema attiva l'intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
. L'app deve ascoltare questo intento per consentirti di modificare il suo comportamento quando cambiano le impostazioni di configurazione.
Nota:l'intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
viene inviato solo agli ascoltatori registrati dinamicamente, non a quelli dichiarati nel manifest dell'app.
Il seguente codice mostra come registrare dinamicamente un'entità di ricezione di annunci per questo intent:
Kotlin
val restrictionsFilter = IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED) val restrictionsReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // Get the current configuration bundle val appRestrictions = myRestrictionsMgr.applicationRestrictions // Check current configuration settings, change your app's UI and // functionality as necessary. } } registerReceiver(restrictionsReceiver, restrictionsFilter)
Java
IntentFilter restrictionsFilter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Get the current configuration bundle Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions(); // Check current configuration settings, change your app's UI and // functionality as necessary. } }; registerReceiver(restrictionsReceiver, restrictionsFilter);
Nota:in genere, non è necessario che l'app riceva una notifica relativa alle modifiche alla configurazione quando è in pausa. Devi invece annullare la registrazione del tuo ricevitore di trasmissione quando l'app è in pausa. Quando l'app riprende, controlla innanzitutto le configurazioni gestite correnti (come discusso in Verificare le configurazioni gestite), quindi registra il tuo ricevitore di trasmissione per assicurarti di ricevere una notifica relativa alle modifiche alla configurazione che si verificano quando l'app è attiva.
Inviare feedback sulla configurazione gestita agli EMM
Dopo aver applicato le modifiche alla configurazione gestita alla tua app, è buona prassi informare gli EMM dello stato della modifica. Android supporta una funzionalità chiamata stati dell'app con chiave, che puoi utilizzare per inviare feedback ogni volta che la tua app tenta di applicare modifiche alla configurazione gestita. Questo feedback può fungere da conferma dell'impostazione corretta delle configurazioni gestite o includere un messaggio di errore se l'app non è riuscita ad applicare le modifiche specificate.
I provider EMM sono in grado di recuperare questo feedback e di visualizzarlo nelle loro console per consentirne la visualizzazione agli amministratori IT. Per ulteriori informazioni sull'argomento, consulta Inviare feedback sull'app agli EMM, inclusa una guida dettagliata su come aggiungere il supporto per i feedback alla tua app.
Altri esempi di codice
L'esempio ManagedConfigurations dimostra ulteriormente l'utilizzo delle API trattate in questa pagina.
Inserire app nella lista consentita/nella lista bloccata nel profilo personale
I store di app di terze parti potrebbero esprimere interesse nell'utilizzo delle configurazioni gestite per avere un modo affidabile per applicare una lista consentita o una lista bloccata di app sia al profilo personale sia alla funzionalità consumer Spazio privato, ovvero uno spazio personale aggiuntivo in cui gli utenti possono conservare le app sensibili. Se sviluppi un app store per uso aziendale e vuoi utilizzare questa funzionalità, invia questo modulo per esprimere il tuo interesse e seleziona Interesse per l'inserimento nella lista consentita degli store di terze parti come Motivo della risposta nel modulo.