分发应用

Google Play EMM API 支持以下公开和专用应用分发方法:

  • 用户可以从 Google Play 企业版商店手动安装应用。
  • IT 管理员可以远程安装应用到用户设备上。

手动安装 Google Play 企业版商店中的应用

您可以在 Devicepolicy 中定义用户可以安装哪些应用,并通过调用 Devices.update 进行设置。在预配新设备时,您应先设置政策,然后再将受管 Google Play 账号添加到设备,否则在将账号添加到设备后,系统将不会在短时间内应用该政策。

受管 Play 商店行为由 policy.productAvailabilityPolicy 的值定义:

  • all:Play 商店中的所有公开应用均可用。
  • whitelist:仅 policy.productPolicy 中列出的应用可用。

在这两种情况下,policy.productPolicy 中的所有应用都会默认添加到企业的商店布局中。选择 whitelist 时,企业的商店布局是 Google Play 企业版商店的主页;选择 all 时,可以在“工作应用”标签页中访问该布局。您可以通过嵌入 Google Play 企业版 iframe,允许客户自定义企业的商店布局(请参阅使用 Google Play 企业版 iframe 整理应用)。

远程将应用安装到用户设备上

如需在用户设备上远程安装(也称为“推送安装”)应用,请在 Devicepolicy 中设置 policy.productPolicy.autoInstallPolicy。在预配新设备时,您应先设置政策,然后再将受管 Google Play 账号添加到设备,否则在将账号添加到设备后,系统将不会在短时间内应用该政策。

autoInstallMode 可以设置为:

  • doNotAutoInstall:应用未自动安装。
  • autoInstallOnce:系统会自动安装一次应用,如果用户卸载该应用,系统不会再次安装。
  • forceAutoInstall:系统会自动安装该应用,如果用户卸载该应用,系统会再次安装该应用。在受管理的设备上,DPC 应使用 DevicePolicyManager.setUninstallBlocked 阻止卸载。

如果安装失败(连接中断、存储空间不足等),系统会自动重试,直到安装成功。系统会应用指数退避重试策略,以避免在发生不可恢复的失败时浪费电池电量和数据流量。

安装优先级

您可以通过设置 autoInstallPriority 来选择安装顺序。优先级必须为无符号整数,默认值为 0。应用将按优先级顺序安装,也就是说,优先级值较低的应用会先安装。

安装限制

您可以通过设置 autoInstallConstraint 为每个应用设置安装约束条件,以便控制设备在安装期间的所需状态:

  • 设备是否应连接到 Wi-Fi 网络,
  • 设备是否应充电
  • 以及设备是否应处于空闲状态(用户未主动使用)。

如果未立即满足限制条件,受影响的安装将加入队列,直至满足限制条件。

autoInstallConstraint 中,系统会在字段之间应用“AND”规则。例如,使用以下 autoInstallConstraint 时,设备必须同时处于充电状态并连接到不按流量计费的网络(例如 Wi-Fi),才能安装应用:

"autoInstallConstraint": [
  "chargingStateConstraint" : "chargingRequired",
  "networkTypeConstraint" : "unmeteredNetwork"
]

在新配置的设备上自动安装应用

Google Play EMM API 会在设备首次配置时发送 NewDeviceEvent 通知。如需将应用自动推送安装到新配置的设备上,请监听 NewDeviceEvent 通知。从每个 NewDeviceEvent 检索 userIddeviceId,然后调用 Devices.update 为该设备设置政策。

如需了解如何订阅 EMM 通知,请参阅设置 EMM 通知

应用自动安装错误反馈

与应用安装相关的错误会通过应用反馈报告,DPC 可以监控通过 KeyedAppStatesService 发送的 EnterprisePolicyStatus 消息。

如需解码 Base64 编码数据,DPC 必须根据 EnterprisePolicyStatus 的 proto 定义生成类。如需了解如何生成 proto 类,请参阅 Protocol Buffers 文档。

