客户 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()
使用 patch 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
参数。如果 nextPageToken
为 null
,则说明您的应用已请求
最后一页。
以下示例方法展示了您的应用可能如何输出设备列表, 每次加载网页:
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、 .NET 和 Python。您可以使用 Colab 查看 API 调用的示例,并尝试自行调用 API。