導入使用者帳戶

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 管理版帳戶,並新增至裝置做為備案。

這個新註冊流程的重點是管理裝置對 Google 服務的存取權。根據預設,裝置會處於受限狀態,而 EMM 則會在裝置符合規定後,扮演啟用存取權的重要角色。

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 取代現有的 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 註冊流程包含下列步驟:

重要初始裝置狀態:使用自訂 DPC 註冊裝置時,新增至裝置的 Google 帳戶會處於停用狀態。也就是說,您一開始無法存取 Google 服務,包括 Google Play。

如果符合下列條件,裝置預設會處於「已停用」狀態,且 EMM 必須將裝置標示為符合規定 (例如呼叫 Devices.SetState):

  1. 該機構已向 Google 驗證網域擁有權。
  2. IT 管理員已在 Google 管理控制台中,為使用者的特定機構單位明確啟用第三方 Android 行動管理服務。
  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 服務:自訂 DPC 完全佈建裝置並確認裝置符合所有企業政策後,EMM 伺服器必須呼叫 Devices.setState(),並將 accountState 參數設為 "enabled"

    • 為何這項呼叫至關重要:這項 API 呼叫會將裝置標示為符合規定。
    • 未撥打電話的後果:如果沒有撥打這通 Devices.setState(setStateRequest) 電話,帳戶會維持「已停用」狀態。使用者將無法存取 Google Play (安裝或更新應用程式),以及其他需要帳戶驗證的 Google 服務。

管理裝置狀態和服務存取權

完成初始註冊後,EMM 會根據裝置的合規狀態,負責維護裝置的 Google 服務存取權。

處理服務中斷:BAD_DEVICE_MANAGEMENT

如果裝置無法存取 Google 服務,Google Play 服務 (GMSCore) 會以 com.google.android.gms.auth.BAD_DEVICE_MANAGEMENT 動作廣播 Intent。問題的原因如下:

  • EMM 從未在初始裝置註冊後呼叫 Devices.setState("enabled")。
  • 裝置不再符合 EMM 政策,且 EMM 尚未重新啟用裝置。
  • EMM 透過呼叫 Devices.setState(),並將 accountState 設為「disabled」,明確將裝置狀態設為「已停用」。這可能是因為安全疑慮、管理員採取行動或其他原因。

這個 Intent 包含狀態碼,例如 "ThirdPartyDeviceManagementRequired"

自訂 DPC「必須」實作 BroadcastReceiver,才能監聽這個 BAD_DEVICE_MANAGEMENT 意圖。

收到這項廣播後,DPC 應:

  1. 重新評估合規性:檢查裝置目前是否符合 EMM 設定的所有政策。
  2. 採取行動:
    • 如果符合規定:DPC 應通知 EMM 伺服器。接著,EMM 伺服器應針對特定使用者 ID 和裝置 ID,呼叫 Devices.setState() 並將 accountState 設為 "enabled",嘗試還原服務存取權。
    • 如果不符合規定:解決問題並確保裝置符合規定後,EMM 應撥打 Devices.setState()

這項機制可確保裝置失去 Google 服務存取權時,系統能偵測到並從這種情況中復原。

企業接管注意事項

機構的帳戶類型可能會變更 (例如從 ManagedGoogleDomainType.TYPE_TEAM 變更為 ManagedGoogleDomainType.TYPE_DOMAIN)。雖然這個程序通常不會中斷 EMM 繫結,但有時可能會導致裝置無法存取 Google 服務。

EMM 應注意,如果使用者在已知接管事件後回報服務存取問題,即使裝置符合 EMM 政策,可能仍需要呼叫 Devices.setState(),才能在新客戶架構下,將裝置狀態與 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.
    
                    // IMPORTANT: The device/account is now added but *DISABLED*
                    // for Google services. Your EMM backend MUST be notified to
                    // perform policy compliance checks and then call Devices.setState()
                    // to activate Google Play and other services.
    
                }
                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 Device Policy,預期會輸出空白內容。

  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。