Funktionsweise

Einführung

Mit der Zero-Touch-Registrierungs-API können Geräte-Reseller die Integration automatisieren. Die Vertriebstools Ihrer Organisation können die Zero-Touch-Registrierung ermöglichen, wodurch Ihre Nutzer und Ihre Kunden produktiver werden. Mit der API unterstützen Sie Ihre Nutzer bei folgenden Aufgaben:

  • Gekaufte Geräte dem Konto eines Kunden für die Zero-Touch-Registrierung zuweisen.
  • Erstellen von Kundenkonten mit Zero-Touch-Registrierung
  • Hängen Sie die Telefon- und Bestellmetadaten Ihrer Organisation an Geräte an.
  • Erstellen von Berichten über Geräte, die Ihren Kunden zugewiesen sind

In diesem Dokument wird die API vorgestellt und die Muster erläutert. Wenn Sie die API selbst erkunden möchten, verwenden Sie eine Kurzanleitung für Java, .NET oder Python.

API-Konzepte

Kunden und Geräte sind die wichtigsten Ressourcen, die Sie in der API verwenden. Rufen Sie zum Erstellen von Kunden create auf. Sie können Geräte mithilfe der Claim API-Methoden erstellen (siehe unten). Ihre Organisation kann Kunden und Geräte auch über das Portal für die Zero-Touch-Registrierung erstellen.

Beziehung zwischen Gerät und Kundenressourcen

Kunde
Unternehmen, an die Ihr Unternehmen Geräte verkauft. Kunden haben eine name und eine ID. Verwende einen Kunden, wenn du seine Geräte beanspruchen oder finden möchtest. Weitere Informationen finden Sie unter Customer.
Gerät
Ein Android- oder ChromeOS-Gerät mit Zero-Touch-Registrierung, das Ihre Organisation an Kunden verkauft. Geräte haben Hardware-IDs, Metadaten und Kundenanforderungen. Geräte sind ein zentraler Bestandteil der API und werden in fast allen Methoden verwendet. Weitere Informationen finden Sie unter Device.
DeviceIdentifier
Kapselt Hardware-IDs wie IMEI oder MEID, um ein hergestelltes Gerät zu identifizieren. Verwenden Sie einen DeviceIdentifier, um eine Ausrichtung auf das Gerät vorzunehmen, das Sie suchen, aktualisieren oder beanspruchen möchten. Weitere Informationen finden Sie unter Kennungen.
DeviceMetadata
Speichert Schlüssel/Wert-Paare von Metadaten für das Gerät Verwenden Sie DeviceMetadata, um die Metadaten Ihrer Organisation zu speichern. Weitere Informationen finden Sie unter Gerätemetadaten.

Eine Liste aller API-Methoden und -Ressourcen, die die Anwendung verwenden kann, finden Sie in der API-Referenz.

Kunden erstellen

Bei Android-Geräten ist der Reseller dafür verantwortlich, das Kundenkonto im Namen seines Kunden zu erstellen. Der Kunde verwendet dieses Konto, um auf das Zero-Touch-Portal zuzugreifen und die Bereitstellungseinstellungen für seine Geräte zu konfigurieren. Bei ChromeOS-Geräten ist dies nicht erforderlich, da sie bereits ein Google Workspace-Konto haben, das sie zum Konfigurieren ihrer Nutzerverwaltungseinstellungen verwenden.

Sie können die API-Methode create aufrufen, um Kundenkonten für die Zero-Touch-Registrierung zu erstellen. Da Ihre Kunden den Namen des Unternehmens in ihrem Portal für die Zero-Touch-Registrierung sehen, sollte der Nutzer Ihrer Anwendung bestätigen, dass er korrekt ist. Sie können den Namen eines Kunden nicht mehr bearbeiten, nachdem Sie den Kunden erstellt haben.

Sie müssen mindestens eine geschäftliche E-Mail-Adresse angeben, die mit einem Google-Konto verknüpft ist, um Inhaber zu sein. Private Gmail-Konten können nicht mit der API verwendet werden. Wenn der Kunde Hilfe beim Verknüpfen des Kontos benötigt, sende die Anleitung unter Google-Konto verknüpfen.

Nachdem Sie einen Kunden durch Aufrufen der API erstellt haben, verwaltet dieser den Portalzugriff seiner Mitarbeiter. Sie können die Nutzer Ihrer Kunden nicht mithilfe der API bearbeiten. Das folgende Snippet zeigt, wie Sie einen Kunden erstellen können:

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

Weitere Informationen zu den Inhaber- und Administratorrollen für Mitarbeiter Ihres Kunden finden Sie unter Portalnutzer.

Geräte für Kunden beanspruchen

Nachdem Ihre Kunden Geräte gekauft haben, möchten sie die Bereitstellungseinstellungen für diese Geräte in ihrem Konto konfigurieren. Wenn Sie ein Gerät beanspruchen, wird es der Zero-Touch-Registrierung hinzugefügt und der Kunde kann die Einstellungen für die Nutzerverwaltung konfigurieren.

