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 提供了与设备上的 Android 设备政策进行交互所需的 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 建议按需创建令牌,并使用新 API 替换现有 API 以管理 Google Play 企业版账号,从而尽可能减少更改。
改进后的自定义 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 会调用 AMAPI SDK 中的
launchAuthenticationActivityAPI,并传递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 服务器应针对特定用户 ID 和设备 ID 调用
Devices.setState(),并将accountState设置为"enabled",以尝试恢复服务访问权限。 - 如果不合规:解决问题并使设备合规后,EMM 应调用
Devices.setState()。
- 如果合规:DPC 应通知 EMM 服务器。然后,EMM 服务器应针对特定用户 ID 和设备 ID 调用
此机制可确保在设备无法访问 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。