借助生成的类,DPC 可以解码 EnterprisePolicyStatus 对象:

EnterprisePolicyStatus enterprisePolicyStatus = EnterprisePolicyStatus.parseFrom(
    BaseEncoding.base64().decode(base64EncodedString)
);

设备政策现在包含新的可选字段 PolicyId。创建或更新政策时,EMM 可以将 PolicyId 设置为任何字符串值,以便识别特定的设备政策版本。

如果可用,应用安装反馈将报告 PolicyId,以便 DPC 将收到的错误与特定政策进行匹配。

EnterprisePolicyStatus

message EnterprisePolicyStatus {
  // Individual status for an app in the policy
  repeated ApplicationStatus app_status = 1;

  // Version of the policy for which this status applies.
  PolicyVersion version = 2;
}

ApplicationStatus

// Individual status for an app.
message ApplicationStatus {
  // The package name for the app.
  string package_name = 1;

  // The install status for the app. Only includes status for apps scheduled
  // to be auto-installed via the policy resource.
  AutoInstallStatus install_status = 2;
}

AutoInstallStatus

// Auto-install status for an app.
message AutoInstallStatus {
  // The error causing the install to fail if state is INSTALL_ERROR.
  EnterpriseAutoInstallError error = 1;

  // The current install state of the app.
  EnterpriseAutoInstallState state = 2;
}

PolicyVersion

// The version of the policy which these install states apply to.
message PolicyVersion {
  // A policy id which may be optionally set by the EMM.
  string policy_id = 1;
}

EnterpriseAutoInstallError

// Install errors resulting in failure to install an app.
enum EnterpriseAutoInstallError {
  // Catch-all for unrecognized enum values.
  ENTERPRISE_AUTO_INSTALL_ERROR_UNKNOWN = 0;

  // The app could not be found.
  ENTERPRISE_AUTO_INSTALL_ERROR_NOT_FOUND = 1;

  // The app is not available in the user's country.
  ENTERPRISE_AUTO_INSTALL_ERROR_UNAVAILABLE_COUNTRY = 2;

  // The app is not compatible with the device hardware.
  ENTERPRISE_AUTO_INSTALL_ERROR_NOT_COMPATIBLE_WITH_DEVICE = 3;

  // No license remained to grant ownership of the app, and the user did not
  // already own the app.
  ENTERPRISE_AUTO_INSTALL_ERROR_NO_LICENSES_REMAINING = 4;

  // Required permissions for the app have not been accepted.
  ENTERPRISE_AUTO_INSTALL_ERROR_MISSING_PERMISSION = 5;

  // The app is not available based on the enterprise availability policy.
  ENTERPRISE_AUTO_INSTALL_ERROR_NOT_APPROVED_OR_UNAVAILABLE = 6;

  // The app is not available to the user or device.
  ENTERPRISE_AUTO_INSTALL_ERROR_APP_UNAVAILABLE = 7;

  // Failed to grant license because the user already has ownership.
  ENTERPRISE_AUTO_INSTALL_ERROR_INCOMPATIBLE_OWNERSHIP = 8;

  // The admin has not accepted the terms of service.
  ENTERPRISE_AUTO_INSTALL_ERROR_TOS_NOT_ACCEPTED = 9;

  // The device does not have enough RAM.
  ENTERPRISE_AUTO_INSTALL_ERROR_INSUFFICIENT_RAM = 10;

  // The app is incompatible with the device carrier.
  ENTERPRISE_AUTO_INSTALL_ERROR_NOT_COMPATIBLE_WITH_DEVICE_CARRIER = 11;

  // The app is incompatible with the country or carrier.
  ENTERPRISE_AUTO_INSTALL_ERROR_NOT_COMPATIBLE_WITH_DEVICE_COUNTRY_OR_CARRIER = 12;

  // The app is incompatible with the safe search level.
  ENTERPRISE_AUTO_INSTALL_ERROR_NOT_COMPATIBLE_WITH_DEVICE_SAFE_SEARCH_LEVEL = 13;

