Jak to działa

Wprowadzenie

Interfejs API rejestracji typu zero-touch ułatwia sprzedawcom urządzeń automatyzację integracji. Narzędzia sprzedażowe Twojej organizacji mogą zawierać rejestrację bezdotynkową, co zwiększa produktywność użytkowników i klientów. Używaj interfejsu API, aby pomagać użytkownikom:

  • Przypisz zakupione urządzenia do konta rejestracji typu zero-touch klienta.
  • Utwórz konto rejestracji typu zero-touch klienta.
  • Dołącz do urządzeń metadane numeru telefonu i zamówienia organizacji.
  • tworzyć raporty o urządzeniach przypisanych klientom.

Ten dokument przedstawia interfejs API i omawia wzorce. Jeśli chcesz samodzielnie zapoznać się z interfejsem API, wypróbuj krótkie wprowadzenie do Java, .NET lub Python.

Pojęcia związane z interfejsem API

Klienci i urządzenia to podstawowe zasoby używane w interfejsie API. Aby utworzyć klientów, zadzwoń pod numer create. Możesz tworzyć urządzenia za pomocą metod interfejsu API roszczeń (patrz niżej). Twoja organizacja może też tworzyć klientów i urządzenia w portalu rejestracji typu zero-touch.

Relacja między urządzeniem a zasobem klienta

Klient
Firmy, którym Twoja organizacja sprzedaje urządzenia. Klienci mają name i ID. Użyj klienta, gdy chcesz zgłosić lub znaleźć jego urządzenia. Do więcej informacji: Customer.
Urządzenie
Urządzenie z Androidem lub ChromeOS obsługujące rejestrację typu zero-touch, które Twoja organizacja sprzedaje klientowi. Urządzenia mają identyfikator sprzętu, metadane i klienta roszczeniami. Urządzenia są kluczowe dla interfejsu API, dlatego używasz ich w prawie wszystkich metodach. Więcej informacji: Device.
DeviceIdentifier (identyfikator urządzenia)
Obejmuje identyfikatory sprzętowe, takie jak IMEI lub MEID, aby zidentyfikować wyprodukowane urządzenie. Użyj DeviceIdentifier, aby wskazać urządzenie, które chcesz znaleźć, zaktualizować lub zgłosić. Więcej informacji: Identyfikatory.
DeviceMetadata
Przechowuje pary klucz-wartość metadanych urządzenia. Użyj DeviceMetadata do przechowywania metadanych organizacji. Aby dowiedzieć się więcej, przeczytaj artykuł Metadane urządzeń.

Listę wszystkich metod i zasobów interfejsu API, których może używać Twoja aplikacja, znajdziesz w dokumentacji interfejsu API.

Tworzenie klientów

W przypadku urządzeń z Androidem sprzedawca jest odpowiedzialny za utworzenie konta klienta w imieniu klienta. Klient będzie używać tego konta do: w portalu rejestracji typu zero-touch skonfigurować ustawienia obsługi administracyjnej urządzenia. Nie jest to konieczne na urządzeniach z ChromeOS, które mają już Konto Workspace, którego będzie używać do konfigurowania ustawień obsługi administracyjnej.

Aby utworzyć konta klientów na potrzeby rejestracji typu zero-touch, możesz wywołać metodę interfejsu API create. Klienci widzą nazwę firmy w portalu rejestracji typu zero-touch, dlatego użytkownik aplikacji powinien potwierdzić, że jest ona prawidłowa. Po utworzeniu klienta nie możesz edytować jego nazwy.

Aby być właścicielem, musisz podać co najmniej 1 adres e-mail firmowy powiązany z kontem Google. Nie można używać osobistych kont Gmail z API. Jeśli klient potrzebuje pomocy w powiązaniu konta, wyślij wiadomość instrukcje z Powiąż konto Google

Po utworzeniu klienta przez wywołanie interfejsu API klient zarządza dostępem swoich pracowników do portalu – nie możesz edytować użytkowników klientów za pomocą interfejsu API. Fragment poniżej pokazuje, jak możesz utworzyć klienta:

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

Aby dowiedzieć się więcej o rolach właściciela i administratora dla pracowników klienta, przeczytaj artykuł Użytkownicy portalu.

Reklamowanie urządzeń klientów

Gdy klienci kupią urządzenia, będą musieli skonfigurować obsługę administracyjną ustawień tych urządzeń. Zgłoszenie własności urządzenia powoduje dodanie urządzenia do rejestracji typu zero-touch i pozwala klientowi ustawienia obsługi administracyjnej.

