使用方法

客户 API 支持以编程方式控制设备和 Android 零触摸注册的配置。本文档介绍了 面向企业移动管理 (EMM) 提供商和企业 IT 的 API 开发者。阅读本文档后,您应该已经了解了 API 中使用的资源及其交互方式。如果您刚开始接触零触摸服务 注册时,请阅读简短的 android.com 简介

概览

客户 API 可帮助购买 Android 零触摸注册的组织 设备。您的应用或工具可帮助 IT 管理员执行以下操作:

  • 创建、修改和删除配置设置。
  • 对设备应用或移除配置。
  • 为添加到零触摸注册的所有设备选择默认配置 。

通过该 API,IT 管理员还可以为设备取消注册零触摸注册 注册。要管理其组织的用户或接受《服务条款》, IT 管理员使用零触摸注册门户

此 API 的典型用户可能是:

  • EMM 提供商向其控制台添加了对零触摸注册的支持。
  • 企业 IT 开发者打造自动化零触摸注册工具 任务。

核心资源

配置和设备是您在该 API 中使用的核心资源。一个 组织也可以使用零触摸功能创建配置和设备 注册门户。

设备和客户资源之间的关系

配置
IT 管理员使用某一配置为设备设置配置选项。 配置包括 EMM 移动设备政策和联系信息,这些信息会向 为用户提供帮助。配置是 API 的核心,因此可用于许多场景 方法。如需了解详情,请参阅下文的配置
设备
单位购买且支持零触摸注册的 Android 设备 联系。应用配置以将设备纳入零触摸模式 注册。设备具有硬件 ID 和附加的元数据。如需了解详情,请参阅 设备如下。
设备政策控制器 (DPC)
对 EMM 的 DPC(设备政策)的只读引用 控制器)。添加设备政策控制器 (DPC) 配置,以便为设备选择 EMM 解决方案。列出的所有设备政策控制器 (DPC) 支持零触摸注册,并已在 Google Play 中提供。接收者 如需了解详情,请参阅 Dpc

如需列出您的应用可以使用的所有 API 方法和资源,请参阅 API 参考文档

配置

Configuration API 资源结合了 以下:

  • 设备上安装的 EMM 的 DPC。
  • 在设备上强制执行 EMM 政策。
  • 设备上显示的联系信息,用于在设置过程中帮助用户。

借助该 API,您的应用可以为 IT 管理员管理配置。调用 API 以 提取、创建、更新和删除配置。以下示例展示了如何 创建新配置:

Java

// Add metadata to help the device user during provisioning.
Configuration configuration = new Configuration();
configuration.setConfigurationName("Sales team");
configuration.setCompanyName("XYZ Corp.");
configuration.setContactEmail("it-support@example.com");
configuration.setContactPhone("+1 (800) 555-0112");
configuration.setCustomMessage("We're setting up your phone. Call or email for help.");

// Set the DPC that zero-touch enrollment downloads and installs from Google Play.
configuration.setDpcResourcePath(dpc.getName());

// Set the JSON-formatted EMM provisioning extras that are passed to the DPC.
configuration.setDpcExtras("{"
      + "\"android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED\":true,"
      + "\"android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE\":{"
      + "\"default_min_password_length\":6,"
      + "\"company_name\":\"XYZ Corp\","
      + "\"management_server\":\"emm.example.com\","
      + "\"terms_url\":\"https://www.example.com/policies/terms/\","
      + "\"allowed_user_domains\":\"[\\\"example.com\\\", \\\"example.org\\\"]\""
      + "}"
      + "}");

// Create the new configuration on the server.
AndroidProvisioningPartner.Customers.Configurations.Create request =
      service.customers().configurations().create(customerAccount, configuration);
Configuration response = request.execute();

.NET

// Add metadata to help the device user during provisioning.
Configuration configuration = new Configuration
{
    ConfigurationName = "Sales team",
    CompanyName = "XYZ Corp.",
    ContactEmail = "it-support@example.com",
    ContactPhone = "+1 (800) 555-0112",
    CustomMessage = "We're setting up your phone. Call or email for help."
};

// Set the DPC that zero-touch enrollment downloads and installs from Google Play.
configuration.DpcResourcePath = dpc.Name;

