Android Developer Console API 是一项 RESTful 服务,可让经过验证的开发者在 Android 开发者管理中心内自动执行 Android 开发者验证工作流,包括检索开发者账号、检查关键资格要求、注册 Android 软件包名称、注册应用签名密钥以及验证密钥所有权。
概览、应用场景和实现背景
主要应用场景和功能
- 自动化 CI/CD 软件包名称注册:以编程方式注册数十或数百个 Android 软件包名称 (
CreateAndroidPackage)。 - 预检历史密钥政策检查:以编程方式检查 Google 之前是否在生态系统中观察到某个软件包名称,以及注册特定签名证书是否需要进行密钥所有权验证 (
GetAndroidPackageRegistrationPolicy)。 - 自动注册应用签名密钥和验证所有权:注册公开签名证书 SHA-256 指纹 (
CreateAndroidPackageKey),检索唯一的验证质询令牌 (verificationToken),并使用单请求或可续传的已签名 APK 上传 (VerifyAndroidPackageKeyOwnership) 自动证明私钥所有权。 - 以编程方式提交理由:提交所有权理由 (
JustifyAndroidPackageKeyRegistration)。 - 状态监控:监控各个开发者账号、软件包名称和应用签名密钥(
GetDeveloperAccount、ListDeveloperAccounts、GetAndroidPackage、ListAndroidPackages、GetAndroidPackageKey、ListAndroidPackageKeys)的注册状态。
端到端实现工作流程
- 在界面中验证开发者身份一次:在 Android 开发者管理中心内完成开发者身份验证(
INDIVIDUAL或ORGANIZATION),以便verificationState为VERIFIED。 - 启用 API 并进行身份验证:在 Google Cloud 云项目中启用
androiddeveloperconsole.googleapis.com,并获取范围为https://www.googleapis.com/auth/androiddeveloperconsole的用户委托 OAuth 2.0 Bearer 访问令牌。 - 查找您的开发者账号资源名称:调用
GET /v1/developerAccounts(ListDeveloperAccounts) 以检索developerAccounts/{developer_account}并验证verificationState是否为VERIFIED。 - 检查软件包名称的注册政策:调用
GET /v1/developerAccounts/{id}/androidPackages/{pkg}/registrationPolicy(GetAndroidPackageRegistrationPolicy) 以检查keySelectionStrategy(SELECT_KEY_FROM_LIST或USE_ANY_KEY)和任何已知的历史签名密钥 (knownKeys)。 - 创建 Android 软件包资源:调用
POST /v1/developerAccounts/{id}/androidPackages?androidPackageId={pkg}(CreateAndroidPackage),正文为{"name": ""}(在DRAFT状态下创建资源)。 - 注册应用签名密钥指纹:使用 JSON 正文
{"certificateFingerprintSha256": "..."}调用POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys(CreateAndroidPackageKey)。检查返回的状态:DRAFT:需要提供私钥所有权证明,并且响应中包含第 7 步所需的唯一verificationToken。IN_REVIEW:系统会自动跳过所有权证明和理由说明(例如,注册从未在 Android 上出现过的新软件包名称时,或者您已针对同一DeveloperAccount中的其他软件包名称验证了此签名密钥的所有权时)。跳过第 7 步和第 8 步中的理由说明调用,直接轮询GetAndroidPackage和GetAndroidPackageKey。
- 构建并上传验证 APK(如果状态为
DRAFT):将返回的verificationToken字符串嵌入到与packageName匹配的最小 APK 内的assets/adi-registration.properties中,使用您的私有应用签名密钥为其签名,然后使用POST /upload/v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:verify(VerifyAndroidPackageKeyOwnership) 将其上传。 - 提交理由(如果需要)并轮询注册状态:如果密钥处于
OWNERSHIP_VERIFIED状态且registrationJustificationRequired为true,请调用POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:justifyAndroidPackageKeyRegistration(JustifyAndroidPackageKeyRegistration)。轮询GetAndroidPackage和GetAndroidPackageKey,直到state达到REGISTERED。
用于准备密钥指纹和验证 APK 的本地 CLI 命令
从密钥库 (
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 开发者管理中心界面和 API 功能
| 任务 | Android 开发者管理中心 Web 界面 (android.google.com/developerconsole) |
Android 开发者管理中心 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) |
| 添加应用签名密钥并生成质询令牌 | 软件包详情 > 添加签名密钥 | POST /v1/{parent}/keys (CreateAndroidPackageKey) |
证明私钥所有权 (adi-registration.properties) |
在控制台界面中上传已签名的代码段 APK | POST /upload/v1/{name}:verify (VerifyAndroidPackageKeyOwnership) |
| 在密钥需要人工审核时提交理由 | 密钥注册工作流期间的文本提示词 | POST /v1/{name}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration) |
服务配置和身份验证
所有 API 请求都必须使用 HTTPS,并包含使用 OAuth 2.0 Web 服务器流程为已在 Android 开发者管理中心内完成开发者身份验证的 Google 账号获取的 Authorization: Bearer
ACCESS_TOKEN 标头。
| 属性 | 值 |
|---|---|
| 基本 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 Developer Console 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 |
标识符。资源名称,格式为 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 |
标识符。资源名称,格式为 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 |
标识符。资源名称,格式为 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 后立即转换)。 |
枚举: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 |
标识符。服务器分配的资源名称,格式为 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 密钥或服务账号进行身份验证。 | 获取具有 https://www.googleapis.com/auth/androiddeveloperconsole 范围的全新用户委托 OAuth 2.0 Bearer 访问令牌。 |
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
}
其他资源
- 使用 Android 开发者管理中心 API 注册软件包名称
- 使用 Android Developer ID Status API 检查应用注册状态
- 在 Android 开发者管理中心内注册
- 在 Google Play 管理中心内注册