打造裝置政策控制器

本指南說明如何為 Android 企業部署中的裝置開發裝置政策控制器 (DPC)。DPC 應用程式過去稱為工作政策控制器,可控制裝置上的本機裝置政策和系統應用程式。

關於裝置政策控制器 (DPC)

在 Android 企業部署作業中,企業可以維護使用者裝置的各種層面,例如將工作相關資訊與使用者的個人資料區隔開來、針對環境預先設定已核准的應用程式,或停用裝置功能 (例如相機)。

EMM 屬於 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 供應商社群下載程式庫。您必須將程式庫新增至 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. 在 build.gradle 檔案中新增 11.4.0 Google Play 服務驗證用戶端程式庫

    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 時,收到隨附的 XML 結構定義 (應用程式開發人員,詳情請參閱「設定受管理的設定」)。

您會從應用程式擷取這個結構定義,以便在 EMM 控制台中向客戶管理員顯示,提供一個 UI 以顯示結構定義顯示的各種選項,並讓管理員預先調整應用程式設定。由管理員設定的受管理設定通常會儲存在 EMM 伺服器上,該伺服器會使用 Play EMM API 設定「Managedconfigurationsfordevice」或「Managedconfigurationsforuser」。詳情請參閱「透過 Play 管理化設定」。

您可以使用 Play EMM API (建議做法) 或直接透過 DPC (直接從 DPC 套用受管理的設定),將受管理的設定套用至應用程式。使用 Play EMM API 有許多優點,包括能夠輕鬆實作,因為您可以使用 DPC 支援資料庫簡化 DPC 工作。此外,Play EMM API:

  • 在新應用程式安裝完成後,以不可分割的形式進行設定,確保使用者首次啟動應用程式時,應用程式已就緒。
  • 可讓您管理各使用者的設定,避免監控各裝置佈建的情形。

透過 Play EMM API 套用受管理的設定

如要使用 Play EMM API 進行受管理設定,DPC 必須允許 Google Play 調整設定。DPC 支援資料庫會透過 Proxy 處理 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 中編寫這些工作的程式碼。詳情請參閱「 透過 Google Play 的受管理設定」。

直接從 DPC 套用受管理的設定

如要透過 DPC 變更應用程式的配置設定,請呼叫 DevicePolicyManager.setApplicationRestrictions() 方法並傳遞 DPC 應用程式的 DeviceAdminReceiver 參數、目標應用程式的套件名稱,以及由管理員設定的應用程式受管理設定套裝組合。詳情請參閱「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 範例,瞭解如何以設定檔擁有者身分設定其他應用程式的設定,請參閱 AppRestrictionLaunchr