Arbeitsprofile

Über die Android-Plattform können Geräte Arbeitsprofile (manchmal auch als verwaltete Profile bezeichnet) haben. Ein Arbeitsprofil wird von einem IT-Administrator gesteuert und die ihm verfügbare Funktionalität wird getrennt von der Funktionalität des primären Profils des Nutzers festgelegt. Mit diesem Ansatz können Organisationen die Umgebung steuern, in der unternehmensspezifische Apps und Daten auf dem Gerät eines Nutzers ausgeführt werden. Nutzer können jedoch weiterhin ihre privaten Apps und Profile verwenden.

In dieser Lektion erfahren Sie, wie Sie Ihre Anwendung so ändern, dass sie auf einem Gerät mit Arbeitsprofil zuverlässig funktioniert. Sie müssen abgesehen von den üblichen Best Practices für die Anwendungsentwicklung nichts weiter tun. Einige dieser Best Practices sind jedoch auf Geräten mit Arbeitsprofilen besonders wichtig. In diesem Dokument werden die Probleme aufgezeigt, die Sie kennen müssen.

Übersicht

Nutzer*innen möchten ihre privaten Geräte oft im Rahmen eines Unternehmens verwenden. Diese Situation kann Unternehmen vor ein Dilemma stellen. Wenn der Nutzer sein eigenes Gerät verwenden kann, muss sich die Organisation darum kümmern, dass sich vertrauliche Informationen (z. B. E-Mails und Kontakte von Mitarbeitern) auf einem Gerät befinden, das von der Organisation nicht kontrolliert wird.

Deshalb können Organisationen mit Android 5.0 (API-Level 21) Arbeitsprofile einrichten. Wenn ein Gerät ein Arbeitsprofil hat, werden die Profileinstellungen vom IT-Administrator gesteuert. Der IT-Administrator kann auswählen, welche Apps für dieses Profil zugelassen sind, und steuern, welche Gerätefunktionen für das Profil zur Verfügung stehen.

Wenn ein Gerät ein Arbeitsprofil hat, hat das Auswirkungen auf die auf dem Gerät ausgeführten Apps, unabhängig davon, unter welchem Profil die App ausgeführt wird:

  • Standardmäßig wechseln die meisten Intents nicht von einem Profil zum anderen. Wenn eine im Profil ausgeführte Anwendung einen Intent auslöst, ist für den Intent in diesem Profil kein Handler vorhanden und der Intent darf aufgrund von Profileinschränkungen nicht mit dem anderen Profil wechseln. In diesem Fall schlägt die Anfrage fehl und die Anwendung wird möglicherweise unerwartet heruntergefahren.
  • Der IT-Administrator des Profils kann einschränken, welche Systemanwendungen im Arbeitsprofil verfügbar sind. Diese Einschränkung kann auch dazu führen, dass für einige häufige Intents im Arbeitsprofil kein Handler vorhanden ist.
  • Da das private und das Arbeitsprofil separate Speicherbereiche haben, ist ein Datei-URI, der für das eine Profil gültig ist, für das andere nicht gültig. Intents, die für ein Profil ausgelöst werden, können je nach Profileinstellungen auch für das andere verarbeitet werden. Daher ist es nicht sicher, Datei-URIs an Intents anzuhängen.

Fehlgeschlagene Intents verhindern

Auf einem Gerät mit einem Arbeitsprofil gibt es Einschränkungen dafür, ob Intents von einem Profil zum anderen übertragen werden können. In den meisten Fällen wird ein Intent in dem Profil verarbeitet, in dem er ausgelöst wurde. Ist für den Intent in diesem Profil kein Handler vorhanden, wird er nicht verarbeitet und die App, die ihn ausgelöst hat, wird möglicherweise unerwartet heruntergefahren – auch wenn im anderen Profil ein Handler für den Intent vorhanden ist.