Der Bereitstellungseintrag eines Geräts enthält einen Abschnitt für die Zero-Touch-Registrierung. Sie weisen das Gerät zu, indem Sie den Bereich für die Zero-Touch-Registrierung des Eintrags für einen Kunden beanspruchen. Rufen Sie die Methode partners.devices.claim oder partners.devices.claimAsync mit dem Kunden als Argument auf. Geben Sie immer SECTION_TYPE_ZERO_TOUCH als Wert für sectionType an.

Sie müssen zuerst den Anspruch auf das Gerät eines Kunden zurückziehen (siehe unten), bevor Sie es für einen anderen Kunden beanspruchen können. Die Beanspruchungsmethoden validate die DeviceIdentifier-Felder, einschließlich der IMEI oder MEID oder der Seriennummer, des Namens des Herstellers und des Modells sowie der attestierten Geräte-ID für ChromeOS-Geräte, wenn ein neues Gerät erstellt wird.

Das folgende Snippet zeigt, wie Sie ein Gerät beanspruchen können:

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

Anspruch auf Geräte zurückziehen

Ihre Organisation kann den Anspruch auf ein Gerät von einem Kunden zurückziehen. Wenn Sie die Inhaberschaft eines Geräts aufheben, wird es aus der Zero-Touch-Registrierung entfernt. Ein Reseller kann den Anspruch auf ein Gerät zurückziehen, das er zu einem anderen Konto migriert, zurückgegeben oder versehentlich beansprucht wurde. Rufen Sie die Methode partners.devices.unclaim oder partners.devices.unclaimAsync auf, um den Anspruch auf ein Gerät für einen Kunden aufzuheben.

Anbieter

Sie können Anbieter verwenden, um Reseller-Partner in Ihrem Händlernetzwerk, lokale Betreiber in einem globalen Reseller-Netzwerk oder jede Organisation, die Geräte in Ihrem Namen verkauft, zu vertreten. Anbieter helfen Ihnen, Nutzer, Kunden und Geräte voneinander zu trennen:

  • Von Ihnen erstellte Anbieter können weder Ihr Konto für die Zero-Touch-Registrierung noch die Konten der anderen Anbieter sehen.
  • Sie können sich die Kunden und Geräte Ihrer Anbieter ansehen und deren Geräte abmelden. Sie können jedoch den Kunden Ihrer Anbieter keine Geräte zuweisen.

Verwenden Sie das Portal, um Anbieter für Ihre Organisation zu erstellen. Sie können die API nicht verwenden. Ihre Kontorolle muss Inhaber sein, um einen neuen Anbieter erstellen zu können. Wenn Ihre Organisation Anbieter hat, können Sie partners.vendors.list aufrufen, um Ihre Anbieter aufzulisten, und partners.vendors.customers.list aufrufen, um die Kunden Ihres Anbieters zu gewinnen. Im folgenden Beispiel werden beide Methoden verwendet, um einen Bericht zu drucken, in dem der Status der Nutzungsbedingungen für die Kunden der Anbieter aufgeführt ist:

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

Wenn Sie eine Sammlung von Geräten haben, müssen Sie möglicherweise wissen, welcher Reseller oder Anbieter das Gerät beansprucht hat. Die numerische Reseller-ID erhalten Sie, wenn Sie den Wert des Felds resellerId im Anforderungseintrag eines Geräts prüfen.

Ihre Organisation kann den Anspruch auf ein vom Anbieter beanspruchtes Gerät zurückziehen. Bei anderen API-Aufrufen, die Geräte ändern, sollten Sie prüfen, ob Ihre Organisation das Gerät beansprucht hat, bevor Sie die API-Methode aufrufen. Das folgende Beispiel zeigt, wie das geht:

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

Lang andauernde Batchvorgänge

Die API enthält asynchrone Versionen der Gerätemethoden. Diese Methoden ermöglichen die Batchverarbeitung vieler Geräte, während die synchronen Methoden für jede API-Anfrage ein Gerät verarbeiten. Die Namen der asynchronen Methoden haben ein asynchrones Suffix, z. B. claimAsync.

Asynchrone API-Methoden geben ein Ergebnis zurück, bevor die Verarbeitung abgeschlossen ist. Asynchrone Methoden tragen außerdem dazu bei, dass Ihre Anwendung (oder Ihr Tool) für Nutzer reagiert, wenn sie auf den Abschluss eines lang andauernden Vorgangs warten. Ihre Anwendung sollte den Status des Vorgangs regelmäßig prüfen.

Operations

Sie verwenden einen Operation, um einen lang andauernden Batchvorgang zu verfolgen. Ein erfolgreicher Aufruf einer asynchronen Methode gibt einen Verweis auf den Vorgang in der Antwort zurück. Das folgende JSON-Snippet zeigt eine typische Antwort nach dem Aufruf von updateMetadataAsync:

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

