Android Developer Console API

Android 開發人員控制台 API 是一項 RESTful 服務,可讓通過驗證的開發人員在 Android 開發人員控制台中自動執行 Android 開發人員驗證工作流程,包括擷取開發人員帳戶、檢查金鑰資格規定、註冊 Android 套件名稱、註冊應用程式簽署金鑰,以及驗證金鑰擁有權。

總覽、用途和實作背景資訊

主要用途和功能

  • 自動化 CI/CD 套件名稱註冊:透過程式輔助方式 (CreateAndroidPackage) 註冊數十或數百個 Android 套件名稱。
  • 預先檢查歷史金鑰政策:透過程式輔助方式,檢查 Google 先前是否曾在生態系統中觀察到套件名稱,以及註冊特定簽署憑證是否需要驗證金鑰擁有權 (GetAndroidPackageRegistrationPolicy)。
  • 自動註冊應用程式簽署金鑰及驗證擁有權:註冊公開簽署憑證 SHA-256 指紋 (CreateAndroidPackageKey)、擷取不重複的驗證驗證權杖 (verificationToken),並使用單一要求或可續傳的已簽署 APK 上傳作業 (VerifyAndroidPackageKeyOwnership),自動驗證私密金鑰擁有權。
  • 以程式輔助方式提交理由:提交擁有權理由 (JustifyAndroidPackageKeyRegistration)。
  • 狀態監控:監控開發人員帳戶、套件名稱和應用程式簽署金鑰的註冊狀態 (GetDeveloperAccount、ListDeveloperAccounts、GetAndroidPackage、ListAndroidPackages、GetAndroidPackageKey、ListAndroidPackageKeys)。

端對端導入工作流程

  1. 在使用者介面中驗證開發人員身分一次:在 Android 開發人員控制台完成開發人員身分驗證 (INDIVIDUAL 或 ORGANIZATION),讓 verificationState 變成 VERIFIED。
  2. 啟用 API 並驗證:在 Google Cloud 雲端專案中啟用 androiddeveloperconsole.googleapis.com,並取得範圍為 https://www.googleapis.com/auth/androiddeveloperconsole 的使用者委派 OAuth 2.0 Bearer 存取權杖。
  3. 找出開發人員帳戶資源名稱:呼叫 GET /v1/developerAccounts (ListDeveloperAccounts) 擷取 developerAccounts/{developer_account},並確認 verificationState 為 VERIFIED。
  4. 檢查套件名稱的註冊政策:呼叫 GET /v1/developerAccounts/{id}/androidPackages/{pkg}/registrationPolicy (GetAndroidPackageRegistrationPolicy) 檢查 keySelectionStrategy (SELECT_KEY_FROM_LIST 或 USE_ANY_KEY) 和任何已知的歷來簽署金鑰 (knownKeys)。
  5. 建立 Android 套件資源:使用主體 {"name": ""} 呼叫 POST /v1/developerAccounts/{id}/androidPackages?androidPackageId={pkg} (CreateAndroidPackage) (在 DRAFT 狀態中建立資源)。
  6. 註冊應用程式簽署金鑰指紋:使用 JSON 主體 {"certificateFingerprintSha256": "..."} 呼叫 POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys (CreateAndroidPackageKey)。檢查傳回的狀態:
    • DRAFT:必須提供私密金鑰擁有權證明,回應中會包含步驟 7 的專屬 verificationToken。
    • IN_REVIEW:系統會自動略過擁有權證明和理由說明 (例如註冊 Android 上從未出現過的新套件名稱,或您已驗證同一 DeveloperAccount 中其他套件名稱的這個簽署金鑰擁有權)。請略過步驟 7 和步驟 8 的理由說明呼叫,直接輪詢 GetAndroidPackage 和 GetAndroidPackageKey。
  7. 建構並上傳驗證 APK (如果狀態為 DRAFT):將傳回的 verificationToken 字串嵌入 assets/adi-registration.properties,並放入符合 packageName 的最小 APK 中,然後使用私密應用程式簽署金鑰簽署,並透過 POST /upload/v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:verify (VerifyAndroidPackageKeyOwnership) 上傳。
  8. 提交理由 (如有需要) 並輪詢註冊狀態:如果金鑰處於 OWNERSHIP_VERIFIED 狀態,且 registrationJustificationRequired 為 true,請呼叫 POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration)。輪詢 GetAndroidPackage 和 GetAndroidPackageKey,直到 state 達到 REGISTERED。

