導入使用者帳戶

Android Enterprise 註冊作業主要有兩種使用者身分類型:Google Play 管理版帳戶和受管理 Google 帳戶。受管理 Google Play 帳戶以裝置為中心,因此不會與特定使用者的 Google 身分識別資訊連結。相較之下,受管理 Google 帳戶會連結至使用者的公司 Google 身分,讓使用者在裝置上保持登入狀態,提升使用體驗。

Google Play 管理版帳戶過去是標準做法,不過,Google 現在建議所有新開發人員使用改良後的註冊流程,該流程預設會建立 Google 管理帳戶。

雖然本文結尾會提供舊版實作方式的指引,但所有新開發作業都應遵循本文詳述的新註冊流程。

總覽

改良後的裝置註冊流程運用多個新元件,並改變自訂裝置政策控制器 (DPC) 的實作方式,簡化裝置設定程序。這項新方法需要自訂 DPC 解決方案,才能與 Android Management API (AMAPI) SDK 和 Android Device Policy 整合,執行裝置準備和使用者註冊功能。

AMAPI SDK 提供必要的 API,可與裝置上的 Android 裝置政策互動。在伺服器端,企業行動管理 (EMM) 解決方案會使用 Play EMM API 產生註冊權杖,啟動裝置註冊程序。

Android Device Policy 應用程式現在在處理裝置端作業時,扮演著核心角色。AMAPI SDK 用於管理裝置上的安裝作業和必要更新。Android Device Policy 也會接管使用者驗證流程,直接處理使用者驗證,並向 EMM 提供使用者身分。如果 Google 無法驗證使用者身分,系統會建立新的 Google Play 管理版帳戶,並新增至裝置做為備案。

API 整合

開始使用前,請確認您使用的是最新版的 Play EMM API 用戶端和 AMAPI SDK。

註冊實作指南

本指南提供實作註冊程序的必要步驟。內容包括準備環境、處理不同註冊方式,以及管理裝置生命週期。

準備環境

開始設定帳戶前,請先準備裝置環境。準備工作包括將 Play 商店更新至最新版本,以及在裝置上以無聲模式安裝 Android Device Policy (com.google.android.apps.work.clouddpc)。Android Device Policy 應用程式是帳戶設定程序的重要環節,因此請務必安裝。EMM 無須手動準備環境。請改用 EnvironmentClient,如文件所述,並遵循提供的程式碼範例。

程式碼範例

如要使用 AccountSetup API 在裝置上新增公司帳戶,DPC 必須先確認裝置環境是否已準備就緒。

  • 使用 EnvironmentClientFactory 例項化 EnvironmentClient,並呼叫 prepareEnvironmentprepareEnvironmentAsync

    val notificationReceiverServiceName = ComponentName(context,
    NotificationReceiver::class.java)
    
    // An EMM should implement android.app.admin.DeviceAdminReceiver and use that
    // class to instantiate a ComponentName
    
    val admin = ComponentName(this, com.example.dpc.DeviceAdminReceiver::class.java)
    
    EnvironmentClientFactory.create(context)
        .prepareEnvironment(
            PrepareEnvironmentRequest.builder()
                .setRoles(
                    listOf(
                        Role.builder().setRoleType(
                            Role.RoleType.DEVICE_POLICY_CONTROLLER
                        ).build()
                    )
                )
        .setAdmin(admin)
                .build(),
              notificationReceiverServiceName,
            )
    
    [Proceed with AccountSetup]
    
    

這項作業可能需要幾秒或幾分鐘,因為系統可能會安裝或更新應用程式,以驗證工作環境是否正常運作。Google 建議盡早開始在背景執行這項程序,並在使用者等待時顯示適當的 UI。作業完成後,裝置即可供 DPC 使用 AccountSetup API。

註冊流程

EMM 必須停止在所有裝置上使用 users.generateAuthenticationToken()users.insert()。EMM 必須呼叫裝置端 API,才能執行使用者驗證。新版 API 會將 userIdemail 傳回給 DPC。如果 Google 無法驗證使用者身分,系統會建立受管理 Google Play 帳戶並新增至裝置。在這種情況下,Google 會傳回該帳戶的 userId