Der Profiladministrator kann auswählen, welche Intents von einem Profil zum anderen wechseln dürfen. Da diese Entscheidung vom IT-Administrator getroffen wird, können Sie nicht im Voraus wissen, welche Intents diese Grenze überschreiten dürfen. Der IT-Administrator legt diese Richtlinie fest und kann sie jederzeit ändern.

Bevor Ihre Anwendung eine Aktivität startet, sollten Sie prüfen, ob eine geeignete Lösung gefunden werden kann. Sie können prüfen, ob es eine akzeptable Lösung gibt, indem Sie Intent.resolveActivity() aufrufen. Wenn es keine Möglichkeit gibt, den Intent aufzulösen, gibt die Methode null zurück. Wenn die Methode einen anderen Wert als null zurückgibt, gibt es mindestens eine Möglichkeit, den Intent aufzulösen, und der Intent kann ohne Bedenken ausgelöst werden. In diesem Fall kann der Intent aufgelöst werden, entweder weil sich im aktuellen Profil ein Handler befindet oder weil der Intent zu einem Handler im anderen Profil wechseln darf. Weitere Informationen zum Auflösen von Intents finden Sie unter Allgemeine Intents.

Wenn Ihre App beispielsweise Timer einstellen muss, muss geprüft werden, ob es einen gültigen Handler für den Intent ACTION_SET_TIMER gibt. Wenn die Anwendung den Intent nicht auflösen kann, sollte eine entsprechende Maßnahme ergriffen werden (z. B. eine Fehlermeldung).

Kotlin

fun startTimer(message: String, seconds: Int) {

    // Build the "set timer" intent
    val timerIntent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }

    // Check if there's a handler for the intent
    if (timerIntent.resolveActivity(packageManager) == null) {

        // Can't resolve the intent! Fail this operation cleanly
        // (perhaps by showing an error message)

    } else {
        // Intent resolves, it's safe to fire it off
        startActivity(timerIntent)

    }
}

Java

public void startTimer(String message, int seconds) {

    // Build the "set timer" intent
    Intent timerIntent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);

    // Check if there's a handler for the intent
    if (timerIntent.resolveActivity(getPackageManager()) == null) {

        // Can't resolve the intent! Fail this operation cleanly
        // (perhaps by showing an error message)

    } else {
        // Intent resolves, it's safe to fire it off
        startActivity(timerIntent);

    }
}

Dateien profilübergreifend freigeben

Manchmal muss eine App anderen Apps Zugriff auf ihre eigenen Dateien gewähren. Beispielsweise kann eine Bildergalerie-App ihre Bilder für Bildeditoren freigeben. Es gibt zwei Möglichkeiten, eine Datei normalerweise freizugeben: über einen Datei-URI oder einen Inhalts-URI.

Ein Datei-URI beginnt mit dem Präfix file:, gefolgt vom absoluten Pfad der Datei im Speicher des Geräts. Da das Arbeitsprofil und das private Profil jedoch separate Speicherbereiche haben, ist ein Datei-URI, der für das eine Profil gültig ist, für das andere nicht gültig. Wenn Sie einen Datei-URI an einen Intent anhängen und der Intent im anderen Profil verarbeitet wird, kann der Handler in diesem Fall nicht auf die Datei zugreifen.

Stattdessen sollten Sie Dateien mit Inhalts-URIs freigeben. Inhalts-URIs identifizieren die Datei sicherer und können freigegeben werden. Der Inhalts-URI enthält den Dateipfad, aber auch die Zertifizierungsstelle, die die Datei bereitstellt, und eine ID-Nummer, durch die die Datei identifiziert wird. Mithilfe einer FileProvider lässt sich eine Content-ID für jede Datei generieren. Diese Content-ID kannst du dann für andere Apps freigeben (auch für das andere Profil). Der Empfänger kann die Content-ID verwenden, um Zugriff auf die eigentliche Datei zu erhalten.

So ermitteln Sie beispielsweise den Inhalts-URI für einen bestimmten Datei-URI:

