EMM 整合指南

這份指南可協助企業行動管理服務 (EMM) 供應商整合 透過控制台執行零接觸註冊機制。 請繼續閱讀,進一步瞭解註冊流程,並查看最佳做法建議, 以便佈建裝置。如果你有 DPC 您將瞭解佈建裝置的最佳做法及取得相關建議 持續開發及測試產品

IT 管理員專屬功能

使用客戶 API,讓 IT 管理員直接在以下位置設定零接觸註冊機制: 管理控制台。以下是 IT 管理員可在控制台中完成的部分工作:

  • 根據下列資料,建立、編輯及刪除零接觸註冊機制設定 行動裝置政策。
  • 選取預設設定,讓 DPC 在未來佈建任何裝置 機構的購買交易
  • 為裝置套用個別設定,或從零接觸註冊機制移除裝置 。

如要進一步瞭解零接觸註冊機制,請參閱 簡介

必要條件

在 EMM 控制台中新增零接觸註冊機制前,請先確認 解決方案支援下列項目:

  • 您的 EMM 解決方案需要佈建公司擁有的 Android 8.0 以上版本 (Pixel 7.1 以上版本) 裝置處於全代管模式公司擁有的 Android 10 以上版本裝置 全代管或工作資料夾
  • 零接觸註冊機制會自動下載並安裝 DPC, DPC 平台必須在 Google Play 上架。我們備有相容 DPC 清單 IT 管理員可透過客戶 API 或入口網站進行設定提交 透過 EMM 供應商社群提出的產品修改要求 將 DPC 加入清單。
  • 您的客戶需要零接觸註冊機制帳戶才能呼叫客戶 API。 在以下情況下,合作夥伴經銷商會為 IT 管理員的機構設定帳戶 機構購買自己的裝置。
  • 裝置必須與 Google 行動服務 (GMS) 相容 必須隨時啟用 Google Play 服務,才能採用零接觸註冊機制 才能正常運作

呼叫 API

控制台的使用者 (使用他們的 Google 帳戶) 可將您的 API 要求授權給 客戶 API此流程與您為其執行的授權程序不同 和其他 EMM API 搭配使用請參閱「授權」,瞭解如何在應用程式中執行這項作業。

處理《服務條款》

使用者必須在以下日期前接受最新的《服務條款》 (ToS) 呼叫 API如果 API 呼叫傳回 HTTP 403 Forbidden 狀態碼, 回應主體包含 TosError,提示使用者接受 登入零接觸註冊機制入口網站取得《服務條款》。以下範例 示範其中一種做法:

Java

// Authorize this method call as a user that hasn't yet accepted the ToS.
final String googleApiFormatHttpHeader = "X-GOOG-API-FORMAT-VERSION";
final String googleApiFormatVersion = "2";
final String tosErrorType =
      "type.googleapis.com/google.android.device.provisioning.v1.TosError";

try {
  // Send an API request to list all the DPCs available including the HTTP header
  // X-GOOG-API-FORMAT-VERSION with the value 2. Import the  exception:
  // from googleapiclient.errors import HttpError
  AndroidProvisioningPartner.Customers.Dpcs.List request =
        service.customers().dpcs().list(customerAccount);
  request.getRequestHeaders().put(googleApiFormatHttpHeader, googleApiFormatVersion);
  CustomerListDpcsResponse response = request.execute();
  return response.getDpcs();

} catch (GoogleJsonResponseException e) {
  // Get the error details. In your app, check details exists first.
  ArrayList<Map> details = (ArrayList<Map>) e.getDetails().get("details");
  for (Map detail : details) {
    if (detail.get("@type").equals(tosErrorType)
          && (boolean) detail.get("latestTosAccepted") != true) {
      // Ask the user to accept the ToS. If they agree, open the portal in a browser.
      // ...
    }
  }
  return null;
}

.NET

// Authorize this method call as a user that hasn't yet accepted the ToS.
try
{
    var request = service.Customers.Dpcs.List(customerAccount);
    CustomerListDpcsResponse response = request.Execute();
    return response.Dpcs;
}
catch (GoogleApiException e)
{
    foreach (SingleError error in e.Error?.Errors)
    {
        if (error.Message.StartsWith("The user must agree the terms of service"))
        {
            // Ask the user to accept the ToS. If they agree, open the portal in a browser.
            // ...
        }
    }
}

Python

# Authorize this method call as a user that hasn't yet accepted the ToS.
tos_error_type = ('type.googleapis.com/'
                  'google.android.device.provisioning.v1.TosError')
portal_url = 'https://partner.android.com/zerotouch'

# Send an API request to list all the DPCs available including the HTTP
# header X-GOOG-API-FORMAT-VERSION with the value 2. Import the exception:
# from googleapiclient.errors import HttpError
try:
  request = service.customers().dpcs().list(parent=customer_account)
  request.headers['X-GOOG-API-FORMAT-VERSION'] = '2'
  response = request.execute()
  return response['dpcs']

