Giới thiệu
API đăng ký không tiếp xúc giúp người bán lại thiết bị tự động hoá việc tích hợp. Các công cụ bán hàng của tổ chức có thể tích hợp tính năng đăng ký không tiếp xúc, giúp người dùng và khách hàng của bạn làm việc hiệu quả hơn. Sử dụng API để giúp người dùng:
- Chỉ định thiết bị đã mua cho tài khoản thiết lập tự động của khách hàng.
- Tạo tài khoản thiết lập tự động cho khách hàng của bạn.
- Đính kèm siêu dữ liệu về số điện thoại và đơn đặt hàng của tổ chức vào thiết bị.
- Tạo báo cáo về các thiết bị được chỉ định cho khách hàng của bạn.
Tài liệu này giới thiệu về API và giải thích các mẫu. Nếu bạn muốn tự khám phá API, thử bắt đầu nhanh về Java, .NET hoặc Python.
Khái niệm về API
Khách hàng và thiết bị là các tài nguyên cốt lõi mà bạn sử dụng trong API. Để tạo khách hàng, hãy gọi create
. Bạn có thể tạo các thiết bị
bằng các phương thức API xác nhận quyền sở hữu (xem bên dưới). Tổ chức của bạn cũng có thể
tạo khách hàng và thiết bị bằng cổng thiết lập tự động.
- Khách hàng
- Các công ty mà tổ chức của bạn bán thiết bị. Khách hàng có
name
vàID
. Sử dụng một khách hàng khi bạn muốn xác nhận quyền sở hữu hoặc tìm thiết bị của họ. Để tìm hiểu thêm, hãy xemCustomer
. - Thiết bị
- Một thiết bị Android hoặc ChromeOS có thể thiết lập tự động cho tổ chức của bạn
bán cho khách hàng. Thiết bị có mã nhận dạng phần cứng, siêu dữ liệu và khiếu nại của khách hàng. Thiết bị là trọng tâm của API, vì vậy bạn sử dụng chúng trong hầu hết
. Để tìm hiểu thêm, hãy xem
Device
. - DeviceIdentifier
- Đóng gói mã phần cứng, chẳng hạn như IMEI hoặc MEID, để xác định sản phẩm
thiết bị. Sử dụng
DeviceIdentifier
để nhắm mục tiêu thiết bị mà bạn muốn tìm, cập nhật hoặc xác nhận quyền sở hữu. Để tìm hiểu thêm, hãy đọc Giá trị nhận dạng. - DeviceMetadata
- Lưu trữ các cặp khoá-giá trị của siêu dữ liệu cho thiết bị. Sử dụng
DeviceMetadata
để lưu trữ siêu dữ liệu của tổ chức. Người nhận tìm hiểu thêm, hãy đọc bài viết Siêu dữ liệu thiết bị.
Để liệt kê tất cả phương thức API và tài nguyên mà ứng dụng của bạn có thể dùng, hãy xem Tài liệu tham khảo API.
Tạo khách hàng
Đối với thiết bị Android, đại lý chịu trách nhiệm tạo khách hàng tài khoản thay mặt cho khách hàng của mình. Khách hàng sẽ sử dụng tài khoản này để truy cập vào cổng thiết lập tự động nhằm định cấu hình chế độ cài đặt cấp phép cho thiết bị của họ. Điều này không cần thiết đối với các thiết bị ChromeOS, vì người dùng đã có tài khoản Google Workspace để định cấu hình chế độ cài đặt cấp phép.
Bạn có thể gọi phương thức API create
để tạo
các tài khoản khách hàng để thiết lập tự động. Vì khách hàng của bạn sẽ thấy tên công ty trong cổng đăng ký không tiếp xúc, nên người dùng ứng dụng của bạn phải xác nhận rằng tên đó là chính xác. Bạn không thể chỉnh sửa tên của khách hàng sau khi tạo khách hàng.
Bạn cần thêm ít nhất một địa chỉ email công ty được liên kết với một Tài khoản Google để trở thành chủ sở hữu. Bạn không thể sử dụng tài khoản Gmail cá nhân có API. Nếu khách hàng cần trợ giúp liên kết tài khoản, hãy gửi hướng dẫn trong phần Liên kết Tài khoản Google.
Sau khi bạn tạo khách hàng bằng cách gọi API, họ sẽ quản lý các nhân viên của mình quyền truy cập cổng thông tin — bạn không thể chỉnh sửa thông tin người dùng sử dụng API. Đoạn mã dưới đây cho biết cách bạn có thể tạo khách hàng:
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()
Để tìm hiểu thêm về vai trò của chủ sở hữu và quản trị viên đối với nhân viên của khách hàng, hãy đọc bài viết Người dùng cổng thông tin.
Xác nhận quyền sở hữu thiết bị cho khách hàng
Sau khi khách hàng của bạn mua thiết bị, họ sẽ muốn định cấu hình cấp phép cho các thiết bị này trong tài khoản của mình. Việc xác nhận quyền sở hữu một thiết bị sẽ thêm thiết bị đó thiết lập tự động và cho phép khách hàng thiết lập cài đặt cấp phép.
Bản ghi cấp phép của thiết bị có một phần để thiết lập tự động. Bạn
gán thiết bị bằng cách xác nhận phần thiết lập tự động của bản ghi cho
khách hàng. Gọi phương thức partners.devices.claim
hoặc partners.devices.claimAsync
với đối số là khách hàng. Luôn cung cấp SECTION_TYPE_ZERO_TOUCH
làm giá trị cho sectionType
.
Bạn cần huỷ xác nhận quyền sở hữu (xem bên dưới) thiết bị của một khách hàng trước khi có thể xác nhận quyền sở hữu cùng một thiết bị cho một khách hàng khác. Phương thức xác nhận quyền sở hữu
xác thực các trường DeviceIdentifier
,
bao gồm IMEI hoặc MEID hoặc số sê-ri,
tên nhà sản xuất, kiểu máy và
mã thiết bị được chứng thực đối với thiết bị ChromeOS khi tạo một thiết bị mới.
Đoạn mã dưới đây cho biết cách xác nhận quyền sở hữu thiết bị:
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()
Đang huỷ xác nhận quyền sở hữu thiết bị
Tổ chức của bạn có thể huỷ xác nhận quyền sở hữu thiết bị của khách hàng. Khi bạn huỷ xác nhận quyền sở hữu một thiết bị, thiết bị đó sẽ bị xoá khỏi quy trình thiết lập tự động. Đại lý có thể huỷ xác nhận quyền sở hữu thiết bị
họ muốn di chuyển sang một tài khoản khác, bị trả lại hoặc nội dung bị xác nhận quyền sở hữu do nhầm lẫn.
Gọi phương thức partners.devices.unclaim
hoặc partners.devices.unclaimAsync
để huỷ xác nhận quyền sở hữu thiết bị của khách hàng.
Nhà cung cấp
Bạn có thể sử dụng nhà cung cấp để đại diện cho đối tác đại lý trong mạng lưới đại lý, nhà mạng tại địa phương trong mạng lưới đại lý toàn cầu hoặc bất kỳ tổ chức nào thay mặt bạn bán thiết bị. Nhà cung cấp giúp bạn phân tách người dùng, khách hàng và thiết bị:
- Các nhà cung cấp mà bạn tạo không thể xem tài khoản thiết lập tự động của bạn hoặc từng nhà cung cấp tài khoản của người khác.
- Bạn có thể xem khách hàng và thiết bị của nhà cung cấp và có thể huỷ đăng ký thiết bị của nhà cung cấp. Tuy nhiên, bạn không thể chỉ định thiết bị cho khách hàng của nhà cung cấp.
Sử dụng cổng thông tin để tạo nhà cung cấp cho
tổ chức – bạn không thể sử dụng API. Vai trò của tài khoản phải là Chủ sở hữu thì bạn mới có thể tạo nhà cung cấp mới. Nếu tổ chức của bạn có nhà cung cấp,
bạn có thể gọi partners.vendors.list
để liệt kê
nhà cung cấp và partners.vendors.customers.list
để có được khách hàng của nhà cung cấp. Ví dụ sau đây sử dụng cả hai phương thức này để in báo cáo cho thấy trạng thái Điều khoản dịch vụ của khách hàng của nhà cung cấp:
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'])
Nếu có một tập hợp thiết bị, bạn có thể cần biết đại lý hoặc
Nhà cung cấp đã xác nhận thiết bị này. Để biết mã đại lý dạng số, hãy kiểm tra giá trị của
trường resellerId
trong hồ sơ xác nhận quyền sở hữu của thiết bị.
Tổ chức của bạn có thể huỷ xác nhận quyền sở hữu đối với thiết bị mà nhà cung cấp đã xác nhận quyền sở hữu. Đối với các lệnh gọi API khác có thể chỉnh sửa thiết bị, bạn nên kiểm tra để đảm bảo rằng tổ chức của bạn đã xác nhận quyền sở hữu thiết bị trước khi gọi phương thức API. Ví dụ sau đây cho thấy cách bạn có thể thực hiện việc này:
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
Thao tác hàng loạt chạy trong thời gian dài
API này bao gồm các phiên bản không đồng bộ của phương thức thiết bị.
Các phương thức này cho phép xử lý hàng loạt nhiều thiết bị, trong khi các phương thức đồng bộ xử lý một thiết bị cho mỗi yêu cầu API. Tên phương thức không đồng bộ có hậu tố Async, ví dụ: claimAsync
.
Các phương thức API không đồng bộ trả về kết quả trước khi quá trình xử lý hoàn tất. Các phương thức không đồng bộ cũng giúp ứng dụng (hoặc công cụ) của bạn duy trì khả năng thích ứng cho người dùng trong khi họ chờ một hoạt động chạy trong thời gian dài hoàn tất. Ứng dụng của bạn nên kiểm tra trạng thái của thao tác theo định kỳ.
Hoạt động tính toán
Bạn sử dụng Operation
để theo dõi một thao tác hàng loạt diễn ra trong thời gian dài. Một lệnh gọi thành công đến một phương thức không đồng bộ sẽ trả về một tệp tham chiếu đến thao tác trong phản hồi. Đoạn mã JSON bên dưới cho thấy một phản hồi thông thường sau khi gọi updateMetadataAsync
:
{
"name": "operations/apibatchoperation/1234567890123476789"
}
Mỗi thao tác chứa một danh sách các tác vụ riêng lẻ. Gọi điện
operations.get
để tìm hiểu thông tin về trạng thái và
kết quả của các tác vụ có trong tác vụ. Đoạn mã dưới đây cho biết cách bạn có thể thực hiện việc này. Trong ứng dụng của riêng mình, bạn sẽ cần xử lý mọi lỗi.
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()
Để tìm hiểu xem một thao tác đã hoàn tất hay chưa, hãy kiểm tra thao tác đó đối với trường done
có giá trị true
. Nếu thiếu done
hoặc false
thì thao tác vẫn sẽ có hiệu lực
đang chạy.
Phản hồi
Sau khi một thao tác hoàn tất, API sẽ cập nhật thao tác đó bằng kết quả – ngay cả khi tất cả hoặc không có tác vụ nào thành công. Trường response
là một
DevicesLongRunningOperationResponse
đối tượng nêu chi tiết quá trình xử lý của từng thiết bị trong thao tác.
Kiểm tra trường successCount
để tìm hiểu một cách hiệu quả xem có thao tác nào không thành công và không
tránh lặp lại thông qua những danh sách kết quả lớn. Trường perDeviceStatus
của DevicesLongRunningOperationResponse
là danh sách các thực thể OperationPerDevice
, trong đó nêu chi tiết từng thiết bị trong thao tác. Thứ tự danh sách khớp với các công việc trong yêu cầu ban đầu.
Mỗi tác vụ OperationPerDevice
chứa một trường result
và một bản tóm tắt nhắc nhở về yêu cầu mà máy chủ nhận được. Kiểm tra xem tác vụ thành công hay không thành công
bằng trường result
.
Đoạn mã JSON dưới đây cho thấy một phần của một phản hồi điển hình của một thao tác sau
một lệnh gọi đến updateMetadataAsync
:
"response": {
"perDeviceStatus": [
{
"result": {
"deviceId": "12345678901234567",
"status": "SINGLE_DEVICE_STATUS_SUCCESS"
},
"updateMetadata": {
"deviceId": "12345678901234567",
"deviceMetadata": {
"entries": {
"phonenumber": "+1 (800) 555-0100"
}
}
}
}
],
"successCount": 1
}
Theo dõi tiến trình
Nếu ứng dụng của bạn cần theo dõi tiến trình, bạn nên định kỳ tìm nạp lại
hoạt động. Trường metadata
chứa một thực thể DevicesLongRunningOperationMetadata
để giúp ứng dụng của bạn kiểm tra tiến trình mới nhất của một thao tác đang chạy. Sử dụng các trường của DevicesLongRunningOperationMetadata
được liệt kê trong bảng sau để theo dõi tiến trình của thao tác:
Trường | Cách sử dụng thông thường |
---|---|
processingStatus
|
Thay đổi từ BATCH_PROCESS_PENDING thành BATCH_PROCESS_IN_PROGRESS , sau đó thành BATCH_PROCESS_PROCESSED khi thao tác diễn ra. |
progress
|
Tỷ lệ phần trăm bản cập nhật được xử lý. Ứng dụng của bạn có thể sử dụng thông tin này để ước tính thời gian hoàn tất. Vì progress
giá trị có thể là 100 trong khi thao tác kết thúc,
kiểm tra trường done của một toán tử để biết
đã hoàn tất và có một kết quả. |
devicesCount
|
Cho biết số lượng bản cập nhật trong hoạt động. Số lượng này có thể khác với số lượng nội dung cập nhật trong yêu cầu của bạn nếu API không thể phân tích cú pháp một số nội dung cập nhật. |
Ví dụ đơn giản bên dưới cho thấy cách một ứng dụng có thể sử dụng siêu dữ liệu về tiến trình để đặt khoảng thời gian thăm dò. Trong ứng dụng, bạn có thể cần một trình chạy tác vụ phức tạp hơn để thăm dò ý kiến. Bạn cũng cần thêm tính năng xử lý lỗi.
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)
Chọn phương pháp thăm dò ý kiến phù hợp với người dùng ứng dụng của bạn. Một số người dùng ứng dụng có thể hưởng lợi từ việc cập nhật tiến trình thường xuyên nếu họ đang chờ một quy trình hoàn tất.
Kết quả được phân trang
Phương thức API partners.devices.findByOwner
có thể trả về một danh sách rất lớn gồm nhiều thiết bị. Để giảm kích thước phản hồi, phương thức này và các phương thức API khác (chẳng hạn như partners.devices.findByIdentifier
) hỗ trợ kết quả được phân trang. Với kết quả được phân trang, ứng dụng của bạn có thể lặp lại yêu cầu và xử lý các danh sách lớn theo từng trang.
Sau khi gọi phương thức API, hãy kiểm tra xem phản hồi có chứa giá trị cho
nextPageToken
. Nếu nextPageToken
không phải là null
, ứng dụng của bạn có thể sử dụng nó để tìm nạp một trang thiết bị khác bằng cách gọi
phương thức đó một lần nữa. Bạn cần đặt giới hạn trên cho số lượng thiết bị trong
tham số limit
. Nếu nextPageToken
là null
, thì ứng dụng của bạn đã yêu cầu trang cuối cùng.
Phương thức mẫu bên dưới cho biết cách ứng dụng của bạn có thể in danh sách thiết bị, mỗi lần một trang:
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);
Các bước tiếp theo
Giờ bạn đã biết cách thức hoạt động của API, hãy xem thử các ví dụ một cách bắt đầu nhanh về Java, .NET hoặc Python. Bạn có thể sử dụng colab để xem ví dụ về lệnh gọi API và thử tự gọi API.