Принцип работы

Введение

API автоматической регистрации помогает реселлерам устройств автоматизировать их интеграцию. Инструменты продаж вашей организации могут обеспечить автоматическую регистрацию, что повысит продуктивность ваших пользователей и ваших клиентов. Используйте API, чтобы помочь вашим пользователям:

  • Назначьте приобретенные устройства учетной записи клиента с автоматической регистрацией.
  • Создайте учетную запись для автоматической регистрации вашего клиента.
  • Прикрепите телефон вашей организации и закажите метаданные на устройства.
  • Создавайте отчеты об устройствах, назначенных вашим клиентам.

В этом документе представлен API и объяснены шаблоны. Если вы хотите самостоятельно изучить API, попробуйте краткое руководство по Java , .NET или Python .

Концепции API

Клиенты и устройства — это основные ресурсы, которые вы используете в API. Чтобы создать клиентов, вызовите create . Вы можете создавать устройства, используя методы API утверждений ( см. ниже ). Ваша организация также может создавать клиентов и устройства с помощью портала автоматической регистрации.

Взаимоотношения устройств и ресурсов клиента

Клиент
Компании, которым ваша организация продает устройства. У клиентов есть name и ID . Используйте клиента, когда хотите заявить права или найти его устройства. Дополнительную информацию см. в разделе Customer .
Устройство
Устройство Android или ChromeOS с возможностью автоматической регистрации, которое ваша организация продает клиенту. У устройств есть идентификаторы оборудования, метаданные и претензии клиентов. Устройства занимают центральное место в API, поэтому вы используете их практически во всех методах. Дополнительную информацию см. в разделе Device .
Идентификатор устройства
Инкапсулирует идентификаторы оборудования, такие как IMEI или MEID, для идентификации произведенного устройства. Используйте DeviceIdentifier для определения устройства, которое вы хотите найти, обновить или заявить права. Чтобы узнать больше, прочитайте Идентификаторы .
Метаданные устройства
Хранит пары ключ-значение метаданных для устройства. Используйте DeviceMetadata для хранения метаданных вашей организации. Чтобы узнать больше, прочтите Метаданные устройства .

Чтобы перечислить все методы и ресурсы API, которые может использовать ваше приложение, см. Справочник по API .

Создание клиентов

На устройствах Android реселлер несет ответственность за создание учетной записи клиента от имени своего клиента. Клиент будет использовать эту учетную запись для доступа к автоматизированному порталу и настройки параметров подготовки для своих устройств. Это не обязательно для устройств ChromeOS, у которых уже есть учетная запись Google Workspace, которую они будут использовать для настройки параметров подготовки.

Вы можете вызвать метод API create , чтобы создать учетные записи клиентов для автоматической регистрации. Поскольку ваши клиенты видят название компании на портале автоматической регистрации, пользователь вашего приложения должен подтвердить его правильность. Вы не можете редактировать имя клиента после его создания.

Чтобы стать владельцем, вам необходимо указать хотя бы один корпоративный адрес электронной почты, связанный с аккаунтом Google. Вы не можете использовать личные учетные записи Gmail с API. Если клиенту нужна помощь с привязкой учетной записи, отправьте инструкции из раздела «Связывание учетной записи Google» .

После того, как вы создадите клиента, вызвав API, он управляет доступом к порталу своих сотрудников — вы не можете редактировать пользователей своих клиентов с помощью API. В приведенном ниже фрагменте показано, как можно создать клиента:

Джава

// Provide the customer data as a Company type.
// The API requires a name and owners.
Company customer = new Company();
customer.setCompanyName("XYZ Corp");
customer.setOwnerEmails(Arrays.asList("liz@example.com", "darcy@example.com"));
customer.setAdminEmails(Collections.singletonList("jane@example.com"));

// Use our reseller ID for the parent resource name.
String parentResource = String.format("partners/%d", PARTNER_ID);

// Call the API to create the customer using the values in the company object.
CreateCustomerRequest body = new CreateCustomerRequest();
body.setCustomer(customer);
Company response = service.partners().customers().create(parentResource, body).execute();

.СЕТЬ

