Android Developer Console API הוא שירות RESTful שמאפשר למפתחים מאומתים להפוך את תהליכי העבודה של אימות למפתחי Android לאוטומטיים ב-Android Developer Console, כולל אחזור חשבונות פיתוח, בדיקת דרישות הסף של המפתחות, רישום שמות של חבילות Android, רישום מפתחות לחתימת אפליקציות ואימות הבעלות על המפתחות.
סקירה כללית, תרחישים לדוגמה והקשר ההטמעה
תרחישי שימוש ותכונות עיקריים
- רישום אוטומטי של שמות חבילות ב-CI/CD: רישום של עשרות או מאות שמות של חבילות Android באופן פרוגרמטי (
CreateAndroidPackage). - בדיקה מקדימה של מדיניות המפתחות ההיסטורית: בדיקה פרוגרמטית אם Google זיהתה בעבר שם חבילה בסביבה העסקית, ואם רישום של אישור חתימה ספציפי מחייב אימות בעלות על המפתח (
GetAndroidPackageRegistrationPolicy). - רישום אוטומטי של מפתחות לחתימת אפליקציות ואימות בעלות:
רישום טביעות אצבע מסוג SHA-256 של אישורי חתימה ציבוריים
(
CreateAndroidPackageKey), אחזור טוקנים ייחודיים של אתגרי אימות (verificationToken) ואוטומציה של הוכחת החזקה של מפתח פרטי באמצעות העלאות של קובצי APK חתומים בבקשה אחת או בהעלאות שניתן להמשיך (VerifyAndroidPackageKeyOwnership). - שליחת הצדקות באופן פרוגרמטי: שליחת הצדקות לבעלות (
JustifyAndroidPackageKeyRegistration). - מעקב אחרי סטטוס: מעקב אחרי סטטוס הרישום בחשבונות פיתוח, שמות חבילות ומפתחות לחתימת אפליקציות (
GetDeveloperAccount,ListDeveloperAccounts,GetAndroidPackage,ListAndroidPackages,GetAndroidPackageKey,ListAndroidPackageKeys).
תהליך עבודה להטמעה מקצה לקצה
- אימות זהות המפתח פעם אחת בממשק המשתמש: משלימים את אימות זהות המפתח (
INDIVIDUALאוORGANIZATION) ב-Android Developer Console כדי ש-verificationStateיהיהVERIFIED. - מפעילים את ה-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) ואת כל מפתחות החתימה ההיסטוריים הידועים (knownKeys). - יוצרים את המשאב של חבילת Android: מפעילים את
POST /v1/developerAccounts/{id}/androidPackages?androidPackageId={pkg}(CreateAndroidPackage) עם גוף{"name": ""}(יוצר משאב במצבDRAFT). - רישום טביעת האצבע של מפתח לחתימת אפליקציות: שולחים קריאה ל-
POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys(CreateAndroidPackageKey) עם גוף JSON{"certificateFingerprintSha256": "..."}. בודקים את המצב שהוחזר:-
DRAFT: נדרשת הוכחה לבעלות על המפתח הפרטי, והתשובה כוללתverificationTokenייחודי לשלב 7. -
IN_REVIEW: המערכת מדלגת באופן אוטומטי על הוכחת הבעלות וההצדקה (לדוגמה, כשרושמים שם חבילה חדש שלא הופיע אף פעם ב-Android, או כשכבר אימתתם את הבעלות על מפתח החתימה הזה בשביל שם חבילה אחר באותוDeveloperAccount). דלגו על שלב 7 ועל הקריאה להצדקה בשלב 8, והמשיכו ישירות לדגימה שלGetAndroidPackageו-GetAndroidPackageKey.
-
- יוצרים ומעלים את קובץ ה-APK לאימות (אם הסטטוס הוא
DRAFT): מטמיעים את המחרוזתverificationTokenשהוחזרה ב-assets/adi-registration.propertiesבתוך קובץ APK מינימלי שתואם ל-packageName, חותמים עליו באמצעות המפתח הפרטי לחתימת אפליקציות ומעלים אותו באמצעות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 ממאגר מפתחות (
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
יכולות ממשק המשתמש וה-API של Android Developer Console
| משימה | ממשק המשתמש של Android Developer Console באינטרנט (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) |
| הוספת מפתח לחתימת אפליקציות ויצירת אסימון אתגר | פרטי החבילה > הוספת מפתח חתימה | POST /v1/{parent}/keys (CreateAndroidPackageKey) |
הוכחת בעלות על מפתח פרטי (adi-registration.properties) |
העלאת קובץ APK חתום של קטע קוד בממשק המשתמש של המסוף | POST /upload/v1/{name}:verify (VerifyAndroidPackageKeyOwnership) |
| שליחת הצדקה כשנדרשת בדיקה ידנית של המפתח | פרומפט טקסטואלי במהלך תהליך העבודה של רישום המפתח | POST /v1/{name}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration) |
הגדרת שירות ואימות
כל בקשות ה-API חייבות להשתמש ב-HTTPS ולכלול כותרת Authorization: Bearer
ACCESS_TOKEN שהתקבלה באמצעות תהליך שרת האינטרנט של OAuth 2.0 לחשבון Google שהשלים את אימות זהות המפתח ב-Android Developer Console.
| מאפיין (property) | ערך |
|---|---|
| נקודת קצה בסיסית של 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) |
פלט בלבד. סטטוס אימות הזהות הנוכחי של המפתח בחשבון. |
ערכים לדוגמה: DeveloperAccount.VerificationState
| ערך | תיאור |
|---|---|
VERIFIED |
תהליך אימות הזהות של המפתח הושלם. החשבון יכול לרשום שמות של חבילות ומפתחות לחתימת אפליקציות. |
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 |
פלט בלבד. מציין אם שם החבילה הזה פעיל כרגע כחנות אפליקציות רשומה. |
Enum: AndroidPackage.State
| ערך | תיאור |
|---|---|
DRAFT |
משאב שם החבילה נוצר, והרישום של מפתח לחתימת אפליקציות או אימות הבעלות עדיין בתהליך. |
IN_REVIEW |
הרישום של שם החבילה וההצדקה הנדרשת לשימוש במפתח נשלחו ונמצאים בבדיקה של Google. חבילה עוברת מסטטוס DRAFT לסטטוס IN_REVIEW מיד אחרי CreateAndroidPackageKey (אם דילגתם על אימות הבעלות על המפתח, כולל אם המפתח כבר אומת לשם חבילה אחר באותו 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 |
פלט בלבד. טביעת אצבע מנורמלת של SHA-256 בבסיס הקסדצימלי עם 64 תווים באותיות קטנות של אישור החתימה ההיסטורי (ללא נקודתיים). |
knownKeys[].justificationRequirement |
enum (JustificationRequirement) |
פלט בלבד. מציין אם רישום המפתח הזה מחייב קריאה ל-JustifyAndroidPackageKeyRegistration (REQUIRED או NOT_REQUIRED). אם מפתח החתימה אומת בעבר בשם חבילה אחר באותו DeveloperAccount, המערכת מדלגת על VerifyAndroidPackageKeyOwnership ועל JustifyAndroidPackageKeyRegistration גם אם הערך של justificationRequirement הוא REQUIRED. |
keySelectionStrategy |
enum (KeySelectionStrategy) |
פלט בלבד. מדיניות בחירת המפתחות לרישום שם החבילה הזה: SELECT_KEY_FROM_LIST (צריך לרשום מפתח מ-knownKeys) או USE_ANY_KEY (אפשר לרשום כל מפתח חוקי לחתימת אפליקציות שנמצא בבעלות המפתח). |
ערך נספר (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, הגורם המבקש יכול לרשום כל מפתח חוקי לחתימת אפליקציות שלא נצפה בעבר בסביבה העסקית של Android. |
Methods: AndroidPackage
| שיטה | בקשת HTTP | תיאור |
|---|---|---|
GetAndroidPackageRegistrationPolicy |
GET /v1/{name=developerAccounts/*/androidPackages/*/registrationPolicy} |
אחזור של אסטרטגיית בחירת המפתחות ומפתחות החתימה ההיסטוריים הידועים של שם חבילה. |
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
מייצג טביעת אצבע לאישור חתימת אפליקציה ציבורי שמשויך ל-AndroidPackage, ועוקב אחרי מצב אימות הבעלות ובדיקת הרישום.
| שדה | סוג | תיאור |
|---|---|---|
name |
string |
מזהה. שם המשאב שהוקצה על ידי השרת בפורמט developerAccounts/{developer_account}/androidPackages/{android_package}/keys/{key}, כאשר {key} היא טביעת אצבע מנורמלת של SHA-256 הקסדצימלי באותיות קטנות באורך 64 תווים ללא נקודתיים. צריך להשמיט את השדה או להשאיר אותו ריק כשמפעילים את 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, צריך להטמיע את המחרוזת הזו בתוך 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 |
המפתח לחתימת האפליקציות רשום באופן פעיל לשם החבילה הזה לצורך אימות למפתחי Android. |
PENDING_TRANSFER |
רישום המפתח לחתימת האפליקציה ממתין להשלמת ההעברה. |
Methods: AndroidPackageKey
| שיטה | בקשת HTTP | תיאור |
|---|---|---|
CreateAndroidPackageKey |
POST /v1/{parent=developerAccounts/*/androidPackages/*}/keys |
רושמת טביעת אצבע חדשה לאישור חתימת אפליקציה מסוג SHA-256 ב-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 |
טוקן הגישה מסוג OAuth 2.0 Bearer חסר, לא תקין או שפג תוקפו, או שבוצע ניסיון לאימות באמצעות מפתח API או חשבון שירות. | מקבלים אסימון גישה חדש מסוג OAuth 2.0 Bearer עם היקף ההרשאות https://www.googleapis.com/auth/androiddeveloperconsole, שהוקצה למשתמש. |
403 Forbidden |
PERMISSION_DENIED |
למשתמש המאומת אין הרשאה ב-DeveloperAccount או ב-AndroidPackage, או ש-Android Developer Console API לא מופעל בפרויקט בענן ב-Google Cloud. |
צריך לאמת את החברות בחשבון באמצעות 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. |
הטמיעו השהיה מעריכית לפני ניסיון חוזר (exponential backoff) עם ריצוד (jitter) והימנעו מלולאות דגימה בתדירות גבוהה. |
500 / 503 |
INTERNAL / UNAVAILABLE |
שגיאה זמנית בקצה העורפי או חוסר זמינות זמני של השירות. | נסו שוב לשלוח בקשות אידמפוטנטיות עם השהיה מעריכית קטועה לפני ניסיון חוזר (truncated 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