Google 現在導入註冊權杖,必須傳遞至驗證 API。EMM 會決定建立權杖的時間和方式,權杖可以做為現有註冊酬載的一部分 (例如 QR code 或零接觸設定)。

不過,Google 建議您視需要建立權杖,並以新版 API 取代現有的 Managed Google Play 帳戶 API,盡量減少變更。

使用舊版 API 整合 DPC 的一般做法
圖 1. 與先前 API 整合的典型 DPC
DPC 整合範例:適用於無使用者裝置的新 API
圖 2. Example DPC integration with new APIs for userless devices
DPC 整合範例,適用於使用者裝置的新 API
圖 3. 範例:DPC 與使用者裝置的新 API 整合

改良後的自訂 DPC 註冊流程包含下列步驟:

  1. 建立註冊權杖:EMM 會使用 Play EMM API 建立註冊權杖。
  2. 準備環境:自訂 DPC 會使用「準備環境」流程,確認裝置已準備好註冊。
  3. 啟動註冊程序:自訂 DPC 會在 AMAPI SDK 中叫用 startAccountSetup API,並傳遞註冊權杖。注意:呼叫此 API 前,DPC 必須是裝置擁有者或設定檔擁有者。
  4. 啟動 Google 驗證活動:如有需要,自訂 DPC 會在 AMAPI SDK 中呼叫 launchAuthenticationActivity API,並傳遞 AccountSetupAttempt。這會啟動 Google 驗證活動,並在驗證成功後將使用者帶回自訂 DPC。使用者也可以略過這項程序。在這種情況下,裝置會新增 Google Play 管理版帳戶。您可以使用 googleAuthenticationOptions 設定這個選項。
  5. 完成註冊:AMAPI SDK 會將註冊結果通知自訂 DPC。
  6. 啟用 Google 服務:如果使用者裝置上的受管理 Google 帳戶符合企業政策,EMM 必須呼叫 Devices.setState()。這項操作可讓裝置上的帳戶存取 Google 服務。 如果沒有這項呼叫,Play 商店和其他 Google 服務就無法運作。

帳戶設定 - 程式碼範例

  1. 如要嘗試啟動帳戶設定,呼叫應用程式可以使用 AccountSetupClient,並呼叫 startAccountSetup()startAccountSetupFuture() 方法。如需實作範例,請參閱下列程式碼範例:

    // Create AccountSetupClient
    val client = AccountSetupClientFactory.create(
        this,
        activityResultRegistry
    )
    lifecycle.addObserver(client.lifecycleObserver)
    
    // Create adminComponent
    val notificationReceiver = ComponentName(this, AccountSetupNotificationReceiver::class.java)
    // Helper method to get enrollment token created with Play EMM API
    val enrollmentToken = getEnrollmentToken()
    val request =
              StartAccountSetupRequest.builder()
                  .setEnrollmentToken(enteredText)
                  .setNotificationReceiverServiceComponentName(notificationReceiver)
                  .setAdminComponentName(
                      ComponentName(this, com.example.dpc.DeviceAdminReceiver::class.java))
                  .build()
    try {
        val accountSetupAttempt = client.startAccountSetup(request)
        // handle attempt
    } catch (e: Exception) {
        // handle exception
    }
      ```
    
  2. 實作 AccountSetupListener 介面,並提供處理收到的狀態更新的實作方式。

  3. 擴充 NotificationReceiverService 並覆寫 getAccountSetupListener(),提供步驟 2 中建立的 AccountSetupListener 例項。

    // Handles account setup changes
    class AccountSetupNotificationReceiver :
          NotificationReceiverService(),
          AccountSetupListener {
    
        override fun getAccountSetupListener(): AccountSetupListener = this
    
        override fun onAccountSetupChanged(accountSetupAttempt:
      AccountSetupAttempt) {
    
            when (accountSetupAttempt.state.kind) {
                StateCase.ADDED_ACCOUNT -> {
                    val enterpriseAccount = state.addedAccount()
                    val userId = enterpriseAccount.userId
                    val deviceId = enterpriseAccount.deviceId
                    // Handle account added state.
    
                }
                StateCase.AUTHENTICATION_ACTIVITY_LAUNCH_REQUIRED -> {
                    val request = LaunchAuthenticationActivityRequest.builder()
                .setAccountSetupAttempt(accountSetupAttempt)
                .build();
                    // Send the attempt to the foreground activity to call:
                    accountSetupClient.launchAuthenticationActivity(request)
                }
                StateCase.ACCOUNT_SETUP_ERROR -> {
                    // Handle error state.
                    val failureReason = state.accountSetupError().failureReason
                }
                else -> {
                    // Handle unknown account setup attempt state.
                }
            }
        }
    }
    
      ```
    
  4. 將擴充 NotificationReceiverService 類別新增至 AndroidManifest.xml,並確認已匯出。

      <application>
        <service
            android:name = ".accountsetup.AccountSetupNotificationReceiver"
            android:exported = "true" />
      </application>
    

    如果應用程式指定 SDK 30 以上版本,則 AndroidManifest.xml 中必須有 queries 元素,才能指定與 ADP 互動。

      <queries>
        <package android:name="com.google.android.apps.work.clouddpc" />
      </queries>
    