// Provide the customer data as a Company type.
// The API requires a name and owners.
var customer = new Company
{
    CompanyName = "XYZ Corp",
    OwnerEmails = new String[] { "liz@example.com", "darcy@example.com" },
    AdminEmails = new String[] { "jane@example.com" }
};

// Use our reseller ID for the parent resource name.
var parentResource = String.Format("partners/{0}", PartnerId);

// Call the API to create the customer using the values in the company object.
var body = new CreateCustomerRequest
{
    Customer = customer
};
var request = service.Partners.Customers.Create(body, parentResource);
var response = request.Execute();

Питон

# Provide the customer data as a Company type. The API requires
# a name and at least one owner.
company = {'companyName':'XYZ Corp', \
  'ownerEmails':['liz@example.com', 'darcy@example.com'], \
  'adminEmails':['jane@example.com']}

# Use our reseller ID for the parent resource name.
parent_resource = 'partners/{0}'.format(PARTNER_ID)

# Call the API to create the customer using the values in the company object.
response = service.partners().customers().create(parent=parent_resource,
    body={'customer':company}).execute()

Чтобы узнать больше о ролях владельца и администратора для сотрудников вашего клиента, прочтите Пользователи портала .

Заявить права на устройства для клиентов

После того как ваши клиенты приобретут устройства, они захотят настроить параметры подготовки для этих устройств в своей учетной записи. Заявка на устройство добавляет устройство к автоматической регистрации и дает клиенту возможность настраивать параметры подготовки.

В записи подготовки устройства есть раздел для автоматической регистрации. Вы назначаете устройство, заявляя о разделе автоматической регистрации записи для клиента. Вызовите методы partners.devices.claim или partners.devices.claimAsync с клиентом в качестве аргумента. Всегда указывайте SECTION_TYPE_ZERO_TOUCH в качестве значения sectionType .

Прежде чем вы сможете заявить права на то же устройство для другого клиента, вам необходимо будет отменить претензии ( см. ниже ) на устройство клиента. Методы утверждения проверяют поля DeviceIdentifier , включая IMEI или MEID или серийный номер, имя производителя и модель, а также сертифицированный идентификатор устройства для устройств ChromeOS при создании нового устройства.

Во фрагменте ниже показано, как заявить права на устройство:

Джава

// Identify the device to claim.
DeviceIdentifier identifier = new DeviceIdentifier();
// The manufacturer value is optional but recommended for cellular devices
identifier.setManufacturer("Google");
identifier.setImei("098765432109875");

// Create the body to connect the customer with the device.
ClaimDeviceRequest body = new ClaimDeviceRequest();
body.setDeviceIdentifier(identifier);
body.setCustomerId(customerId);
body.setSectionType("SECTION_TYPE_ZERO_TOUCH");

// Claim the device.
ClaimDeviceResponse response = service.partners().devices().claim(PARTNER_ID, body).execute();

.СЕТЬ

// Identify the device to claim.
var deviceIdentifier = new DeviceIdentifier
{
    // The manufacturer value is optional but recommended for cellular devices
    Manufacturer = "Google",
    Imei = "098765432109875"
};

// Create the body to connect the customer with the device.
ClaimDeviceRequest body = new ClaimDeviceRequest
{
    DeviceIdentifier = deviceIdentifier,
    CustomerId = CustomerId,
    SectionType = "SECTION_TYPE_ZERO_TOUCH"
};

// Claim the device.
var response = service.Partners.Devices.Claim(body, PartnerId).Execute();

Питон

# Identify the device to claim.
# The manufacturer value is optional but recommended for cellular devices
device_identifier = {'manufacturer':'Google', 'imei':'098765432109875'}

# Create the body to connect the customer with the device.
request_body = {'deviceIdentifier':device_identifier, \
    'customerId':customer_id, \
    'sectionType':'SECTION_TYPE_ZERO_TOUCH'}

# Claim the device.
response = service.partners().devices().claim(partnerId=PARTNER_ID,
    body=request_body).execute()

Отмена претензий на устройства

