طريقة العمل

مقدمة

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

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

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

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

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

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

العميل
الشركات التي تبيع مؤسستك الأجهزة لها لدى العملاء name. وID. استخدِم حساب عميل عندما تريد المطالبة بأجهزة العميل أو العثور عليها. إلى لمزيد من المعلومات، يُرجى الاطّلاع على Customer.
الجهاز
جهاز Android أو ChromeOS مزوّد بميزة "إعداد الأجهزة الجوّالة للمؤسسات دفعةً واحدة"، والذي تبيعه مؤسستك إلى عميل تحتوي الأجهزة على أرقام تعريف الأجهزة والبيانات الوصفية وطلبات العميل . الأجهزة هي أساس واجهة برمجة التطبيقات، وبالتالي يمكنك استخدامها في جميع الطرق. لمزيد من المعلومات، يُرجى الاطّلاع على Device.
معرّف الجهاز
ملفًا يتضمّن معرّفات الأجهزة، مثل 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.

يجب إلغاء المطالبة بجهاز العميل (انظر أدناه) قبل أن تتمكّن من الحصول على الجهاز نفسه لعميل مختلف. طرق المطالبة التحقّق من صحة حقول 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

العمليات المجمّعة التي تستغرق وقتًا طويلاً

تتضمّن واجهة برمجة التطبيقات إصدارات غير متزامنة من طُرق الجهاز. وتسمح هذه الطرق بالمعالجة المجمّعة للعديد من الأجهزة بينما معالجة جهاز واحد لكل طلب بيانات من واجهة برمجة التطبيقات. تحتوي أسماء الطرق غير المتزامنة على اللاحقة Async، على سبيل المثال 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. يمكنك استخدام colab للاطّلاع على مثال على طلبات بيانات من واجهة برمجة التطبيقات وتجربة طلب البيانات من واجهة برمجة التطبيقات بنفسك.