W rekordzie obsługi administracyjnej urządzenia znajduje się sekcja dotycząca rejestracji typu zero-touch. Ty przypisać urządzenie, zgłaszając prawa do sekcji rejestracji typu zero-touch dla domeny klienta. Zadzwoń pod numer partners.devices.claim lub partners.devices.claimAsync z klienta jako argumentu. Wartością atrybutu sectionType zawsze jest SECTION_TYPE_ZERO_TOUCH.

Aby móc to zrobić, musisz cofnąć rezerwację urządzenia klienta (patrz poniżej). zgłosić roszczenie do tego samego urządzenia w imieniu innego klienta. Metody zgłaszania roszczeń sprawdź poprawność pól DeviceIdentifier, łącznie z numerem IMEI, MEID lub numerem seryjnym, nazwę producenta i model, potwierdzony identyfikator urządzenia z ChromeOS podczas tworzenia nowego urządzenia,

Fragment kodu poniżej pokazuje, jak zgłosić prawa do urządzenia:

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

Usuwanie rezerwacji urządzeń

Organizacja może anulować rezerwację urządzenia od klienta. Usuwanie rezerwacji urządzenia spowoduje usunięcie go z rejestracji typu zero-touch. Sprzedawca może anulować zgłoszenie urządzenia, które chce przenieść na inne konto, zwrócić lub które zostało zgłoszone przez pomyłkę. Wywołaj metodę partners.devices.unclaim lub partners.devices.unclaimAsync, aby usunąć rezerwację: urządzenie od klienta.

Dostawcy

Do reprezentowania partnerów w sieci sprzedawców możesz używać dostawców, lokalnych operatorów w globalnej sieci sprzedawców lub dowolnej organizacji, która sprzedaje urządzenia w Twoim imieniu. Dostawcy pomagają w oddzielaniu użytkowników, klientów i urządzeń:

  • Utworzeni przez Ciebie dostawcy nie mogą zobaczyć Twojego konta do rejestracji typu zero-touch ani kont innych użytkowników.
  • Możesz wyświetlać informacje o klientach i urządzeniach dostawców oraz je wyrejestrować na urządzeniach dostawców. Nie możesz jednak przypisywać urządzeń klientom dostawców.
.

W portalu możesz utworzyć dostawców dla nie możesz korzystać z interfejsu API. Aby utworzyć nowego dostawcę, musisz mieć rolę Właściciel. Jeśli Twoja organizacja ma dostawców, możesz zadzwonić pod numer partners.vendors.list, aby wyświetlić dostawcy i partners.vendors.customers.list pozyskać klientów dostawcy. Następujący przykład wykorzystuje obie te metody aby wydrukować raport przedstawiający stan Warunków korzystania z usługi dla dostawców klienci:

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

Jeśli masz kolekcję urządzeń, może być konieczne sprawdzenie, który sprzedawca lub sprzedawca zgłosił urządzenie. Aby uzyskać liczbowy identyfikator sprzedawcy, sprawdź wartość pola resellerId w rekordzie roszczenia urządzenia.

Organizacja może zrzec się prawa do urządzenia, którego zażądał sprzedawca. W przypadku innych wywołań interfejsu API, które modyfikują urządzenia, przed wywołaniem metody interfejsu API sprawdź, czy Twoja organizacja zażądała urządzenia. Z przykładu poniżej dowiesz się, jak to zrobić:

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

Długotrwałe operacje zbiorcze

Interfejs API zawiera asynchroniczne wersje metod urządzenia. Te metody umożliwiają wsadowe przetwarzanie wielu urządzeń, podczas gdy przetwarzają jedno urządzenie dla każdego żądania do interfejsu API. Nazwy metod asynchronicznych mają sufiks Asynchroniczny, np. claimAsync.

Asynchroniczne metody interfejsu API zwracają wynik przed zakończeniem przetwarzania. Metody asynchroniczne również pomagają aplikacji (lub narzędziu) w elastyczności użytkowników w czasie, gdy oczekują na zakończenie długo trwającej operacji. Aplikacja powinna okresowo sprawdzaj stan operacji.

Operacje

Używasz Operation do śledzenia długotrwałej operacji zbiorczej. O udane wywołanie metody asynchronicznej zwraca odwołanie do operacji w odpowiedzi. Poniższy fragment kodu JSON zawiera typową odpowiedź po wywołaniu updateMetadataAsync:

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

