Android Developer Console API เป็นบริการ RESTful ที่ช่วยให้นักพัฒนาแอปที่ได้รับการยืนยันสามารถทำให้เวิร์กโฟลว์การยืนยันนักพัฒนาแอป Android เป็นแบบอัตโนมัติใน Android Developer Console ซึ่งรวมถึงการดึงข้อมูลบัญชีนักพัฒนาแอป การตรวจสอบข้อกำหนดของการได้รับสิทธิ์ที่สำคัญ การลงทะเบียนชื่อแพ็กเกจ Android การลงทะเบียนคีย์ App Signing และการยืนยันการเป็นเจ้าของคีย์
ภาพรวม กรณีการใช้งาน และบริบทการใช้งาน
กรณีการใช้งานและฟีเจอร์หลัก
- การลงทะเบียนชื่อแพ็กเกจ CI/CD อัตโนมัติ: ลงทะเบียนชื่อแพ็กเกจ Android หลายสิบหรือหลายร้อยรายการแบบเป็นโปรแกรม (
CreateAndroidPackage) - การตรวจสอบนโยบายคีย์ที่ผ่านมาล่วงหน้า: ตรวจสอบแบบเป็นโปรแกรมว่า Google เคยพบชื่อแพ็กเกจในระบบนิเวศหรือไม่ และการลงทะเบียนใบรับรองการลงนามที่เฉพาะเจาะจงต้องมีการยืนยันการเป็นเจ้าของคีย์ (
GetAndroidPackageRegistrationPolicy) หรือไม่ - การลงทะเบียนคีย์ App Signing และการยืนยันการเป็นเจ้าของแบบอัตโนมัติ:
ลงทะเบียนลายนิ้วมือ SHA-256 ของใบรับรองการลงนามสาธารณะ
(
CreateAndroidPackageKey) ดึงโทเค็นคำถามเพื่อยืนยันตัวตนที่ไม่ซ้ำกัน (verificationToken) และพิสูจน์การครอบครองคีย์ส่วนตัวโดยอัตโนมัติโดยใช้ การอัปโหลด APK ที่ลงนามแบบคำขอเดียวหรือแบบดำเนินการต่อได้ (VerifyAndroidPackageKeyOwnership) - การส่งเหตุผลรองรับแบบเป็นโปรแกรม: ส่งเหตุผลรองรับการเป็นเจ้าของ (
JustifyAndroidPackageKeyRegistration) - การตรวจสอบสถานะ: ตรวจสอบสถานะการลงทะเบียนในบัญชีนักพัฒนาแอป ชื่อแพ็กเกจ และคีย์ App Signing (
GetDeveloperAccount,ListDeveloperAccounts,GetAndroidPackage,ListAndroidPackages,GetAndroidPackageKey,ListAndroidPackageKeys)
เวิร์กโฟลว์การติดตั้งใช้งานตั้งแต่ต้นจนจบ
- ยืนยันตัวตนของนักพัฒนาแอปใน UI เพียงครั้งเดียว: ยืนยันตัวตนของนักพัฒนาแอป (
INDIVIDUALหรือORGANIZATION) ให้เสร็จสมบูรณ์ใน Android Developer Console เพื่อให้verificationStateVERIFIED - เปิดใช้ API และตรวจสอบสิทธิ์: เปิดใช้
androiddeveloperconsole.googleapis.comในโปรเจ็กต์ Google Cloud และรับโทเค็นเพื่อการเข้าถึง Bearer ของ OAuth 2.0 ที่ได้รับมอบสิทธิ์จากผู้ใช้ซึ่งมีขอบเขตhttps://www.googleapis.com/auth/androiddeveloperconsole - ค้นหาชื่อทรัพยากรของบัญชีนักพัฒนาแอป: เรียกใช้
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) และคีย์ Signing ที่รู้จักในอดีต (knownKeys) - สร้างทรัพยากรแพ็กเกจ Android: เรียกใช้
POST /v1/developerAccounts/{id}/androidPackages?androidPackageId={pkg}(CreateAndroidPackage) โดยมีเนื้อหา{"name": ""}(สร้างทรัพยากรในสถานะDRAFT) - ลงทะเบียนลายนิ้วมือของคีย์ App Signing: เรียกใช้
POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys(CreateAndroidPackageKey) ด้วยเนื้อหา JSON{"certificateFingerprintSha256": "..."}ตรวจสอบสถานะที่แสดงผลดังนี้DRAFT: ต้องมีหลักฐานการเป็นเจ้าของคีย์ส่วนตัว และการตอบกลับจะมีverificationTokenที่ไม่ซ้ำกันสำหรับขั้นตอนที่ 7IN_REVIEW: ระบบจะข้ามหลักฐานการเป็นเจ้าของและเหตุผลโดยอัตโนมัติ (เช่น เมื่อลงทะเบียนชื่อแพ็กเกจใหม่ที่ไม่เคยเห็นใน Android หรือเมื่อคุณยืนยันการเป็นเจ้าของคีย์ Signing นี้สำหรับชื่อแพ็กเกจอื่นในDeveloperAccountเดียวกันแล้ว) ข้ามขั้นตอนที่ 7 และการเรียกเหตุผลในขั้นตอนที่ 8 แล้วดำเนินการต่อโดยตรงไปยังการสำรวจความคิดเห็นGetAndroidPackageและGetAndroidPackageKey
- สร้างและอัปโหลด APK สำหรับการยืนยัน (หากสถานะเป็น
DRAFT): ฝังสตริงverificationTokenที่แสดงผลลงในassets/adi-registration.propertiesภายใน APK ขั้นต่ำที่ตรงกับpackageName, รับรองด้วยคีย์ App Signing ส่วนตัว และอัปโหลดโดยใช้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
คำสั่ง CLI ในเครื่องสำหรับการเตรียมฟิงเกอร์ปรินต์ของคีย์และ APK สำหรับการยืนยัน
ดึงข้อมูลลายนิ้วมือของใบรับรอง SHA-256 จาก Keystore (
keytool):keytool -list -v -keystore release-key.jks -alias my-key-aliasยืนยันไดเจสต์ใบรับรองการลงนาม SHA-256 ใน APK ที่สร้างขึ้น (
apksigner)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
ความสามารถของ UI และ API ของ Android Developer Console
| งาน | UI บนเว็บของ Android Developer Console (android.google.com/developerconsole) |
Android Developer Console API |
|---|---|---|
| การยืนยันตัวตนของนักพัฒนาแอป (KYC/KYB) และการชำระค่าธรรมเนียม | รองรับ (ต้องมีข้อกำหนดเบื้องต้นแบบครั้งเดียว) | ไม่รองรับการใช้ API (การตรวจสอบสถานะแบบอ่านอย่างเดียวโดยใช้ GetDeveloperAccount และ ListDeveloperAccounts) |
| ดูบัญชีนักพัฒนาแอปที่ลิงก์ | ตัวสลับบัญชีในส่วนหัวของคอนโซล | GET /v1/developerAccounts (ListDeveloperAccounts) |
| ตรวจสอบคีย์ Signing และนโยบายที่ผ่านมาสำหรับชื่อแพ็กเกจ | แสดงระหว่างวิซาร์ด "ลงทะเบียนชื่อแพ็กเกจ" | GET /v1/.../registrationPolicy (GetAndroidPackageRegistrationPolicy) |
| ลงทะเบียนชื่อแพ็กเกจ Android ใหม่ | ชื่อแพ็กเกจ > ลงทะเบียนชื่อแพ็กเกจ | POST /v1/{parent}/androidPackages?androidPackageId=... (CreateAndroidPackage) |
| ดูหรือแสดงรายการชื่อแพ็กเกจที่ลงทะเบียนและฉบับร่าง | ตารางแดชบอร์ดชื่อแพ็กเกจ | GET /v1/{name} (GetAndroidPackage), GET /v1/{parent}/androidPackages (ListAndroidPackages) |
| เพิ่มคีย์ App Signing และสร้างโทเค็นคำถาม | รายละเอียดแพ็กเกจ > เพิ่มคีย์ Signing | POST /v1/{parent}/keys (CreateAndroidPackageKey) |
พิสูจน์การเป็นเจ้าของคีย์ส่วนตัว (adi-registration.properties) |
อัปโหลด APK ของข้อมูลโค้ดที่รับรองแล้วใน UI ของคอนโซล | POST /upload/v1/{name}:verify (VerifyAndroidPackageKeyOwnership) |
| ส่งเหตุผลเมื่อคีย์ต้องได้รับการตรวจสอบด้วยตนเอง | พรอมต์ข้อความระหว่างเวิร์กโฟลว์การลงทะเบียนคีย์ | POST /v1/{name}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration) |
การกำหนดค่าบริการและการตรวจสอบสิทธิ์
คำขอ API ทั้งหมดต้องใช้ HTTPS และมีส่วนหัว Authorization: Bearer
ACCESS_TOKEN ที่ได้รับโดยใช้ขั้นตอนของเว็บเซิร์ฟเวอร์ OAuth 2.0 สำหรับบัญชี Google ที่ยืนยันตัวตนนักพัฒนาแอปใน Android Developer Console เสร็จสมบูรณ์แล้ว
| พร็อพเพอร์ตี้ | ค่า |
|---|---|
| ปลายทาง REST พื้นฐาน | https://androiddeveloperconsole.googleapis.com |
| ปลายทางการอัปโหลดสื่อ | https://androiddeveloperconsole.googleapis.com/upload |
| เวอร์ชัน API | v1 |
| ขอบเขต OAuth 2.0 ที่จำเป็น | https://www.googleapis.com/auth/androiddeveloperconsole |
| ขีดจำกัดโควต้าเริ่มต้น | คำขอ 2,000 รายการต่อวันต่อโปรเจ็กต์ Google Cloud ต่อเมธอด |
ทรัพยากรและปลายทาง 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 Developer Console ที่เชื่อมโยงกับข้อมูลประจำตัวของนักพัฒนาแอป
| ช่อง | ประเภท | คำอธิบาย |
|---|---|---|
name |
string |
ตัวระบุ ชื่อทรัพยากรในรูปแบบ developerAccounts/{developer_account} |
displayName |
string |
เอาต์พุตเท่านั้น ชื่อที่มนุษย์อ่านได้ซึ่งเชื่อมโยงกับบัญชีนักพัฒนาแอป (ชื่อบุคคลธรรมดาหรือชื่อองค์กร) |
verificationState |
enum (VerificationState) |
เอาต์พุตเท่านั้น สถานะการยืนยันตัวตนของนักพัฒนาแอปปัจจุบันของบัญชี |
Enum: DeveloperAccount.VerificationState
| ค่า | คำอธิบาย |
|---|---|
VERIFIED |
การยืนยันตัวตนของนักพัฒนาแอปเสร็จสมบูรณ์แล้ว บัญชีสามารถลงทะเบียนชื่อแพ็กเกจและคีย์ App Signing ได้ |
NOT_VERIFIED |
การยืนยันตัวตนของนักพัฒนาแอปยังไม่เสร็จสมบูรณ์ใน Android Developer Console |
วิธีการ: DeveloperAccount
| วิธีการ | คำขอ HTTP | คำอธิบาย |
|---|---|---|
GetDeveloperAccount |
GET /v1/{name=developerAccounts/*} |
เรียกข้อมูลเมตาและสถานะการยืนยันสำหรับ DeveloperAccount รายการเดียว |
ListDeveloperAccounts |
GET /v1/developerAccounts |
แสดงรายการออบเจ็กต์ DeveloperAccount ทั้งหมดที่บัญชี Google ที่ตรวจสอบสิทธิ์แล้วเข้าถึงได้ (ไม่มีการแบ่งหน้า) |
ทรัพยากร: AndroidPackage
แสดงชื่อแพ็กเกจ Android ที่ลงทะเบียนหรือกำลังลงทะเบียนภายใต้ DeveloperAccount
| ช่อง | ประเภท | คำอธิบาย |
|---|---|---|
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 |
เอาต์พุตเท่านั้น ระบุว่าชื่อแพ็กเกจนี้ใช้งานอยู่ในปัจจุบันในฐานะ App Store ที่ลงทะเบียนหรือไม่ |
Enum: AndroidPackage.State
| ค่า | คำอธิบาย |
|---|---|
DRAFT |
สร้างทรัพยากรชื่อแพ็กเกจแล้ว และการลงทะเบียนคีย์ App Signing หรือการยืนยันการเป็นเจ้าของยังอยู่ระหว่างดำเนินการ |
IN_REVIEW |
ส่งการลงทะเบียนชื่อแพ็กเกจและการให้เหตุผลเกี่ยวกับคีย์ที่จำเป็นแล้ว และ Google กำลังตรวจสอบ แพ็กเกจจะเปลี่ยนสถานะจากDRAFTเป็นIN_REVIEWทันทีเมื่อCreateAndroidPackageKey (เมื่อข้ามการยืนยันการเป็นเจ้าของคีย์ รวมถึงเมื่อคีย์ได้รับการยืนยันแล้วสำหรับชื่อแพ็กเกจอื่นในDeveloperAccountเดียวกัน) หรือหลังจากทำVerifyAndroidPackageKeyOwnershipและJustifyAndroidPackageKeyRegistration (หากจำเป็น) เสร็จสมบูรณ์ |
REGISTERED |
ชื่อแพ็กเกจได้รับการลงทะเบียนอย่างสม่ำเสมอกับบัญชีนักพัฒนาแอปนี้สำหรับการยืนยันนักพัฒนาแอป Android |
PENDING_TRANSFER |
ชื่อแพ็กเกจกำลังรอการโอนความเป็นเจ้าของไปยังบัญชีนักพัฒนาแอปอื่นให้เสร็จสมบูรณ์ |
ทรัพยากร: AndroidPackageRegistrationPolicy
ทรัพยากร Singleton ที่แสดงผลโดย GetAndroidPackageRegistrationPolicy ซึ่งอธิบายคีย์การลงนามสาธารณะที่ผ่านมาซึ่งตรวจพบสำหรับชื่อแพ็กเกจ และการลงทะเบียนชื่อแพ็กเกจด้วยคีย์การลงนามที่ระบุต้องมีเหตุผลเป็นลายลักษณ์อักษรหรือไม่
| ช่อง | ประเภท | คำอธิบาย |
|---|---|---|
name |
string |
ตัวระบุ ชื่อทรัพยากรในรูปแบบ developerAccounts/{developer_account}/androidPackages/{android_package}/registrationPolicy |
knownKeys[] |
object (KnownKey) |
รายการคีย์ App Signing ที่ใช้ในอดีตซึ่งก่อนหน้านี้พบว่ามีการเผยแพร่แอปที่มีชื่อแพ็กเกจนี้ โดยจัดเรียงตามพจนานุกรมตาม certificateFingerprintSha256 |
knownKeys[].certificateFingerprintSha256 |
string |
เอาต์พุตเท่านั้น ลายนิ้วมือ SHA-256 เลขฐาน 16 ตัวพิมพ์เล็ก 64 อักขระที่แปลงเป็นรูปแบบมาตรฐานของใบรับรองการลงนามที่ผ่านมา (ไม่มีโคลอน) |
knownKeys[].justificationRequirement |
enum (JustificationRequirement) |
เอาต์พุตเท่านั้น ระบุว่าการลงทะเบียนคีย์นี้ต้องเรียกใช้ JustifyAndroidPackageKeyRegistration (REQUIRED หรือ NOT_REQUIRED) หรือไม่ หากคีย์ Signing ได้รับการยืนยันก่อนหน้านี้ในชื่อแพ็กเกจอื่นภายใต้ DeveloperAccount เดียวกัน ระบบจะข้ามทั้ง VerifyAndroidPackageKeyOwnership และ JustifyAndroidPackageKeyRegistration แม้ว่า justificationRequirement จะเป็น REQUIRED ก็ตาม |
keySelectionStrategy |
enum (KeySelectionStrategy) |
เอาต์พุตเท่านั้น นโยบายการเลือกคีย์สำหรับการลงทะเบียนชื่อแพ็กเกจนี้: SELECT_KEY_FROM_LIST (ต้องลงทะเบียนคีย์จาก knownKeys) หรือ USE_ANY_KEY (ลงทะเบียนคีย์ App Signing ที่ถูกต้องซึ่งนักพัฒนาแอปเป็นเจ้าของได้) |
Enum: KnownKey.JustificationRequirement
| ค่า | คำอธิบาย |
|---|---|
REQUIRED |
การลงทะเบียนคีย์ที่รู้จักนี้ต้องส่งเหตุผลเป็นลายลักษณ์อักษรโดยใช้ JustifyAndroidPackageKeyRegistration หลังจากทำ VerifyAndroidPackageKeyOwnership เสร็จแล้ว (เว้นแต่ว่าคีย์ได้รับการยืนยันก่อนหน้านี้ในชื่อแพ็กเกจอื่นภายใต้ DeveloperAccount เดียวกัน ซึ่งในกรณีนี้จะข้ามทั้ง VerifyAndroidPackageKeyOwnership และ JustifyAndroidPackageKeyRegistration) |
NOT_REQUIRED |
การลงทะเบียนคีย์ที่รู้จักนี้ไม่จำเป็นต้องระบุเหตุผลรองรับ คีย์จะเปลี่ยนไปใช้ IN_REVIEW โดยตรงหลังจากวันที่ VerifyAndroidPackageKeyOwnership (หรือทันทีในวันที่ CreateAndroidPackageKey หากคีย์ได้รับการยืนยันก่อนหน้านี้ในชื่อแพ็กเกจอื่นภายใต้ DeveloperAccount เดียวกัน) |
Enum: AndroidPackageRegistrationPolicy.KeySelectionStrategy
| ค่า | คำอธิบาย |
|---|---|
SELECT_KEY_FROM_LIST |
ผู้โทรต้องลงทะเบียนคีย์ย้อนหลังรายการใดรายการหนึ่งที่แสดงใน knownKeys |
USE_ANY_KEY |
นอกเหนือจากคีย์ใน knownKeys แล้ว ผู้โทรสามารถลงทะเบียนคีย์ App Signing ที่ถูกต้องซึ่งไม่เคยพบในระบบนิเวศของ Android มาก่อน |
วิธีการ: AndroidPackage
| วิธีการ | คำขอ HTTP | คำอธิบาย |
|---|---|---|
GetAndroidPackageRegistrationPolicy |
GET /v1/{name=developerAccounts/*/androidPackages/*/registrationPolicy} |
ดึงข้อมูลกลยุทธ์การเลือกคีย์และคีย์ Signing ที่ทราบในอดีตสำหรับชื่อแพ็กเกจ |
CreateAndroidPackage |
POST /v1/{parent=developerAccounts/*}/androidPackages?androidPackageId={package_name} |
สร้างทรัพยากร AndroidPackage ใหม่ในสถานะ DRAFT เพื่อเริ่มลงทะเบียนชื่อแพ็กเกจ |
GetAndroidPackage |
GET /v1/{name=developerAccounts/*/androidPackages/*} |
ดึงข้อมูลรายละเอียดและสถานะการลงทะเบียนปัจจุบันของ AndroidPackage ที่มีอยู่ |
ListAndroidPackages |
GET /v1/{parent=developerAccounts/*}/androidPackages |
แสดงรายการออบเจ็กต์ AndroidPackage รายการภายใต้ DeveloperAccount (pageSize สูงสุด 1000, pageToken) |
ทรัพยากร: AndroidPackageKey
แสดงลายนิ้วมือของใบรับรอง App Signing สาธารณะที่เชื่อมโยงกับ AndroidPackage และติดตามสถานะการยืนยันการเป็นเจ้าของและการตรวจสอบการลงทะเบียน
| ช่อง | ประเภท | คำอธิบาย |
|---|---|---|
name |
string |
ตัวระบุ ชื่อทรัพยากรที่เซิร์ฟเวอร์กำหนดในรูปแบบ developerAccounts/{developer_account}/androidPackages/{android_package}/keys/{key} โดยที่ {key} คือลายนิ้วมือ SHA-256 เลขฐาน 16 ตัวพิมพ์เล็ก 64 อักขระที่แปลงเป็นรูปแบบมาตรฐานโดยไม่มีโคลอน ต้องละเว้นหรือเว้นว่างไว้เมื่อเรียกใช้ CreateAndroidPackageKey |
certificateFingerprintSha256 |
string |
จำเป็น เปลี่ยนแปลงไม่ได้ แฮช SHA-256 ของใบรับรอง App Signing เมื่อป้อนข้อมูลใน CreateAndroidPackageKey ระบบจะยอมรับเลขฐาน 16 แบบธรรมดา 64 อักขระ (60e860e8...) หรือเลขฐาน 16 ที่คั่นด้วยโคลอน (60:E8:60:E8:...) เมื่อแสดงผลลัพธ์ ระบบจะปรับให้เป็นเลขฐาน 16 ตัวพิมพ์เล็ก 64 อักขระที่ไม่มีโคลอนเสมอ |
state |
enum (AndroidPackageKey.State) |
เอาต์พุตเท่านั้น สถานะวงจรการยืนยันและการลงทะเบียนปัจจุบันของคีย์ |
verificationToken |
string |
เอาต์พุตเท่านั้น โทเค็นคำถามที่ไม่ซ้ำกันซึ่ง Google สร้างขึ้น ใช้เฉพาะเมื่อสถานะเป็น DRAFT (สามารถละเว้นได้เมื่อ CreateAndroidPackageKey เปลี่ยนคีย์เป็น IN_REVIEW โดยตรง) เมื่อสถานะเป็น DRAFT ให้ฝังสตริงนี้ไว้ใน assets/adi-registration.properties ใน APK ที่รับรองแล้วเพื่อดำเนินการ VerifyAndroidPackageKeyOwnership ให้เสร็จสมบูรณ์ |
registrationJustificationRequired |
boolean |
เอาต์พุตเท่านั้น หาก true และคีย์อยู่ในสถานะ OWNERSHIP_VERIFIED คุณต้องส่งเหตุผลที่เป็นลายลักษณ์อักษรโดยใช้ JustifyAndroidPackageKeyRegistration ก่อนที่การลงทะเบียนจะดำเนินการต่อใน IN_REVIEW หาก CreateAndroidPackageKey เปลี่ยนคีย์เป็น IN_REVIEW โดยตรง (เนื่องจากคีย์ได้รับการยืนยันก่อนหน้านี้ในชื่อแพ็กเกจอื่นใน DeveloperAccount เดียวกัน) ระบบจะข้ามการให้เหตุผล |
Enum: 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 |
คีย์ App Signing ได้รับการลงทะเบียนอย่างสม่ำเสมอกับชื่อแพ็กเกจนี้สำหรับการยืนยันนักพัฒนาแอป Android |
PENDING_TRANSFER |
การลงทะเบียนคีย์ App Signing กำลังรอให้การโอนเสร็จสมบูรณ์ |
วิธีการ: AndroidPackageKey
| วิธีการ | คำขอ HTTP | คำอธิบาย |
|---|---|---|
CreateAndroidPackageKey |
POST /v1/{parent=developerAccounts/*/androidPackages/*}/keys |
ลงทะเบียนลายนิ้วมือ SHA-256 ของใบรับรอง App Signing ใหม่ภายใต้ AndroidPackage แสดงผลคีย์ในสถานะ DRAFT (เมื่อต้องใช้หลักฐานการเป็นเจ้าของโดยใช้ VerifyAndroidPackageKeyOwnership) หรือแสดงผลคีย์ในสถานะ IN_REVIEW โดยตรง (เมื่อข้ามการยืนยันการเป็นเจ้าของ เช่น สำหรับชื่อแพ็กเกจใหม่ที่ไม่เคยเห็นใน Android หรือคีย์ที่ยืนยันแล้วในชื่อแพ็กเกจอื่นใน DeveloperAccount เดียวกัน) |
GetAndroidPackageKey |
GET /v1/{name=developerAccounts/*/androidPackages/*/keys/*} |
ดึงข้อมูลสถานะ ฟิงเกอร์ปรินต์ และข้อมูลเมตาการยืนยันของ AndroidPackageKey ที่เฉพาะเจาะจง |
ListAndroidPackageKeys |
GET /v1/{parent=developerAccounts/*/androidPackages/*}/keys |
แสดงรายการออบเจ็กต์ AndroidPackageKey ทั้งหมดที่ลงทะเบียนภายใต้ AndroidPackage (pageSize สูงสุด 1000, pageToken) |
VerifyAndroidPackageKeyOwnership |
POST /upload/v1/{name=developerAccounts/*/androidPackages/*/keys/*}:verify |
อัปโหลด APK ขั้นต่ำที่รับรองแล้วซึ่งมี verificationToken ใน assets/adi-registration.properties เพื่อยืนยันการเป็นเจ้าของคีย์ส่วนตัวและส่งคีย์ที่พร้อมใช้งานเพื่อรับการตรวจสอบ |
JustifyAndroidPackageKeyRegistration |
POST /v1/{name=developerAccounts/*/androidPackages/*/keys/*}:justifyAndroidPackageKeyRegistration |
ส่งบริบทเหตุผลเพิ่มเติมเมื่อ registrationJustificationRequired เป็น true และส่งคีย์ที่ยืนยันแล้วเพื่อรับการตรวจสอบ |
การจัดการข้อผิดพลาด
เมื่อคำขอ API ไม่สำเร็จ Android Developer Console API จะแสดงรหัสสถานะ HTTP 4xx หรือ 5xx และเนื้อหาข้อผิดพลาด JSON มาตรฐาน google.rpc.Status ดังนี้
{
"error": {
"code": 400,
"message": "Invalid certificate fingerprint SHA256 format.",
"status": "INVALID_ARGUMENT",
"details": []
}
}
รหัสสถานะ HTTP และการแก้ไขที่พบบ่อย
| โค้ด HTTP | สถานะ gRPC | สาเหตุที่พบบ่อย | ความละเอียด |
|---|---|---|---|
400 Bad Request |
INVALID_ARGUMENT |
ไม่มี androidPackageId สไตล์ Java หรือไม่ถูกต้อง รูปแบบ certificateFingerprintSha256 ไม่ถูกต้อง ช่อง name ไม่ว่างเปล่าใน CreateAndroidPackage หรือ CreateAndroidPackageKey APK ที่อัปโหลดไม่ได้ลงนาม เสียหาย ไม่มี assets/adi-registration.properties ไม่มี verificationToken ที่ตรงกัน หรือลงนามด้วยใบรับรองที่ไม่ตรงกัน |
ตรวจสอบรูปแบบคำขอกับสคีมาทรัพยากร ละเว้นหรือเว้นว่าง name ในการเรียกใช้การสร้าง และยืนยันลายเซ็น APK และโทเค็นที่ฝังไว้โดยใช้ apksigner verify --print-certs และ unzip -p app-release.apk assets/adi-registration.properties ก่อนอัปโหลด |
400 Bad Request |
FAILED_PRECONDITION |
DeveloperAccount มี verificationState: NOT_VERIFIED; การเลือกคีย์ละเมิด AndroidPackageRegistrationPolicy (SELECT_KEY_FROM_LIST); การเรียกใช้ VerifyAndroidPackageKeyOwnership หรือ JustifyAndroidPackageKeyRegistration ในสถานะที่ไม่มีสิทธิ์ |
ทำการยืนยันตัวตนของนักพัฒนาแอปให้เสร็จสมบูรณ์ใน Android Developer Console โดยตรวจสอบ GetAndroidPackageRegistrationPolicy ก่อน แล้วจึงตรวจสอบ state ปัจจุบันของทรัพยากร |
401 Unauthorized |
UNAUTHENTICATED |
โทเค็นเพื่อการเข้าถึง Bearer ของ OAuth 2.0 หายไป หมดอายุ หรือไม่ถูกต้อง หรือพยายามตรวจสอบสิทธิ์โดยใช้คีย์ API หรือบัญชีบริการ | รับโทเค็นเพื่อการเข้าถึง OAuth 2.0 Bearer ที่ผู้ใช้มอบสิทธิ์ใหม่ซึ่งมีขอบเขต https://www.googleapis.com/auth/androiddeveloperconsole |
403 Forbidden |
PERMISSION_DENIED |
ผู้ใช้ที่ตรวจสอบสิทธิ์แล้วไม่มีสิทธิ์ใน DeveloperAccount หรือ AndroidPackage เป้าหมาย หรือไม่ได้เปิดใช้ Android Developer Console API ในโปรเจ็กต์ที่อยู่ในระบบคลาวด์ของ Google |
ยืนยันการเป็นสมาชิกบัญชีโดยใช้ ListDeveloperAccounts และตรวจสอบว่าเปิดใช้ androiddeveloperconsole.googleapis.com ในคอนโซล Google Cloud แล้ว |
404 Not Found |
NOT_FOUND |
ไม่มีเส้นทางทรัพยากร DeveloperAccount, AndroidPackage หรือ AndroidPackageKey ที่ระบุ |
ยืนยันเส้นทางทรัพยากรโดยใช้ ListDeveloperAccounts, ListAndroidPackages หรือ ListAndroidPackageKeys ตรวจสอบว่ารหัส {key} ใช้เลขฐานสิบหกตัวพิมพ์เล็กโดยไม่มีโคลอน |
409 Conflict |
ALREADY_EXISTS |
มีการลงทะเบียนชื่อแพ็กเกจหรือลายนิ้วมือของใบรับรอง SHA-256 ภายใต้บัญชีนักพัฒนาแอปนี้หรือบัญชีอื่นแล้ว | ตรวจสอบการจดทะเบียนที่มีอยู่โดยใช้ GetAndroidPackage หรือ GetAndroidPackageKey หรือตรวจสอบการเป็นเจ้าของที่ผ่านมาโดยใช้ GetAndroidPackageRegistrationPolicy |
429 Too Many Requests |
RESOURCE_EXHAUSTED |
เกินโควต้าต่อเมธอด 2,000 คำขอต่อวันต่อโปรเจ็กต์ Google Cloud |
ใช้ Exponential Backoff ที่มี Jitter และหลีกเลี่ยงลูปการโพลความถี่สูง |
500 / 503 |
INTERNAL / UNAVAILABLE |
ข้อผิดพลาดของแบ็กเอนด์ชั่วคราวหรือบริการไม่พร้อมใช้งานชั่วคราว | ลองส่งคำขอ Idempotent อีกครั้งโดยใช้ Exponential Backoff แบบตัดปลาย |
ตัวอย่างคำขอ 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
ตัวเลือก ก: การอัปโหลดสื่อแบบคำขอเดียว
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"ตัวเลือก ข: โปรโตคอลการอัปโหลดที่ดำเนินการต่อได้ (แนะนำสำหรับ 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 Developer Console API
- ตรวจสอบสถานะการลงทะเบียนแอปด้วย Android Developer ID Status API
- ลงทะเบียนใน Android Developer Console
- ลงทะเบียนใน Google Play Console