用於準備金鑰指紋和驗證 APK 的本機 CLI 指令

  • 從 KeyStore (keytool) 擷取 SHA-256 憑證指紋:

    keytool -list -v -keystore release-key.jks -alias my-key-alias
  • 驗證已建構 APK (apksigner) 的 SHA-256 簽署憑證摘要:

    apksigner verify --print-certs app-release.apk
  • 上傳前,請檢查 APK 套件名稱和內嵌權杖檔案 (aapt2 和 unzip):

    aapt2 dump badging app-release.apk | head -n 1
    unzip -p app-release.apk assets/adi-registration.properties

Android 開發人員控制台 UI 和 API 功能

工作 Android 開發人員控制台網頁 UI (android.google.com/developerconsole) Android Developer Console API
開發人員身分驗證 (KYC/KYB) 和費用支付 支援 (須滿足一次性必要條件) 不支援使用 API (使用 GetDeveloperAccount 和 ListDeveloperAccounts 檢查唯讀狀態)
查看已連結的開發人員帳戶 控制台標頭中的帳戶切換器 GET /v1/developerAccounts (ListDeveloperAccounts)
檢查套件名稱的歷來簽署金鑰和政策 在「註冊套件名稱」精靈中顯示 GET /v1/.../registrationPolicy (GetAndroidPackageRegistrationPolicy)
註冊新的 Android 套件名稱 「套件名稱」 >「註冊套件名稱」 POST /v1/{parent}/androidPackages?androidPackageId=... (CreateAndroidPackage)
查看或列出已註冊和草稿套件名稱 「套件名稱」資訊主頁表格 GET /v1/{name} (GetAndroidPackage),GET /v1/{parent}/androidPackages (ListAndroidPackages)
新增應用程式簽署金鑰並產生驗證權杖 「Package detail」(套件詳細資料) >「Add signing key」(新增簽署金鑰) POST /v1/{parent}/keys (CreateAndroidPackageKey)
證明私密金鑰擁有權 (adi-registration.properties) 在控制台 UI 中上傳已簽署的程式碼片段 APK POST /upload/v1/{name}:verify (VerifyAndroidPackageKeyOwnership)
金鑰需要人工審查時提交理由 金鑰註冊工作流程中的文字提示詞 POST /v1/{name}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration)

服務設定和驗證

所有 API 要求都必須使用 HTTPS,並包含透過 OAuth 2.0 網路伺服器流程取得的 Authorization: Bearer ACCESS_TOKEN 標頭,用於已在 Android 開發人員控制台完成開發人員身分驗證的 Google 帳戶。

屬性 值
基本 REST 端點 https://androiddeveloperconsole.googleapis.com
媒體上傳端點 https://androiddeveloperconsole.googleapis.com/upload
API 版本 v1
必要的 OAuth 2.0 範圍 https://www.googleapis.com/auth/androiddeveloperconsole
預設配額限制 每個 Google Cloud 雲端專案每種方法每天 2,000 項要求

API 資源和端點

Android 開發人員控制台 API 會按照下列階層組織資源:

  • DeveloperAccount (developerAccounts/{developer_account})
    • AndroidPackage (developerAccounts/{developer_account}/androidPackages/{android_package})
      • AndroidPackageRegistrationPolicy (developerAccounts/{developer_account}/androidPackages/{android_package}/registrationPolicy)
      • AndroidPackageKey (developerAccounts/{developer_account}/androidPackages/{android_package}/keys/{key})

資源:DeveloperAccount

代表 Android 開發人員控制台中與開發人員身分相關聯的帳戶。

欄位 類型 說明
name string ID。資源名稱格式為 developerAccounts/{developer_account}。
displayName string 僅供輸出。與開發人員帳戶相關聯的人類可讀名稱 (個人或機構名稱)。
verificationState enum (VerificationState) 僅供輸出。帳戶目前的開發人員身分驗證狀態。

列舉:DeveloperAccount.VerificationState

值 說明
VERIFIED 開發人員身分驗證已完成。該帳戶可以註冊套件名稱和應用程式簽署金鑰。
NOT_VERIFIED 尚未在 Android 開發人員控制台完成開發人員身分驗證。

方法:DeveloperAccount

