Anwendungsrollen verwalten

Mit der Funktion für Anwendungsrollen kann ein IT-Administrator einer verwalteten Anwendung auf einem Android-Gerät spezielle Berechtigungen gewähren. Durch die Zuweisung einer bestimmten Rolle kann eine App von Energie- und Hintergrundbeschränkungen, der Sperrung und dem Ruhezustand (ab Android 14) ausgenommen werden. Außerdem können Nutzersteuerungen (z. B. Nutzeraktionen wie das Erzwingen des Beendens und das Löschen von App-Daten) deaktiviert werden (ab Android 11), damit die App ihre kritische Funktion ohne Unterbrechung ausführen kann. Darüber hinaus kann die App über ihre zugewiesenen Rollen benachrichtigt werden, sodass sie ohne Nutzereingriff gestartet werden kann.

Eine Liste der verfügbaren Anwendungsrollen und der speziellen Berechtigungen, die jeder Rolle gewährt werden, finden Sie unter RoleType.

Vorbereitung

Das Gerät wird von einem AMAPI-basierten EMM verwaltet. EMMs mit einem benutzerdefinierten DPC werden nicht unterstützt.

App für die Verwendung der Funktion vorbereiten

Die Integration in das AMAPI SDK ist nur erforderlich, wenn die App über ihre zugewiesenen Rollen benachrichtigt werden soll, damit sie automatisch gestartet werden kann (d.h. ohne Nutzerinteraktion).

In das AMAPI SDK in der App einbinden

Weitere Informationen zum AMAPI SDK und zum Hinzufügen zu Ihrer App finden Sie in der AMAPI SDK-Integrationsanleitung.

Erforderliche Metadaten dem Manifest der App hinzufügen

Android Device Policy (ADP) muss den ComponentName Ihrer Klasse kennen, die NotificationReceiverService implementiert, um Ihre App über ihre zugewiesenen Rollen zu benachrichtigen. Sie müssen Ihren Dienst in AndroidManifest.xml entsprechend taggen, damit er automatisch von ADP erkannt werden kann.

  • Ihre App muss genau einen Dienst haben, der enabled ist und meta-data mit android:name gleich com.google.android.managementapi.notification.NotificationReceiverService.SERVICE_APP_ROLES hat.
  • Für diesen Dienst muss android:exported auf true gesetzt sein.
  • android:value der meta-data muss auf einen leeren String gesetzt sein.
<service
 android:name=".MyNotificationReceiverService"
 android:exported="true">
    <meta-data android:name="com.google.android.managementapi.notification.NotificationReceiverService.SERVICE_APP_ROLES" android:value="" />
</service>

Wenn Sie die Rolle COMPANION_APP testen, sollten Sie Ihrem Dienst auch die folgenden meta-data hinzufügen, damit Android Device Policy lokale Befehlsstatusaktualisierungen an Ihre App senden kann:

<meta-data android:name="com.google.android.managementapi.notification.NotificationReceiverService.SERVICE_COMMAND_STATUS" android:value="" />

Dienst erstellen, der NotificationReceiverService erweitert (oder vorhandenen Dienst aktualisieren)

Erstellen oder aktualisieren Sie Ihren vorhandenen NotificationReceiverService und implementieren Sie einen AppRolesListener, um auf Rollen zu warten, die Ihrer App zugewiesen wurden. Nur getAppRolesListener() ist erforderlich, um auf Rollen zu warten, die Ihrer App zugewiesen wurden. Wenn Ihrer App die Rolle COMPANION_APP zugewiesen ist, sollten Sie auch getCommandListener() implementieren:

import android.util.Log
import com.google.android.managementapi.approles.AppRolesListener
import com.google.android.managementapi.approles.model.AppRolesSetRequest
import com.google.android.managementapi.approles.model.AppRolesSetResponse
import com.google.android.managementapi.commands.CommandListener
import com.google.android.managementapi.commands.model.Command
import com.google.android.managementapi.notification.NotificationReceiverService

class MyNotificationReceiverService : NotificationReceiverService() {

  // If your app wants to listen for roles assigned
  override fun getAppRolesListener(): AppRolesListener =
    object : AppRolesListener {
      override fun onAppRolesSet(request: AppRolesSetRequest): AppRolesSetResponse {
        val roleTypes = request.roles.map { role -> role.roleType }
        Log.i(TAG, "onAppRolesSet: $roleTypes")

        return AppRolesSetResponse.getDefaultInstance()
      }
    }

