مهم: ما دیگر ثبت نام های جدید برای Play EMM API را نمی پذیریم.
بیشتر بدانید .
ارسال درخواست های دسته ای
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
این سند نشان میدهد که چگونه میتوانید تماسهای API را با هم دستهبندی کنید تا تعداد اتصالهایی که مشتری شما باید برقرار کند را کاهش دهید.
این سند به طور خاص در مورد ایجاد یک درخواست دسته ای با استفاده از کتابخانه مشتری جاوا است. یک مثال اولیه نیز در Google API Client Library برای دات نت موجود است. سیستم دستهای برای Google Play EMM API از دستور HTTP مشابه سیستم پردازش دستهای OData استفاده میکند.
نمای کلی
هر درخواستی که مشتری شما از طریق Google Play EMM API ارائه میکند، منجر به مقدار معینی سربار میشود. Google Play EMM API از دستهبندی پشتیبانی میکند تا به مشتری شما اجازه دهد چندین تماس API را در یک درخواست قرار دهد.
در اینجا چند نمونه از موقعیت هایی وجود دارد که ممکن است بخواهید در آنها از دسته بندی استفاده کنید:
- دامنه ای به تازگی ثبت شده است و اکنون داده های زیادی برای آپلود دارد.
- زمانی که برنامه شما آفلاین بود، یک کاربر تغییراتی در دادهها ایجاد کرد، بنابراین برنامه شما باید مقدار زیادی از دادههای محلی را با سرور همگامسازی کند.
در مواردی از این قبیل، به جای ارسال هر تماس جداگانه، می توانید آنها را در یک درخواست واحد گروه بندی کنید. حتی میتوانید درخواستهای چند کاربر یا چندین API Google را گروهبندی کنید.
با این حال، شما محدود به 1000 تماس در یک درخواست دسته ای هستید. اگر نیاز به تماس بیشتر از آن دارید، از چندین درخواست دسته ای استفاده کنید.
جزئیات دسته
یک درخواست دسته ای شامل چندین تماس API است که در یک درخواست JSON-RPC ترکیب شده اند. این بخش نحو درخواست دسته ای را با یک مثال در بخش زیر به تفصیل شرح می دهد.
توجه : مجموعهای از n درخواست که با هم جمع شدهاند به عنوان n درخواست به حساب میآیند، نه به عنوان یک درخواست. درخواست دسته ای قبل از پردازش به مجموعه ای از درخواست ها تقسیم می شود.
کتابخانه سرویس گیرنده جاوا شامل تماس هایی برای ایجاد درخواست برای هر تماس Google Play EMM API است. به عنوان مثال، برای فهرست کردن همه برنامه های نصب شده روی یک دستگاه، از موارد زیر استفاده کنید:
AndroidEnterprise enterprise = ...;
InstallsListResponse response = enterprise.installs().list(enterpriseId, userId, deviceId)
.execute();
یک فراخوان batch()
اضافی وجود دارد که می تواند چندین درخواست را در صف قرار دهد، همانطور که در اینجا مشاهده می کنید:
AndroidEnterprise enterprise = ...;
BatchRequest batchRequest = enterprise.batch();
enterprise.installs().list(enterpriseId, userId, deviceId1).queue(batchRequest, callback1);
enterprise.installs().list(enterpriseId, userId, deviceId2).queue(batchRequest, callback2);
enterprise.installs().list(enterpriseId, userId, deviceId3).queue(batchRequest, callback3);
batchRequest.execute();
هنگامی که batchRequest.execute()
فراخوانی می شود، تمام درخواست های در صف به یکباره به عنوان یک آرایه JSON به سرور ارسال می شوند. سرور پارامترهای پرس و جو و هدرهای درخواست بیرونی را (در صورت لزوم) برای هر قسمت اعمال می کند و سپس با هر قسمت به گونه ای رفتار می کند که گویی یک درخواست JSON جداگانه است. پاسخ به درخواست دسته ای
سرور هر درخواست جداگانه را اجرا می کند و نتیجه را در یک پاسخ واحد از یک آرایه واحد گروه بندی می کند. کتابخانه مشتری این پاسخ را به پاسخ های جداگانه تقسیم می کند و هر یک به تابع callback ارسال شده به queue()
ارسال می شود. تماس برگشتی رابطی است که روشی برای شکست و روشی برای موفقیت تعریف می کند. به عنوان مثال، callback1
به عنوان نمونه ای از موارد زیر پیاده سازی می شود:
private class InstallsCallback implements JsonBatchCallback<InstallsListResponse> {
@Override
public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {
...
}
@Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
...
}
}
توجه : سرور ممکن است تماس های شما را به هر ترتیبی انجام دهد، بنابراین به دریافت نتایج به ترتیب مشخص شده در درخواست خود متکی نباشید. اگر میخواهید اطمینان حاصل کنید که دو تماس با یک ترتیب مشخص انجام میشوند، نمیتوانید آنها را در یک درخواست ارسال کنید. در عوض، درخواست اول را به تنهایی ارسال کنید و قبل از ارسال درخواست دوم منتظر پاسخ باشید.
نمونه درخواست دسته ای
مثال زیر نشان می دهد که چگونه می توان همه برنامه های نصب شده در همه دستگاه های کاربر را فهرست کرد. اولین تماس ها برای به دست آوردن شناسه شرکت و کاربر استفاده می شود و بر این اساس باید به صورت متوالی اجرا شوند. هنگامی که همه شناسههای دستگاه با enterprise.devices().list()
به دست آمد، میتوانیم یک درخواست دستهای برای بازیابی همه برنامهها در همه دستگاههای کاربر به طور همزمان انجام دهیم.
package com.google.playenterprise.example;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.batch.BatchRequest;
import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.androidenterprise.AndroidEnterprise;
import com.google.api.services.androidenterprise.AndroidEnterprise.Installs;
import com.google.api.services.androidenterprise.AndroidEnterpriseScopes;
import com.google.api.services.androidenterprise.model.Device;
import com.google.api.services.androidenterprise.model.DevicesListResponse;
import com.google.api.services.androidenterprise.model.Enterprise;
import com.google.api.services.androidenterprise.model.Install;
import com.google.api.services.androidenterprise.model.InstallsListResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Lists all the apps installed on all devices of a given user.
*/
public class ListAllInstalls {
private AndroidEnterprise enterprise;
private final List<String> installList = new ArrayList<>();
public static void main(String[] argv) throws Exception {
if (argv.length != 2) {
throw new IllegalArgumentException("Usage: ListAllInstalls email jsonFilename");
} else if (!argv[0].contains("@")) {
throw new IllegalArgumentException("First parameter should be a valid email.");
}
new ListAllInstalls().run(argv[0], argv[1]);
}
private void run(String userEmail, String jsonKeyPath) throws IOException {
enterprise = createAndroidEnterprise(jsonKeyPath);
// Get the enterprise id, user id, and user devices.
String domain = userEmail.split("@")[1];
List<Enterprise> results = enterprise.enterprises().list(domain).execute().getEnterprise();
if (results.isEmpty()) {
throw new RuntimeException("No enterprise found.");
}
String enterpriseId = results.get(0).getId();
String userId = enterprise
.users()
.list(enterpriseId, userEmail)
.execute()
.getUser()
.get(0)
.getId();
List<Device> devices = getAllDevices(enterpriseId, userId);
// Batch all calls to get installs on all user devices.
gatherAllInstalls(enterpriseId, userId, devices);
for (String entry : installList) {
// Do something.
System.out.println(entry);
}
}
private List<Device> getAllDevices(String enterpriseId, String userId) throws IOException {
DevicesListResponse devices = enterprise.devices().list(enterpriseId, userId).execute();
return devices.getDevice();
}
private void gatherAllInstalls(String enterpriseId, String userId, List<Device> devices)
throws IOException {
BatchRequest batchRequest = enterprise.batch();
for (Device device : devices) {
Installs.List list = enterprise
.installs().list(enterpriseId, userId, device.getAndroidId());
// Each callback can take the specifics of the associated request in its constructor.
list.queue(batchRequest, new InstallsCallback(device.getAndroidId()));
}
// Executes all the queued requests and their callbacks, single-threaded.
batchRequest.execute();
}
private class InstallsCallback extends JsonBatchCallback<InstallsListResponse> {
private final String androidId;
InstallsCallback(String androidId) {
this.androidId = androidId;
}
@Override
public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {
for (Install install : response.getInstall()) {
installList.add(androidId + "," + install.getProductId());
}
}
@Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
throw new RuntimeException("Error fetching a device");
}
}
private AndroidEnterprise createAndroidEnterprise(String jsonKeyPath) throws IOException {
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
InputStream is = new BufferedInputStream(new FileInputStream(jsonKeyPath));
final Credential credential = GoogleCredential.fromStream(is, httpTransport, jsonFactory)
.createScoped(AndroidEnterpriseScopes.all());
HttpRequestInitializer httpRequestInitializer = new HttpRequestInitializer() {
@Override
public void initialize(HttpRequest request) throws IOException {
credential.initialize(request);
}
};
return new AndroidEnterprise.Builder(httpTransport, jsonFactory, httpRequestInitializer)
.build();
}
}
جز در مواردی که غیر از این ذکر شده باشد،محتوای این صفحه تحت مجوز Creative Commons Attribution 4.0 License است. نمونه کدها نیز دارای مجوز Apache 2.0 License است. برای اطلاع از جزئیات، به خطمشیهای سایت Google Developers مراجعه کنید. جاوا علامت تجاری ثبتشده Oracle و/یا شرکتهای وابسته به آن است.
تاریخ آخرین بهروزرسانی 2025-05-08 بهوقت ساعت هماهنگ جهانی.
[null,null,["تاریخ آخرین بهروزرسانی 2025-05-08 بهوقت ساعت هماهنگ جهانی."],[[["\u003cp\u003eBatching API calls in the Google Play EMM API reduces overhead by combining multiple calls into a single HTTP request.\u003c/p\u003e\n"],["\u003cp\u003eThis document focuses on batch requests using the Java client library, with an example demonstrating how to list all apps installed on a user's devices.\u003c/p\u003e\n"],["\u003cp\u003eBatch requests are limited to 1000 calls and count toward usage limits as individual requests.\u003c/p\u003e\n"],["\u003cp\u003eThe server may process batched calls in any order, requiring separate requests for sequential execution.\u003c/p\u003e\n"],["\u003cp\u003eResponses to batch requests are handled by callbacks defined for each individual request within the batch.\u003c/p\u003e\n"]]],[],null,["# Send Batch Requests\n\nThis document shows how to batch API calls together to reduce the number of connections your client has to make.\n\nThis document is specifically about making a batch request using the Java client library.\nA basic example is also available in the [Google API Client Library for .NET](https://developers.google.com/api-client-library/dotnet/guide/batch). The batch system for the Google Play EMM API uses the same HTTP\nsyntax as the [OData batch processing](http://www.odata.org/documentation/odata-version-3-0/batch-processing/) system.\n\nOverview\n--------\n\nEach request that your client makes via the Google Play EMM API results in a certain amount of overhead. The Google Play EMM API supports batching, to allow your client to put several API calls into a single request.\n\nHere are some examples of situations in which you might want to use batching:\n\n- A domain has just been enrolled and now has a lot of data to upload.\n- A user made changes to data while your application was offline, so your application needs to synchronize a great deal of local data with the server.\n\nIn cases such as these, instead of sending each call separately you can group them together into a single request. You can even group requests for multiple users, or for multiple Google APIs.\n\nYou are, however, limited to 1000 calls in a single batch request. If you need to make more calls than that, use multiple batch requests.\n\nBatch details\n-------------\n\nA batch request consists of multiple API calls combined into one JSON-RPC request. This section describes the batch request syntax in detail, with an [example](#example) in the section following.\n\n**Note** : A set of \u003cvar translate=\"no\"\u003en\u003c/var\u003e requests batched together counts toward your usage limit as \u003cvar translate=\"no\"\u003en\u003c/var\u003e requests, not as one request. The batch request is taken apart into a set of requests before processing.\n\n### Format of a batch request\n\nThe Java client library contains calls to create requests for each Google Play EMM API call. For instance, to list all apps installed on a device, you would use the following: \n\n```\nAndroidEnterprise enterprise = ...;\nInstallsListResponse response = enterprise.installs().list(enterpriseId, userId, deviceId)\n .execute();\n```\n\nThere is an additional `batch()` call that can queue several requests, as seen here: \n\n```\nAndroidEnterprise enterprise = ...;\nBatchRequest batchRequest = enterprise.batch();\nenterprise.installs().list(enterpriseId, userId, deviceId1).queue(batchRequest, callback1);\nenterprise.installs().list(enterpriseId, userId, deviceId2).queue(batchRequest, callback2);\nenterprise.installs().list(enterpriseId, userId, deviceId3).queue(batchRequest, callback3);\nbatchRequest.execute();\n```\nWhen `batchRequest.execute()` is called, all the queued requests are sent at once to the server as a JSON array. The server applies the outer request's query parameters and headers (as appropriate) to each part, and then treats each part as if it were a separate JSON request.\n\n\u003cbr /\u003e\n\n### Response to a batch request\n\nThe server executes each separate request, and groups the result into single response made of a single array. The client library splits this response into individual responses, and each one is sent to the callback function passed to `queue()`. The callback is an interface defining a method for failure and a method for success. For instance, `callback1` would be implemented as an instance of the following: \n\n```\nprivate class InstallsCallback implements JsonBatchCallback\u003cInstallsListResponse\u003e {\n\n @Override\n public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {\n ...\n }\n\n @Override\n public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {\n ...\n }\n}\n```\n\n**Note**: The server may perform your calls in any order, so don't rely on receiving results in the order specified in your request. If you want to ensure that two calls occur in a given order, you can't send them in a single request; instead, send the first request by itself, and wait for a response before sending the second.\n\nExample batch request\n---------------------\n\nThe following example shows how to list all the apps installed on all of a given user devices. The first calls are used to obtain the id of the enterprise and of the user, and accordingly must be executed sequentially. Once all the device ids have been obtained with `enterprise.devices().list()`, we can do a batch request to retrieve all of the applications on all the user's devices at once. \n\n```\npackage com.google.playenterprise.example;\n\nimport com.google.api.client.auth.oauth2.Credential;\nimport com.google.api.client.googleapis.auth.oauth2.GoogleCredential;\nimport com.google.api.client.googleapis.batch.BatchRequest;\nimport com.google.api.client.googleapis.batch.json.JsonBatchCallback;\nimport com.google.api.client.googleapis.json.GoogleJsonError;\nimport com.google.api.client.http.HttpHeaders;\nimport com.google.api.client.http.HttpRequest;\nimport com.google.api.client.http.HttpRequestInitializer;\nimport com.google.api.client.http.HttpTransport;\nimport com.google.api.client.http.javanet.NetHttpTransport;\nimport com.google.api.client.json.JsonFactory;\nimport com.google.api.client.json.jackson.JacksonFactory;\nimport com.google.api.services.androidenterprise.AndroidEnterprise;\nimport com.google.api.services.androidenterprise.AndroidEnterprise.Installs;\nimport com.google.api.services.androidenterprise.AndroidEnterpriseScopes;\nimport com.google.api.services.androidenterprise.model.Device;\nimport com.google.api.services.androidenterprise.model.DevicesListResponse;\nimport com.google.api.services.androidenterprise.model.Enterprise;\nimport com.google.api.services.androidenterprise.model.Install;\nimport com.google.api.services.androidenterprise.model.InstallsListResponse;\n\nimport java.io.BufferedInputStream;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Lists all the apps installed on all devices of a given user.\n */\npublic class ListAllInstalls {\n private AndroidEnterprise enterprise;\n private final List\u003cString\u003e installList = new ArrayList\u003c\u003e();\n\n public static void main(String[] argv) throws Exception {\n if (argv.length != 2) {\n throw new IllegalArgumentException(\"Usage: ListAllInstalls email jsonFilename\");\n } else if (!argv[0].contains(\"@\")) {\n throw new IllegalArgumentException(\"First parameter should be a valid email.\");\n }\n new ListAllInstalls().run(argv[0], argv[1]);\n }\n\n private void run(String userEmail, String jsonKeyPath) throws IOException {\n enterprise = createAndroidEnterprise(jsonKeyPath);\n\n // Get the enterprise id, user id, and user devices.\n String domain = userEmail.split(\"@\")[1];\n List\u003cEnterprise\u003e results = enterprise.enterprises().list(domain).execute().getEnterprise();\n if (results.isEmpty()) {\n throw new RuntimeException(\"No enterprise found.\");\n }\n String enterpriseId = results.get(0).getId();\n String userId = enterprise\n .users()\n .list(enterpriseId, userEmail)\n .execute()\n .getUser()\n .get(0)\n .getId();\n List\u003cDevice\u003e devices = getAllDevices(enterpriseId, userId);\n\n // Batch all calls to get installs on all user devices.\n gatherAllInstalls(enterpriseId, userId, devices);\n\n for (String entry : installList) {\n // Do something.\n System.out.println(entry);\n }\n }\n\n private List\u003cDevice\u003e getAllDevices(String enterpriseId, String userId) throws IOException {\n DevicesListResponse devices = enterprise.devices().list(enterpriseId, userId).execute();\n return devices.getDevice();\n }\n\n private void gatherAllInstalls(String enterpriseId, String userId, List\u003cDevice\u003e devices)\n throws IOException {\n BatchRequest batchRequest = enterprise.batch();\n for (Device device : devices) {\n Installs.List list = enterprise\n .installs().list(enterpriseId, userId, device.getAndroidId());\n // Each callback can take the specifics of the associated request in its constructor.\n list.queue(batchRequest, new InstallsCallback(device.getAndroidId()));\n }\n // Executes all the queued requests and their callbacks, single-threaded.\n batchRequest.execute();\n }\n\n private class InstallsCallback extends JsonBatchCallback\u003cInstallsListResponse\u003e {\n private final String androidId;\n\n InstallsCallback(String androidId) {\n this.androidId = androidId;\n }\n\n @Override\n public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {\n for (Install install : response.getInstall()) {\n installList.add(androidId + \",\" + install.getProductId());\n }\n }\n\n @Override\n public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {\n throw new RuntimeException(\"Error fetching a device\");\n }\n }\n\n private AndroidEnterprise createAndroidEnterprise(String jsonKeyPath) throws IOException {\n HttpTransport httpTransport = new NetHttpTransport();\n JsonFactory jsonFactory = new JacksonFactory();\n\n InputStream is = new BufferedInputStream(new FileInputStream(jsonKeyPath));\n final Credential credential = GoogleCredential.fromStream(is, httpTransport, jsonFactory)\n .createScoped(AndroidEnterpriseScopes.all());\n\n HttpRequestInitializer httpRequestInitializer = new HttpRequestInitializer() {\n @Override\n public void initialize(HttpRequest request) throws IOException {\n credential.initialize(request);\n }\n };\n return new AndroidEnterprise.Builder(httpTransport, jsonFactory, httpRequestInitializer)\n .build();\n }\n}\n```"]]