构建设备策略控制器

本指南介绍如何为 Android 企业部署中的设备开发设备策略控制器 (DPC)。DPC 应用(以前称为工作策略控制器)控制设备上的本地设备策略和系统应用。

关于 DPC

在 Android 企业部署中,企业可以控制用户设备的各个方面,例如将与工作相关的信息与用户的个人数据隔离,预配置环境中批准的应用,或禁用设备功能(例如,摄像头)。

作为 EMM,您可以开发一个 DPC 应用,客户可以将其与您的EMM 控制台和服务器结合使用。您的客户会将 DPC 部署到他们管理的用户设备上。DPC 充当您的 EMM 控制台(和服务器)与设备之间的桥梁。管理员使用 EMM 控制台执行一系列任务,包括配置设备设置和应用。

DPC 在安装它的设备上创建和管理工作配置文件。工作配置文件会加密与工作相关的信息,并将其与用户的个人应用和数据分开。在创建工作配置文件之前,DPC 还可以预配一个托管的 Google Play 帐户以在设备上使用。

本指南将向您展示如何开发可以创建和管理工作配置文件的 DPC。

面向 EMM 的 DPC 支持库

面向 EMM 的 DPC 支持库包含实用程序和帮助程序类,这些类有助于在企业环境中预配和管理 Android 设备。该库允许您在 DPC 应用中利用重要功能

  • 托管 Google Play 帐号配置支持:从 DPC 应用配置托管 Google Play 帐号需要 Google Play 和 Google Play 服务应用满足最低版本要求。但是,更新这些应用可能很复杂。DPC 支持库负责更新这些应用,并确保与托管 Google Play 帐号配置过程的未来更新兼容。有关详细信息,请参阅托管 Google Play 帐号配置支持
  • 托管配置支持:使用 Play EMM API 处理已批准应用的托管配置是在您的 DPC 上实施托管配置的最简单方法。DPC 支持库允许您将应用托管配置(以前称为应用限制)的任务委派给 Google Play,这些配置由管理员使用您的 EMM 控制台设置。使用 Play EMM API 处理托管配置允许在安装期间以原子方式应用应用配置。有关如何在您的 DPC 中启用此功能的更多信息,请参阅将托管配置应用于工作应用

请按照以下步骤下载库。本指南中详细介绍的任务假设使用 DPC 支持库。

下载 DPC 支持库

要使用 DPC 支持库,请从Android 企业 EMM 提供商社区下载库。您必须将库添加到您的 build.gradle 文件中,并在构建 DPC 应用时处理其他依赖项。例如,该库需要 11.4.0 版Google Play 服务身份验证客户端库

  1. 将库添加到build.gradle文件中

    Groovy

    implementation(name:'dpcsupport-yyyymmdd', ext:'aar')
    

    Kotlin

    implementation(name = "dpcsupport-yyyymmdd", ext = "aar")
    
  2. 将 11.4.0 版Google Play 服务身份验证客户端库添加到 build.gradle 文件中

    Groovy

    implementation 'com.google.android.gms:play-services-auth:11.4.0'
    

    Kotlin

    implementation("com.google.android.gms:play-services-auth:11.4.0")
    

该库需要某些权限才能运行,因此您必须在上传到 Google Play 时将这些权限添加到 DPC 应用的清单中。

  <uses-permission android:name=
      "android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>
  <uses-permission android:name=
      "android.permission.GET_ACCOUNTS"/>
  <uses-permission android:name=
      "android.permission.MANAGE_ACCOUNTS"/>
  <uses-permission android:name=
      "android.permission.WRITE_SYNC_SETTINGS"/>
  <uses-permission android:name=
      "com.google.android.providers.gsf.permission.READ_GSERVICES"/>

除了这些初步的设置和部署步骤之外,您还必须根据您要实施的功能在您的 DPC 代码中初始化特定的库功能。详细信息包含在下面的相关部分中。

创建 DPC

基于用于设备管理应用的现有模型构建您的 DPC。具体来说,您的应用必须像设备管理中所述那样对DeviceAdminReceiver(来自android.app.admin包的一个类)进行子类化。

创建工作资料

有关演示如何创建基本工作资料的示例,请参阅 GitHub 上的BasicManagedProfile

要在已拥有个人资料的设备上创建工作资料,首先请通过检查FEATURE_MANAGED_USERS系统功能是否存在来确定设备是否支持工作资料。

Kotlin

if (!packageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
    // This device does not support work profiles!
}

Java

PackageManager pm = getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
    // This device does not support work profiles!
}

如果设备支持工作资料,请通过发送具有ACTION_PROVISION_MANAGED_PROFILE操作的 Intent 来创建工作资料。(在某些文档中,托管资料是一个通用术语,在 Android 企业环境中与工作资料含义相同。)将设备管理员包名称作为额外信息包含在内。

Kotlin

val provisioningActivity = getActivity()

// You'll need the package name for the DPC app.
val myDPCPackageName = "com.example.myDPCApp"

// Set up the provisioning intent
val adminComponent = ComponentName(provisioningActivity.applicationContext, MyAdminReceiver::class.java)
provisioningIntent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, adminComponent.flattenToString())
if (provisioningIntent.resolveActivity(provisioningActivity.packageManager) == null) {
    // No handler for intent! Can't provision this device.
    // Show an error message and cancel.
} else {
    // REQUEST_PROVISION_MANAGED_PROFILE is defined
    // to be a suitable request code
    startActivityForResult(provisioningIntent,
            REQUEST_PROVISION_MANAGED_PROFILE)
    provisioningActivity.finish()
}

Java

Activity provisioningActivity = getActivity();
// You'll need the package name for the DPC app.
String myDPCPackageName = "com.example.myDPCApp";
// Set up the provisioning intent
Intent provisioningIntent =
        new Intent("android.app.action.PROVISION_MANAGED_PROFILE");
ComponentName adminComponent = new ComponentName(provisioningActivity.getApplicationContext(), MyAdminReceiver.class);
provisioningIntent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, adminComponent.flattenToString());
if (provisioningIntent.resolveActivity(provisioningActivity.getPackageManager())
         == null) {
    // No handler for intent! Can't provision this device.
    // Show an error message and cancel.
} else {
    // REQUEST_PROVISION_MANAGED_PROFILE is defined
    // to be a suitable request code
    startActivityForResult(provisioningIntent,
            REQUEST_PROVISION_MANAGED_PROFILE);
    provisioningActivity.finish();
}

系统通过执行以下操作来响应此 Intent

  • 验证设备是否已加密。如果不是,系统会提示用户在继续之前加密设备。
  • 创建工作资料。
  • 从工作资料中删除非必需应用。
  • 将 DPC 应用复制到工作资料中,并将 DPC 本身设置为资料所有者。

覆盖onActivityResult()以查看配置是否成功。

Kotlin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    // Check if this is the result of the provisioning activity
    if (requestCode == REQUEST_PROVISION_MANAGED_PROFILE) {
        // If provisioning was successful, the result code is
        // Activity.RESULT_OK
        if (resultCode == Activity.RESULT_OK) {
            // Work profile created and provisioned.
        } else {
            // Provisioning failed.
        }
        return
    } else {
        // This is the result of some other activity. Call the superclass.
        super.onActivityResult(requestCode, resultCode, data)
    }
}

Java

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check if this is the result of the provisioning activity
    if (requestCode == REQUEST_PROVISION_MANAGED_PROFILE) {
        // If provisioning was successful, the result code is
        // Activity.RESULT_OK
        if (resultCode == Activity.RESULT_OK) {
            // Work profile created and provisioned.
        } else {
            // Provisioning failed.
        }
        return;
    } else {
        // This is the result of some other activity. Call the superclass.
        super.onActivityResult(requestCode, resultCode, data);
    }
}

完成启用工作资料

配置资料完成后,系统会调用 DPC 应用的DeviceAdminReceiver.onProfileProvisioningComplete()方法。覆盖此回调方法以完成启用工作资料。

典型的DeviceAdminReceiver.onProfileProvisioningComplete()回调实现执行以下操作

激活工作资料

