构建设备政策控制器

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

设备政策控制器 (DPC) 简介

在 Android Enterprise 部署中,企业可以控制用户设备的各个方面,例如将工作相关信息与用户的个人数据隔离开来、为环境预先配置获批的应用,或停用设备功能(例如相机)。

作为 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 支持库,您可以将管理员使用 EMM 控制台设置的受管理配置(以前称为应用限制)委托给 Google Play。使用 Play EMM API 处理托管配置允许在安装过程中以原子方式应用配置。如需详细了解如何在 DPC 中启用此功能,请参阅将托管配置应用于工作应用

请按照以下步骤下载库。本指南中详述的任务假定使用了 DPC 支持库。

下载 DPC 支持库

如需使用 DPC 支持库,请从 Android Enterprise EMM 提供商社区下载该库。 在构建 DPC 应用时,您必须将该库添加到 build.gradle 文件中并处理其他依赖项。例如,该库需要 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 中的“工作资料”的含义相同。)将设备管理软件包名称作为 extra:

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 控制台查询当前政策,然后使用 Device Administration API 应用政策。

如需了解如何应用设备政策,请参阅 政策

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

通过托管配置,您可以让客户能够预先配置他们已批准用于部署的应用,并在需要更改配置时轻松更新这些应用。在部署之前配置应用可确保应用在目标设备上安装时符合组织的安全政策和其他政策。

应用功能由应用开发者在将应用上传到 Google Play 后随应用一起提供的 XML 架构(托管配置架构)中进行定义(应用开发者请参阅设置托管配置,了解详情)。

您将从应用中检索此架构,以便在 EMM 控制台中向客户管理员显示,提供一个界面来显示架构中定义的各种选项,并让管理员能够预配置应用的设置。管理员设置的托管配置通常存储在 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”是 DeviceAdminReceiverComponentName

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).
        }
};
  • 如需详细了解 Device Administration API,请参阅设备管理
  • 如需了解 Android Enterprise 配置方法,请参阅 Android Enterprise 开发者指南中的配置设备
  • 如需查看演示如何创建基本工作资料的 GitHub 示例,请参阅 BasicManagedProfile
  • 如需查看 GitHub 示例以配置文件所有者的身份在其他应用中设置配置,请参阅 AppRestrictionEnforcer