واجهة برمجة التطبيقات 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. - تفعيل واجهة برمجة التطبيقات والمصادقة: فعِّل
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
إمكانات واجهة المستخدم وواجهة برمجة التطبيقات في Android Developer Console
| المهمة | واجهة مستخدم الويب في Android Developer Console (android.google.com/developerconsole) |
Android Developer Console 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 للمقتطف الموقَّع في واجهة مستخدم Play Console | POST /upload/v1/{name}:verify (VerifyAndroidPackageKeyOwnership) |
| إرسال مبرّر عندما يتطلّب المفتاح مراجعة يدوية | طلب نصّي أثناء سير عمل تسجيل المفتاح | POST /v1/{name}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration) |
إعداد الخدمة والمصادقة
يجب أن تستخدم جميع طلبات البيانات من واجهة برمجة التطبيقات بروتوكول HTTPS وأن تتضمّن عنوان Authorization: Bearer
ACCESS_TOKEN يتم الحصول عليه باستخدام مسار خادم الويب OAuth 2.0 لحساب Google الذي أكمل عملية إثبات هوية المطوّر في Android Developer Console.
| الخاصية | القيمة |
|---|---|
| نقطة نهاية REST الأساسية | https://androiddeveloperconsole.googleapis.com |
| نقطة نهاية تحميل الوسائط | https://androiddeveloperconsole.googleapis.com/upload |
| إصدار واجهة برمجة التطبيقات | v1 |
| نطاق OAuth 2.0 المطلوب | https://www.googleapis.com/auth/androiddeveloperconsole |
| حد الحصة التلقائي | 2,000 طلب في اليوم لكل مشروع على Google Cloud لكل طريقة |
موارد واجهة برمجة التطبيقات ونقاط النهاية
تُنظّم واجهة برمجة التطبيقات 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
مورد Singleton الذي يعرضه
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 المتكاملة. |
الطرق: 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 |
إنّ عملية تسجيل مفتاح توقيع التطبيق في انتظار اكتمال عملية النقل. |
الطرق: 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"، ويتم إرسال المفاتيح التي تم التحقّق منها للمراجعة. |
معالجة الأخطاء
عند تعذُّر طلب بيانات من واجهة برمجة التطبيقات، تعرض واجهة برمجة تطبيقات Android Developer Console رمز حالة 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 مفقود أو منتهي الصلاحية أو غير صالح، أو محاولة المصادقة باستخدام مفتاح واجهة برمجة التطبيقات أو حساب خدمة. | احصل على رمز دخول جديد لحامل OAuth 2.0 مفوَّض من المستخدم مع النطاق https://www.googleapis.com/auth/androiddeveloperconsole. |
403 Forbidden |
PERMISSION_DENIED |
لا يملك المستخدم الذي تمت مصادقته إذنًا على DeveloperAccount أو AndroidPackage المستهدَفَين، أو أنّ واجهة برمجة التطبيقات Android Developer Console API غير مفعَّلة في مشروع Google Cloud. |
يُرجى التحقّق من عضوية الحساب باستخدام ListDeveloperAccounts والتأكّد من تفعيل androiddeveloperconsole.googleapis.com في Google Cloud Console. |
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. |
استخدِم خوارزمية الرقود الأسي الثنائي مع التفاوت وتجنَّب حلقات الاستطلاع العالية التردد. |
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
الخيار "أ": تحميل الوسائط بطلب واحد
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