except HttpError as err:
  # Parse the JSON content of the error. In your app, check ToS exists first.
  error = json.loads(err.content)
  tos_error = error['error']['details'][0]

  # Ask the user to accept the ToS (not shown here). If they agree, then open
  # the portal in a browser.
  if (tos_error['@type'] == tos_error_type
      and tos_error['latestTosAccepted'] is not True):
    if raw_input('Accept the ToS in the zero-touch portal? y|n ') == 'y':
      webbrowser.open(portal_url)

如果您的 Google API 用戶端支援詳細錯誤 (Java、Python 或 HTTP) 要求) 中,請納入 HTTP 標頭 X-GOOG-API-FORMAT-VERSION 並搭配 2。如果您的用戶端不支援詳細錯誤 (.NET 和 其他) 時,比對錯誤訊息。

日後更新《服務條款》時,如果您採用這種做法,您的應用程式 引導使用者重新接受新的《服務條款》。

IT 管理員使用零接觸註冊機制入口網站,為 — 您無法透過客戶 API 提供這項服務。IT 管理員也可以 透過入口網站管理裝置和設定。如果您要連結至 入口網站,請使用這個網址:

https://partner.android.com/zerotouch

建議您通知 IT 管理員,系統提示他們登入 Google 帳戶。

裝置註冊

零接觸註冊機制是一種註冊裝置機制,就像 NFC 註冊或 QR code 註冊您的控制台必須支援受管理的裝置 ,你的 DPC 必須能夠以全代管裝置模式執行。

零接觸註冊機制適用於搭載 Android 8.0 或 IT 管理員必須向合作夥伴購買支援的裝置 經銷商。您的控制台可追蹤 以下日期前,IT 管理員的裝置支援零接觸註冊機制: 呼叫 customers.devices.list

以下簡要說明註冊的運作方式:

  1. 裝置在首次啟動時 (或出廠後) 與 Google 伺服器進行檢查 。
  2. 如果 IT 管理員已為裝置套用設定,零接觸 註冊會執行全代管裝置 Android 設定精靈, 含有設定中繼資料的畫面
  3. 零接觸註冊機制會從 Google Play 下載並安裝 DPC。
  4. DPC 會收到 ACTION_PROVISION_MANAGED_DEVICE 意圖和 佈建裝置。

如果沒有網際網路連線,系統會在裝置連線時進行檢查 廣告。如要進一步瞭解如何透過零接觸註冊機制佈建裝置, 請參閱下方的佈建

預設設定

在 IT 管理員調整預設設定時,零接觸註冊機制最為實用 (適用於機構購買的任何新裝置)。宣傳設定 視需要調整控制台的預設設定。如要查看 將 customers.configurations.isDefault 的值改為 確認機構是否已有預設設定。

以下範例說明如何將現有設定 預設:

Java

// Send minimal data with the request. Just the 2 required fields.
// targetConfiguration is an existing configuration that we want to make the default.
Configuration configuration = new Configuration();
configuration.setIsDefault(true);
configuration.setConfigurationId(targetConfiguration.getConfigurationId());

// Call the API, including the FieldMask to avoid setting other fields to null.
AndroidProvisioningPartner.Customers.Configurations.Patch request = service
      .customers()
      .configurations()
      .patch(targetConfiguration.getName(), configuration);
request.setUpdateMask("isDefault");
Configuration results = request.execute();

.NET

// Send minimal data with the request. Just the 2 required fields.
// targetConfiguration is an existing configuration that we want to make the default.
Configuration configuration = new Configuration
{
    IsDefault = true,
    ConfigurationId = targetConfiguration.ConfigurationId,
};

// Call the API, including the FieldMask to avoid setting other fields to null.
var request = service.Customers.Configurations.Patch(configuration,
                                                     targetConfiguration.Name);
request.UpdateMask = "IsDefault";
Configuration results = request.Execute();

Python

# Send minimal data with the request. Just the 2 required fields.
# target_configuration is an existing configuration we'll make the default.
configuration = {
    'isDefault': True,
    'configurationId': target_configuration['configurationId']}

# Call the API, including the FieldMask to avoid setting other fields to null.
response = service.customers().configurations().patch(
    name=target_configuration['name'],
    body=configuration, updateMask='isDefault').execute()

參照裝置政策控制器 (DPC)

建議使用 API 資源名稱:customers.dpcs.name ,並在設定中使用 DPC。資源名稱包含 DPC 的專屬與不變 ID。致電 customers.dpcs.list 取得所有支援項目的清單 裝置政策控制器 (DPC)。由於資源名稱也包含客戶 ID,請篩選清單 使用最後一個路徑元件尋找相符的 Dpc 例項。範例 下方示範的是如何比對 DPC,以供日後用於 設定:

Java

