Android Developer Console API to usługa RESTful, która umożliwia zweryfikowanym deweloperom automatyzację procesów weryfikacji dewelopera aplikacji na Androida w Konsoli programisty Androida, w tym pobieranie kont deweloperów, sprawdzanie kluczowych wymagań, rejestrowanie nazw pakietów aplikacji na Androida, rejestrowanie kluczy podpisywania aplikacji i weryfikowanie własności kluczy.
Omówienie, przypadki użycia i kontekst implementacji
Najważniejsze przypadki użycia i funkcje
- Automatyczna rejestracja nazw pakietów CI/CD: rejestruj dziesiątki lub setki nazw pakietów na Androida automatycznie (
CreateAndroidPackage). - Wstępna kontrola historycznych zasad dotyczących kluczy: automatyczne sprawdzanie, czy nazwa pakietu była już wcześniej widoczna w ekosystemie Google i czy zarejestrowanie konkretnego certyfikatu podpisywania wymaga weryfikacji własności klucza (
GetAndroidPackageRegistrationPolicy). - Automatyczna rejestracja klucza podpisywania aplikacji i weryfikacja własności: zarejestruj odciski cyfrowe SHA-256 publicznego certyfikatu podpisywania (
CreateAndroidPackageKey), pobierz unikalne tokeny wyzwania weryfikacyjnego (verificationToken) i zautomatyzuj potwierdzanie posiadania klucza prywatnego za pomocą przesyłania podpisanych plików APK w ramach pojedynczego żądania lub z możliwością wznowienia (VerifyAndroidPackageKeyOwnership). - Przesyłanie uzasadnienia automatycznego: prześlij uzasadnienia własności (
JustifyAndroidPackageKeyRegistration). - Monitorowanie stanu: monitoruj stan rejestracji na kontach deweloperów, nazwy pakietów i klucze podpisywania aplikacji (
GetDeveloperAccount,ListDeveloperAccounts,GetAndroidPackage,ListAndroidPackages,GetAndroidPackageKey,ListAndroidPackageKeys).
Kompleksowy proces implementacji
- Jednorazowa weryfikacja tożsamości dewelopera w interfejsie: przeprowadź weryfikację tożsamości dewelopera (
INDIVIDUALlubORGANIZATION) w Konsoli programisty Androida, abyverificationStatebyłaVERIFIED. - Włącz interfejs API i przeprowadź uwierzytelnianie: włącz
androiddeveloperconsole.googleapis.comw projekcie Google Cloud i uzyskaj token dostępu na okaziciela OAuth 2.0 przekazany przez użytkownika z zakresemhttps://www.googleapis.com/auth/androiddeveloperconsole. - Znajdź nazwę zasobu konta dewelopera: wywołaj
GET /v1/developerAccounts(ListDeveloperAccounts), aby pobraćdeveloperAccounts/{developer_account}i sprawdzić, czyverificationStatetoVERIFIED. - Sprawdź zasady rejestracji nazwy pakietu: wywołaj
GET /v1/developerAccounts/{id}/androidPackages/{pkg}/registrationPolicy(GetAndroidPackageRegistrationPolicy), aby sprawdzićkeySelectionStrategy(SELECT_KEY_FROM_LISTlubUSE_ANY_KEY) i wszystkie znane historyczne klucze do podpisywania (knownKeys). - Utwórz zasób pakietu Androida: wywołaj
POST /v1/developerAccounts/{id}/androidPackages?androidPackageId={pkg}(CreateAndroidPackage) z treścią{"name": ""}(tworzy zasób w stanieDRAFT). - Zarejestruj odcisk cyfrowy klucza podpisywania aplikacji: wywołaj
POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys(CreateAndroidPackageKey) z treścią JSON{"certificateFingerprintSha256": "..."}. Sprawdź zwrócony stan:DRAFT: wymagany jest dowód własności klucza prywatnego, a odpowiedź zawiera unikalny identyfikatorverificationTokendla kroku 7.IN_REVIEW: dowód własności i uzasadnienie są pomijane automatycznie (np. podczas rejestrowania nowej nazwy pakietu, która nigdy nie była używana na Androidzie, lub gdy własność tego klucza podpisywania została już zweryfikowana w przypadku innej nazwy pakietu w tym samymDeveloperAccount). Pomiń krok 7 i wywołanie uzasadnienia w kroku 8 i przejdź bezpośrednio do odpytywaniaGetAndroidPackageiGetAndroidPackageKey.
- Utwórz i prześlij plik APK do weryfikacji (jeśli stan to
DRAFT): umieść zwrócony ciąg znakówverificationTokenwassets/adi-registration.propertiesw minimalnym pliku APK pasującym dopackageName, podpisz go prywatnym kluczem podpisywania aplikacji i prześlij za pomocąPOST /upload/v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:verify(VerifyAndroidPackageKeyOwnership). - Prześlij uzasadnienie (jeśli jest wymagane) i sprawdź stan rejestracji: jeśli klucz jest w stanie
OWNERSHIP_VERIFIED, aregistrationJustificationRequiredtotrue, wywołajPOST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:justifyAndroidPackageKeyRegistration(JustifyAndroidPackageKeyRegistration). SprawdzajGetAndroidPackageiGetAndroidPackageKey, ażstateosiągnie stanREGISTERED.
Lokalne polecenia interfejsu wiersza poleceń do przygotowywania odcisków cyfrowych kluczy i plików APK do weryfikacji
Wyodrębnianie odcisku cyfrowego certyfikatu SHA-256 z magazynu kluczy (
keytool):keytool -list -v -keystore release-key.jks -alias my-key-aliasSprawdź skrót certyfikatu podpisywania SHA-256 w utworzonym pakiecie APK (
apksigner):apksigner verify --print-certs app-release.apkSprawdź nazwę pakietu APK i wbudowany plik tokena przed przesłaniem (
aapt2iunzip):aapt2 dump badging app-release.apk | head -n 1 unzip -p app-release.apk assets/adi-registration.properties
Interfejs Konsoli programisty Androida i funkcje interfejsu API
| Zadanie | Interfejs internetowy Konsoli programisty Androida (android.google.com/developerconsole) |
Android Developer Console API |
|---|---|---|
| Weryfikacja tożsamości dewelopera (KYC/KYB) i uiszczenie opłaty | Obsługiwane (wymagane jednorazowe spełnienie wymagań wstępnych) | Nieobsługiwane za pomocą interfejsu API (sprawdzanie stanu tylko do odczytu za pomocą GetDeveloperAccount i ListDeveloperAccounts) |
| Wyświetlanie połączonych kont dewelopera | Przełącznik kont w nagłówku konsoli | GET /v1/developerAccounts (ListDeveloperAccounts) |
| Sprawdzanie historycznych kluczy podpisywania i zasad dotyczących nazwy pakietu | Wyświetlane w kreatorze „Zarejestruj nazwę pakietu” | GET /v1/.../registrationPolicy (GetAndroidPackageRegistrationPolicy) |
| Rejestrowanie nowej nazwy pakietu na Androida | Nazwy pakietów > Zarejestruj nazwę pakietu | POST /v1/{parent}/androidPackages?androidPackageId=... (CreateAndroidPackage) |
| Wyświetlanie i wyświetlanie listy zarejestrowanych i roboczych nazw pakietów | Tabela panelu Nazwy pakietów | GET /v1/{name} (GetAndroidPackage), GET /v1/{parent}/androidPackages (ListAndroidPackages) |
| Dodawanie klucza podpisywania aplikacji i generowanie tokena wyzwania | Szczegóły pakietu > Dodaj klucz podpisywania | POST /v1/{parent}/keys (CreateAndroidPackageKey) |
Potwierdzanie własności klucza prywatnego (adi-registration.properties) |
Przesyłanie podpisanego fragmentu kodu APK w interfejsie konsoli | POST /upload/v1/{name}:verify (VerifyAndroidPackageKeyOwnership) |
| Przesyłanie uzasadnienia, gdy klucz wymaga ręcznego sprawdzenia | Prompt tekstowy podczas procesu rejestracji klucza | POST /v1/{name}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration) |
Konfiguracja usługi i uwierzytelnianie
Wszystkie żądania do interfejsu API muszą używać protokołu HTTPS i zawierać nagłówek Authorization: Bearer
ACCESS_TOKEN uzyskany za pomocą procesu serwera WWW OAuth 2.0 dla konta Google, które przeszło weryfikację tożsamości dewelopera w Konsoli programisty Androida.
| Właściwość | Wartość |
|---|---|
| Podstawowy punkt końcowy REST | https://androiddeveloperconsole.googleapis.com |
| Punkt końcowy przesyłania multimediów | https://androiddeveloperconsole.googleapis.com/upload |
| Wersja interfejsu API | v1 |
| Wymagany zakres protokołu OAuth 2.0 | https://www.googleapis.com/auth/androiddeveloperconsole |
| Domyślny limit | 2,000 żądania dziennie na projekt Google Cloud na metodę |
Zasoby i punkty końcowe interfejsu API
Interfejs API Konsoli programisty Androida porządkuje zasoby w następującej hierarchii:
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})
Zasób: DeveloperAccount
Reprezentuje konto w Konsoli programisty Androida powiązane z tożsamością dewelopera.
| Pole | Typ | Opis |
|---|---|---|
name |
string |
Identyfikator. Nazwa zasobu w formacie developerAccounts/{developer_account}. |
displayName |
string |
Tylko dane wyjściowe. Zrozumiała dla człowieka nazwa powiązana z kontem dewelopera (imię i nazwisko lub nazwa organizacji). |
verificationState |
enum (VerificationState) |
Tylko dane wyjściowe. Bieżący stan weryfikacji tożsamości dewelopera na koncie. |
Enum: DeveloperAccount.VerificationState
| Wartość | Opis |
|---|---|
VERIFIED |
Weryfikacja tożsamości dewelopera została zakończona. Konto może rejestrować nazwy pakietów i klucze podpisywania aplikacji. |
NOT_VERIFIED |
Weryfikacja tożsamości dewelopera nie została ukończona w Konsoli programisty Androida. |
Metody: DeveloperAccount
| Metoda | Żądanie HTTP | Opis |
|---|---|---|
GetDeveloperAccount |
GET /v1/{name=developerAccounts/*} |
Pobiera metadane i stan weryfikacji pojedynczego elementu DeveloperAccount. |
ListDeveloperAccounts |
GET /v1/developerAccounts |
Wyświetla listę wszystkich obiektów DeveloperAccount dostępnych dla uwierzytelnionego konta Google (bez podziału na strony). |
Zasób: AndroidPackage
Reprezentuje nazwę pakietu na Androida zarejestrowaną lub rejestrowaną w DeveloperAccount.
| Pole | Typ | Opis |
|---|---|---|
name |
string |
Identyfikator. Nazwa zasobu w formacie developerAccounts/{developer_account}/androidPackages/{android_package}, gdzie {android_package} to nazwa pakietu na Androida (np. com.example.myapp). |
packageName |
string |
Tylko dane wyjściowe. Nazwa pakietu na Androida (np. com.example.myapp). |
state |
enum (AndroidPackage.State) |
Tylko dane wyjściowe. Bieżący stan cyklu życia rejestracji nazwy pakietu. |
registeredAppStore |
boolean |
Tylko dane wyjściowe. Wskazuje, czy ta nazwa pakietu jest obecnie aktywna jako zarejestrowany sklep z aplikacjami. |
Typ wyliczeniowy: AndroidPackage.State
| Wartość | Opis |
|---|---|
DRAFT |
Zasób nazwy pakietu został utworzony, a rejestracja klucza podpisywania aplikacji lub weryfikacja własności jest nadal w toku. |
IN_REVIEW |
Rejestracja nazwy pakietu i wymagane uzasadnienie klucza zostały przesłane i są sprawdzane przez Google. Pakiet przechodzi ze stanu DRAFT do stanu IN_REVIEW natychmiast po CreateAndroidPackageKey (gdy weryfikacja własności klucza zostanie pominięta, w tym gdy klucz został już zweryfikowany pod kątem innej nazwy pakietu w tym samym DeveloperAccount) lub po zakończeniu VerifyAndroidPackageKeyOwnership i w razie potrzeby JustifyAndroidPackageKeyRegistration. |
REGISTERED |
Nazwa pakietu jest aktywnie zarejestrowana na tym koncie dewelopera na potrzeby weryfikacji dewelopera aplikacji na Androida. |
PENDING_TRANSFER |
Nazwa pakietu oczekuje na zakończenie przenoszenia własności na inne konto dewelopera. |
Zasób: AndroidPackageRegistrationPolicy
Zasób typu singleton zwracany przez GetAndroidPackageRegistrationPolicy, który opisuje historyczne publiczne klucze podpisywania wykryte dla nazwy pakietu i określa, czy zarejestrowanie nazwy pakietu z danym kluczem podpisywania wymaga pisemnego uzasadnienia.
| Pole | Typ | Opis |
|---|---|---|
name |
string |
Identyfikator. Nazwa zasobu w formacie developerAccounts/{developer_account}/androidPackages/{android_package}/registrationPolicy. |
knownKeys[] |
object (KnownKey) |
Lista historycznych kluczy podpisywania aplikacji, które były wcześniej używane do rozpowszechniania aplikacji o tej nazwie pakietu, posortowana leksykograficznie według certificateFingerprintSha256. |
knownKeys[].certificateFingerprintSha256 |
string |
Tylko dane wyjściowe. Znormalizowany 64-znakowy szesnastkowy odcisk cyfrowy SHA-256 historycznego certyfikatu podpisywania zapisany małymi literami (bez dwukropków). |
knownKeys[].justificationRequirement |
enum (JustificationRequirement) |
Tylko dane wyjściowe. Wskazuje, czy zarejestrowanie tego klucza wymaga wywołania JustifyAndroidPackageKeyRegistration (REQUIRED lub NOT_REQUIRED). Jeśli klucz podpisywania został wcześniej zweryfikowany w przypadku innej nazwy pakietu w ramach tej samej DeveloperAccount, zarówno VerifyAndroidPackageKeyOwnership, jak i JustifyAndroidPackageKeyRegistration są pomijane, nawet jeśli justificationRequirement to REQUIRED. |
keySelectionStrategy |
enum (KeySelectionStrategy) |
Tylko dane wyjściowe. Zasady wyboru klucza do rejestracji tej nazwy pakietu: SELECT_KEY_FROM_LIST (musisz zarejestrować klucz z knownKeys) lub USE_ANY_KEY (można zarejestrować dowolny prawidłowy klucz podpisywania aplikacji należący do dewelopera). |
Typ wyliczeniowy: KnownKey.JustificationRequirement
| Wartość | Opis |
|---|---|
REQUIRED |
Rejestracja tego znanego klucza wymaga przesłania pisemnego uzasadnienia za pomocą JustifyAndroidPackageKeyRegistration po ukończeniu VerifyAndroidPackageKeyOwnership (chyba że klucz został wcześniej zweryfikowany pod inną nazwą pakietu w ramach tego samego DeveloperAccount, w którym to przypadku zarówno VerifyAndroidPackageKeyOwnership, jak i JustifyAndroidPackageKeyRegistration są pomijane). |
NOT_REQUIRED |
Rejestracja tego znanego klucza nie wymaga uzasadnienia. Klucz przechodzi bezpośrednio do stanu IN_REVIEW po VerifyAndroidPackageKeyOwnership (lub natychmiast po CreateAndroidPackageKey, jeśli klucz został wcześniej zweryfikowany w przypadku innej nazwy pakietu w ramach tej samej DeveloperAccount). |
Typ wyliczeniowy: AndroidPackageRegistrationPolicy.KeySelectionStrategy
| Wartość | Opis |
|---|---|
SELECT_KEY_FROM_LIST |
Element wywołujący musi zarejestrować jeden z kluczy historycznych wymienionych w knownKeys. |
USE_ANY_KEY |
Oprócz kluczy w pakiecie knownKeys element wywołujący może zarejestrować dowolny prawidłowy klucz podpisywania aplikacji, który nie był wcześniej używany w ekosystemie Androida. |
Metody: AndroidPackage
| Metoda | Żądanie HTTP | Opis |
|---|---|---|
GetAndroidPackageRegistrationPolicy |
GET /v1/{name=developerAccounts/*/androidPackages/*/registrationPolicy} |
Pobiera strategię wyboru klucza i znane historyczne klucze podpisywania dla nazwy pakietu. |
CreateAndroidPackage |
POST /v1/{parent=developerAccounts/*}/androidPackages?androidPackageId={package_name} |
Tworzy nowy zasób AndroidPackage w stanie DRAFT, aby rozpocząć rejestrowanie nazwy pakietu. |
GetAndroidPackage |
GET /v1/{name=developerAccounts/*/androidPackages/*} |
Pobiera szczegóły i bieżący stan rejestracji istniejącego zasobu AndroidPackage. |
ListAndroidPackages |
GET /v1/{parent=developerAccounts/*}/androidPackages |
Wyświetla listę obiektów AndroidPackage w obszarze DeveloperAccount (maksymalnie pageSize 1000, pageToken). |
Zasób: AndroidPackageKey
Reprezentuje odcisk cyfrowy publicznego certyfikatu podpisywania aplikacji powiązany z AndroidPackage i śledzi stan weryfikacji własności oraz sprawdzania rejestracji.
| Pole | Typ | Opis |
|---|---|---|
name |
string |
Identyfikator. Nazwa zasobu przypisana przez serwer w formacie developerAccounts/{developer_account}/androidPackages/{android_package}/keys/{key}, gdzie {key} to znormalizowany 64-znakowy odcisk cyfrowy SHA-256 zapisany małymi literami w systemie szesnastkowym bez dwukropków. W przypadku wywołania CreateAndroidPackageKey należy pominąć lub pozostawić puste. |
certificateFingerprintSha256 |
string |
Wymagane. Wartość niezmienna. Identyfikator SHA-256 certyfikatu podpisywania aplikacji. W polu CreateAndroidPackageKey akceptuje zwykły 64-znakowy ciąg szesnastkowy (60e860e8...) lub ciąg szesnastkowy z dwukropkami (60:E8:60:E8:...). Na wyjściu zawsze jest normalizowany do 64-znakowego ciągu szesnastkowego składającego się z małych liter bez dwukropków. |
state |
enum (AndroidPackageKey.State) |
Tylko dane wyjściowe. Bieżący stan cyklu życia klucza w zakresie weryfikacji i rejestracji. |
verificationToken |
string |
Tylko dane wyjściowe. Unikalny token wyzwania wygenerowany przez Google. Używany tylko wtedy, gdy stan to DRAFT (można go zignorować, gdy CreateAndroidPackageKey przenosi klucz bezpośrednio do IN_REVIEW). Gdy stan to DRAFT, umieść ten ciąg znaków w assets/adi-registration.properties w podpisanym pliku APK, aby ukończyć VerifyAndroidPackageKeyOwnership. |
registrationJustificationRequired |
boolean |
Tylko dane wyjściowe. Jeśli true, a klucz jest w stanie OWNERSHIP_VERIFIED, musisz przesłać pisemne uzasadnienie za pomocą JustifyAndroidPackageKeyRegistration, zanim rejestracja przejdzie do stanu IN_REVIEW. Jeśli CreateAndroidPackageKey przeniesie klucz bezpośrednio do stanu IN_REVIEW (ponieważ klucz został wcześniej zweryfikowany w przypadku innej nazwy pakietu w tym samym DeveloperAccount), uzasadnienie zostanie pominięte. |
Typ wyliczeniowy: AndroidPackageKey.State
| Wartość | Opis |
|---|---|
DRAFT |
Zasób klucza został utworzony, ale nadal wymagane jest potwierdzenie posiadania klucza prywatnego przez przesłanie podpisanego pliku APK (VerifyAndroidPackageKeyOwnership), ponieważ własność tego klucza nie została jeszcze zweryfikowana w przypadku żadnej nazwy pakietu w ramach tego DeveloperAccount. |
OWNERSHIP_VERIFIED |
Własność klucza prywatnego została zweryfikowana za pomocą przesłanego podpisanego pliku APK. Jeśli registrationJustificationRequired to true, przed rozpoczęciem sprawdzania nadal wymagane jest uzasadnienie. |
IN_REVIEW |
Rejestracja klucza jest sprawdzana przez Google. Klucz przechodzi do tego stanu natychmiast po CreateAndroidPackageKey, gdy nie jest wymagane potwierdzenie własności (np. w przypadku nowej nazwy pakietu, która nigdy nie była używana na Androidzie, lub gdy klucz został wcześniej zweryfikowany w przypadku innej nazwy pakietu w ramach tego samego DeveloperAccount, co również pomija JustifyAndroidPackageKeyRegistration), bezpośrednio po VerifyAndroidPackageKeyOwnership (jeśli registrationJustificationRequired to false) lub po JustifyAndroidPackageKeyRegistration (jeśli registrationJustificationRequired to true). |
REGISTERED |
Klucz podpisywania aplikacji jest aktywnie zarejestrowany pod tą nazwą pakietu na potrzeby weryfikacji dewelopera aplikacji na Androida. |
PENDING_TRANSFER |
Rejestracja klucza podpisywania aplikacji oczekuje na zakończenie przenoszenia. |
Metody: AndroidPackageKey
| Metoda | Żądanie HTTP | Opis |
|---|---|---|
CreateAndroidPackageKey |
POST /v1/{parent=developerAccounts/*/androidPackages/*}/keys |
Rejestruje nowy odcisk cyfrowy certyfikatu SHA-256 podpisywania aplikacji w ramach AndroidPackage. Zwraca klucz w stanie DRAFT (gdy wymagany jest dowód własności za pomocą VerifyAndroidPackageKeyOwnership) lub bezpośrednio w stanie IN_REVIEW (gdy weryfikacja własności jest pomijana, np. w przypadku nowej nazwy pakietu, która nigdy nie była używana na Androidzie, lub klucza zweryfikowanego już w przypadku innej nazwy pakietu w tym samym DeveloperAccount). |
GetAndroidPackageKey |
GET /v1/{name=developerAccounts/*/androidPackages/*/keys/*} |
Pobiera stan, odcisk cyfrowy i metadane weryfikacji konkretnego elementu AndroidPackageKey. |
ListAndroidPackageKeys |
GET /v1/{parent=developerAccounts/*/androidPackages/*}/keys |
Wyświetla listę wszystkich obiektów AndroidPackageKey zarejestrowanych w AndroidPackage (pageSize, maks. 1000, pageToken). |
VerifyAndroidPackageKeyOwnership |
POST /upload/v1/{name=developerAccounts/*/androidPackages/*/keys/*}:verify |
Przesyła podpisany minimalny plik APK zawierający verificationToken w assets/adi-registration.properties, aby potwierdzić własność klucza prywatnego i przesłać gotowe klucze do sprawdzenia. |
JustifyAndroidPackageKeyRegistration |
POST /v1/{name=developerAccounts/*/androidPackages/*/keys/*}:justifyAndroidPackageKeyRegistration |
Przesyła dodatkowy kontekst uzasadnienia, gdy registrationJustificationRequired to true, i przesyła zweryfikowane klucze do sprawdzenia. |
Obsługa błędów
Gdy żądanie do interfejsu API się nie powiedzie, interfejs API Konsoli programisty Androida zwraca kod stanu HTTP 4xx lub 5xx oraz standardową treść błędu JSON google.rpc.Status:
{
"error": {
"code": 400,
"message": "Invalid certificate fingerprint SHA256 format.",
"status": "INVALID_ARGUMENT",
"details": []
}
}
Kody stanu HTTP i typowe rozwiązania
| Kod HTTP | Stan gRPC | Typowe przyczyny | Rozdzielczość |
|---|---|---|---|
400 Bad Request |
INVALID_ARGUMENT |
Brakujący lub nieprawidłowy element androidPackageId w stylu Javy; nieprawidłowy format certificateFingerprintSha256; niepuste pole name w CreateAndroidPackage lub CreateAndroidPackageKey; przesłany plik APK jest niepodpisany, uszkodzony, nie zawiera elementu assets/adi-registration.properties, nie zawiera pasującego elementu verificationToken lub jest podpisany niezgodnym certyfikatem. |
Sprawdź formaty żądań pod kątem schematów zasobów, pomiń lub pozostaw puste pole name w wywołaniach tworzenia oraz zweryfikuj podpis pliku APK i umieszczony token za pomocą apksigner verify --print-certs i unzip -p app-release.apk assets/adi-registration.properties przed przesłaniem. |
400 Bad Request |
FAILED_PRECONDITION |
DeveloperAccount ma verificationState: NOT_VERIFIED; wybór klucza narusza AndroidPackageRegistrationPolicy (SELECT_KEY_FROM_LIST); wywołanie VerifyAndroidPackageKeyOwnership lub JustifyAndroidPackageKeyRegistration w nieodpowiednim stanie. |
Przejdź weryfikację tożsamości dewelopera w Konsoli programisty Androida, najpierw sprawdź GetAndroidPackageRegistrationPolicy i sprawdź bieżący state zasobu. |
401 Unauthorized |
UNAUTHENTICATED |
Brak tokena dostępu Bearer OAuth 2.0, token wygasł lub jest nieprawidłowy albo próba uwierzytelnienia za pomocą klucza interfejsu API lub konta usługi. | Uzyskaj nowy token dostępu okaziciela OAuth 2.0 przekazany przez użytkownika z zakresem https://www.googleapis.com/auth/androiddeveloperconsole. |
403 Forbidden |
PERMISSION_DENIED |
Uwierzytelniony użytkownik nie ma uprawnień do docelowego elementu DeveloperAccount lub AndroidPackage albo interfejs Android Developer Console API nie jest włączony w projekcie Google Cloud. |
Sprawdź członkostwo konta za pomocą ListDeveloperAccounts i upewnij się, że usługa androiddeveloperconsole.googleapis.com jest włączona w konsoli Google Cloud. |
404 Not Found |
NOT_FOUND |
Podana ścieżka zasobu DeveloperAccount, AndroidPackage lub AndroidPackageKey nie istnieje. |
Potwierdź ścieżki zasobów za pomocą ListDeveloperAccounts, ListAndroidPackages lub ListAndroidPackageKeys. Upewnij się, że identyfikatory {key} używają małych liter w systemie szesnastkowym bez dwukropków. |
409 Conflict |
ALREADY_EXISTS |
Nazwa pakietu lub odcisk cyfrowy certyfikatu SHA-256 są już zarejestrowane na tym lub innym koncie dewelopera. | Sprawdź istniejące rejestracje za pomocą GetAndroidPackage lub GetAndroidPackageKey albo sprawdź historię własności za pomocą GetAndroidPackageRegistrationPolicy. |
429 Too Many Requests |
RESOURCE_EXHAUSTED |
Przekroczono limit 2,000 żądań dziennie na metodę w projekcie Google Cloud. |
Zaimplementuj wzrastający czas do ponowienia z zakłóceniami i unikaj pętli odpytywania o wysokiej częstotliwości. |
500/503 |
INTERNAL/UNAVAILABLE |
Przejściowy błąd backendu lub tymczasowa niedostępność usługi. | Ponów żądania idempotentne ze skróconym wzrastającym czasem do ponowienia. |
Przykłady żądań i odpowiedzi HTTP
Zastąp wartości zmiennych, takie jak ACCESS_TOKEN, 1234567890, com.example.myapp i 60e860e8..., własnymi wartościami.
1. GetDeveloperAccount
curl -X GET \
-H "Authorization: Bearer ACCESS_TOKEN" \
"https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890"Odpowiedź:
{
"name": "developerAccounts/1234567890",
"displayName": "Example Developer",
"verificationState": "VERIFIED"
}
2. ListDeveloperAccounts
curl -X GET \
-H "Authorization: Bearer ACCESS_TOKEN" \
"https://androiddeveloperconsole.googleapis.com/v1/developerAccounts"Odpowiedź:
{
"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"Odpowiedź:
{
"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"Odpowiedź:
{
"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"Odpowiedź:
{
"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"Odpowiedź:
{
"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"Odpowiedź:
{
"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"Odpowiedź:
{
"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"Odpowiedź:
{
"androidPackageKeys": [
{
"name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
"certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
"state": "REGISTERED"
}
],
"nextPageToken": ""
}
10. VerifyAndroidPackageKeyOwnership
Opcja A. Przesyłanie multimediów za pomocą pojedynczego żądania
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"Opcja B. Protokół przesyłania z możliwością wznowienia (zalecany w przypadku dużych plików APK lub CI/CD)
Krok 1. Rozpocznij sesję przesyłania z możliwością wznowienia i wyodrębnij zwrócony nagłówek 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"
}'Krok 2. Prześlij podpisany plik binarny APK do UPLOAD_SESSION_URI i sfinalizuj sesję:
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"Odpowiedź:
{
"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"Odpowiedź:
{
"name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
"certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
"state": "IN_REVIEW",
"registrationJustificationRequired": true
}
Dodatkowe materiały
- Rejestrowanie nazw pakietów za pomocą interfejsu API Konsoli programisty Androida
- Sprawdzanie stanu rejestracji aplikacji za pomocą interfejsu Android Developer ID Status API
- Rejestracja w Konsoli programisty Androida
- Rejestracja w Konsoli Google Play