Zarządzanie rolami aplikacji

Funkcja ról aplikacji umożliwia administratorowi IT przyznawanie specjalnych uprawnień zarządzanej aplikacji na urządzeniu z Androidem. Po przypisaniu określonej roli aplikacja może zostać zwolniona z ograniczeń dotyczących zasilania i działania w tle, zawieszenia i hibernacji (na Androidzie 14 lub nowszym), a opcje sterowania przez użytkownika (np. wymuszenie zatrzymania i wyczyszczenie danych aplikacji) mogą zostać wyłączone (na Androidzie 11 lub nowszym), co pozwoli jej na nieprzerwane wykonywanie kluczowych funkcji. Dodatkowo aplikacja może zostać powiadomiona o przypisanych jej rolach, co pozwala jej na samodzielne uruchomienie bez interwencji użytkownika.

Listę dostępnych ról aplikacji i specjalnych uprawnień przyznanych każdej roli znajdziesz w artykule RoleType.

Wymagania wstępne

Urządzenie jest zarządzane przez usługę EMM opartą na AMAPI (usługi EMM korzystające z niestandardowego kontrolera zasad urządzeń nie są obsługiwane).

Przygotowanie aplikacji do korzystania z funkcji

Integracja z pakietem SDK AMAPI jest wymagana tylko wtedy, gdy aplikacja ma być powiadamiana o przypisanych jej rolach, co umożliwia jej samodzielne uruchamianie (czyli automatyczne uruchamianie bez interakcji użytkownika).

Integracja z pakietem AMAPI SDK w aplikacji

Więcej informacji o pakiecie AMAPI SDK i sposobie dodawania go do aplikacji znajdziesz w przewodniku po integracji z pakietem AMAPI SDK.

Dodawanie wymaganych metadanych do pliku manifestu aplikacji

Android Device Policy (ADP) musi znać ComponentName Twojej klasy, która implementuje NotificationReceiverService, aby powiadomić aplikację o przypisanych rolach. Musisz odpowiednio otagować usługę w AndroidManifest.xml, aby mogła zostać automatycznie wykryta przez ADP.

  • Aplikacja musi mieć dokładnie 1 usługę, która jest enabled i ma meta-data z android:name równym com.google.android.managementapi.notification.NotificationReceiverService.SERVICE_APP_ROLES
  • W tej usłudze parametr android:exported musi mieć wartość true
  • Wartość android:value w meta-data musi być ustawiona na pusty ciąg znaków
<service
 android:name=".MyNotificationReceiverService"
 android:exported="true">
    <meta-data android:name="com.google.android.managementapi.notification.NotificationReceiverService.SERVICE_APP_ROLES" android:value="" />
</service>

Jeśli testujesz rolę COMPANION_APP, dodaj do usługi ten element meta-data, aby aplikacja Android Device Policy mogła wysyłać do Twojej aplikacji aktualizacje stanu poleceń lokalnych:

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

Utwórz usługę rozszerzającą NotificationReceiverService (lub zaktualizuj istniejącą).

Utwórz lub zaktualizuj istniejący element NotificationReceiverService i zaimplementuj AppRolesListener, aby nasłuchiwać ról przypisanych do aplikacji. Do nasłuchiwania ról przypisanych do aplikacji wymagany jest tylko element getAppRolesListener(). Jeśli do aplikacji jest przypisana rola COMPANION_APP, musisz też zaimplementować element getCommandListener():

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

Jeśli role aplikacji zmienią się kilka razy, aplikacja może otrzymać kilka powiadomień. Jeśli wszystkie role zostaną usunięte, aplikacja nadal będzie otrzymywać powiadomienia z pustą listą ról. To powiadomienie spowoduje, że aplikacja wyjdzie ze stanu zatrzymania i będzie mogła uruchomić się bez interakcji użytkownika, korzystając z przyznanych jej zwolnień. Dzięki powiadomieniu o rolach aplikacji i wyjątkom aplikacja może nasłuchiwać transmisji ACTION_BOOT_COMPLETED. Jeśli aplikacja wymaga konfiguracji zarządzanych do uruchomienia, przeczytaj artykuł Konfigurowanie konfiguracji zarządzanych, aby dowiedzieć się, jak odczytywać i nasłuchiwać zmian.