  // The app could not be installed due to an installer error.
  ENTERPRISE_AUTO_INSTALL_ERROR_INSTALL_FAILED = 14;

  // The app could not be installed due to network errors.
  ENTERPRISE_AUTO_INSTALL_ERROR_NETWORK_FAILED = 15;

  // The device does not have enough storage.
  ENTERPRISE_AUTO_INSTALL_ERROR_INSUFFICIENT_STORAGE = 16;
}

EnterpriseAutoInstallState

// The current install state for an app.
enum EnterpriseAutoInstallState {
  // Catch-all for unrecognized enum values.
  INSTALL_STATE_UNKNOWN = 0;

  // The app has been received by Play but an install attempt has not completed
  // yet.
  INSTALL_STATE_PENDING = 1;

  // The latest install attempt failed and will be retried automatically.
  INSTALL_STATE_ERROR = 2;

  // The app has been installed.
  INSTALL_STATE_INSTALLED = 3;
}

分发应用以进行封闭式测试

借助封闭式测试,应用开发者可以从受信任的用户那里获得有关应用早期版本的反馈。开发者可以在 Google Play 管理中心内设置封闭式测试。您可以使用 Play EMM API 让 IT 管理员向特定用户分发应用的封闭式版本(也称为轨道)。您的企业客户不仅可以使用此功能测试第三方应用,还可以测试内部开发的专有应用。

符合条件的应用

在开发者将企业添加到应用的封闭式测试人员名单之前,应用应符合以下条件:

  • 应用的正式版已发布到 Google Play。
  • 在 Google Play 管理中心内,在应用的高级设置页面中启用受管理的 Google Play
  • 应用的所有封闭版本均符合版本代码要求

向封闭式测试添加企业

应用开发者可以将企业添加到使用封闭式 Alpha 版测试使用 Google 群组执行 Alpha 版测试方法的测试中。如需了解相关说明,请参阅有关如何设置开放式测试、封闭式测试或内部测试的指南。开发者需要输入每个参与计划的企业的组织 ID(也称为企业 ID)。IT 管理员可以按照以下步骤向第三方应用开发者提供其组织的 ID:

  1. 登录 Google Play 企业版商店
  2. 点击管理员设置
  3. 复制“组织信息”框中的组织 ID 字符串,并将其发送给开发者。

面向不公开应用的附加要求

对于专用应用,开发者还需要在应用“高级设置”页面的 Google Play 企业版标签页中添加每个参与计划的企业的组织 ID。如需了解相关说明,请参阅发布专用应用

向用户分发封闭轨道

如需检索企业可用于指定应用的轨道列表,请调用 Products.get。响应中包含的 appTracks[] 列表包含适用于每个应用的轨道。appTracks[].trackAlias 是轨道的用户可读名称,您可以在 EMM 控制台中显示该名称;appTracks[].trackId 是轨道的计算机可读 ID。

如需向用户授予对应用的封闭轨道的可见性,请在 Devicepolicy 中设置 policy.productPolicy[].trackIds[]。如果设备有多个轨道可用,系统会安装版本代码最高的可用版本。

在某些情况下(例如以下情况),系统会自动从 Products.get 调用中移除 trackId:

  • 轨道的应用版本已提升到其他轨道或正式版。
  • 正式版的版本号高于轨道的版本号。
  • 开发者停止轨道。

跟踪付费应用许可

对于付费应用,Grouplicenses 对象会跟踪企业拥有的许可数量以及正在使用的许可数量。您可以调用 Grouplicenses.get 来获取应用的许可详情。

在设备上安装付费应用之前,企业需要拥有该应用的许可。如果有许可,系统会在设备上安装该应用并创建 Entitlements 对象。Entitlements 对象可将许可与用户相关联,并递减应用的可用许可数量。如果没有可用的许可,则应用安装会失败,并且系统不会创建 Entitlements 对象。

免费分发的应用不会使用 GrouplicensesEntitlements 对象。