測試指南

本節提供一組指南和最佳做法,協助您測試導入作業。

測試 PrepareEnvironment

  1. 取得裝置的目前狀態:EMM 會執行

    adb shell dumpsys package com.google.android.apps.work.clouddpc | grep versionName
    

    即可查看裝置上的 Android Device Policy 版本。如果未安裝 Android 裝置政策,預期會輸出空白內容。

  2. 整合 PrepareEnvironment:自訂 DPC 會在 AMAPI SDK 中叫用 prepareEnvironment API,並傳遞正確的要求。

  3. 等待 PrepareEnvironment 結果:自訂 DPC 會等待 prepareEnvironment 完成。

  4. 確認 PrepareEnvironment 成功:完成後,EMM 會再次執行

    adb shell dumpsys package com.google.android.apps.work.clouddpc | grep versionName
    

    這次 Android 裝置政策版本應高於步驟 1 中的版本。

測試 Google 帳戶驗證

  1. 建立測試企業:EMM 會建立與測試 EMM 連結的測試網域 Google 企業,並使用 enterprises.generateSignupUrl
  2. 啟用 Google 驗證:EMM 會按照 Google 管理控制台中的這些操作說明,為測試企業啟用 Google 驗證。
  3. 建立註冊權杖:EMM 會使用 Play EMM API 建立註冊權杖,類型為 userDevice
  4. 啟動註冊程序:自訂 DPC 會在 AMAPI SDK 中叫用 startAccountSetup API,並傳遞註冊權杖。
  5. 必須啟動活動:AMAPI SDK 會通知自訂 DPC 必須啟動活動,才能驗證使用者。
  6. 驗證使用者:自訂 DPC 會叫用 launchAuthenticationActivity 來啟動活動。使用者透過受管理 Google 帳戶進行驗證 (這是步驟 1 中建立的企業帳戶)。
  7. 完成註冊:AMAPI SDK 會將註冊結果通知自訂 DPC。

測試略過 Google 驗證

我們會使用先前所述的設定。

這次使用者在步驟 7 中按下「略過」,而不是透過 Google 帳戶驗證。註冊程序順利完成,裝置上會有服務帳戶 (即 AuthenticationType 為匿名)。

測試沒有使用者的裝置

如果停用 Google 驗證,改良後的自訂 DPC 註冊流程會執行下列步驟:

  1. 建立測試企業:這可以是先前建立的同一家企業。
  2. 建立註冊權杖:EMM 使用 Play EMM API 建立註冊權杖,類型為 userlessDevice
  3. 啟動註冊程序:自訂 DPC 會在 AMAPI SDK 中叫用 startAccountSetup API,並傳遞註冊權杖。
  4. 完成註冊:AMAPI SDK 會將註冊結果通知自訂 DPC。