Kotlin

// Open File object from its file URI
val fileToShare = File(fileUriToShare)

val contentUriToShare: Uri = FileProvider.getUriForFile(
        context,
        "com.example.myapp.fileprovider",
        fileToShare
)

Java

// Open File object from its file URI
File fileToShare = new File(fileUriToShare);

Uri contentUriToShare = FileProvider.getUriForFile(getContext(),
        "com.example.myapp.fileprovider", fileToShare);

Wenn Sie die Methode getUriForFile() aufrufen, müssen Sie die Berechtigung des Dateianbieters angeben (in diesem Beispiel "com.example.myapp.fileprovider"), die im Element <provider> Ihres App-Manifests festgelegt ist. Weitere Informationen zur Freigabe von Dateien für Inhalts-URIs finden Sie unter Dateien freigeben.

Auf Benachrichtigungen warten

Eine Anwendung stellt in der Regel eine abgeleitete NotificationListenerService-Klasse bereit, um Callbacks vom System zu Änderungen an Benachrichtigungen zu empfangen. Geräte mit Arbeitsprofilen können sich darauf auswirken, wie NotificationListenerService mit Ihrer Anwendung funktioniert.

In einem Arbeitsprofil

Sie können kein NotificationListenerService aus einer App verwenden, die im Arbeitsprofil ausgeführt wird. Wenn Ihre App in einem Arbeitsprofil ausgeführt wird, ignoriert das System die NotificationListenerService der App. Apps, die im privaten Profil ausgeführt werden, können jedoch auf Benachrichtigungen warten.

In einem privaten Profil

Wenn Ihre Anwendung im privaten Profil ausgeführt wird, erhalten Sie möglicherweise keine Benachrichtigungen für Anwendungen, die im Arbeitsprofil ausgeführt werden. Standardmäßig erhalten alle Apps mit privatem Profil Callbacks. Ein IT-Administrator kann jedoch eine oder mehrere Apps mit privatem Profil auf die Zulassungsliste setzen und zulassen, dass Benachrichtigungsänderungen erfasst werden. Das System blockiert dann Apps, die nicht auf der Zulassungsliste stehen. Unter Android 8.0 (API-Level 26) oder höher kann ein Device Policy Controller (DPC), der ein Arbeitsprofil verwaltet, verhindern, dass deine App die Benachrichtigungen des Arbeitsprofils mit der DevicePolicyManager-Methode setPermittedCrossProfileNotificationListeners() abhört. Deine App erhält weiterhin Rückrufe zu Benachrichtigungen, die im persönlichen Profil gepostet werden.

Teste deine App auf Kompatibilität mit Arbeitsprofilen

Sie sollten Ihre Anwendung in einer Umgebung mit Arbeitsprofilen testen, um Probleme zu erkennen, die dazu führen, dass Ihre Anwendung auf einem Gerät mit Arbeitsprofilen fehlschlägt. Insbesondere Tests auf einem Gerät mit Arbeitsprofil sind eine gute Möglichkeit, sicherzustellen, dass Ihre App Intents ordnungsgemäß verarbeitet. Es werden beispielsweise keine Intents ausgelöst, die nicht verarbeitet werden können, und URIs, die nicht profilübergreifend funktionieren, werden nicht angehängt.

Wir haben die Beispiel-App TestDPC bereitgestellt, mit der Sie ein Arbeitsprofil auf einem Android-Gerät mit Android 5.0 (API-Level 21) und höher einrichten können. Mit dieser Anwendung können Sie Ihre Anwendung auf einfache Weise in einer Umgebung mit einem Arbeitsprofil testen. Sie können diese App auch verwenden, um das Arbeitsprofil so zu konfigurieren:

  • Festlegen, welche Standard-Apps im verwalteten Profil verfügbar sind
  • Konfigurieren Sie, welche Intents von einem Profil zum anderen wechseln dürfen