// Set the JSON-formatted EMM provisioning extras that are passed to the DPC.
configuration.DpcExtras = @"{
    ""android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED"":true,
    ""android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE"":{
    ""default_min_password_length"":6,
    ""company_name"":""XYZ Corp"",
    ""management_server"":""emm.example.com"",
    ""terms_url"":""https://www.example.com/policies/terms/"",
    ""allowed_user_domains"":""[\""example.com\"", \""example.org\""]""
  }
}";

// Create the new configuration on the server.
var request = service.Customers.Configurations.Create(configuration, customerAccount);
var response = request.Execute();

Python

# Add metadata to help the device user during provisioning.
configuration = {
    'configurationName': 'Sales team',
    'companyName': 'XYZ Corp.',
    'contactEmail': 'it-support@example.com',
    'contactPhone': '+1 (800) 555-0112',
    'customMessage': 'We\'re setting up your phone. Call or email for help.'}

# Set the DPC that zero-touch enrollment installs from Google Play.
configuration['dpcResourcePath'] = dpc['name']

# Set the JSON-formatted EMM provisioning extras that are passed to the DPC.
configuration['dpcExtras'] = '''{
    "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED":true,
    "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE":{
      "default_min_password_length":6,
      "company_name":"XYZ Corp",
      "management_server":"emm.example.com",
      "terms_url":"https://www.example.com/policies/terms/",
      "allowed_user_domains":"[\\"example.com\\", \\"example.org\\"]"}
}'''

# Create the new configuration on the server.
response = service.customers().configurations().create(
    parent=customer_account, body=configuration).execute()

使用补丁 API 更新配置时,请务必包含 字段掩码或 值设为 null。请参阅默认 配置(见下文)中的示例,了解如何 高效地更新配置。

删除配置

如果配置仍应用于设备,您将无法删除该配置。如果您尝试 删除使用中的配置时,API 方法会返回 HTTP 400 Bad Request 以及说明有多少设备使用此配置的消息。 致电 customers.devices.removeConfiguration 从设备中移除该配置,然后重试。

默认配置

当组织设置了默认设置时,零触摸注册效果最佳 此配置会应用到该组织购买的所有新设备。 请考虑提示 IT 管理员设置默认配置(如果尚未设置默认配置)。 以下示例展示了如何将现有配置设为默认配置, 将 isDefault 设置为 true

Java

// Send minimal data with the request. Just the 2 required fields.
// targetConfiguration is an existing configuration that we want to make the default.
Configuration configuration = new Configuration();
configuration.setIsDefault(true);
configuration.setConfigurationId(targetConfiguration.getConfigurationId());

// Call the API, including the FieldMask to avoid setting other fields to null.
AndroidProvisioningPartner.Customers.Configurations.Patch request = service
      .customers()
      .configurations()
      .patch(targetConfiguration.getName(), configuration);
request.setUpdateMask("isDefault");
Configuration results = request.execute();

.NET

// Send minimal data with the request. Just the 2 required fields.
// targetConfiguration is an existing configuration that we want to make the default.
Configuration configuration = new Configuration
{
    IsDefault = true,
    ConfigurationId = targetConfiguration.ConfigurationId,
};

// Call the API, including the FieldMask to avoid setting other fields to null.
var request = service.Customers.Configurations.Patch(configuration,
                                                     targetConfiguration.Name);
request.UpdateMask = "IsDefault";
Configuration results = request.Execute();

Python

# Send minimal data with the request. Just the 2 required fields.
# target_configuration is an existing configuration we'll make the default.
configuration = {
    'isDefault': True,
    'configurationId': target_configuration['configurationId']}

# Call the API, including the FieldMask to avoid setting other fields to null.
response = service.customers().configurations().patch(
    name=target_configuration['name'],
    body=configuration, updateMask='isDefault').execute()

只能有一个默认配置。创建新的默认配置 将先前配置的 isDefault 字段设置为 false。您可能需要 刷新任何缓存的 Configuration 实例, isDefault 字段。

引导设备用户

零触摸配置会在设备设置中显示自定义用户指南 为用户提供帮助的向导。您需要提供联系电话号码和电子邮件地址 以及管理设备的 配置。我们还建议您在 customMessage 字段,以详细说明用户的 设备。

