实现设备管理

本部分介绍了如何启用和验证为受管理资料准备设备时所需的设备管理功能。此外,还介绍了企业环境中至关重要的设备所有者用户情境。

除了 AOSP 代码之外,设备还需要以下组件来与受管理资料配合使用。

常规要求

要支持设备管理,设备必须满足以下常规要求。

热 HAL 值

Android 7.0 及更高版本支持 HardwarePropertiesManager API,这是一个设备监控和运行状况报告 API,可让应用查询设备硬件的状态。此 API 通过 android.os.HardwarePropertiesManager 提供,并通过 HardwarePropertiesManagerService 对硬件热 HAL (hardware/libhardware/include/hardware/thermal.h) 进行调用。它是一个受保护的 API,这意味着,只有设备/资料所有者设备政策控制器 (DPC) 应用和当前的 VrListenerService 可以调用它。

要支持 HardwarePropertiesManager API,设备热 HAL 实现必须能够报告以下值:

报告所用单位 启用
[CPU|GPU|电池|设备表面] 的温度 组件的温度(以摄氏度为单位) 应用可以查看设备温度和组件调节/关闭温度
CPU 处于活动状态的时间/总启用时间 毫秒 应用可以查看每个核心的 CPU 使用率
风扇转速 每分钟转数 (RPM) 应用可以查看风扇转速

当核心(或 GPU、电池、风扇)进入离线状态或接通/断开电源时,实现应正确处理报告值对应的情况。

不允许低 RAM

设备不得是低 RAM 设备,这意味着,不得定义 ro.config.low_ram。当定义了 low_ram 标志时,框架会自动将用户数限制为 1。

uses-feature

设备必须定义以下 uses-feature

    android.software.managed_users
    android.software.device_admin
    

要确认在设备上定义了这些 uses-feature 值,请运行:adb shell pm list features

仅限必需应用

默认情况下,在配置受管理设备时,只能启用资料正确运行所必需的应用。OEM 必须确保受管理资料或设备具有所有必需的应用,方法是修改:

    vendor_required_apps_managed_profile.xml
    vendor_required_apps_managed_device.xml
    vendor_disallowed_apps_managed_profile.xml
    vendor_disallowed_apps_managed_device.xml
    /*
     * The following are for Android 9 and higher only
     */
    vendor_required_apps_managed_user.xml
    vendor_disallowed_apps_managed_user.xml
    

受管理用户需要的应用和不允许的应用将应用于通过 DevicePolicyManager#createAndManageUser 创建的次要用户。

Nexus 设备的示例:

Android 8.x 及更低版本

    pacakages/apps/ManagedProvisioning/res/values/vendor_required_apps_managed_device.xml
    

Android 9 及更高版本

    frameworks/base/core/res/res/values/vendor_required_apps_managed_device.xml
    
    <resources>
      <!-- A list of apps to be retained on the managed device -->
      <string-array name="vendor_required_apps_managed_device">
        <item>com.android.vending</item> <!--­Google Play -->
        <item>com.google.android.gms</item> <!--­Required by Play -->
        <item>com.google.android.contacts</item> <!--­Google or OEM Contacts­-->
        <item>com.google.android.googlequicksearchbox</item> <!--­Google Launcher -->
        <item>com.google.android.launcher</item> <!--­Google Launcher or OEM Launcher -->
        <item>com.google.android.dialer</item> <!--­Google or OEM dialer to enable making phone calls -->
      </string-array>
    </resources>
    

Android 8.x 及更低版本

    packages/apps/ManagedProvisioning/res/values/vendor_required_apps_managed_profile.xml
    

Android 9 及更高版本

    frameworks/base/core/res/res/values/vendor_required_apps_managed_profile.xml
    
    <resources>
        <!-- A list of apps to be retained in the managed profile. This includes any Google experience apps required. -->
        <string-array name="vendor_required_apps_managed_profile">
            <item>com.android.vending</item> <!-- Google Play -->
            <item>com.google.android.gms</item> <!-- Required by Play -->
            <item>com.google.android.contacts</item> <!-- Google or OEM Contacts -->
        </string-array>
    </resources>
    

启动器要求

您必须更新启动器,以支持用来标记应用的图标徽章(在 AOSP 中提供,代表受管理应用)以及其他徽章界面元素(如近期活动和通知)。如果您使用 AOSP 中的 launcher3 而不进行修改,那么您可能已经支持此标记功能。

NFC 要求

NFC 设备必须在“开箱即用”过程(即设置向导)中启用 NFC,并配置为接受受管理配置 intent:

    packages/apps/Nfc/res/values/provisioning.xml
    
    <bool name="enable_nfc_provisioning">true</bool>
    <item>application/com.android.managedprovisioning</item>
    

设置要求

包含“开箱即用”过程(即设置向导)的设备应实现设备所有者配置。当“开箱即用”过程开始时,应检查其他进程(如设备所有者配置)是否已完成用户设置,如果已完成,应触发主屏幕 intent 并完成设置。配置应用会捕获此 intent,然后将控制权交给新设置的设备所有者。

要满足设置要求,请将以下代码添加到设备设置的主 Activity 中:

    @Override
       protected void onStart() {
            super.onStart();

            // When returning to a setup wizard activity, check to see if another setup process
            // has intervened and, if so, complete an orderly exit
            boolean completed = Settings.Secure.getInt(getContentResolver(),
                    Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
            if (completed) {
               startActivity(new Intent(Intent.ACTION_MAIN, null)
                    .addCategory(Intent.CATEGORY_HOME)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                            | Intent.FLAG_ACTIVITY_CLEAR_TASK
                            | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED));
               finish();
           }

           ...
       }