Każda operacja zawiera listę poszczególnych zadań. Aby uzyskać informacje o stanie i wynikach zadań zawartych w operacji, zadzwoń pod numer operations.get. Ten fragment kodu pokazuje, może to zrobić. W swojej aplikacji musisz obsługiwać wszelkie błędy.

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

Aby sprawdzić, czy operacja została ukończona, sprawdź, czy w jej przypadku występuje pole done z wartością true. Jeśli brakuje atrybutu done lub false, operacja jest nadal wykonywana w domu.

Odpowiedzi

Po zakończeniu operacji interfejs API aktualizuje ją, podając wynik, nawet jeśli żadne z osobnych zadań nie zostało wykonane lub wszystkie zostały wykonane. Pole response to DevicesLongRunningOperationResponse z opisem przetwarzania poszczególnych urządzeń.

Sprawdź pole successCount, aby szybko sprawdzić, czy jakieś zadania się nie powiodły, i unikaj przeszukiwania dużych list wyników. Pole perDeviceStatus argumentu DevicesLongRunningOperationResponse to lista OperationPerDevice instancje ze szczegółowym opisem każdego urządzenia w całą operację. Kolejność na liście odpowiada zadaniom w pierwotnym żądaniu.

Każde zadanie OperationPerDevice zawiera pole result i podsumowanie przypomnienia żądania otrzymanego przez serwer. Sprawdź, czy udało się wykonać zadanie przy użyciu pola result.

Poniższy fragment kodu JSON zawiera część typowej odpowiedzi pochodzącej z operacji po połączenie z numerem updateMetadataAsync:

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

Śledzenie postępów

Jeśli aplikacja musi śledzić postępy, pobieraj ją co jakiś czas. . Pole metadata zawiera instancję DevicesLongRunningOperationMetadata, która pomaga aplikacji sprawdzać najnowszy postęp uruchomionej operacji. Użyj pola DevicesLongRunningOperationMetadata wymienione w tym w tabeli, aby śledzić postęp operacji:

Pole Typowe zastosowanie
processingStatus Zmiany z BATCH_PROCESS_PENDING na BATCH_PROCESS_IN_PROGRESS, a następnie aby BATCH_PROCESS_PROCESSED w trakcie wykonywania operacji.
progress Odsetek przetworzonych aktualizacji. Twoja aplikacja może użyć tego do oszacowania czasu zakończenia. Podczas gdy operacja się kończy, wartość progress może wynosić 100, dlatego sprawdź pole done operacji, aby dowiedzieć się, czy została ona zakończona i czy ma wynik.
devicesCount Pokazuje liczbę aktualizacji w operacji. Ten może się różnić od liczby aktualizacji w , jeśli interfejs API nie może przeanalizować niektórych aktualizacji.

Uproszczony przykład poniżej pokazuje, jak aplikacja może używać metadanych postępu do ustawiania interwałów sprawdzania. W aplikacji możesz potrzebować bardziej zaawansowanego wykonawcy zadań do obsługi pobierania danych. Trzeba również dodać obsługę błędów.

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)

Wybierz sposób przeprowadzania ankiety, który jest odpowiedni dla użytkowników aplikacji. Niektórzy użytkownicy aplikacji mogą skorzystać na regularnych aktualizacjach dotyczących postępów, jeśli oczekują na rozpoczęcie procesu gotowe.

Wyniki z podziałem na strony

Metoda interfejsu API partners.devices.findByOwner może zwrócić bardzo duże listy urządzeń. Aby zmniejszyć rozmiar odpowiedzi, ta i inne metody interfejsu API (np. partners.devices.findByIdentifier) obsługują wyniki podzielone na strony. Dzięki podziałowi wyników na strony aplikacja może stopniowo przesyłać żądania i przetwarzać duże listy po jednej stronie naraz.

Po wywołaniu metody interfejsu API sprawdź, czy odpowiedź zawiera wartość nextPageToken. Jeśli nextPageToken nie jest null, aplikacja może jej użyć do pobrania innej strony urządzeń, wywołując przy użyciu tej metody. W parametrze limit musisz ustawić górny limit liczby urządzeń. Jeśli nextPageToken to null, aplikacja wysłała żądanie dotyczące ostatniej strony.

Przykładowa metoda poniżej pokazuje, jak aplikacja może wydrukować listę urządzeń. Pierwsza z nich tylko jedną stronę:

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

Dalsze kroki

Wiesz już, jak działa interfejs API, więc zapoznaj się z przykładami z krótkim wprowadzeniem Java .NET lub Python. Możesz użyć colab, aby wyświetlić przykłady wywołań interfejsu API i samodzielnie eksperymentować z wywoływaniem interfejsu API.