طريقة العمل

مقدمة

تساعد واجهة برمجة التطبيقات لبرنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة" مورِّدي الأجهزة على برمجة عملية الدمج. يمكن لأدوات المبيعات في مؤسستك تضمين برنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة"، ما يزيد من إنتاجية المستخدمين والعملاء. يمكنك استخدام واجهة برمجة التطبيقات لمساعدة المستخدمين في ما يلي:

  • تعيين الأجهزة التي تم شراؤها إلى حساب العميل في برنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة".
  • أنشئ حساب عميلك في برنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة".
  • يُرجى إرفاق البيانات الوصفية لرقم الهاتف والطلبات الخاصة بمؤسستك مع الأجهزة.
  • إنشاء تقارير عن الأجهزة التي تم تخصيصها لعملائك.

يقدم هذا المستند واجهة برمجة التطبيقات ويشرح الأنماط. إذا أردت استكشاف واجهة برمجة التطبيقات بنفسك، جرِّب البحث سريعًا عن Java، أو .NET، أو Python.

مفاهيم واجهة برمجة التطبيقات

إن العملاء والأجهزة هم الموارد الأساسية التي تستخدمها في واجهة برمجة التطبيقات. لإنشاء عملاء، اتصل بـ create. يمكنك إنشاء أجهزة باستخدام طرق واجهة برمجة التطبيقات Claim API (انظر أدناه). ويمكن لمؤسستك أيضًا إنشاء عملاء وأجهزة باستخدام بوابة "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة".

العلاقة بمورد العميل والجهاز

العميل
الشركات التي تبيع مؤسستك الأجهزة لها يملك العملاء name وID. يمكنك استخدام حساب عميل عندما تريد المطالبة بأجهزته أو العثور عليها. لمزيد من المعلومات، يُرجى الاطّلاع على Customer.
الجهاز
جهاز Android أو ChromeOS متوافق مع برنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة" والذي تبيعه مؤسستك إلى العميل وتتضمن الأجهزة معرّفات الأجهزة وبيانات وصفية ومطالبات العملاء. تُعد الأجهزة عنصرًا أساسيًا لواجهة برمجة التطبيقات، لذا تستخدمها في جميع الطرق تقريبًا. لمزيد من المعلومات، يمكنك الاطّلاع على Device.
DeviceIdentifier
يغلف معرّفات الأجهزة، مثل IMEI أو MEID، لتحديد الجهاز الذي تم تصنيعه. استخدِم DeviceIdentifier لاستهداف الجهاز الذي تريد العثور عليه أو تحديثه أو المطالبة به. للحصول على مزيد من المعلومات، يمكنك الاطّلاع على المعرِّفات.
DeviceMetadata
تخزين أزواج المفتاح/القيمة للبيانات الوصفية للجهاز. استخدِم DeviceMetadata لتخزين البيانات الوصفية لمؤسستك. لمعرفة المزيد من المعلومات، يُرجى الاطّلاع على البيانات الوصفية للجهاز.

لإدراج جميع طرق واجهة برمجة التطبيقات والموارد التي يمكن لتطبيقك استخدامها، يُرجى الاطّلاع على مرجع واجهة برمجة التطبيقات.

إنشاء عملاء

بالنسبة إلى أجهزة Android، يكون المورد مسؤولاً عن إنشاء حساب العميل نيابةً عن عميله. سيستخدم العميل هذا الحساب للوصول إلى بوابة برنامج "إعداد الأجهزة الجوّالة للمؤسسات دفعةً واحدة" لضبط إعدادات توفير المتطلبات اللازمة لأجهزته. وهذا ليس ضروريًا لأجهزة ChromeOS التي لديها حساب على Google Workspace سيتم استخدامه لضبط إعدادات إدارة الحسابات.