因为用户将无法通过其设置的设备拨打电话或发送电子邮件 请设置电话号码和电子邮件地址的格式,以便于浏览 信息。

设备

转销商可在客户购买零触摸服务时创建设备 注册 - IT 管理员无法创建设备。要使用设备,请调用 Device API 资源。如果您需要搜索 对于设备,列出所有设备并在您的应用中本地过滤每一批设备。对于 有关示例,请参阅下面的分页结果

配置设备

对某个设备应用配置后,即可为该设备注册零触摸注册 注册。要应用配置,请调用 customers.devices.applyConfiguration。 应用配置后,设备会自动 首次启动或下次恢复出厂设置时。以下示例展示了如何将 配置为一组设备:

Java

List<Device> devices = getDevicesToConfigure(service);
Configuration configurationToApply = getConfigurationToApply(service);

// Loop through the collection and apply the configuration to each device. This might
// take some time if the collection contains many devices.
for (Device device : devices) {
    System.out.println(device.getDeviceIdentifier().getImei());

    // Wrap the device ID in a DeviceReference.
    DeviceReference deviceRef = new DeviceReference();
    deviceRef.setDeviceId(device.getDeviceId());

    // Build and send the request to the API.
    CustomerApplyConfigurationRequest body = new CustomerApplyConfigurationRequest();
    body.setConfiguration(configurationToApply.getName());
    body.setDevice(deviceRef);

    AndroidProvisioningPartner.Customers.Devices.ApplyConfiguration request = service
          .customers()
          .devices()
          .applyConfiguration(customerAccount, body);
    request.execute();
}

.NET

IList<Device> devices = GetDevicesToConfigure(service);
Configuration configurationToApply = GetConfigurationToApply(service);

// Loop through the collection and apply the configuration to each device. This might
// take some time if the collection contains many devices.
foreach (Device device in devices)
{
    Console.WriteLine(device.DeviceIdentifier.Imei);

    // Wrap the device ID in a DeviceReference.
    var deviceRef = new DeviceReference
    {
        DeviceId = device.DeviceId
    };

    // Build and send the request to the API.
    CustomerApplyConfigurationRequest body = new CustomerApplyConfigurationRequest
    {
        Configuration = configurationToApply.Name,
        Device = deviceRef
    };
    var request = service.Customers.Devices.ApplyConfiguration(body,
                                                               customerAccount);
    request.Execute();
}

Python

devices = get_devices_to_configure(service)
configuration = get_configuration_to_apply(service)

# Loop through the collection and apply the configuration to each device.
# This might take some time if the collection contains many devices.
for device in devices:
  print(device['deviceIdentifier']['imei'])

  # Wrap the device ID in a DeviceReference.
  device_ref = {'deviceId': device['deviceId']}

  # Build and send the request to the API.
  body = {'configuration': configuration['name'], 'device': device_ref}
  service.customers().devices().applyConfiguration(
      parent=customer_account, body=body).execute()

要从设备中移除配置,请调用 customers.devices.removeConfiguration。 此更改会在设备恢复出厂设置后生效。

取消声明设备所有权

IT 管理员可以取消对设备的所有权,将其从零触摸注册中移除。IT 管理员可能会取消声明要迁移到其他账号的设备、已售出 或将其退回给转销商调用 方法 按 customers.devices.unclaim 可取消声明对设备的所有权 组织权限。

以下示例展示了如何通过 IMEI 识别码取消声明设备所有权 制造商名称:

Java

// Wrap the hardware ID and manufacturer values in a DeviceIdentifier.
// Then wrap the DeviceIdentifier in a DeviceReference.
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setImei("123456789012347");
identifier.setManufacturer("Google");
DeviceReference reference = new DeviceReference();
reference.setDeviceIdentifier(identifier);

// Create the body of the request.
CustomerUnclaimDeviceRequest body = new CustomerUnclaimDeviceRequest();
body.setDevice(reference);

// Call the API method to unclaim the device from the organization.
service.customers().devices().unclaim(customerAccount, body).execute();

.NET

