打造裝置政策控制器

本指南說明如何為 Android Enterprise 部署中的裝置開發裝置政策控制器 (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 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 動作,建立工作資料夾。(在某些文件中,「受管理設定檔」是通用術語,在 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();
}

系統會執行下列動作,回應這項意圖:

  • 確認裝置是否已加密。如果沒有,系統會提示使用者先加密裝置,再繼續操作。
  • 建立工作資料夾。
  • 從工作資料夾中移除非必要應用程式。
  • 將 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 套用政策。

如要瞭解如何套用裝置政策,請參閱「 政策」一文。

將受管理設定套用至工作應用程式

透過受管理設定,客戶可以預先設定已核准部署的應用程式,並在需要變更設定時輕鬆更新這些應用程式。在部署應用程式前進行設定,可確保應用程式安裝在目標裝置上時,符合機構的安全性和其他政策。

應用程式開發人員會在 XML 結構定義 (受管理設定結構定義) 中定義應用程式功能,並在將應用程式上傳至 Google Play 時一併提供 (應用程式開發人員如需詳細資料,請參閱「設定受管理設定」)。

您從應用程式擷取這個結構定義,在 EMM 控制台中向客戶管理員顯示,提供 UI 來顯示結構定義中定義的各種選項,並讓管理員預先設定應用程式設定。管理員設定的代管設定通常會儲存在 EMM 伺服器上,然後伺服器會使用 Play EMM API 設定 ManagedconfigurationsfordeviceManagedconfigurationsforuser。詳情請參閱「透過 Google 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 傳送的設定設為 Proxy。

如要使用 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 中編寫這些工作的程式碼。詳情請參閱「 透過 Google 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).
        }
};
  • 如要進一步瞭解裝置管理 API,請參閱裝置管理
  • 如要瞭解 Android Enterprise 佈建方法,請參閱 Android Enterprise 開發人員指南中的「佈建裝置」。
  • 如需示範如何建立基本工作設定檔的 GitHub 範例,請參閱「BasicManagedProfile」。
  • 如需 GitHub 範例,瞭解如何以設定檔擁有者身分設定其他應用程式,請參閱 AppRestrictionEnforcer