يمكنك استدعاء طريقة واجهة برمجة التطبيقات create لإنشاء حسابات عملاء لبرنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة". بما أنّ اسم الشركة يظهر للعملاء في بوابة برنامج "إعداد الأجهزة الجوّالة للمؤسسات دفعةً واحدة"، على مستخدم التطبيق التأكّد من صحته. لا يمكنك تعديل اسم العميل بعد إنشائه.

عليك تضمين عنوان بريد إلكتروني واحد على الأقل للشركة، ومرتبط بحساب على Google، لتكون المالك. لا يمكنك استخدام حسابات Gmail الشخصية مع واجهة برمجة التطبيقات. إذا كان العميل بحاجة إلى مساعدة في ربط الحساب، أرسِل التعليمات من ربط حساب Google.

بعد إنشاء عميل من خلال الاتصال بواجهة برمجة التطبيقات، يدير العميل إمكانية الدخول إلى بوابة الموظفين، ولا يمكنك تعديل المستخدمين لدى العملاء باستخدام واجهة برمجة التطبيقات. يبيّن المقتطف أدناه كيفية إنشاء عميل:

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

لمعرفة المزيد من المعلومات عن أدوار المالك والمشرف لموظفي العميل، يُرجى الاطّلاع على مقالة مستخدمو المنصة.

طلب الأجهزة للعملاء

بعد أن يشتري عملاؤك الأجهزة، سيرغبون في ضبط إعدادات توفير المتطلبات اللازمة لهذه الأجهزة في حساباتهم. تؤدي المطالبة بجهاز إلى إضافة الجهاز إلى برنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة" ومنح العميل القدرة على ضبط إعدادات إدارة الحسابات.

يحتوي سجلّ إدارة حسابات الجهاز على قسم لبرنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة". ويمكنك تخصيص الجهاز من خلال المطالبة بقسم "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة" في السجلّ للعميل. يمكنك استدعاء طرق partners.devices.claim أو partners.devices.claimAsync مع العميل كوسيطة. يجب دائمًا تقديم SECTION_TYPE_ZERO_TOUCH كقيمة للسمة sectionType.

عليك إلغاء المطالبة بجهاز العميل (انظر أدناه) قبل أن تتمكن من المطالبة بالجهاز نفسه لعميل آخر. عند إنشاء جهاز جديد، تعمل طرق المطالبة على validate من حقول DeviceIdentifier، بما في ذلك رمز IMEI أو رمز MEID أو الرقم التسلسلي واسم الشركة المصنّعة والطراز ورقم تعريف الجهاز المعتمَد لأجهزة ChromeOS.

يوضّح المقتطف أدناه كيفية المطالبة بجهاز:

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

جارٍ إلغاء المطالبة بالأجهزة

يمكن لمؤسستك إلغاء المطالبة بجهاز من عميل. ويؤدي إلغاء المطالبة بالجهاز إلى إزالته من برنامج "إعداد الأجهزة الجوّالة للمؤسّسات دفعةً واحدة". قد يلغي المورّد المطالبة بالجهاز الذي يريد نقله إلى حساب آخر، أو تم إرجاعه، أو تمت المطالبة به عن طريق الخطأ. يمكنك الاتصال بالطريقة partners.devices.unclaim أو partners.devices.unclaimAsync لإلغاء المطالبة بجهاز من العميل.

المورّدون

يمكنك الاستعانة بالمورّدين لتمثيل شركاء المورّدين في شبكة الوكلاء التي تتعامل معها، أو المشغّلين المحليين ضمن شبكة مورّدين عالمية، أو أي مؤسسة تبيع الأجهزة نيابةً عنك. يساعدك الموردون على فصل المستخدمين والعملاء والأجهزة:

  • لا يمكن للمورّدين الذين تنشئهم الاطّلاع على حسابك في برنامج "إعداد الأجهزة الجوّالة للمؤسسات دفعةً واحدة" أو حسابات بعضهم البعض.
  • يمكنك الاطّلاع على عملاء المورّدين وأجهزتهم، ويمكنك إلغاء تسجيل أجهزة المورّدين. ومع ذلك، لا يمكنك تعيين أجهزة لعملاء الموردين لديك.