// Wrap the hardware ID and manufacturer values in a DeviceIdentifier.
// Then wrap the DeviceIdentifier in a DeviceReference.
DeviceIdentifier identifier = new DeviceIdentifier
{
    Imei = "123456789012347",
    Manufacturer = "Google"
};
DeviceReference reference = new DeviceReference();
reference.DeviceIdentifier = identifier;

// Create the body of the request.
CustomerUnclaimDeviceRequest body = new CustomerUnclaimDeviceRequest();
body.Device = reference;

// Call the API method to unclaim the device from the organization.
service.Customers.Devices.Unclaim(body, customerAccount).Execute();

Python

# Wrap the hardware ID and manufacturer values in a DeviceIdentifier.
# Then wrap the DeviceIdentifier in a DeviceReference.
identifier = {'imei': '123456789012347', 'manufacturer': 'Google'}
reference = {'deviceIdentifier': identifier}

# Create the body of the request.
body = {'device': reference}

# Call the API method to unclaim the device from the organization.
service.customers().devices().unclaim(
    parent=customer_account, body=body).execute()

设备元数据

IT 管理员可以查看转销商为设备附加的元数据。显示屏 设备元数据,以帮助 IT 管理员识别设备。

要详细了解您可能会看到的元数据,请参阅设备 元数据指南。

分页结果

customers.devices.list API 方法可能会返回 非常大的设备列表。为了减小响应大小,此 API 和其他 API 方法(例如 customers.list)支持分页结果。包含 分页结果,您的应用可以以迭代方式请求和处理大型列表 每次一页。

调用 API 方法后,检查响应是否包含 nextPageToken。如果 nextPageToken 不是 null,您的应用可以调用 方法。您需要设置 pageSize 参数。如果 nextPageTokennull,则说明您的应用已请求 最后一页。

以下示例方法展示了您的应用可能如何输出设备列表, 每次加载网页:

Java

private void printDevices(AndroidProvisioningPartner service, String customerAccount,
      String pageToken) throws IOException {

    // Call the API to get a page of Devices. Send a page token from the method argument.
    // If the page token is null, the API returns the first page.
    AndroidProvisioningPartner.Customers.Devices.List request =
          service.customers().devices().list(customerAccount);
    request.setPageSize(50L);
    request.setPageToken(pageToken);
    CustomerListDevicesResponse response = request.execute();

    // Print the devices included in this page of results.
    for (Device device : response.getDevices()) {
        System.out.format("Device: %s\n", device.getName());
    }
    System.out.println("---");

    // Check to see if another page of devices is available. If yes, fetch & print the devices.
    if (response.getNextPageToken() != null) {
        this.printDevices(service, customerAccount, response.getNextPageToken());
    }
}

.NET

private void PrintDevices(AndroidProvisioningPartnerService service, String customerAccount,
                          String pageToken)
{
    // Call the API to get a page of Devices. Send a page token from the method argument.
    // If the page token is null, the API returns the first page.
    var request = service.Customers.Devices.List(customerAccount);
    request.PageSize = 50;
    request.PageToken = pageToken;
    var response = request.Execute();

    // Print the devices included in this page of results.
    foreach (Device device in response.Devices)
    {
        Console.WriteLine("Device: {0}", device.Name);
    }
    Console.WriteLine("---");

    // Check to see if another page of devices is available. If yes, fetch and print the devices.
    if (response.NextPageToken != null)
    {
        this.PrintDevices(service, customerAccount, response.NextPageToken);
    }
}

Python

def print_devices(service, customer_account, page_token):
  """Demonstrates how to loop through paginated lists of devices."""

  # Call the API to get a page of Devices. Send a page token from the method
  # argument. If the page token is None, the API returns the first page.
  response = service.customers().devices().list(
      parent=customer_account, pageSize=50, pageToken=page_token).execute()

  # Print the devices included in this page of results.
  for device in response['devices']:
    print('Device: {0}'.format(device['name']))
  print('---')

  # Check to see if another page of devices is available. If yes,
  # fetch and print the devices.
  if 'nextPageToken' in response:
    print_devices(service, customer_account, response['nextPageToken'])

开始使用

接下来,请参阅授权,了解如何向 API 调用授权。如果您想 请查看有关 API 的快速入门指南 Java.NETPython。您可以使用 Colab 查看 API 调用的示例,并尝试自行调用 API。