La fonctionnalité de rôles d'application permet à un administrateur informatique d'accorder des droits spéciaux à une application gérée sur un appareil Android. En attribuant un rôle spécifique, une application peut être exemptée des restrictions d'alimentation et d'arrière-plan, de la suspension et de l'hibernation (sur Android 14 ou version ultérieure). Les commandes utilisateur (c'est-à-dire les actions utilisateur telles que l'arrêt forcé et l'effacement des données de l'application) peuvent également être désactivées (sur Android 11 ou version ultérieure), ce qui lui permet d'exécuter sa fonction critique sans interruption. De plus, l'application peut être informée des rôles qui lui sont attribués, ce qui lui permet de s'amorcer sans intervention de l'utilisateur.
Pour obtenir la liste des rôles d'application disponibles et des privilèges spéciaux accordés à chaque rôle, consultez RoleType.
Prérequis
L'appareil est géré par un EMM basé sur AMAPI (les EMM utilisant un DPC personnalisé ne sont pas compatibles).
Préparer votre application à utiliser la fonctionnalité
L'intégration au SDK AMAPI n'est requise que si l'application souhaite être informée des rôles qui lui sont attribués, ce qui lui permet de s'amorcer (c'est-à-dire de se lancer automatiquement sans interaction de l'utilisateur).
Intégrer le SDK AMAPI à votre application
Pour en savoir plus sur le SDK AMAPI et sur la façon de l'ajouter à votre application, consultez le guide d'intégration du SDK AMAPI.
Ajouter les métadonnées requises au fichier manifeste de l'application
Android Device Policy (ADP) doit connaître le ComponentName de votre classe qui implémente NotificationReceiverService pour informer votre application des rôles qui lui sont attribués. Vous devez taguer votre service dans AndroidManifest.xml de manière appropriée pour qu'il puisse être détecté automatiquement par ADP.
- Votre application doit comporter exactement un service qui est
enabledet qui possèdemeta-dataavecandroid:nameégal àcom.google.android.managementapi.notification.NotificationReceiverService.SERVICE_APP_ROLES. - Ce service doit avoir
android:exporteddéfini surtrue. - La valeur
android:valuedemeta-datadoit être définie sur une chaîne vide.
<service
android:name=".MyNotificationReceiverService"
android:exported="true">
<meta-data android:name="com.google.android.managementapi.notification.NotificationReceiverService.SERVICE_APP_ROLES" android:value="" />
</service>
Si vous testez le rôle COMPANION_APP, vous devez également ajouter l'élément meta-data suivant à votre service afin qu'Android Device Policy puisse envoyer des mises à jour de l'état des commandes locales à votre application :
<meta-data android:name="com.google.android.managementapi.notification.NotificationReceiverService.SERVICE_COMMAND_STATUS" android:value="" />
Créez un service qui étend NotificationReceiverService (ou mettez à jour le service existant).
Créez ou mettez à jour votre NotificationReceiverService existant et implémentez un AppRolesListener pour écouter les rôles attribués à votre application. Seul getAppRolesListener() est requis pour écouter les rôles attribués à votre application. Si un rôle COMPANION_APP est attribué à votre application, vous devez également implémenter 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"
}
}
Votre application peut être notifiée plusieurs fois si ses rôles changent plusieurs fois. Si tous les rôles sont supprimés, votre application sera toujours avertie avec une liste de rôles vide. Cette notification permet à votre application de quitter l'état d'arrêt. Grâce aux exceptions accordées à votre application, celle-ci peut s'amorcer sans aucune interaction de l'utilisateur. Grâce à la notification et aux exemptions des rôles d'application, votre application peut écouter les diffusions ACTION_BOOT_COMPLETED. Si votre application dépend de ses configurations gérées pour s'amorcer, consultez Configurer des configurations gérées pour savoir comment lire et écouter les modifications.
À partir de la version 1.9.0 du SDK AMAPI, chaque rôle de AppRolesSetRequest inclut également le Role.ExtraCapabilities que l'administrateur informatique a accordé dans la règle. Par exemple, une application associée peut vérifier si elle est autorisée à émettre une commande d'effacement local :
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()
}
Seul l'administrateur informatique peut accorder des fonctionnalités supplémentaires. Si vous définissez extraCapabilities sur un rôle que vous transmettez à EnvironmentClient, l'appel échoue avec une erreur InvalidArgumentException.
Provisionner l'appareil avec des règles de rôles d'application
Les développeurs d'applications peuvent tester l'attribution de rôles à leur application à l'aide d'un EMM ou en suivant le guide de démarrage rapide de l'API Android Management. Le notebook Colab AMAPI vous permet d'enregistrer une entreprise, de créer une règle et de provisionner un appareil.
Définir la stratégie de votre application avec des rôles d'application
Configurez un policy avec les rôles d'application que votre application est censée avoir à l'aide de ApplicationPolicy.roles.
L'exemple suivant montre comment configurer le rôle pour les applications MTD :
{
"applications": [
{
"packageName": "com.example.mtd",
"installType": "FORCE_INSTALLED",
"roles": [
{ "roleType": "MOBILE_THREAT_DEFENSE_ENDPOINT_DETECTION_RESPONSE" }
]
}
]
}
Seul le rôle COMPANION_APP est compatible avec extraCapabilities. Pour permettre à l'application associée d'effacer l'appareil ou le profil professionnel localement, définissez extraCapabilities.localDeviceWipeCommand sur LOCAL_DEVICE_WIPE_COMMAND_ALLOWED pour ce rôle.
Avant d'attribuer les rôles comme spécifié dans la règle, le système vérifie que l'empreinte du certificat de clé de signature de l'application sur l'appareil correspond à celle du Play Store.
Si l'empreinte est différente, les rôles ne seront pas attribués à l'application et la non-conformité NonComplianceReason.APP_SIGNING_CERT_MISMATCH sera signalée à l'EMM.
{
"applications": [
{
"packageName": "com.example.mtd",
"installType": "FORCE_INSTALLED",
"signingKeyCerts": [
{ "signingKeyCertFingerprintSha256": "base64-encoded-sha256" }
],
"roles": [
{ "roleType": "MOBILE_THREAT_DEFENSE_ENDPOINT_DETECTION_RESPONSE" }
]
}
]
}
Si votre application dispose d'une configuration gérée, l'administrateur informatique peut configurer une configuration initiale pour les restriction pertinents dans les règles de l'application :
{
"applications": [
{
"packageName": "com.example.mtd",
"installType": "FORCE_INSTALLED",
"roles": [
{ "roleType": "MOBILE_THREAT_DEFENSE_ENDPOINT_DETECTION_RESPONSE" }
],
"managedConfiguration": {
"<key>": "<value>"
}
}
]
}
Vérifier l'état de l'exemption de batterie
Les applications ayant le rôle Mobile Threat Defense (MTD) sont automatiquement exemptées des restrictions d'alimentation standard en arrière-plan. Toutefois, cette exemption est implémentée par le bucket de mise en veille des applications plutôt que par la liste d'autorisation d'alimentation du système.
Pour vérifier si l'exemption d'application est active :
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