استخدم البوابة من أجل إنشاء موردين لمؤسستك، ولا يمكنك استخدام واجهة برمجة التطبيقات. يجب أن يكون دورك في الحساب مالكًا لإنشاء مورّد جديد. إذا كان لدى مؤسستك بائعون، يمكنك الاتصال بـ partners.vendors.list لإدراج المورّدين وpartners.vendors.customers.list للتواصل مع عملاء المورّد. يستخدم المثال التالي كلتا الطريقتين لطباعة تقرير يعرض حالة بنود الخدمة لعملاء الموردين:

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

إذا كان لديك مجموعة من الأجهزة، قد تحتاج إلى معرفة المورّد أو المورّد الذي طالب بملكية الجهاز. للحصول على رقم تعريف المورّد الرقمي، افحص قيمة حقل resellerId في سجلّ مطالبة الجهاز.

يمكن لمؤسستك إلغاء المطالبة بجهاز تمت المطالبة به من قِبل المورِّد. بالنسبة إلى طلبات البيانات من واجهة برمجة التطبيقات الأخرى التي يتم من خلالها تعديل الأجهزة، عليك التحقق من أنّ مؤسستك قد طالبت بالجهاز قبل طلب طريقة واجهة برمجة التطبيقات. يوضّح المثال التالي كيفية إجراء ذلك:

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

العمليات المجمّعة طويلة المدى

تتضمّن واجهة برمجة التطبيقات إصدارات غير متزامنة من طرق الأجهزة. تسمح هذه الطرق بالمعالجة المجمّعة للعديد من الأجهزة، بينما تعالج الطرق المتزامنة جهازًا واحدًا لكل طلب من واجهة برمجة التطبيقات. تحتوي أسماء الطرق غير المتزامنة على لاحقة غير متزامنة، على سبيل المثال claimAsync.

تعرِض طرق واجهة برمجة التطبيقات غير المتزامنة نتيجة قبل اكتمال المعالجة. تساعد الطرق غير المتزامنة أيضًا تطبيقك (أو أداتك) في أن يظل مستجيبًا للمستخدمين أثناء انتظارهم حتى تكتمل عملية طويلة المدى. يجب أن يفحص التطبيق حالة العملية بشكل دوري.

العمليات

يمكنك استخدام Operation لتتبُّع عملية مجمّعة تم إجراؤها لفترة طويلة. ينتج عن الاستدعاء الناجح لطريقة غير متزامنة إشارة إلى العملية في الاستجابة. يعرض مقتطف JSON أدناه استجابة نموذجية بعد استدعاء updateMetadataAsync:

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

وتحتوي كل عملية على قائمة بالمهام الفردية. يمكنك استدعاء operations.get للاطّلاع على معلومات حول حالة ونتائج المهام المضمّنة في العملية. يوضح المقتطف أدناه كيف يمكنك القيام بذلك. في تطبيقك الخاص، ستحتاج إلى معالجة أي أخطاء.

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

لمعرفة ما إذا انتهت العملية، تحقَّق من العملية بحثًا عن حقل done بقيمة true. إذا كان done غير متوفّر أو false، يعني هذا أنّ العملية لا تزال قيد التشغيل.

الردود

بعد انتهاء العملية، تحدّث واجهة برمجة التطبيقات العملية بالنتيجة - حتى إذا لم تنجح جميع المهام الفردية أو لم تنجح أي منها. والحقل response هو عنصر DevicesLongRunningOperationResponse يوضّح بالتفصيل معالجة كل جهاز في العملية.

افحص حقل successCount لمعرفة ما إذا كانت أي مهام قد تعذّر إكمالها وتجنُّب التكرار من خلال قوائم النتائج الكبيرة الحقل perDeviceStatus في DevicesLongRunningOperationResponse هو قائمة بمثيلات OperationPerDevice توضح بالتفصيل كل جهاز في العملية. يتطابق ترتيب القائمة مع المهام في الطلب الأصلي.

تحتوي كل مهمة OperationPerDevice على الحقل result وملخّص تذكير بالطلب الذي استلمه الخادم. تحقق مما إذا كانت المهمة نجحت أو فشلت باستخدام الحقل result.

يعرض مقتطف JSON أدناه جزءًا من استجابة نموذجية من عملية بعد إجراء مكالمة إلى updateMetadataAsync:

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

تتبُّع مستوى التقدّم

إذا كان تطبيقك بحاجة إلى تتبع مستوى التقدم، يجب عليك إعادة جلب العملية بشكل دوري. يحتوي الحقل metadata على مثيل DevicesLongRunningOperationMetadata لمساعدة تطبيقك على التحقّق من آخر تقدّم في عملية قيد التشغيل. استخدِم حقول DevicesLongRunningOperationMetadata المدرَجة في الجدول التالي لتتبُّع مستوى تقدُّم العملية:

الحقل معدّل الاستخدام
processingStatus التغييرات من BATCH_PROCESS_PENDING إلى BATCH_PROCESS_IN_PROGRESS، ثم إلى BATCH_PROCESS_PROCESSED مع تقدّم العملية
progress النسبة المئوية للتحديثات التي تمت معالجتها. يمكن لتطبيقك استخدام هذا لتقدير وقت الانتهاء. بما أنّ القيمة progress قد تكون 100 أثناء انتهاء العملية، راجِع الحقل done من العملية لمعرفة ما إذا كانت قد انتهت ونتج عنها.
devicesCount يعرِض عدد التعديلات في العملية. وقد يختلف ذلك عن عدد التحديثات في طلبك إذا لم تتمكن واجهة برمجة التطبيقات من تحليل بعض التحديثات.

يوضّح المثال المُبسّط أدناه كيف يمكن لتطبيق أن يستخدم البيانات الوصفية للتقدّم لضبط فواصل الاستطلاع. في تطبيقك، قد تحتاج إلى برنامج تشغيل مهام أكثر تعقيدًا لإجراء الاستطلاعات. ويجب أيضًا إضافة إعدادات معالجة الأخطاء.

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)

اختَر أسلوب استطلاع رأي يناسب مستخدمي تطبيقك. قد يستفيد بعض مستخدمي التطبيق من التحديثات المنتظمة للتقدم إذا كانوا ينتظرون اكتمال العملية.

نتائج مقسّمة إلى صفحات

قد تعرض طريقة واجهة برمجة التطبيقات partners.devices.findByOwner قوائم كبيرة جدًا من الأجهزة. لتقليل حجم الاستجابة، تتوافق هذه الطريقة وطرق واجهة برمجة التطبيقات الأخرى (مثل partners.devices.findByIdentifier) مع النتائج المقسّمة على صفحات. باستخدام النتائج المقسّمة على صفحات، يمكن لتطبيقك طلب القوائم الكبيرة من صفحة واحدة في كل مرة ومعالجتها على نحو متكرر.

بعد طلب طريقة واجهة برمجة التطبيقات، تأكَّد مما إذا كان الردّ يتضمّن قيمة للسمة nextPageToken. إذا لم تكن nextPageToken هي null، يمكن لتطبيقك استخدامه لاسترجاع صفحة أخرى من الأجهزة من خلال استدعاء الطريقة مرة أخرى. يجب ضبط حدّ أقصى لعدد الأجهزة في المعلّمة limit. إذا كانت قيمة nextPageToken هي null، يعني ذلك أنّ تطبيقك طلب الصفحة الأخيرة.

وتوضح الطريقة التالية كمثال كيف يمكن لتطبيقك طباعة قائمة بالأجهزة، صفحة واحدة في كل مرة:

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

الخطوات التالية

والآن بعد أن تعرّفت على آلية عمل واجهة برمجة التطبيقات، جرِّب الأمثلة مع لمحة عن التشغيل السريع Java، أو .NET، أو Python.