方法 HTTP 要求 說明
GetDeveloperAccount GET /v1/{name=developerAccounts/*} 擷取單一DeveloperAccount的中繼資料和驗證狀態。
ListDeveloperAccounts GET /v1/developerAccounts 列出已驗證 Google 帳戶可存取的所有 DeveloperAccount 物件 (未分頁)。

資源:AndroidPackage

代表已在 DeveloperAccount 下註冊或正在註冊的 Android 套件名稱。

欄位 類型 說明
name string ID。資源名稱格式為 developerAccounts/{developer_account}/androidPackages/{android_package},其中 {android_package} 是 Android 套件名稱 (例如 com.example.myapp)。
packageName string 僅供輸出。Android 套件名稱 (例如 com.example.myapp)。
state enum (AndroidPackage.State) 僅供輸出。套件名稱目前的註冊生命週期狀態。
registeredAppStore boolean 僅供輸出。指出這個套件名稱目前是否已註冊為應用程式商店。

列舉:AndroidPackage.State

值 說明
DRAFT 套件名稱資源已建立,應用程式簽署金鑰註冊或擁有權驗證程序仍在進行中。
IN_REVIEW 套件名稱註冊資訊和任何必要的金鑰理由說明已提交,Google 正在審查中。套件會在 CreateAndroidPackageKey 後立即從 DRAFT 轉換為 IN_REVIEW (略過金鑰擁有權驗證時,包括金鑰已在相同 DeveloperAccount 中驗證其他套件名稱),或在完成 VerifyAndroidPackageKeyOwnership 後轉換,並視需要完成 JustifyAndroidPackageKeyRegistration。
REGISTERED 套件名稱已註冊至這個開發人員帳戶,用於 Android 開發人員驗證。
PENDING_TRANSFER 套件名稱正在等待擁有權轉移至其他開發人員帳戶。

資源:AndroidPackageRegistrationPolicy

GetAndroidPackageRegistrationPolicy 傳回的單例模式資源,說明系統偵測到套件名稱的歷來公開簽署金鑰,以及使用特定簽署金鑰註冊套件名稱時,是否需要提供書面理由。

欄位 類型 說明
name string ID。資源名稱格式為 developerAccounts/{developer_account}/androidPackages/{android_package}/registrationPolicy。
knownKeys[] object (KnownKey) 先前用於發布此套件名稱應用程式的應用程式簽署金鑰清單,依 certificateFingerprintSha256 字母順序排列。
knownKeys[].certificateFingerprintSha256 string 僅供輸出。歷來簽署憑證的標準化 64 字元小寫十六進位 SHA-256 指紋 (不含冒號)。
knownKeys[].justificationRequirement enum (JustificationRequirement) 僅供輸出。指出註冊這組金鑰時,是否需要呼叫 JustifyAndroidPackageKeyRegistration (REQUIRED 或 NOT_REQUIRED)。如果簽署金鑰先前已在相同 DeveloperAccount 下的其他套件名稱上驗證,即使 justificationRequirement 為 REQUIRED,系統也會略過 VerifyAndroidPackageKeyOwnership 和 JustifyAndroidPackageKeyRegistration。
keySelectionStrategy enum (KeySelectionStrategy) 僅供輸出。註冊這個套件名稱的金鑰選取政策:SELECT_KEY_FROM_LIST (必須註冊 knownKeys 的金鑰) 或 USE_ANY_KEY (可註冊開發人員擁有的任何有效應用程式簽署金鑰)。

列舉:KnownKey.JustificationRequirement

值 說明
REQUIRED 如要註冊這個已知金鑰,請先完成VerifyAndroidPackageKeyOwnership,再透過JustifyAndroidPackageKeyRegistration提交書面理由 (如果金鑰先前已在同一個DeveloperAccount下的其他套件名稱上通過驗證,則可略過VerifyAndroidPackageKeyOwnership和JustifyAndroidPackageKeyRegistration)。
NOT_REQUIRED 註冊這個已知金鑰時,不需提供理由。金鑰會在 VerifyAndroidPackageKeyOwnership 後直接轉換為 IN_REVIEW (如果金鑰先前已在相同 DeveloperAccount 下的其他套件名稱上驗證,則會在 CreateAndroidPackageKey 後立即轉換)。

Enum: AndroidPackageRegistrationPolicy.KeySelectionStrategy

值 說明
SELECT_KEY_FROM_LIST 呼叫端必須註冊 knownKeys 中列出的其中一個歷來金鑰。
USE_ANY_KEY 除了 knownKeys 中的任何金鑰外,呼叫端也可以註冊先前未在 Android 生態系統中觀察到的任何有效應用程式簽署金鑰。

方法:AndroidPackage

方法 HTTP 要求 說明
GetAndroidPackageRegistrationPolicy GET /v1/{name=developerAccounts/*/androidPackages/*/registrationPolicy} 擷取套件名稱的金鑰選取策略和已知歷來簽署金鑰。
CreateAndroidPackage POST /v1/{parent=developerAccounts/*}/androidPackages?androidPackageId={package_name} 在 DRAFT 狀態下建立新的 AndroidPackage 資源,開始註冊套件名稱。
GetAndroidPackage GET /v1/{name=developerAccounts/*/androidPackages/*} 擷取現有 AndroidPackage 的詳細資料和目前註冊狀態。
ListAndroidPackages GET /v1/{parent=developerAccounts/*}/androidPackages 列出 DeveloperAccount 下的 AndroidPackage 物件 (pageSize,最多 1000,pageToken)。

資源:AndroidPackageKey

代表與 AndroidPackage 相關聯的公開應用程式簽署憑證指紋,並追蹤擁有權驗證和註冊審查狀態。

欄位 類型 說明
name string ID。伺服器指派的資源名稱,格式為 developerAccounts/{developer_account}/androidPackages/{android_package}/keys/{key},其中 {key} 是標準化的 64 個字元小寫十六進位 SHA-256 指紋,不含冒號。呼叫 CreateAndroidPackageKey 時,必須省略或留空。
certificateFingerprintSha256 string 必要項目。不可變動。應用程式簽署憑證的 SHA-256 雜湊。在 CreateAndroidPackageKey 中輸入時,接受純 64 字元十六進位 (60e860e8...) 或以半形冒號分隔的十六進位 (60:E8:60:E8:...)。輸出時,一律正規化為 64 字元小寫十六進位,不含半形冒號。
state enum (AndroidPackageKey.State) 僅供輸出。金鑰目前的驗證和註冊生命週期狀態。
verificationToken string 僅供輸出。Google 產生的專屬驗證問題權杖。只有在狀態為 DRAFT 時才會使用 (如果 CreateAndroidPackageKey 直接將金鑰轉換為 IN_REVIEW,則可忽略)。當狀態為 DRAFT 時,請將這個字串嵌入已簽署 APK 的 assets/adi-registration.properties 中,以完成 VerifyAndroidPackageKeyOwnership。
registrationJustificationRequired boolean 僅供輸出。如果 true 且金鑰處於 OWNERSHIP_VERIFIED 狀態,您必須先使用 JustifyAndroidPackageKeyRegistration 提交書面理由,才能繼續註冊 IN_REVIEW。如果 CreateAndroidPackageKey 直接將金鑰轉換為 IN_REVIEW (因為金鑰先前已在相同 DeveloperAccount 的其他套件名稱上驗證),則會略過理由。

列舉:AndroidPackageKey.State

值 說明
DRAFT 金鑰資源已建立,但仍須上傳已簽署的 APK (VerifyAndroidPackageKeyOwnership) 來證明您擁有私密金鑰,因為這個金鑰的擁有權尚未在這個 DeveloperAccount 的任何套件名稱上完成驗證。
OWNERSHIP_VERIFIED 已透過上傳已簽署的 APK 驗證私密金鑰擁有權。如果 registrationJustificationRequired 為 true,則仍須提供理由,才能開始審查。
IN_REVIEW Google 正在審查金鑰註冊。金鑰會在此階段轉換,轉換時間點可能是在 CreateAndroidPackageKey 後立即進行 (如果不需要擁有權證明,例如 Android 上從未出現過的新套件名稱,或金鑰先前已在同一 DeveloperAccount 下的其他套件名稱上驗證過,這也會略過 JustifyAndroidPackageKeyRegistration)、在 VerifyAndroidPackageKeyOwnership 後直接進行 (如果 registrationJustificationRequired 為 false),或在 JustifyAndroidPackageKeyRegistration 後進行 (如果 registrationJustificationRequired 為 true)。
REGISTERED 應用程式簽署金鑰已註冊到這個套件名稱,用於 Android 開發人員驗證。
PENDING_TRANSFER 應用程式簽署金鑰註冊程序正在等待轉移完成。

方法:AndroidPackageKey

方法 HTTP 要求 說明
CreateAndroidPackageKey POST /v1/{parent=developerAccounts/*/androidPackages/*}/keys 在 AndroidPackage 下註冊新的應用程式簽署憑證 SHA-256 指紋。傳回處於 DRAFT 狀態的金鑰 (需要使用 VerifyAndroidPackageKeyOwnership 證明擁有權時),或直接傳回處於 IN_REVIEW 狀態的金鑰 (略過擁有權驗證時,例如 Android 上從未出現過的新套件名稱,或已在相同 DeveloperAccount 中其他套件名稱上驗證的金鑰)。
GetAndroidPackageKey GET /v1/{name=developerAccounts/*/androidPackages/*/keys/*} 擷取特定 AndroidPackageKey 的狀態、指紋和驗證中繼資料。
ListAndroidPackageKeys GET /v1/{parent=developerAccounts/*/androidPackages/*}/keys 列出在 AndroidPackage 下註冊的所有 AndroidPackageKey 物件 (pageSize 最大 1000,pageToken)。
VerifyAndroidPackageKeyOwnership POST /upload/v1/{name=developerAccounts/*/androidPackages/*/keys/*}:verify 上傳已簽署的最小 APK,其中包含 assets/adi-registration.properties 中的 verificationToken,以驗證私密金鑰擁有權,並提交準備好的金鑰以供審查。
JustifyAndroidPackageKeyRegistration POST /v1/{name=developerAccounts/*/androidPackages/*/keys/*}:justifyAndroidPackageKeyRegistration 當 registrationJustificationRequired 為 true 時,提交額外的理由背景資訊,並提交已驗證的金鑰以供審查。

處理錯誤

API 要求失敗時,Android 開發人員控制台 API 會傳回 HTTP 4xx 或 5xx 狀態碼,以及標準 google.rpc.Status JSON 錯誤主體:

{
  "error": {
    "code": 400,
    "message": "Invalid certificate fingerprint SHA256 format.",
    "status": "INVALID_ARGUMENT",
    "details": []
  }
}

HTTP 狀態碼和常見解決方法

HTTP 代碼 gRPC 狀態 常見原因 解析度
400 Bad Request INVALID_ARGUMENT 缺少或無效的 Java 樣式 androidPackageId;無效的 certificateFingerprintSha256 格式;CreateAndroidPackage 或 CreateAndroidPackageKey 上的 name 欄位非空白;上傳的 APK 未簽署、損毀、缺少 assets/adi-registration.properties、缺少相符的 verificationToken,或使用不相符的憑證簽署。 請根據資源結構定義驗證要求格式,在建立呼叫時省略或清空 name,並在上傳前使用 apksigner verify --print-certs 和 unzip -p app-release.apk assets/adi-registration.properties 驗證 APK 簽章和內嵌權杖。
400 Bad Request FAILED_PRECONDITION DeveloperAccount 具有 verificationState: NOT_VERIFIED;金鑰選取違反 AndroidPackageRegistrationPolicy (SELECT_KEY_FROM_LIST);在不符合資格的狀態下呼叫 VerifyAndroidPackageKeyOwnership 或 JustifyAndroidPackageKeyRegistration。 請在 Android 開發人員控制台完成開發人員身分驗證,先查看 GetAndroidPackageRegistrationPolicy,並檢查資源目前的state。
401 Unauthorized UNAUTHENTICATED 缺少 OAuth 2.0 Bearer 存取權杖、權杖已過期或無效,或嘗試使用 API 金鑰或服務帳戶進行驗證。 取得新的使用者委派 OAuth 2.0 不記名存取權杖,範圍為 https://www.googleapis.com/auth/androiddeveloperconsole。
403 Forbidden PERMISSION_DENIED 已驗證的使用者缺少目標 DeveloperAccount 或 AndroidPackage 的權限,或 Google Cloud 專案未啟用 Android Developer Console API。 使用 ListDeveloperAccounts 驗證帳戶成員資格,並確認已在 Google Cloud 控制台中啟用 androiddeveloperconsole.googleapis.com。
404 Not Found NOT_FOUND 找不到指定的 DeveloperAccount、AndroidPackage 或 AndroidPackageKey 資源路徑。 使用 ListDeveloperAccounts、ListAndroidPackages 或 ListAndroidPackageKeys 確認資源路徑。確認 {key} ID 使用小寫十六進位值,且不含冒號。
409 Conflict ALREADY_EXISTS 套件名稱或 SHA-256 憑證指紋已在這個或其他開發人員帳戶註冊。 使用 GetAndroidPackage 或 GetAndroidPackageKey 檢查現有註冊資訊,或使用 GetAndroidPackageRegistrationPolicy 查看歷來擁有權。
429 Too Many Requests RESOURCE_EXHAUSTED 超過每個 Google Cloud 雲端專案每天 2,000 次要求的方法配額。 實作指數輪詢 (含隨機抖動),並避免高頻率輪詢迴圈。
500/503 INTERNAL/UNAVAILABLE 暫時性後端錯誤或服務暫時無法使用。 以部分指數輪詢方式重試冪等要求。

HTTP 要求和回應範例

將 ACCESS_TOKEN、1234567890、com.example.myapp 和 60e860e8... 等預留位置值替換成您自己的值。

1. GetDeveloperAccount

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890"

回覆:

{
  "name": "developerAccounts/1234567890",
  "displayName": "Example Developer",
  "verificationState": "VERIFIED"
}

2. ListDeveloperAccounts

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts"

回覆:

{
  "developerAccounts": [
    {
      "name": "developerAccounts/1234567890",
      "displayName": "Example Developer",
      "verificationState": "VERIFIED"
    }
  ]
}

3. GetAndroidPackageRegistrationPolicy

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/registrationPolicy"

回覆:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/registrationPolicy",
  "knownKeys": [
    {
      "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
      "justificationRequirement": "NOT_REQUIRED"
    }
  ],
  "keySelectionStrategy": "SELECT_KEY_FROM_LIST"
}

4. CreateAndroidPackage

curl -X POST \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{"name": ""}' \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages?androidPackageId=com.example.myapp"

回覆:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp",
  "packageName": "com.example.myapp",
  "state": "DRAFT",
  "registeredAppStore": false
}

5. GetAndroidPackage

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp"

回覆:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp",
  "packageName": "com.example.myapp",
  "state": "REGISTERED",
  "registeredAppStore": false
}

6. ListAndroidPackages

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages?pageSize=100"

回覆:

{
  "androidPackages": [
    {
      "name": "developerAccounts/1234567890/androidPackages/com.example.myapp",
      "packageName": "com.example.myapp",
      "state": "REGISTERED",
      "registeredAppStore": false
    }
  ],
  "nextPageToken": ""
}

7. CreateAndroidPackageKey

curl -X POST \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{
    "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123"
  }' \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys"

回覆:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "state": "DRAFT",
  "verificationToken": "token_xyz987654321"
}

8. GetAndroidPackageKey

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123"

回覆:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "state": "REGISTERED"
}

9. ListAndroidPackageKeys

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys?pageSize=100"

回覆:

{
  "androidPackageKeys": [
    {
      "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
      "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
      "state": "REGISTERED"
    }
  ],
  "nextPageToken": ""
}

10. VerifyAndroidPackageKeyOwnership

選項 A:單一要求媒體上傳

curl -X POST \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @app-release.apk \
  "https://androiddeveloperconsole.googleapis.com/upload/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123:verify?uploadType=media"

方法 B:支援續傳的上傳作業通訊協定 (建議用於大型 APK 或 CI/CD)

步驟 1:啟動支援續傳的上傳作業工作階段,並擷取傳回的 X-Goog-Upload-URL 標頭:

curl -i -X POST \
  "https://androiddeveloperconsole.googleapis.com/upload/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123:verify" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "X-Goog-Upload-Protocol: resumable" \
  -H "X-Goog-Upload-Command: start" \
  -H "X-Goog-Upload-Header-Content-Length: FILE_SIZE_IN_BYTES" \
  -H "X-Goog-Upload-Header-Content-Type: application/vnd.android.package-archive" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123"
  }'

步驟 2:將已簽署的 APK 二進位檔上傳至 UPLOAD_SESSION_URI,並完成工作階段:

curl -X PUT \
  "UPLOAD_SESSION_URI" \
  -H "Content-Length: FILE_SIZE_IN_BYTES" \
  -H "X-Goog-Upload-Offset: 0" \
  -H "X-Goog-Upload-Command: upload, finalize" \
  --data-binary "@app-release.apk"

回覆:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "state": "IN_REVIEW"
}

11. JustifyAndroidPackageKeyRegistration

curl -X POST \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{
    "justification": "We previously distributed com.example.myapp directly from https://downloads.example.com and are migrating to our rotated production key."
  }' \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123:justifyAndroidPackageKeyRegistration"

回覆:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "state": "IN_REVIEW",
  "registrationJustificationRequired": true
}

其他資源