Jeder Vorgang enthält eine Liste einzelner Aufgaben. Rufen Sie operations.get auf, um Informationen zum Status und zu den Ergebnissen der im Vorgang enthaltenen Aufgaben zu erhalten. Das folgende Snippet zeigt, wie Sie dies tun können. In Ihrer eigenen Anwendung müssen Sie alle Fehler beheben.

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

Wenn Sie wissen möchten, ob ein Vorgang abgeschlossen wurde, prüfen Sie den Vorgang auf das Feld done mit dem Wert true. Wenn done oder false fehlt, wird der Vorgang noch ausgeführt.

Antworten

Nachdem ein Vorgang abgeschlossen ist, aktualisiert die API den Vorgang mit dem Ergebnis, auch wenn alle oder keine der einzelnen Aufgaben erfolgreich waren. Das Feld response ist ein DevicesLongRunningOperationResponse-Objekt, das die Verarbeitung jedes Geräts im Vorgang detailliert beschreibt.

Prüfen Sie das Feld successCount, um effizient festzustellen, ob Aufgaben fehlgeschlagen sind, und um Iterationen über große Ergebnislisten zu vermeiden. Das Feld perDeviceStatus von DevicesLongRunningOperationResponse ist eine Liste von OperationPerDevice-Instanzen, in denen jedes Gerät im Vorgang beschrieben wird. Die Listenreihenfolge entspricht den Aufgaben in der ursprünglichen Anfrage.

Jede OperationPerDevice-Aufgabe enthält ein result-Feld und eine Erinnerungszusammenfassung an die vom Server empfangene Anfrage. Prüfen Sie mithilfe des Felds result, ob die Aufgabe erfolgreich war oder fehlgeschlagen ist.

Das folgende JSON-Snippet zeigt einen Teil einer typischen Antwort eines Vorgangs nach einem Aufruf von updateMetadataAsync:

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

Fortschritt verfolgen

Wenn die Anwendung den Fortschritt verfolgen muss, sollten Sie den Vorgang regelmäßig noch einmal abrufen. Das Feld metadata enthält eine DevicesLongRunningOperationMetadata-Instanz, mit der die Anwendung den letzten Fortschritt eines laufenden Vorgangs prüfen kann. Verwenden Sie die Felder von DevicesLongRunningOperationMetadata, die in der folgenden Tabelle aufgeführt sind, um den Fortschritt des Vorgangs zu verfolgen:

Feld Typischer Einsatzzweck
processingStatus Wechselt sich von BATCH_PROCESS_PENDING zu BATCH_PROCESS_IN_PROGRESS und dann im Laufe des Vorgangs zu BATCH_PROCESS_PROCESSED.
progress Der Prozentsatz der verarbeiteten Updates. Ihre App kann dies verwenden, um die Endzeit zu schätzen. Da der Wert von progress während des Vorgangs 100 sein kann, sollten Sie im Feld done eines Vorgangs prüfen, ob er abgeschlossen wurde und ein Ergebnis vorliegt.
devicesCount Zeigt die Anzahl der Aktualisierungen im Vorgang an. Diese kann von der Anzahl der Aktualisierungen in Ihrer Anfrage abweichen, wenn die API einige der Aktualisierungen nicht parsen kann.

Das vereinfachte Beispiel unten zeigt, wie eine Anwendung die Metadaten zum Fortschritt verwenden kann, um Abfrageintervalle festzulegen. In Ihrer Anwendung benötigen Sie möglicherweise einen komplexeren Task-Runner für das Abfragen. Außerdem müssen Sie eine Fehlerbehandlung hinzufügen.

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)

Wählen Sie einen Abfrageansatz, der für die Nutzer Ihrer App sinnvoll ist. Einige App-Nutzer profitieren möglicherweise von regelmäßigen Fortschrittsupdates, wenn sie auf den Abschluss eines Prozesses warten.

Seitenbezogene Ergebnisse

Über die API-Methode partners.devices.findByOwner werden möglicherweise sehr große Listen von Geräten zurückgegeben. Diese und andere API-Methoden (z. B. partners.devices.findByIdentifier) unterstützen ausgelagerte Ergebnisse, um die Antwortgröße zu reduzieren. Mit Seitenergebnissen kann Ihre Anwendung iterativ große Listen seitenweise anfordern und verarbeiten.

Prüfen Sie nach dem Aufrufen der API-Methode, ob die Antwort einen Wert für nextPageToken enthält. Wenn nextPageToken nicht null ist, kann Ihre App damit eine weitere Seite mit Geräten abrufen, indem die Methode noch einmal aufgerufen wird. Sie müssen im Parameter limit eine Obergrenze für die Anzahl der Geräte festlegen. Wenn nextPageToken den Wert null hat, hat Ihre Anwendung die letzte Seite angefordert.

Die folgende Beispielmethode zeigt, wie Ihre App eine Seite für eine Liste von Geräten ausgeben könnte:

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

Nächste Schritte

Sie wissen jetzt, wie die API funktioniert. Probieren Sie die Beispiele mit einer Kurzanleitung für Java, .NET oder Python aus.