Wenn Sie eine App manuell über ein USB-Kabel auf einem Gerät mit Arbeitsprofil installieren, wird die App sowohl im privaten als auch im Arbeitsprofil installiert. Nachdem Sie die App installiert haben, können Sie sie unter den folgenden Bedingungen testen:

  • Wenn ein Intent normalerweise von einer Standard-App (z. B. der Kamera-App) verarbeitet wird, deaktivieren Sie diese Standard-App im Arbeitsprofil. Prüfen Sie dann, ob die App dies entsprechend verarbeitet.
  • Wenn Sie einen Intent auslösen und erwarten, dass er von einer anderen Anwendung verarbeitet wird, aktivieren und deaktivieren Sie die Berechtigung dieses Intents für den Wechsel von einem Profil zum anderen. Prüfen Sie, ob die Anwendung in beiden Fällen ordnungsgemäß funktioniert. Wenn der Intent nicht zwischen Profilen wechseln darf, prüfen Sie das Verhalten der Anwendung, sowohl wenn ein geeigneter Handler im Profil der Anwendung vorhanden ist als auch, wenn dies nicht der Fall ist. Wenn Ihre App beispielsweise einen kartenbezogenen Intent auslöst, versuchen Sie es mit den folgenden Szenarien:
    • Das Gerät ermöglicht Zuordnungs-Intents, von einem Profil zum anderen zu wechseln. Außerdem gibt es einen geeigneten Handler für das andere Profil (das Profil, auf dem die App nicht ausgeführt wird).
    • Das Gerät lässt keine Verbindungen zwischen Karten-Intents zu, aber im Profil der App gibt es einen geeigneten Handler
    • Auf dem Gerät ist der Austausch von Karten-Intents zwischen Profilen nicht zulässig und es gibt keinen geeigneten Handler für Karten-Intents im Geräteprofil des Geräts.
  • Wenn Sie Inhalte an einen Intent anhängen, prüfen Sie, ob der Intent sowohl beim Verarbeiten im Profil der Anwendung als auch beim Wechseln zwischen Profilen ordnungsgemäß funktioniert.

Arbeitsprofile testen: Tipps und Tricks

Für Tests auf einem Gerät mit Arbeitsprofil können einige Tricks hilfreich sein.

  • Wie bereits erwähnt, wird eine Anwendung, die Sie per Sideload auf ein Gerät mit Arbeitsprofil übertragen, auf beiden Profilen installiert. Wenn Sie möchten, können Sie die App aus einem Profil löschen und im anderen belassen.
  • Die meisten in der Android Debug Bridge-Shell (ADB) verfügbaren Befehle des Aktivitätsmanagers unterstützen das Flag --user, mit dem Sie angeben können, als welcher Nutzer ausgeführt werden soll. Durch Angabe eines Nutzers können Sie auswählen, ob er als nicht verwalteter primärer Nutzer oder Arbeitsprofil ausgeführt werden soll. Weitere Informationen finden Sie unter ADB-Shell-Befehle.
  • Verwenden Sie den Befehl list users des ADB-Paketmanagers, um die aktiven Nutzer auf einem Gerät zu ermitteln. Die erste Zahl im Ausgabestring ist die Nutzer-ID, die Sie mit dem Flag --user verwenden können. Weitere Informationen finden Sie unter ADB Shell-Befehle.

Führen Sie beispielsweise folgenden Befehl aus, um die Nutzer auf einem Gerät zu finden:

$ adb shell pm list users
UserInfo{0:Drew:13} running
UserInfo{10:Work profile:30} running

In diesem Fall hat der Hauptnutzer („Drew“) die Nutzer-ID 0 und das Arbeitsprofil die Nutzer-ID 10. Um eine App im Arbeitsprofil auszuführen, verwenden Sie einen Befehl wie diesen:

$ adb shell am start --user 10 \
-n "com.example.myapp/com.example.myapp.testactivity" \
-a android.intent.action.MAIN -c android.intent.category.LAUNCHER