完成这些任务后,请调用设备策略管理器的方法setProfileEnabled()以激活工作资料。

Kotlin

// Get the device policy manager
val myDevicePolicyMgr = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val componentName = myDeviceAdminReceiver.getComponentName(this)
// Set the name for the newly created work profile.
myDevicePolicyMgr.setProfileName(componentName, "My New Work Profile")
// ...and enable the profile
myDevicePolicyMgr.setProfileEnabled(componentName)

Java

// Get the device policy manager
DevicePolicyManager myDevicePolicyMgr =
        (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName componentName = myDeviceAdminReceiver.getComponentName(this);
// Set the name for the newly created work profile.
myDevicePolicyMgr.setProfileName(componentName, "My New Work Profile");
// ...and enable the profile
myDevicePolicyMgr.setProfileEnabled(componentName);

设置设备策略

DPC 应用会应用管理员设置的设备策略,以满足组织的要求和约束。例如,安全策略可能要求设备在一定次数的密码输入错误后锁定。DPC 查询 EMM 控制台以获取当前策略,然后使用设备管理 API 应用这些策略。

有关如何应用设备策略的信息,请参阅策略

将托管配置应用于工作应用

托管配置允许您为您的客户提供预配置他们已批准部署的应用以及在配置需要更改时轻松更新这些应用的功能。在部署之前配置应用可确保在目标设备上安装应用后满足组织的安全和其他策略。

应用功能由应用开发者在 XML 模式(托管配置模式)中定义,该模式随应用上传到 Google Play 时一同提供(应用开发者,有关详细信息,请参阅设置托管配置)。

您可以从应用中检索此模式以显示在您的 EMM 控制台中供您的客户管理员使用,提供一个 UI 以显示模式中定义的各种选项,并启用管理员预配置应用设置的功能。管理员设置的生成的托管配置通常存储在 EMM 服务器上,然后该服务器使用 Play EMM API 设置ManagedconfigurationsfordeviceManagedconfigurationsforuser。有关详细信息,请参阅通过 Play 进行托管配置

可以通过使用 Play EMM API(推荐方法)或直接从 DPC(在直接从 DPC 应用托管配置中描述)来应用托管配置。使用 Play EMM API 有几个优点,包括易于实施,因为您可以使用DPC 支持库简化 DPC 任务。此外,Play EMM API

  • 在安装新应用时以原子方式设置配置,从而确保用户首次启动应用时应用已准备就绪。
  • 允许您按用户管理配置,因此您可以避免按设备监控配置。

使用 Play EMM API 应用托管配置

要将 Play EMM API 用于托管配置,DPC 必须允许 Google Play 设置配置。DPC 支持库通过代理 Google Play 发送的配置为您处理此任务。

要使用 Play EMM API,请下载DPC 支持库,然后在您的 DPC 中启用托管配置支持。

在您的 DPC 中启用托管配置支持

在您的 DPC 中导入此类

com.google.android.apps.work.dpcsupport.ManagedConfigurationsSupport

初始化托管配置库。在此示例中,“admin”是DeviceAdminReceiver的 ComponentName。

Kotlin

var managedConfigurationsSupport = ManagedConfigurationsSupport(context, admin)

Java

ManagedConfigurationsSupport managedConfigurationsSupport =
    new ManagedConfigurationsSupport(context, admin);

启用托管配置

Kotlin

managedConfigurationsSupport.enableManagedConfigurations()

Java

managedConfigurationsSupport.enableManagedConfigurations();

通过在您的 DPC 中初始化此库,您可以在您的 EMM 控制台和服务器中使用Google Play EMM API将托管配置应用于已批准的应用,而不是直接在 DPC 中编码这些任务。有关详细信息,请参阅通过 Play 进行托管配置

直接从 DPC 应用托管配置

要直接从 DPC 更改应用的配置设置,请调用DevicePolicyManager.setApplicationRestrictions()方法,并传递 DPC 应用的DeviceAdminReceiver、目标应用的包名称以及包含管理员设置的应用托管配置的Bundle的参数。有关详细信息,请参阅您的 DPC 和 EMM 控制台如何交互设置托管配置。但是,请注意,在托管 Google Play 帐号部署中不建议使用这种应用托管配置的替代方法。

托管 Google Play 帐号配置支持

DPC 支持库包括对配置托管 Google Play 帐号的支持。要使用此支持,您必须首先初始化库,然后您可以确保工作环境添加托管 Google Play 帐号

在您的 DPC 中初始化托管 Google Play 帐号支持

在您的 DPC 中导入此类

com.google.android.apps.work.dpcsupport.AndroidForWorkAccountSupport

初始化配置兼容性库。在此示例中,“admin”是ComponentNameDeviceAdminReceiver

Kotlin

var androidForWorkAccountSupport = AndroidForWorkAccountSupport(context, admin)

Java

AndroidForWorkAccountSupport androidForWorkAccountSupport =
    new AndroidForWorkAccountSupport(context, admin);

确保托管 Google Play 帐号的工作环境

在 DPC 在资料所有者模式(ACTION_PROVISION_MANAGED_PROFILE)或设备所有者模式(ACTION_PROVISION_MANAGED_DEVICE)下配置设备后,请确保设备可以通过调用以下方法支持托管 Google Play 帐号

Kotlin

androidForWorkAccountSupport.ensureWorkingEnvironment(callback)

Java

androidForWorkAccountSupport.ensureWorkingEnvironment(callback);

回调报告此过程的成功或失败。当回调成功返回时,可以添加托管 Google Play 帐户。如果回调报告错误,请提示用户确保设备已连接网络(例如,如果下载失败)。在其他情况下,将失败报告给 Google。

Kotlin

object : WorkingEnvironmentCallback() {
    override fun onSuccess() {
        // Can now provision the managed Google Play Account
    }
    override fun onFailure(error: Error) {
        // Notify user, handle error (check network connection)
    }
}

Java

new WorkingEnvironmentCallback() {
    @Override
    public void onSuccess() {
        // Can now provision the managed Google Play Account
    }

    @Override
    public void onFailure(Error error) {
        // Notify user, handle error (check network connection)
    }
}

添加托管 Google Play 帐户

Android 框架的AccountManager可以将托管 Google Play 帐户添加到设备。为了简化与AccountManager的交互,请使用来自DPC 支持库的辅助函数(如下例所示)。该函数处理 Google Play 服务器返回的令牌,并促进托管 Google Play 帐户的配置。该函数在托管 Google Play 帐户处于有效状态时返回。

Kotlin

androidForWorkAccountSupport.addAndroidForWorkAccount(token, accountAddedCallback)

Java

androidForWorkAccountSupport.addAndroidForWorkAccount(token, accountAddedCallback);
  • token—Google Play EMM API Users.generateAuthenticationToken() 调用生成的用户信息令牌。
  • accountAddedCallback—返回成功添加到设备的托管 Google Play 帐户。此回调应包括onAccountReady()onFailure() 方法。

Kotlin

val workAccountAddedCallback = object : WorkAccountAddedCallback() {
    override fun onAccountReady(account: Account, deviceHint: String) {
        // Device account was successfully added to the device
        // and is ready to be used.
    }

    override fun onFailure(error: Error) {
        // The account was not successfully added. Check that the token
        // provided was valid (it expires after a certain period of time).
    }
}

Java

WorkAccountAddedCallback workAccountAddedCallback =
    new WorkAccountAddedCallback() {
        @Override
        public void onAccountReady(Account account, String deviceHint) {
            // Device account was successfully added to the device
            // and is ready to be used.
        }

        @Override
        public void onFailure(Error error) {
            // The account was not successfully added. Check that the token
            // provided was valid (it expires after a certain period of time).
        }
};
  • 要了解有关设备管理 API 的更多信息,请参阅设备管理
  • 要了解有关 Android 企业配置方法的更多信息,请参阅 Android 企业开发者指南中的配置设备
  • 有关演示如何创建基本工作配置文件的 GitHub 示例,请参阅BasicManagedProfile
  • 有关演示如何作为配置文件所有者设置其他应用上的配置的 GitHub 示例,请参阅AppRestrictionEnforcer