Ваша организация может отменить требование устройства у клиента. Отказ от прав на устройство удаляет его из автоматической регистрации. Реселлер может отозвать права на устройство, которое он хочет перенести в другую учетную запись, вернуть или которое было заявлено по ошибке. Вызовите метод partners.devices.unclaim или partners.devices.unclaimAsync , чтобы отменить требование устройства у клиента.

Продавцы

Вы можете использовать поставщиков для представления партнеров-реселлеров в вашей дилерской сети, местных операторов в глобальной сети реселлеров или любой организации, которая продает устройства от вашего имени. Поставщики помогают вам разделить пользователей, клиентов и устройства:

  • Созданные вами поставщики не смогут видеть вашу учетную запись автоматической регистрации или учетные записи друг друга.
  • Вы можете просматривать клиентов и устройства ваших поставщиков, а также отменить регистрацию устройств поставщиков. Однако вы не можете назначать устройства клиентам ваших поставщиков.

Используйте портал для создания поставщиков для вашей организации — вы не можете использовать API. Для создания нового поставщика роль вашей учетной записи должна быть «Владелец» . Если в вашей организации есть поставщики, вы можете вызвать partners.vendors.list , чтобы получить список своих поставщиков, и partners.vendors.customers.list , чтобы получить список клиентов вашего поставщика. В следующем примере оба этих метода используются для печати отчета, показывающего состояние Условий обслуживания для клиентов поставщиков:

Джава

// First, get the organization's vendors.
String parentResource = String.format("partners/%d", PARTNER_ID);
ListVendorsResponse results = service.partners().vendors().list(parentResource).execute();
if (results.getVendors() == null) {
  return;
}

// For each vendor, report the company name and a maximum 5 customers.
for (Company vendor: results.getVendors()) {
  System.out.format("\n%s customers\n", vendor.getCompanyName());
  System.out.println("---");
  // Use the vendor's API resource name as the parent resource.
  AndroidProvisioningPartner.Partners.Vendors.Customers.List customerRequest =
      service.partners().vendors().customers().list(vendor.getName());
  customerRequest.setPageSize(5);
  ListVendorCustomersResponse customerResponse = customerRequest.execute();

  List<Company> customers = customerResponse.getCustomers();
  if (customers == null) {
    System.out.println("No customers");
    break;
  } else {
    for (Company customer: customers) {
      System.out.format("%s: %s\n",
          customer.getCompanyName(),
          customer.getTermsStatus());
    }
  }
}

.СЕТЬ

// First, get the organization's vendors.
var parentResource = String.Format("partners/{0}", PartnerId);
var results = service.Partners.Vendors.List(parentResource).Execute();
if (results.Vendors == null)
{
    return;
}

// For each vendor, report the company name and a maximum 5 customers.
foreach (Company vendor in results.Vendors)
{
    Console.WriteLine("\n{0} customers", vendor);
    Console.WriteLine("---");
    // Use the vendor's API resource name as the parent resource.
    PartnersResource.VendorsResource.CustomersResource.ListRequest customerRequest =
        service.Partners.Vendors.Customers.List(vendor.Name);
    customerRequest.PageSize = 5;
    var customerResponse = customerRequest.Execute();

    IList<Company> customers = customerResponse.Customers;
    if (customers == null)
    {
        Console.WriteLine("No customers");
        break;
    }
    else
    {
        foreach (Company customer in customers)
        {
            Console.WriteLine("{0}: {1}", customer.Name, customer.TermsStatus);
        }
    }
}

Питон

# First, get the organization's vendors.
parent_resource = 'partners/{0}'.format(PARTNER_ID)
vendor_response = service.partners().vendors().list(
    parent=parent_resource).execute()
if 'vendors' not in vendor_response:
  return

# For each vendor, report the company name and a maximum 5 customers.
for vendor in vendor_response['vendors']:
  print '\n{0} customers'.format(vendor['companyName'])
  print '---'
  # Use the vendor's API resource name as the parent resource.
  customer_response = service.partners().vendors().customers().list(
      parent=vendor['name'], pageSize=5).execute()
  if 'customers' not in customer_response:
    print 'No customers'
    break
  for customer in customer_response['customers']:
    print '  {0}: {1}'.format(customer['name'], customer['termsStatus'])