Od wersji AMAPI SDK 1.9.0 każda rola w AppRolesSetRequest obejmuje też uprawnienia Role.ExtraCapabilities przyznane przez administratora IT w zasadach. Na przykład aplikacja towarzysząca może sprawdzić, czy może wydać polecenie lokalnego czyszczenia:

import com.google.android.managementapi.approles.model.AppRolesSetRequest
import com.google.android.managementapi.approles.model.AppRolesSetResponse
import com.google.android.managementapi.common.model.Role
...

  override fun onAppRolesSet(request: AppRolesSetRequest): AppRolesSetResponse {
    val canWipeLocally =
      request.roles.any { role ->
        role.roleType == Role.RoleType.COMPANION_APP &&
          role.extraCapabilities.localDeviceWipeCommand ==
            Role.ExtraCapabilities.LocalDeviceWipeCommand.LOCAL_DEVICE_WIPE_COMMAND_ALLOWED
      }
    Log.i(TAG, "onAppRolesSet: canWipeLocally=$canWipeLocally")

    return AppRolesSetResponse.getDefaultInstance()
  }

Tylko administrator IT może przyznać dodatkowe uprawnienia. Jeśli ustawisz extraCapabilities w roli przekazywanej do EnvironmentClient, wywołanie zakończy się błędem InvalidArgumentException.

Zapewnianie urządzeniu zasad ról aplikacji

Deweloperzy aplikacji mogą przetestować przypisywanie ról aplikacji do swojej aplikacji za pomocą EMM lub postępując zgodnie z krótkim wprowadzeniem do interfejsu Android Management API. Notatnik Colab AMAPI umożliwia zarejestrowanie firmy, utworzenie zasad i udostępnienie urządzenia.

Konfigurowanie zasad aplikacji za pomocą ról aplikacji

Skonfiguruj policy z rolami aplikacji, które ma mieć Twoja aplikacja, za pomocą ApplicationPolicy.roles.

Poniższy przykład pokazuje, jak skonfigurować rolę dla aplikacji MTD:

{
  "applications": [

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

Tylko rola COMPANION_APP obsługuje extraCapabilities. Aby zezwolić aplikacji towarzyszącej na lokalne czyszczenie urządzenia lub profilu służbowego, ustaw extraCapabilities.localDeviceWipeCommand na LOCAL_DEVICE_WIPE_COMMAND_ALLOWED dla tej roli.

Przed przypisaniem ról określonych w zasadach system sprawdzi, czy odcisk cyfrowy certyfikatu klucza podpisywania aplikacji na urządzeniu jest zgodny z odciskiem cyfrowym ze Sklepu Play. Jeśli odcisk cyfrowy jest inny, role nie zostaną przypisane do aplikacji, a do dostawcy usług EMM zostanie zgłoszona niezgodność z zasadami NonComplianceReason.APP_SIGNING_CERT_MISMATCH.

{
  "applications": [

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

Jeśli aplikacja ma konfigurację zarządzaną, administrator IT może skonfigurować początkową konfigurację odpowiednich restriction w zasadach dotyczących aplikacji:

{
  "applications": [

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

Sprawdzanie stanu zwolnienia z obowiązku podatkowego

Aplikacje z rolą Mobile Threat Defense (MTD) są automatycznie wyłączone ze standardowych ograniczeń dotyczących zasilania w tle. Jednak to zwolnienie jest implementowane przez zasobnik czuwania aplikacji, a nie przez systemową listę dozwolonych aplikacji.

Aby sprawdzić, czy zwolnienie aplikacji jest aktywne:

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