Wenn Sie Anwendungen für den Unternehmensmarkt entwickeln, müssen Sie möglicherweise bestimmte Anforderungen erfüllen, die in den Richtlinien einer Organisation festgelegt sind. Mit verwalteten Konfigurationen, die früher als Anwendungseinschränkungen bezeichnet wurden, kann der IT-Administrator der Organisation per Remote-Zugriff Einstellungen für Anwendungen festlegen. Diese Funktion ist besonders nützlich für Anwendungen, die von der Organisation genehmigt wurden und in einem Arbeitsprofil bereitgestellt werden.
Beispielsweise kann eine Organisation festlegen, dass der IT-Administrator mit genehmigten Anwendungen Folgendes tun kann:
- URLs für Webbrowser zulassen oder blockieren
- Festlegen, ob eine App Inhalte über Mobilfunknetz oder nur über WLAN synchronisieren darf
- E-Mail-Einstellungen der Anwendung konfigurieren
In diesem Leitfaden wird beschrieben, wie Sie Einstellungen für verwaltete Konfigurationen in Ihrer App implementieren. Beispiel-Apps mit einer verwalteten Konfiguration finden Sie unter ManagedConfigurations. Wenn Sie ein EMM-Entwickler (Enterprise Mobility Management) sind, lesen Sie bitte den Leitfaden zur Android Management API.
Hinweis: Aus historischen Gründen werden diese Konfigurationseinstellungen als Einschränkungen bezeichnet und mit Dateien und Klassen implementiert, die diesen Begriff verwenden (z. B. RestrictionsManager
). Durch diese Einschränkungen können jedoch eine Vielzahl von Konfigurationsoptionen implementiert werden, nicht nur Einschränkungen in Bezug auf die App-Funktionen.
Remotekonfiguration – Übersicht
Anwendungen definieren die verwalteten Konfigurationsoptionen, die von einem IT-Administrator remote festgelegt werden können. Dies sind beliebige Einstellungen, die von einem Anbieter verwalteter Konfigurationen geändert werden können. Wenn deine Anwendung in einem Arbeitsprofil ausgeführt wird, kann der IT-Administrator die verwaltete Konfiguration deiner Anwendung ändern.
Der Anbieter für verwaltete Konfigurationen ist eine andere App, die auf demselben Gerät ausgeführt wird. Diese App wird normalerweise vom IT-Administrator verwaltet. Der IT-Administrator teilt der Anwendung des Anbieters verwalteter Konfigurationen Konfigurationsänderungen mit. Diese Anwendung ändert wiederum die Konfigurationen in der Anwendung.
So stellen Sie extern verwaltete Konfigurationen bereit:
- Deklariere die verwalteten Konfigurationen in deinem App-Manifest. So kann der IT-Administrator die Konfigurationen der App über Google Play APIs lesen.
- Wenn die Anwendung fortgesetzt wird, prüfen Sie mit dem Objekt
RestrictionsManager
die aktuell verwalteten Konfigurationen und ändern Sie die UI und das Verhalten der Anwendung so, dass sie diesen Konfigurationen entspricht. - Warten Sie auf den Intent
ACTION_APPLICATION_RESTRICTIONS_CHANGED
. Wenn Sie diesen Broadcast erhalten, prüfen Sie dieRestrictionsManager
, um die aktuellen verwalteten Konfigurationen zu sehen und alle erforderlichen Änderungen am Verhalten der Anwendung vorzunehmen.
Verwaltete Konfigurationen definieren
Ihre App kann jede verwaltete Konfiguration unterstützen, die Sie definieren möchten. Sie deklarieren die verwalteten Konfigurationen der Anwendung in einer verwalteten Konfigurationsdatei und die Konfigurationsdatei im Manifest. Wenn Sie eine Konfigurationsdatei erstellen, können andere Anwendungen die verwalteten Konfigurationen Ihrer Anwendung untersuchen. EMM-Partner können die Konfigurationen deiner App mithilfe von Google Play APIs lesen.
Um die Remote-Konfigurationsoptionen Ihrer App zu definieren, fügen Sie das folgende Element in das Element
<application>
Ihres Manifests ein:
<meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions" />
Erstellen Sie im Verzeichnis res/xml
Ihrer Anwendung eine Datei mit dem Namen app_restrictions.xml
. Die Struktur dieser Datei wird in der Referenz zu RestrictionsManager
beschrieben. Die Datei hat auf oberster Ebene ein einzelnes <restrictions>
-Element, das für jede Konfigurationsoption der App ein untergeordnetes <restriction>
-Element enthält.
Hinweis:Erstellen Sie keine lokalisierten Versionen der verwalteten Konfigurationsdatei. Ihre Anwendung darf nur eine einzige verwaltete Konfigurationsdatei haben. Daher sind die Konfigurationen für Ihre Anwendung in allen Sprachen einheitlich.
In einer Unternehmensumgebung nutzt ein EMM in der Regel das verwaltete Konfigurationsschema, um eine Remote-Konsole für IT-Administratoren zu generieren, damit die Administratoren Ihre Anwendung remote konfigurieren können.
Der Anbieter verwalteter Konfigurationen kann die Anwendung abfragen, um Details zu den verfügbaren Konfigurationen der Anwendung, einschließlich des Beschreibungstexts, zu erhalten. Der Konfigurationsanbieter und der IT-Administrator können die verwalteten Konfigurationen Ihrer Anwendung jederzeit ändern, auch wenn die Anwendung nicht ausgeführt wird.
Angenommen, Ihre App kann per Fernzugriff so konfiguriert werden, dass sie das Herunterladen von Daten über eine Mobilfunkverbindung zulässt oder verbietet. Ihre App könnte ein <restriction>
-Element wie dieses haben:
<?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>
Mit dem Attribut android:key
jeder Konfiguration können Sie deren Wert aus einem verwalteten Konfigurationspaket lesen. Aus diesem Grund muss jede Konfiguration einen eindeutigen Schlüsselstring haben und der String kann nicht lokalisiert werden. Er muss mit einem Stringliteral angegeben werden.
Hinweis:In einer Produktions-App sollten android:title
und android:description
aus einer lokalisierten Ressourcendatei abgerufen werden, wie unter Mit Ressourcen lokalisieren beschrieben.
Eine App definiert Einschränkungen mithilfe von Bundles in einer bundle_array
.
Beispielsweise könnte eine Anwendung mit mehreren VPN-Verbindungsoptionen jede VPN-Serverkonfiguration in einem bundle
definieren, wobei mehrere Bundles in einem Bundle-Array gruppiert sind:
<?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>
Die unterstützten Typen für das Element android:restrictionType
sind in Tabelle 1 aufgeführt und in der Referenz zu RestrictionsManager
und RestrictionEntry
dokumentiert.
Typ | android:restrictionType | Typische Verwendung |
---|---|---|
TYPE_BOOLEAN
|
"bool" |
Boolescher Wert, wahr oder falsch. |
TYPE_STRING
|
"string" |
Ein Stringwert, z. B. ein Name. |
TYPE_INTEGER
|
"integer" |
Eine Ganzzahl mit einem Wert zwischen MIN_VALUE und MAX_VALUE .
|
TYPE_CHOICE
|
"choice" |
Ein aus android:entryValues ausgewählter Stringwert, der in der Regel als Liste mit Einzelauswahl dargestellt wird.
|
TYPE_MULTI_SELECT
|
"multi-select" |
Ein String-Array mit Werten aus android:entryValues .
Verwende diese Option, um eine Liste mit Mehrfachauswahl zu präsentieren, in der mehr als ein Eintrag ausgewählt werden kann, z. B. um bestimmte Titel für die Zulassungsliste auszuwählen.
|
TYPE_NULL
|
"hidden" |
Ausgeblendeter Einschränkungstyp. Verwenden Sie diesen Typ für Informationen, die übertragen werden müssen, dem Nutzer aber nicht in der UI angezeigt werden sollen. Speichert einen einzelnen Stringwert. |
TYPE_BUNDLE_ARRAY
|
"bundle_array" |
Wird zum Speichern von Arrays mit der Einschränkung bundles verwendet. Verfügbar in Android 6.0 (API-Level 23).
|
Hinweis: android:entryValues
sind maschinenlesbar und können nicht lokalisiert werden. Verwenden Sie android:entries
, um menschenlesbare Werte darzustellen, die lokalisiert werden können.
Jeder Eintrag muss einen entsprechenden Index in android:entryValues
haben.
Verwaltete Konfigurationen prüfen
Ihre Anwendung wird nicht automatisch benachrichtigt, wenn andere Apps ihre Konfigurationseinstellungen ändern. Stattdessen müssen Sie prüfen, welche verwalteten Konfigurationen vorhanden sind, wenn Ihre Anwendung gestartet oder fortgesetzt wird, und auf einen System-Intent warten, um festzustellen, ob sich die Konfigurationen während der Ausführung der Anwendung ändern.
Ihre Anwendung verwendet ein RestrictionsManager
-Objekt, um die aktuellen Konfigurationseinstellungen zu ermitteln. Die Anwendung sollte zu folgenden Zeiten nach den aktuell verwalteten Konfigurationen suchen:
- Wenn die App gestartet oder fortgesetzt wird, in ihrer
onResume()
-Methode - Wenn die Anwendung über eine Konfigurationsänderung benachrichtigt wird, wie unter Auf Änderungen der verwalteten Konfiguration warten beschrieben
Für das Objekt RestrictionsManager
rufen Sie die aktuelle Aktivität mit getActivity()
ab und rufen dann die Methode Activity.getSystemService()
dieser Aktivität auf:
Kotlin
var myRestrictionsMgr = activity?.getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager
Java
RestrictionsManager myRestrictionsMgr = (RestrictionsManager) getActivity() .getSystemService(Context.RESTRICTIONS_SERVICE);
Sobald Sie eine RestrictionsManager
haben, können Sie die aktuellen Konfigurationseinstellungen durch Aufrufen der entsprechenden getApplicationRestrictions()
-Methode abrufen:
Kotlin
var appRestrictions: Bundle = myRestrictionsMgr.applicationRestrictions
Java
Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
Hinweis: Sie können die aktuellen Konfigurationen auch mit einer UserManager
abrufen, indem Sie UserManager.getApplicationRestrictions()
aufrufen. Diese Methode verhält sich genau wie RestrictionsManager.getApplicationRestrictions()
.
Die Methode getApplicationRestrictions()
muss aus dem Datenspeicher auslesen, daher sollte sie sparsam eingesetzt werden. Rufen Sie diese Methode nicht jedes Mal auf, wenn Sie die aktuelle Konfiguration kennen müssen. Stattdessen sollten Sie es einmal aufrufen, wenn Ihre Anwendung gestartet oder fortgesetzt wird, und das abgerufene Paket verwalteter Konfigurationen im Cache speichern. Warten Sie dann auf den Intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
, um festzustellen, ob sich die Konfiguration ändert, während die Anwendung aktiv ist, wie unter Auf Änderungen der verwalteten Konfiguration warten beschrieben.
Verwaltete Konfigurationen lesen und anwenden
Die Methode getApplicationRestrictions()
gibt ein Bundle
zurück, das für jede festgelegte Konfiguration ein Schlüssel/Wert-Paar enthält. Die Werte sind alle vom Typ Boolean
, int
, String
und String[]
. Sobald Sie die verwalteten Konfigurationen Bundle
haben, können Sie die aktuellen Konfigurationseinstellungen mit den standardmäßigen Bundle
-Methoden für diese Datentypen prüfen, z. B. getBoolean()
oder getString()
.
Hinweis: Die verwalteten Konfigurationen Bundle
enthalten ein Element für jede Konfiguration, die explizit von einem Anbieter verwalteter Konfigurationen festgelegt wurde. Sie können jedoch nicht davon ausgehen, dass das Bundle eine Konfiguration enthält, nur weil Sie in der XML-Datei für verwaltete Konfigurationen einen Standardwert definiert haben.
Es liegt an Ihrer Anwendung, basierend auf den aktuellen verwalteten Konfigurationseinstellungen geeignete Maßnahmen zu ergreifen. Wenn deine App beispielsweise eine Konfiguration hat, die angibt, ob sie Daten über eine Mobilfunkverbindung herunterladen kann, und diese Konfiguration auf false
gesetzt ist, musst du den Datendownload deaktivieren, es sei denn, das Gerät hat eine WLAN-Verbindung, wie im folgenden Beispielcode gezeigt:
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 }
Wenn Sie mehrere verschachtelte Einschränkungen anwenden möchten, lesen Sie den Einschränkungseintrag bundle_array
als Sammlung von Parcelable
-Objekten und wandeln Sie ihn als Bundle
um. In diesem Beispiel werden die Konfigurationsdaten jedes VPNs geparst und verwendet, um eine Liste mit Auswahlmöglichkeiten für die Serververbindung zu erstellen:
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 }
Auf verwaltete Konfigurationsänderungen warten
Bei jeder Änderung der verwalteten Konfigurationen einer App löst das System den Intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
aus. Ihre App muss auf diesen Intent warten, damit Sie das Verhalten der Anwendung ändern können, wenn sich die Konfigurationseinstellungen ändern.
Hinweis: Der Intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
wird nur an Listener gesendet, die dynamisch registriert werden, nicht an Listener, die im App-Manifest deklariert sind.
Der folgende Code zeigt, wie ein Broadcast-Empfänger für diesen Intent dynamisch registriert wird:
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);
Hinweis:Normalerweise muss Ihre Anwendung nicht über Konfigurationsänderungen benachrichtigt werden, wenn sie pausiert wird. Stattdessen sollten Sie die Registrierung des Übertragungsempfängers aufheben, wenn die App pausiert ist. Wenn die Anwendung fortgesetzt wird, prüfen Sie zuerst die aktuellen verwalteten Konfigurationen (wie unter Verwaltete Konfigurationen prüfen beschrieben) und registrieren Sie dann den Broadcast-Empfänger, damit Sie über Konfigurationsänderungen benachrichtigt werden, die während der aktiven Anwendung erfolgen.
Feedback zur verwalteten Konfiguration an EMMs senden
Nachdem Sie verwaltete Konfigurationsänderungen auf Ihre App angewendet haben, sollten Sie die EMM-Anbieter über den Status der Änderung informieren. Android unterstützt eine Funktion namens Schlüssel-App-Status, mit der du jedes Mal Feedback senden kannst, wenn deine App versucht, Änderungen an der verwalteten Konfiguration anzuwenden. Dieses Feedback kann als Bestätigung dafür dienen, dass die verwalteten Konfigurationen Ihrer App festgelegt wurden. Es kann aber auch eine Fehlermeldung enthalten, wenn die festgelegten Änderungen in Ihrer App nicht übernommen werden konnten.
EMM-Anbieter können dieses Feedback abrufen und in ihrer Konsole für IT-Administratoren anzeigen lassen. Weitere Informationen zu diesem Thema finden Sie unter App-Feedback an EMMs senden, einschließlich einer detaillierten Anleitung zum Hinzufügen von Feedbacksupport zu Ihrer App.
Zusätzliche Codebeispiele
Im Beispiel ManagedConfigurations wird die Verwendung der auf dieser Seite behandelten APIs weiter veranschaulicht.