Если у вас есть коллекция устройств, вам может потребоваться узнать, какой торговый посредник или поставщик заявил права на это устройство. Чтобы получить числовой идентификатор реселлера, проверьте значение поля resellerId в записи утверждения устройства.

Ваша организация может отменить права на устройство, заявленное поставщиком. Для других вызовов API, которые изменяют устройства, вам следует убедиться, что ваша организация заявила права на устройство, прежде чем вызывать метод API. В следующем примере показано, как это можно сделать:

Джава

// Get the devices claimed for two customers: one of our organization's
// customers and one of our vendor's customers.
FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest();
body.setSectionType("SECTION_TYPE_ZERO_TOUCH");
body.setCustomerId(Arrays.asList(resellerCustomerId, vendorCustomerId));
body.setLimit(MAX_PAGE_SIZE);
FindDevicesByOwnerResponse response =
    service.partners().devices().findByOwner(PARTNER_ID, body).execute();
if (response.getDevices() == null) {
  return;
}

for (Device device: response.getDevices()) {
  // Confirm the device was claimed by our reseller and not a vendor before
  // updating metadata in another method.
  for (DeviceClaim claim: device.getClaims()) {
    if (claim.getResellerId() == PARTNER_ID) {
      updateDeviceMetadata(device.getDeviceId());
      break;
    }
  }
}

.СЕТЬ

// Get the devices claimed for two customers: one of our organization's
// customers and one of our vendor's customers.
FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest
{
    Limit = MaxPageSize,
    SectionType = "SECTION_TYPE_ZERO_TOUCH",
    CustomerId = new List<long?>
    {
        resellerCustomerId,
        vendorCustomerId
    }
};
var response = service.Partners.Devices.FindByOwner(body, PartnerId).Execute();
if (response.Devices == null)
{
    return;
}

foreach (Device device in response.Devices)
{
    // Confirm the device was claimed by our reseller and not a vendor before
    // updating metadata in another method.
    foreach (DeviceClaim claim in device.Claims)
    {
        if (claim.ResellerId == PartnerId)
        {
            UpdateDeviceMetadata(device.DeviceId);
            break;
        }
    }
}

Питон

# Get the devices claimed for two customers: one of our organization's
# customers and one of our vendor's customers.
request_body = {'limit':MAX_PAGE_SIZE, \
  'pageToken':None, \
  'customerId':[reseller_customer_id, vendor_customer_id], \
  'sectionType':'SECTION_TYPE_ZERO_TOUCH'}
response = service.partners().devices().findByOwner(partnerId=PARTNER_ID,
    body=request_body).execute()

for device in response['devices']:
  # Confirm the device was claimed by our reseller and not a vendor before
  # updating metadata in another method.
  for claim in device['claims']:
    if claim['resellerId'] == PARTNER_ID:
      update_device_metadata(device['deviceId'])
      break

Длительные пакетные операции

API включает асинхронные версии методов устройства . Эти методы позволяют пакетную обработку множества устройств, тогда как синхронные методы обрабатывают одно устройство для каждого запроса API. Имена асинхронных методов имеют суффикс Async , claimAsync .

Асинхронные методы API возвращают результат до завершения обработки. Асинхронные методы также помогают вашему приложению (или инструменту) оставаться отзывчивым для пользователей, пока они ждут завершения длительной операции. Ваше приложение должно периодически проверять статус операции.

Операции

Вы используете Operation для отслеживания длительной пакетной операции. Успешный вызов асинхронного метода возвращает ссылку на операцию в ответе. В приведенном ниже фрагменте JSON показан типичный ответ после вызова updateMetadataAsync :

{
  "name": "operations/apibatchoperation/1234567890123476789"
}

Каждая операция содержит список отдельных задач. Вызовите operations.get , чтобы узнать информацию о статусе и результатах задач, содержащихся в операции. В приведенном ниже фрагменте показано, как это можно сделать. В вашем собственном приложении вам придется обрабатывать любые ошибки.

Джава

// Build out the request body to apply the same order number to a customer's
// purchase of 2 devices.
UpdateMetadataArguments firstUpdate = new UpdateMetadataArguments();
firstUpdate.setDeviceMetadata(metadata);
firstUpdate.setDeviceId(firstTargetDeviceId);

UpdateMetadataArguments secondUpdate = new UpdateMetadataArguments();
secondUpdate.setDeviceMetadata(metadata);
secondUpdate.setDeviceId(firstTargetDeviceId);

// Start the device metadata update.
UpdateDeviceMetadataInBatchRequest body = new UpdateDeviceMetadataInBatchRequest();
body.setUpdates(Arrays.asList(firstUpdate, secondUpdate));
Operation response = service
    .partners()
    .devices()
    .updateMetadataAsync(PARTNER_ID, body)
    .execute();

// Assume the metadata update started, so get the Operation for the update.
Operation operation = service.operations().get(response.getName()).execute();

.СЕТЬ

// Build out the request body to apply the same order number to a customer's
// purchase of 2 devices.
var updates = new List<UpdateMetadataArguments>
{
    new UpdateMetadataArguments
    {
        DeviceMetadata = metadata,
        DeviceId = firstTargetDeviceId
    },
    new UpdateMetadataArguments
    {
        DeviceMetadata = metadata,
        DeviceId = secondTargetDeviceId
    }
};

// Start the device metadata update.
UpdateDeviceMetadataInBatchRequest body = new UpdateDeviceMetadataInBatchRequest
{
    Updates = updates
};
var response = service.Partners.Devices.UpdateMetadataAsync(body, PartnerId).Execute();

// Assume the metadata update started, so get the Operation for the update.
Operation operation = service.Operations.Get(response.Name).Execute();

Питон

# Build out the request body to apply the same order number to a customer's
# purchase of 2 devices.
updates = [{'deviceMetadata':metadata,'deviceId':first_target_device_id},
    {'deviceMetadata':metadata,'deviceId':second_target_device_id}]

# Start the device metadata update.
response = service.partners().devices().updateMetadataAsync(
    partnerId=PARTNER_ID, body={'updates':updates}).execute()

# Assume the metadata update started, so get the Operation for the update.
operation = service.operations().get(name=response['name']).execute()

Чтобы узнать, завершилась ли операция, проверьте операцию на наличие поля done со значением true . Если done отсутствует или false , операция все еще выполняется.

Ответы

После завершения операции API обновляет ее результат, даже если все отдельные задачи или ни одна из них не были выполнены успешно. Поле response представляет собой объект DevicesLongRunningOperationResponse , подробно описывающий обработку каждого устройства в операции.

Проверьте поле successCount , чтобы эффективно определить, не удалось ли выполнить какие-либо задачи, и избежать повторения больших списков результатов. Поле perDeviceStatus в DevicesLongRunningOperationResponse представляет собой список экземпляров OperationPerDevice с подробным описанием каждого устройства, участвующего в операции. Порядок списка соответствует задачам в исходном запросе.

Каждая задача OperationPerDevice содержит поле result и сводку напоминания о запросе, полученном сервером. Проверьте, удалось ли выполнить задачу, используя поле result .

В приведенном ниже фрагменте JSON показана часть типичного ответа операции после вызова updateMetadataAsync :

"response": {
  "perDeviceStatus": [
    {
      "result": {
        "deviceId": "12345678901234567",
        "status": "SINGLE_DEVICE_STATUS_SUCCESS"
      },
      "updateMetadata": {
        "deviceId": "12345678901234567",
        "deviceMetadata": {
          "entries": {
            "phonenumber": "+1 (800) 555-0100"
          }
        }
      }
    }
  ],
  "successCount": 1
}

Отслеживайте прогресс

Если вашему приложению необходимо отслеживать ход выполнения, вам следует периодически обновлять операцию. Поле metadata содержит экземпляр DevicesLongRunningOperationMetadata , который поможет вашему приложению проверять последний ход выполняемой операции. Используйте поля DevicesLongRunningOperationMetadata , перечисленные в следующей таблице, чтобы отслеживать ход операции:

Поле Типичное использование
processingStatus Меняется с BATCH_PROCESS_PENDING на BATCH_PROCESS_IN_PROGRESS , а затем на BATCH_PROCESS_PROCESSED по мере выполнения операции.
progress Процент обработанных обновлений. Ваше приложение может использовать это для оценки времени окончания. Поскольку значение progress может быть равно 100 во время завершения операции, проверьте поле done операции, чтобы узнать, завершилась ли она и есть ли результат.
devicesCount Показывает количество обновлений в операции. Это число может отличаться от количества обновлений в вашем запросе, если API не может проанализировать некоторые обновления.

В приведенном ниже упрощенном примере показано, как приложение может использовать метаданные хода выполнения для установки интервалов опроса. В вашем приложении вам может понадобиться более сложный инструмент запуска задач для опроса. Вам также потребуется добавить обработку ошибок.

Джава

// Milliseconds between polling the API.
private static long MIN_INTERVAL = 2000;
private static long MAX_INTERVAL = 10000;

// ...
// Start the device metadata update.
Operation response = service
    .partners()
    .devices()
    .updateMetadataAsync(PARTNER_ID, body)
    .execute();
String operationName = response.getName();

// Start polling for completion.
long startTime = new Date().getTime();
while (true) {

  // Get the latest update on the operation's progress using the API.
  Operation operation = service.operations().get(operationName).execute();

  if (operation.get("done") != null && operation.getDone()) {
    // The operation is finished. Print the status.
    System.out.format("Operation complete: %s of %s successful device updates\n",
        operation.getResponse().get("successCount"),
        operation.getMetadata().get("devicesCount"));
    break;

  } else {
    // Estimate how long the operation *should* take - within min and max value.
    BigDecimal opProgress = (BigDecimal) operation.getMetadata().get("progress");
    double progress = opProgress.longValue();
    long interval = MAX_INTERVAL;
    if (progress > 0) {
      interval = (long) ((new Date().getTime() - startTime) *
          ((100.0 - progress) / progress));
    }
    interval = Math.max(MIN_INTERVAL, Math.min(interval, MAX_INTERVAL));

    // Sleep until the operation should be complete.
    Thread.sleep(interval);
  }
}

.СЕТЬ

// Milliseconds between polling the API.
private static double MinInterval = 2000;
private static double MaxInterval = 10000;

// ...
// Start the device metadata update.
var response = service.Partners.Devices.UpdateMetadataAsync(body, PartnerId).Execute();
var operationName = response.Name;

// Start polling for completion.
var startTime = DateTime.Now;
while (true)
{

    // Get the latest update on the operation's progress using the API.
    Operation operation = service.Operations.Get(operationName).Execute();

    if (operation.Done == true)
    {
        // The operation is finished. Print the status.
        Console.WriteLine("Operation complete: {0} of {1} successful device updates",
                          operation.Response["successCount"],
                          operation.Metadata["devicesCount"]);
        break;
    }
    else
    {
        // Estimate how long the operation *should* take - within min and max value.
        double progress = (double)(long)operation.Metadata["progress"];
        double interval = MaxInterval;
        if (progress > 0)
        {
            interval = DateTime.Now.Subtract(startTime).TotalMilliseconds *
                                     ((100.0 - progress) / progress);
        }
        interval = Math.Max(MinInterval, Math.Min(interval, MaxInterval));

        // Sleep until the operation should be complete.
        System.Threading.Thread.Sleep((int)interval);
    }
}

Питон

# Seconds between polling the API.
MIN_INTERVAL = 2;
MAX_INTERVAL = 10;

# ...
# Start the device metadata update
response = service.partners().devices().updateMetadataAsync(
  partnerId=PARTNER_ID, body={'updates':updates}).execute()

op_name = response['name']
start_time = time.time()

# Start polling for completion
while True:
  # Get the latest update on the operation's progress using the API
  op = service.operations().get(name=op_name).execute()

  if 'done' in op and op['done']:
    # The operation is finished. Print the status.
    print('Operation complete: {0} of {1} successful device updates'.format(
      op['response']['successCount'], op['metadata']['devicesCount']
    ))
    break
  else:
    # Estimate how long the operation *should* take - within min and max.
    progress = op['metadata']['progress']
    interval = MIN_INTERVAL
    if progress > 0:
      interval = (time.time() - start_time) * ((100.0 - progress) / progress)
    interval = max(MIN_INTERVAL, min(interval, MAX_INTERVAL))

    # Sleep until the operation should be complete.
    time.sleep(interval)

Выберите метод опроса, который имеет смысл для пользователей вашего приложения. Некоторым пользователям приложений могут быть полезны регулярные обновления хода выполнения, если они ждут завершения процесса.

Постраничные результаты

Метод API partners.devices.findByOwner может возвращать очень большие списки устройств. Чтобы уменьшить размер ответа, этот и другие методы API (например, partners.devices.findByIdentifier ) поддерживают постраничное отображение результатов. Благодаря постраничному отображению результатов ваше приложение может итеративно запрашивать и обрабатывать большие списки по одной странице за раз.

После вызова метода API проверьте, содержит ли ответ значение nextPageToken . Если nextPageToken не имеет null , ваше приложение может использовать его для получения другой страницы устройств, вызвав метод еще раз. Вам необходимо установить верхний предел количества устройств в параметре limit . Если nextPageToken имеет значение null , ваше приложение запросило последнюю страницу.

В приведенном ниже примере метода показано, как ваше приложение может распечатать список устройств, по одной странице за раз:

Джава

private static long MAX_PAGE_SIZE = 10;

// ...
/**
 * Demonstrates how to loop through paginated lists of devices.
 * @param pageToken       The token specifying which result page to return.
 * @throws IOException    If the zero-touch API call fails.
 */
private void printDevices(String pageToken) throws IOException {

  // Create the request body to find the customer's devices.
  FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest();
  body.setLimit(MAX_PAGE_SIZE);
  body.setSectionType("SECTION_TYPE_ZERO_TOUCH");
  body.setCustomerId(Collections.singletonList(targetCustomerId));

  // Call the API to get a page of Devices. Send a page token from the method
  // argument (might be None). If the page token is None, the API returns the first page.
  FindDevicesByOwnerResponse response =
      service.partners().devices().findByOwner(PARTNER_ID, body).execute();
  if (response.getDevices() == null) {
    return;
  }

  // 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 and print the devices.
  if (response.getNextPageToken() != null) {
    this.printDevices(response.getNextPageToken());
  }
}

// ...
// Pass null to start printing the first page of devices.
printDevices(null);

.СЕТЬ

private static int MaxPageSize = 10;

// ...
/// <summary>Demonstrates how to loop through paginated lists of devices.</summary>
/// <param name="pageToken">The token specifying which result page to return.</param>
private void PrintDevices(string pageToken)
{
    // Create the request body to find the customer's devices.
    FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest
    {
        PageToken = pageToken,
        Limit = MaxPageSize,
        SectionType = "SECTION_TYPE_ZERO_TOUCH",
        CustomerId = new List<long?>
        {
            targetCustomerId
        }
    };

    // Call the API to get a page of Devices. Send a page token from the method
    // argument (might be None). If the page token is None, the API returns the first page.
    var response = service.Partners.Devices.FindByOwner(body, PartnerId).Execute();
    if (response.Devices == null)
    {
        return;
    }

    // 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(response.NextPageToken);
    }
}

// ...
// Pass null to start printing the first page of devices.
PrintDevices(null);

Питон

MAX_PAGE_SIZE = 10;

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

  Args:
    page_token: The token specifying which result page to return.
  """

   # Create the body to find the customer's devices.
  request_body = {'limit':MAX_PAGE_SIZE, \
    'pageToken':page_token, \
    'customerId':[target_customer_id], \
    'sectionType':'SECTION_TYPE_ZERO_TOUCH'}

  # Call the API to get a page of Devices. Send a page token from the method
  # argument (might be None). If the page token is None,
  # the API returns the first page.
  response = service.partners().devices().findByOwner(partnerId=PARTNER_ID,
    body=request_body).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(response['nextPageToken'])

# ...
# Pass None to start printing the first page of devices.
print_devices(None);

Следующие шаги

Теперь, когда вы знаете, как работает API, попробуйте примеры с кратким руководством для Java , .NET или Python .