 // If your app wants to listen for local command status updates
 // Only relevant for COMPANION_APP role
 override fun getCommandListener(): CommandListener {
    return object : CommandListener {
      override fun onCommandStatusChanged(command: Command) {
         Log.i(TAG, "onCommandStatusChanged")
      }
    }
  }

  private companion object {
    const val TAG = "MyNotificationReceiverService"
  }
}

Ihre App kann mehrmals benachrichtigt werden, wenn sich ihre Rollen mehrmals ändern. Wenn alle Rollen entfernt werden, wird Ihre App trotzdem mit einer leeren Liste von Rollen benachrichtigt. Durch diese Benachrichtigung wird Ihre App aus dem angehaltenen Zustand entfernt. Zusammen mit den für Ihre App gewährten Ausnahmen kann Ihre App ohne Nutzerinteraktion gestartet werden. Dank der Benachrichtigung und der Ausnahmen für Anwendungsrollen kann Ihre App auf ACTION_BOOT_COMPLETED Broadcasts warten. Wenn Ihre App auf ihre verwalteten Konfigurationen angewiesen ist, um gestartet zu werden, finden Sie unter Verwaltete Konfigurationen einrichten Informationen zum Lesen und Warten auf Änderungen.

Gerät mit Richtlinien für Anwendungsrollen bereitstellen

App-Entwickler können die Zuweisung von Anwendungsrollen zu ihrer Anwendung mit einem EMM testen oder der Android Management API-Schnellstartanleitungfolgen. Mit dem AMAPI Colab-Notebook können Sie ein Unternehmen registrieren, eine Richtlinie erstellen und ein Gerät bereitstellen.

Richtlinie für Ihre App mit Anwendungsrollen festlegen

Richten Sie eine policy mit den Anwendungsrollen ein, die Ihre App haben soll, indem Sie die ApplicationPolicy.roles verwenden.

Das folgende Beispiel zeigt, wie die Rolle für MTD-Apps konfiguriert wird:

{
  "applications": [

    {
      "packageName": "com.example.mtd",
      "installType": "FORCE_INSTALLED",
      "roles": [
        { "roleType": "MOBILE_THREAT_DEFENSE_ENDPOINT_DETECTION_RESPONSE" }
      ]
    }
  ]
}

Bevor die in der Richtlinie angegebenen Rollen zugewiesen werden, prüft das System, ob der Zertifikat-Fingerabdruck des Signaturschlüssels der App auf dem Gerät mit dem im Google Play Store übereinstimmt. Wenn der Fingerabdruck unterschiedlich ist, werden der App keine Rollen zugewiesen und dem EMM wird die NonComplianceReason.APP_SIGNING_CERT_MISMATCH Nichteinhaltung gemeldet.

{
  "applications": [

    {
      "packageName": "com.example.mtd",
      "installType": "FORCE_INSTALLED",
      "signingKeyCerts": [
         { "signingKeyCertFingerprintSha256": "base64-encoded-sha256" }
       ],
      "roles": [
        { "roleType": "MOBILE_THREAT_DEFENSE_ENDPOINT_DETECTION_RESPONSE" }
      ]
    }
  ]
}

Wenn Ihre App eine verwaltete Konfiguration hat, kann der IT-Administrator eine initiale Konfiguration für die relevanten restrictions in der Anwendungsrichtlinie einrichten:

{
  "applications": [

    {
      "packageName": "com.example.mtd",
      "installType": "FORCE_INSTALLED",
      "roles": [
        { "roleType": "MOBILE_THREAT_DEFENSE_ENDPOINT_DETECTION_RESPONSE" }
      ],
      "managedConfiguration": {
        "<key>": "<value>"
      }
    }
  ]
}

Status der Ausnahme für den Akku prüfen

Apps mit der Rolle „Mobile Threat Defense“ (MTD) sind automatisch von den Standardbeschränkungen für den Hintergrundbetrieb ausgenommen. Diese Ausnahme wird jedoch nicht durch die Zulassungsliste für den Energieverbrauch des Systems, sondern durch den App-Standby-Bucket implementiert.

So prüfen Sie, ob die Ausnahme für die App aktiv ist:

import android.app.usage.UsageStatsManager
import android.content.Context

// UsageStatsManager.STANDBY_BUCKET_EXEMPTED is annotated as a @SystemApi. We can redefine it for clarity.
// Define this at the top level of your file, or inside a companion object
private const val STANDBY_BUCKET_EXEMPTED = 5

private fun isAppExemptedFromAppStandbyBucket(): Boolean =
    (getSystemService(Context.USAGE_STATS_SERVICE) as? UsageStatsManager)
        ?.appStandbyBucket == STANDBY_BUCKET_EXEMPTED