重要資訊:我們目前不接受新的 Play EMM API 註冊。
瞭解詳情。
傳送批次要求
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
本文說明如何批次處理 API 呼叫,以減少用戶端必須建立的連線數量。
本文件專門說明如何使用 Java 用戶端程式庫提出批次要求。
你也可以在
適用於 .NET 的 Google API 用戶端程式庫。Google Play EMM API 的批次系統使用相同的 HTTP
OData 批次處理系統的語法。
總覽
您的用戶端透過 Google Play EMM API 提出的每項要求,都會造成一定程度的負擔。Google Play EMM API 支援批次作業,可讓用戶端在單一要求中加入數個 API 呼叫。
以下列舉幾個您可能想使用批次處理的情況:
- 網域剛註冊,現在有很多資料需要上傳。
- 使用者在您的應用程式離線時變更了資料,因此應用程式需要同步處理大量本機資料與伺服器。
在這種情況下,您不必逐一傳送通話,只要把這些通話整合成單一要求即可。您甚至可以將多個使用者或多個 Google API 的要求分組。
不過,單一批次要求最多可包含 1,000 個呼叫。如果您需要進行更多呼叫,請使用多個批次要求。
批次詳細資料
批次要求是由多個 API 呼叫合併成一個 JSON-RPC 要求。本節詳細說明批次要求語法,並在下一節中使用範例。
注意:一組批次處理的 n 要求將計入用量限制,並計為 n 要求,而非單一要求。處理之前,批次要求會分成一組要求。
Java 用戶端程式庫內含用來為每個 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 要求。
回應批次要求
伺服器會執行每個個別的要求,並將結果分組成由單一陣列產生的單一回應。用戶端程式庫會將此回應分割成個別回應,每個回應都會傳送至傳遞至 queue()
的回呼函式。回呼是用於定義失敗方法和成功方法的介面。舉例來說,callback1
會實作為以下例項:
private class InstallsCallback implements JsonBatchCallback<InstallsListResponse> {
@Override
public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {
...
}
@Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
...
}
}
注意:伺服器可能會按任意順序執行呼叫,因此請勿按照要求中指定的順序接收結果。如果您想確保兩次呼叫按照指定順序發生,則不能在單一要求中傳送這些呼叫;而是先傳送第一個要求,然後等待回應再傳送第二個要求。
批次要求範例
以下範例說明如何列出安裝在所有特定使用者裝置上的所有應用程式。第一個呼叫是用來取得企業和使用者的 ID,因此必須依序執行。透過 enterprise.devices().list()
取得所有裝置 ID 後,就可以執行批次要求,同時擷取使用者所有裝置中的所有應用程式。
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();
}
}
除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 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```"]]