Android 企业版注册有两种主要的用户身份类型:Google Play 企业版账号和受管理的 Google 账号。Google Play 企业版账号以设备为中心,这意味着它们与特定用户的 Google 身份无关。相比之下,受管理的 Google 账号与用户的企业 Google 身份相关联,这有助于用户在设备上保持登录状态,从而改善用户体验。
Google Play 企业版账号曾经是标准账号。不过,Google 现在鼓励所有新开发项目都使用改进后的注册流程,该流程默认创建受管理的 Google 账号。
虽然本文档末尾提供了有关旧版实现的指南,以供参考,但所有新开发项目都应遵循此处详细介绍的新注册流程。
概览
改进后的设备注册流程利用多个新组件,并更改了自定义设备政策控制器 (DPC) 的实现方式,从而简化了设备设置。这种新方法要求自定义 DPC 解决方案与 Android Management API (AMAPI) SDK 和 Android Device Policy 集成,以执行设备准备和用户注册功能。
AMAPI SDK 提供了与设备上的 Android Device Policy 进行交互所需的 API。在服务器端,企业移动管理 (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并调用prepareEnvironment或prepareEnvironmentAsyncval 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 建议在后台尽早启动此流程,并在用户等待时显示适当的界面。操作完成后,设备即可供 DPC 使用 AccountSetup API。
注册流程
EMM 必须停止对所有设备使用 users.generateAuthenticationToken() 和 users.insert()。相反,EMM 必须调用设备上的
API
来执行最终用户身份验证。新 API 会将 userId 和 email 返回给 DPC。如果
Google 无法对用户进行身份验证,系统会创建一个 Google Play 企业版账号并将其添加到设备。在这种情况下,Google 会返回该账号的
userId 。
Google 现在引入了注册令牌的使用,这些令牌必须传递给身份验证 API。EMM 确定何时以及如何创建令牌,并且该令牌可以是现有注册载荷(例如二维码或零接触配置)的一部分。
现有注册令牌的豁免
部分客户使用有效期较长的注册令牌来执行重复注册。为了确保这些现有工作流不会中断,在首次启用“使用 Google 进行身份验证”要求之前创建的所有令牌均不受新登录提示的限制。 这些旧令牌将继续像以前一样工作,允许用户注册设备,而无需经过 Google 身份验证流程。 不过,在首次启用 Google 身份验证要求之后创建的所有令牌都将遵循新的身份验证规则。这意味着,使用这些较新令牌的设备将要求用户根据 IT 管理员选择的设置进行身份验证。
Google 建议按需创建令牌,并将现有 Google Play 企业版账号 API 替换为新 API,以最大限度地减少更改。
改进后的自定义 DPC 注册流程涉及以下步骤:
重要的初始设备状态 :使用自定义 DPC 注册设备时,添加到设备的 Google 账号最初处于停用 状态。这意味着,对 Google 服务(包括 Google Play)的访问权限最初受到限制。
此默认“停用”状态以及后续要求 EMM 将设备标记为合规(例如,通过调用 Devices.SetState)专门适用于以下情况:
- 组织已向 Google 验证其网域的所有权。
- IT 管理员已在 Google 管理控制台中为用户的特定组织部门 (OU) 明确启用了第三方 Android 移动设备管理。
- 创建注册令牌 :EMM 使用 Play EMM API 创建注册令牌。
- 准备环境:自定义 DPC 使用准备环境流程 来验证设备是否已准备好进行注册。
- 启动注册 :自定义 DPC 调用 AMAPI SDK 中的
startAccountSetupAPI,并传递注册令牌。 注意:在调用此 API 之前,DPC 必须是设备所有者或资料所有者。 - 启动 Google 身份验证 activity: 如果需要,自定义 DPC
会调用
launchAuthenticationActivityAMAPI SDK 中的 API,并传递AccountSetupAttempt。这会启动 Google 身份验证 activity,并在身份验证成功后将用户返回到自定义 DPC。用户也可以跳过此流程。在这种情况下,系统会将 Google Play 企业版账号添加到设备。可以使用googleAuthenticationOptions配置此选项。 - 完成注册 :AMAPI SDK 会将注册结果通知自定义 DPC。
- 启用 Google 服务:自定义 DPC 完全配置
设备并确认其符合所有企业政策后,EMM
服务器必须 调用
Devices.setState(),并将accountState参数设置为"enabled"。
- 重要性 :此 API 调用会将设备标记为合规。
- 不调用的后果 :如果没有此
Devices.setState(setStateRequest)调用,账号将保持“停用”状态。用户将无法访问 Google Play(安装或更新应用)以及其他需要账号身份验证的 Google 服务。
管理设备状态和服务访问权限
初始注册后,EMM 负责根据设备的合规状态维护设备对 Google 服务的访问权限。
处理服务中断:BAD_DEVICE_MANAGEMENT
如果设备对 Google 服务的访问权限被阻止,Google Play 服务 (GMSCore) 将广播一个 Intent,其操作为:com.google.android.gms.auth.BAD_DEVICE_MANAGEMENT。发生这种情况的原因有多种:
- EMM 在初始设备注册后从未调用 Devices.setState("enabled")。
- 设备不再符合 EMM 政策,并且 EMM 尚未重新启用该设备。
- EMM 通过调用 Devices.setState() 并将 accountState 设置为“disabled”,明确将设备状态设置为“disabled”。这可能是出于安全考虑、管理操作或其他原因。
此 Intent 包含一个状态代码,例如 "ThirdPartyDeviceManagementRequired"。
自定义 DPC 必须实现 BroadcastReceiver 以监听此 BAD_DEVICE_MANAGEMENT Intent。
收到此广播后,DPC 应执行以下操作:
- 重新评估合规性 :检查设备是否符合 EMM 设置的所有政策。
- 采取行动:
- 如果合规 :DPC 应通知 EMM 服务器。然后,EMM 服务器
应调用
Devices.setState(),并将特定用户 ID 和 设备 ID 的accountState设置为"enabled",以尝试恢复服务访问权限。 - 如果不合规 :解决问题并确保设备合规后,EMM 应调用
Devices.setState()。
- 如果合规 :DPC 应通知 EMM 服务器。然后,EMM 服务器
应调用
此机制可确保在设备失去对 Google 服务的访问权限时,能够检测到这种情况并从中恢复。
企业接管注意事项
组织的账号类型可能会发生变化(例如,从 ManagedGoogleDomainType.TYPE_TEAM 更改为
ManagedGoogleDomainType.TYPE_DOMAIN)。虽然此过程通常不会破坏 EMM 绑定,但有时可能会中断设备上的
Google 服务访问权限。
EMM 应注意,如果用户在已知接管事件后报告服务访问权限问题,即使设备看起来符合 EMM 政策,也可能需要调用
Devices.setState(),以便在新客户结构下将设备的状态与 Google 的后端重新同步。通常不需要在接管后主动调用所有设备,但它是解决访问权限问题的关键工具。
账号设置 - 示例代码
如需启动账号设置尝试,调用应用可以使用
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 }实现
AccountSetupListener接口,并提供有关如何处理收到的 状态更新的实现。扩展
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. } } } }将扩展的
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
获取设备 的当前状态:EMM 运行
adb shell dumpsys package com.google.android.apps.work.clouddpc | grep versionName以获取设备上存在的 Android Device Policy 版本。如果未安装 Android Device Policy,则预期输出为空。
集成 PrepareEnvironment:自定义 DPC 调用 AMAPI SDK 中的
prepareEnvironmentAPI,并传递正确的请求。等待 PrepareEnvironment 结果 :自定义 DPC 等待
prepareEnvironment完成。确认 PrepareEnvironment 成功 :完成后,EMM 再次运行
adb shell dumpsys package com.google.android.apps.work.clouddpc | grep versionName这次,Android Device Policy 版本应高于第 1 步中的版本。
测试 Google 账号身份验证
- 创建测试企业:EMM 创建与测试 EMM 关联的测试网域 Google 企业
,并使用
enterprises.generateSignupUrl。 - 启用 Google 身份验证:EMM 按照 Google 管理控制台中的这些说明为 测试企业 启用 Google 身份验证。
- 创建注册令牌 :EMM 使用 Play EMM API 创建类型为 userDevice 的注册令牌。
- 启动注册 :自定义 DPC 调用 AMAPI SDK 中的
startAccountSetupAPI,并传递注册令牌。 - 启动所需 activity :AMAPI SDK 通知自定义 DPC 必须启动 activity 才能对用户进行身份验证。
- 对用户进行身份验证:自定义 DPC 调用
launchAuthenticationActivity以启动 activity。用户使用受管理的 Google 账号(在第 1 步中创建的企业的一部分)进行身份验证。 - 完成注册 :AMAPI SDK 会将注册结果通知自定义 DPC。
测试跳过 Google 身份验证
我们将使用前面介绍的设置。
这次,在第 7 步中,用户按“跳过”而不是使用其 Google 账号进行身份验证。 注册成功完成,设备上有一个服务
账号(即
AuthenticationType
为“匿名”)。
测试无用户设备
改进后的自定义 DPC 注册流程在停用 Google 身份验证时使用以下步骤:
- 创建测试企业 :这可以是之前创建的同一企业。
- 创建注册令牌 :EMM 使用 Play EMM API 创建类型为 userlessDevice 的注册令牌。
- 启动注册 :自定义 DPC 调用 AMAPI SDK 中的
startAccountSetupAPI,并传递注册令牌。 - 完成注册 :AMAPI SDK 会将注册结果通知自定义 DPC。