// Return a customer Dpc instance for the specified DPC ID.
String myDpcIdentifier = "AH6Gbe4aiS459wlz58L30cqbbXbUa_JR9...xMSWCiYiuHRWeBbu86Yjq";
final int dpcIdIndex = 3;
final String dpcComponentSeparator = "/";
// ...
for (Dpc dpcApp : dpcs) {
    // Because the DPC name is in the format customers/{CUST_ID}/dpcs/{DPC_ID}, check the
    // fourth component matches the DPC ID.
    String dpcId = dpcApp.getName().split(dpcComponentSeparator)[dpcIdIndex];
    if (dpcId.equals(myDpcIdentifier)) {
        System.out.format("My DPC is: %s\n", dpcApp.getDpcName());
        return dpcApp;
    }
}
// Handle the case when the DPC isn't found...

.NET

// Return a customer Dpc instance for the specified DPC ID.
var myDpcIdentifer = "AH6Gbe4aiS459wlz58L30cqbbXbUa_JR9...fE9WdHcxMSWCiYiuHRWeBbu86Yjq";
const int dpcIdIndex = 3;
const String dpcComponentSeparator = "/";
// ...
foreach (Dpc dpcApp in dpcs)
{
    // Because the DPC name is in the format customers/{CUST_ID}/dpcs/{DPC_ID}, check the
    // fourth component matches the DPC ID.
    String dpcId = dpcApp.Name.Split(dpcComponentSeparator)[dpcIdIndex];
    if (dpcId.Equals(myDpcIdentifer))
    {
        Console.WriteLine("Matched DPC is: {0}", dpcApp.DpcName);
        return dpcApp;
    }
}
// Handle the case when the DPC isn't found...

Python

# Return a customer Dpc instance for the specified DPC ID.
my_dpc_id = 'AH6Gbe4aiS459wlz58L30cqb...fE9WdHcxMSWCiYiuHRWeBbu86Yjq'
# ...
for dpc_app in dpcs:
  # Because the DPC name is in the format customers/{CUST_ID}/dpcs/{DPC_ID},
  # check the fourth component matches the DPC ID.
  dpc_id = dpc_app['name'].split('/')[3]
  if dpc_id == my_dpc_id:
    return dpc_app

# Handle the case when the DPC isn't found...

如果您需要在控制台使用者介面中顯示 DPC 名稱,請在 customers.dpcs.dpcName 傳回的值。

佈建中

請趁此機會提供優質的裝置佈建體驗。 使用者名稱和密碼應包含佈建裝置所需的所有使用者名稱和密碼。 提醒您,經銷商可能會將裝置直接提供給遠端使用者。包含 所有其他設定,例如 EMM 伺服器或機構單位 customers.configuration.dpcExtras

下列 JSON 程式碼片段為設定範例的一部分:

{
  "android.app.extra.PROVISIONING_LOCALE": "en_GB",
  "android.app.extra.PROVISIONING_TIME_ZONE": "Europe/London",
  "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED": true,
  "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE": {
    "workflow_type": 3,
    "default_password_quality": 327680,
    "default_min_password_length": 6,
    "company_name": "XYZ Corp",
    "organizational_unit": "sales-uk",
    "management_server": "emm.example.com",
    "detail_tos_url": "https://www.example.com/policies/terms/",
    "allowed_user_domains": "[\"example.com\", \"example.org\", \"example.net\"]"
    }
}

零接觸註冊機制會使用 Android 意圖安裝並啟動 DPC。 系統會傳送 連結至 DPC 的 android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE JSON 屬性 當做額外項目您的 DPC 可透過 PersistableBundle 使用相同金鑰。

建議:請使用下列意圖額外項目 設定裝置政策控制器:

不建議使用,請勿加入以下屬性 可能用於其他註冊方法的額外功能:

如要瞭解如何在 DPC 中擷取及使用這些設定,請參閱佈建 客戶的裝置

開發和測試

如要開發及測試控制台的零接觸註冊機制功能, 包括:

  • 支援的裝置
  • 客戶零接觸註冊機制帳戶

開發及測試支援零接觸機制的裝置 註冊,例如 Google Pixel。您不一定要 向經銷商合作夥伴購買您的開發裝置

與我們聯絡,取得測試客戶帳戶並存取 零接觸註冊機制入口網站。請透過以下電子郵件地址使用貴公司的電子郵件地址: 與 Google 。告訴我們製造商 以及一兩部裝置的 IMEI 號碼,我們會將這些裝置加入 讓他們使用服務帳戶

提醒您,由於零接觸註冊機制會自動下載並安裝 DPC,必須先在 Google Play 下載 DPC,才能進行測試 佈建工作您無法使用 DPC 開發版本進行測試。

IT 管理員支援服務

如需透過控制台介面或說明文件協助 IT 管理員 如需相關指引,請參閱「適用於 IT 管理員的零接觸註冊機制」。個人中心 也可以引導控制台使用者參閱該篇說明中心文章。

延伸閱讀

請參閱這些文件,瞭解如何將零接觸註冊機制整合至 主控台: