Como funciona

Introdução

A API de registro sem toque ajuda os revendedores de dispositivos a automatizar a integração. As ferramentas de vendas da sua organização podem integrar o registro sem toque. Assim, usuários e clientes mais produtivos. Use a API para ajudar seus usuários a:

  • Atribuir os dispositivos comprados à conta de registro sem toque de um cliente
  • Criação da conta de registro sem toque para clientes
  • Anexe os metadados de telefone e pedido da sua organização a dispositivos.
  • Criação de relatórios sobre dispositivos atribuídos aos seus clientes

Este documento apresenta a API e explica os padrões. Se você quiser conheça a API, confira o guia de início rápido Java .NET ou Python.

Conceitos da API

Os clientes e dispositivos são os principais recursos que você usa na API. Para criar clientes, ligue para create. É possível criar dispositivos usando os métodos da API de declaração (veja abaixo). Sua organização também pode criar clientes e dispositivos usando o portal do registro sem toque.

Relação entre recursos do dispositivo e do cliente

Cliente
Empresas para as quais sua organização vende dispositivos. Os clientes têm uma name e um ID. Use um cliente quando quiser reivindicar ou encontrar os dispositivos dele. Para Para saber mais, consulte Customer.
Dispositivo
Um dispositivo Android ou ChromeOS com recurso de registro sem toque para sua organização e as vendas para um cliente. Os dispositivos têm IDs de hardware, metadados e IDs de reivindicações. Os dispositivos são essenciais para a API, então você os usa em quase todas métodos. Para saber mais, consulte Device.
DeviceIdentifier
Encapsula IDs de hardware, como IMEI ou MEID, para identificar os dispositivo. Use um DeviceIdentifier para segmentar o dispositivo. que você quer encontrar, atualizar ou reivindicar. Para saber mais, leia Identificadores.
DeviceMetadata
Armazena pares de chave-valor de metadados para o dispositivo. Usar DeviceMetadata para armazenar os metadados da sua organização. Para Saiba mais em Metadados do dispositivo.

Para listar todos os métodos e recursos de API que seu aplicativo pode usar, consulte Referência da API.

Criar clientes

Para dispositivos Android, o revendedor é responsável por criar o cliente do cliente em nome do cliente. O cliente vai usar essa conta para acessar o portal de registro sem toque para definir as configurações de provisionamento da dispositivos. Isso não é necessário para dispositivos ChromeOS, que já têm uma Conta do Google do Google Workspace que será usada para definir as configurações de provisionamento.

Você pode chamar o método da API create para criar contas de clientes para o registro sem toque. Como seus clientes veem o nome da empresa no portal de registro sem toque, o usuário do seu app precisa confirme se elas estão corretas. Não é possível editar o nome de um cliente depois de criar o para o cliente.

Você precisa incluir pelo menos um endereço de e-mail corporativo, associado a um Conta do Google, para ser a proprietária. Não é possível usar contas pessoais do Gmail com as API. Se o cliente precisar de ajuda para associar a conta, envie o instruções de Associar uma Conta do Google.

Depois que você chama a API para criar um cliente, ele gerencia as contas de ao portal, e não é possível editar usuários que usam a API. O snippet mostra como criar um cliente:

Java

// 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();

.NET

// 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();

Python

# 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()

Para saber mais sobre as funções de proprietário e administrador dos funcionários do seu cliente, leia Usuários do portal.

Reivindicar dispositivos para clientes

Depois que seus clientes comprarem os dispositivos, eles precisarão configurar o provisionamento configurações para esses dispositivos na conta deles. A reivindicação de um dispositivo o adiciona ao registro sem toque e dá ao cliente a capacidade de configurar configurações de provisionamento.

O registro de provisionamento de um dispositivo tem uma seção para o registro sem toque. Você atribuir o dispositivo reivindicando a seção de registro sem toque do registro para uma para o cliente. Chame o método partners.devices.claim ou partners.devices.claimAsync com os cliente como argumento. Sempre forneça SECTION_TYPE_ZERO_TOUCH como um valor para sectionType.

Você precisará cancelar a reivindicação do dispositivo de um cliente (veja abaixo) antes de poder reivindicar o mesmo dispositivo para outro cliente. Métodos de reivindicação validar os campos DeviceIdentifier; incluindo o IMEI ou MEID ou o número de série, o o nome do fabricante e o modelo, ID do dispositivo atestado para dispositivos ChromeOS ao criar um novo dispositivo.

O snippet abaixo mostra como reivindicar um dispositivo:

Java

// 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();

.NET

// 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();

Python

# 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()

Cancelando reivindicação de dispositivos

Sua organização pode cancelar a reivindicação de um dispositivo de um cliente. Como cancelar a reivindicação de um dispositivo ele será removido do registro sem toque. Um revendedor pode cancelar a reivindicação de um dispositivo eles querem migrar para outra conta, devolvidos ou que foram reivindicados por engano. Chame o método partners.devices.unclaim ou partners.devices.unclaimAsync para cancelar a reivindicação de um dispositivo de um cliente.

Fornecedores

Você pode usar fornecedores para representar parceiros de revenda na sua rede de revendedores, operadores em uma rede de revendedores global ou qualquer organização que venda dispositivos em seu nome. Os fornecedores ajudam você a separar seus usuários, clientes dispositivos:

  • Os fornecedores que você criar não terão acesso à sua conta de registro sem toque nem cada uma as contas de outras pessoas.
  • Você pode conferir os clientes e dispositivos dos seus fornecedores e cancelar o registro dispositivos dos fornecedores. No entanto, não é possível atribuir dispositivos aos fornecedores para os clientes.
.

Use o portal para criar fornecedores para sua organização, ou seja, não é possível usar a API. Sua função na conta precisa ser Proprietário para criar um novo fornecedor. Se sua organização tem fornecedores, você pode chamar partners.vendors.list para listar suas fornecedores e partners.vendors.customers.list para conseguir os clientes do seu fornecedor. O exemplo a seguir usa esses dois métodos para imprimir um relatório com o status dos Termos de Serviço clientes:

Java

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

.NET

// 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);
        }
    }
}

Python

# 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'])

Se você tiver uma coleção de dispositivos, talvez precise saber qual revendedor ou o fornecedor reivindicou o dispositivo. Para encontrar o ID numérico do revendedor, inspecione o valor do no campo resellerId no registro de reivindicação de um dispositivo.

Sua organização pode cancelar a reivindicação de um dispositivo reivindicado pelo fornecedor. Para outras chamadas de API que modificar dispositivos, verifique se a organização reivindicou o dispositivo antes de chamar o método da API. O exemplo abaixo mostra como fazer isso:

Java

// 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;
    }
  }
}

.NET

// 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;
        }
    }
}

Python

# 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

Operações em lote de longa duração

A API inclui versões assíncronas dos métodos de dispositivo. Esses métodos permitem o processamento em lote de vários dispositivos, enquanto a processam um dispositivo para cada solicitação de API. Os nomes de métodos assíncronos ter um sufixo Async, por exemplo, claimAsync.

Os métodos assíncronos de API retornam um resultado antes que o processamento seja concluído. Os métodos assíncronos também ajudam seu aplicativo (ou ferramenta) a permanecer responsivo para usuários enquanto eles aguardam a conclusão de uma operação de longa duração. Seu app precisa verificar o status da operação periodicamente.

Operações

Use um Operation para rastrear uma operação em lote de longa duração. Um chamada bem-sucedida para um método assíncrono retorna uma referência à operação na resposta. O snippet JSON abaixo mostra uma resposta típica após a chamada updateMetadataAsync:

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

Cada operação contém uma lista de tarefas individuais. Ligação operations.get para saber mais sobre o status e resultados das tarefas contidas na operação. O snippet abaixo mostra como você pode fazer isso. No seu próprio app, você precisará lidar com todos os erros.

Java

// 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();

.NET

// 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();

Python

# 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()

Para descobrir se uma operação foi concluída, verifique se há um campo done na operação. com um valor de true. Se done estiver ausente ou false, a operação ainda será em execução.

Respostas

Depois que uma operação é concluída, a API atualiza a operação com o resultado, mesmo se todas ou nenhuma das tarefas individuais tiver êxito. O campo response é um DevicesLongRunningOperationResponse objeto que detalha o processamento de cada dispositivo na operação.

Inspecione o campo successCount para descobrir de forma eficiente se alguma tarefa falhou e evite iterar em listas grandes de resultados. O campo perDeviceStatus de DevicesLongRunningOperationResponse é uma lista de Instâncias do OperationPerDevice detalhando cada dispositivo em a operação. A ordem da lista corresponde às tarefas na solicitação original.

Cada tarefa OperationPerDevice contém um campo result e um resumo do lembrete da solicitação recebida pelo servidor. Verificar se a tarefa foi bem-sucedida ou falhou usando o campo result.

O snippet JSON abaixo mostra parte de uma resposta típica de uma operação após uma chamada para updateMetadataAsync:

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

Acompanhe o progresso.

Se o app precisar acompanhar o progresso, refaça periodicamente a busca operação O campo metadata contém uma DevicesLongRunningOperationMetadata para ajudar seu app a verificar o progresso mais recente de uma operação em execução. Usar os campos de DevicesLongRunningOperationMetadata listados no para acompanhar o progresso da operação:

Campo Uso normal
processingStatus Altera de BATCH_PROCESS_PENDING para BATCH_PROCESS_IN_PROGRESS, depois para BATCH_PROCESS_PROCESSED à medida que a operação progride.
progress A porcentagem de atualizações processadas. Seu app pode usar para estimar o tempo de conclusão. Como o progress o valor pode ser 100 enquanto a operação é concluída, verificar o campo done de uma operação para saber se ela terminou e tem um resultado.
devicesCount Mostra o número de atualizações na operação. Isso pode ser diferente do número de atualizações nas se a API não puder analisar algumas das atualizações.

O exemplo simplificado abaixo mostra como um app pode usar os metadados de progresso para definir intervalos de sondagem. No seu app, talvez você precise de uma tarefa mais sofisticada executor para sondagem. Você também vai precisar adicionar o tratamento de erros.

Java

// 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);
  }
}

.NET

// 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);
    }
}

Python

# 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)

Escolha uma abordagem de pesquisa que faça sentido para os usuários do seu app. Alguns usuários do app podem se beneficiar de atualizações regulares de progresso se estiverem aguardando um processo para concluído.

Resultados paginados

Método da API partners.devices.findByOwner pode retornar listas muito grandes de dispositivos. Para reduzir o tamanho da resposta, outros métodos de API (como partners.devices.findByIdentifier). oferecer suporte a resultados paginados. Com os resultados paginados, seu aplicativo pode solicitar e processar listas grandes, uma página por vez.

Depois de chamar o método da API, verifique se a resposta inclui um valor para nextPageToken Se nextPageToken não for null, seu aplicativo poderá usá-lo para buscar outra página de dispositivos chamando o método novamente. Você precisa definir um limite máximo para o número de dispositivos em o parâmetro limit. Se nextPageToken for null, o app solicitou a na última página.

O exemplo de método abaixo mostra como o app pode mostrar uma lista de dispositivos, um página por vez:

Java

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);

.NET

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);

Python

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);

Próximas etapas

Agora que você sabe como a API funciona, teste os exemplos com um guia de início rápido para Java .NET ou Python.