فئات وواجهات LVL
يسرد الجدول 1 جميع الملفات المصدر في "مكتبة التحقّق من الترخيص"
(LVL) المتاحة من خلال حزمة تطوير البرامج (SDK) لنظام التشغيل Android. تُعد كل الملفات جزءًا من
حزمة com.android.vending.licensing
.
الفئة | الاسم | الوصف |
---|---|---|
التحقّق من الترخيص ونتائجه | أداة التحقّق من التراخيص | الفئة التي تنشئ مثيلاً لها (أو فئة فرعية) لبدء التحقّق من الترخيص. |
LicenseCheckerCallback | الواجهة التي تستخدمها لمعالجة نتيجة التحقّق من الترخيص. | |
السياسة | السياسة | الواجهة التي تنفّذها لتحديد ما إذا كان سيتم السماح بالوصول إلى التطبيق استنادًا إلى استجابة الترخيص. |
سياسة إدارة الخادم | عملية التنفيذ التلقائية للقاعدة Policy . تستخدم هذه السياسة الإعدادات التي يوفّرها خادم الترخيص لإدارة التخزين المحلي لبيانات الترخيص وصلاحية الترخيص
وإعادة المحاولة. |
|
سياسة متشددة | طريقة تنفيذ Policy بديلة ينفذ الترخيص استنادًا إلى استجابة
الترخيص المباشرة من الخادم فقط. ليس هناك تخزين مؤقت أو طلب إعادة المحاولة. |
|
تشويش البيانات (اختياري) |
أداة تشويش | الواجهة التي تنفّذها إذا كنت تستخدم واجهة Policy (مثل
ServerManagedPolicy) التي تخزّن بيانات استجابة الترخيص في متجر دائم.
يطبق خوارزمية التشويش على ترميز وفك ترميز البيانات التي تتم كتابتها أو قراءتها. |
خوارزمية التشفير المتقدّم (AES) | هو التطبيق التلقائي لأداة Obfuscator الذي يستخدم خوارزمية التشفير AES/فك التشفير لتشويش البيانات أو إزالة تشويشها. | |
الحد الأقصى لعدد الأجهزة (اختياري) |
Devicelimiter | الواجهة التي تنفّذها إذا أردت حصر استخدام أحد التطبيقات بجهاز معين. تم استدعاء الدالة من License Verificationator. لا يُنصَح بتنفيذ Devicelimiteder في معظم التطبيقات لأنّها تتطلّب خادم خلفية وقد تتسبب في فقدان المستخدم لإمكانية الوصول إلى التطبيقات المُرخَّصة، ما لم يتم تصميمها بحرص. |
NullDevicelimiter | عملية تنفيذ Devicelimiter التلقائية التي لا تعمل (يسمح بالوصول إلى جميع الأجهزة). | |
تطبيق أساسي للمكتبة، لا حاجة إلى أي دمج | بيانات الاستجابة | الفئة التي تحتوي على حقول استجابة الترخيص. |
أداة التحقّق من صحة التراخيص | الفئة التي تفك تشفير استجابة تم استلامها من خادم الترخيص وتتحقق منها. | |
التحقّق من الاستثناء | فئة تشير إلى الأخطاء التي تحدث عند التحقّق من سلامة البيانات التي يديرها برنامج Obfuscator. | |
تفضيل | فئة الأداة التي تكتب/تقرأ البيانات التي تم تشويشها في متجر
SharedPreferences الخاص بالنظام. |
|
ILicensingService | واجهة IPC أحادية الاتجاه التي يتم من خلالها تمرير طلب التحقق من الترخيص إلى عميل Google Play. | |
ILicenseResultListener | تنفيذ معاودة الاتصال IPC الأحادي الاتجاه الذي يتلقى التطبيق من خلاله استجابة غير متزامنة من خادم الترخيص. |
استجابة الخادم
يسرد الجدول 2 جميع حقول استجابة الترخيص التي يعرضها خادم الترخيص.
الحقل | الوصف |
---|---|
responseCode |
رمز الاستجابة الذي يعرضه خادم الترخيص. يتم توضيح رموز الاستجابة في رموز استجابة الخادم. |
signedData |
يشير ذلك المصطلح إلى تسلسل سلاسل يضم البيانات التي يعرضها خادم الترخيص، على النحو التالي: responseCode|nonce|packageName|versionCode|userId|timestamp:extras .
|
signature |
توقيع signedData باستخدام مفتاح خاص بالتطبيق.
|
رموز استجابة الخادم
يسرد الجدول 3 جميع رموز استجابة الترخيص المتوافقة مع خادم الترخيص. بشكل عام، يجب أن يعالج التطبيق جميع رموز الاستجابة هذه. وبشكل تلقائي، توفّر فئة LicensePolicyator في LVL كل عمليات المعالجة اللازمة لرموز الاستجابة هذه.
رمز الاستجابة | تمثيل القيمة الصحيحة | الوصف | هل تم التوقيع؟ | محتوى إضافي | التعليقات |
---|---|---|---|---|---|
LICENSED |
0 |
تم ترخيص التطبيق للمستخدم. اشترى المستخدم التطبيق، أو يملك إذنًا بتنزيل وتثبيت الإصدار ألفا أو التجريبي من التطبيق | نعم | VT ، GT ، GR |
السماح بالوصول وفقًا لقيود Policy |
LICENSED_OLD_KEY |
2 |
يتم ترخيص التطبيق للمستخدم، ولكن يتوفر إصدار محدّث من التطبيق موقَّع بمفتاح مختلف. | نعم | VT وGT وGR وUT |
يمكنك السماح بالوصول وفقًا لقيود Policy إذا أردت ذلك.
يمكن أن يشير إلى أن زوج المفاتيح المستخدم في إصدار التطبيق المثبت غير صالح أو مخترَق. يمكن للتطبيق السماح بالوصول إذا لزم الأمر أو إبلاغ المستخدم بتوفّر ترقية والحدّ من الاستخدام الإضافي حتى الترقية. |
NOT_LICENSED |
1 |
لم يتم ترخيص التطبيق للمستخدم. | لا | عدم السماح بالوصول: | |
ERROR_CONTACTING_SERVER |
257 |
خطأ محلي: تعذّر على تطبيق Google Play الوصول إلى خادم الترخيص، ربما بسبب مشاكل في مدى توفُّر الشبكة. | لا | إعادة محاولة فحص الترخيص وفقًا لحدود إعادة المحاولة Policy . |
|
ERROR_SERVER_FAILURE |
4 |
خطأ في الخادم - لم يتمكن الخادم من تحميل زوج مفاتيح التطبيق للترخيص. | لا | إعادة محاولة فحص الترخيص وفقًا لحدود إعادة المحاولة Policy .
|
|
ERROR_INVALID_PACKAGE_NAME |
258 |
خطأ محلي - طلب التطبيق فحص الترخيص لحزمة غير مثبتة على الجهاز. | لا | عدم إعادة محاولة التحقّق من الترخيص
يحدث هذا عادةً بسبب خطأ في التطوير. |
|
ERROR_NON_MATCHING_UID |
259 |
خطأ محلي - طلب التطبيق فحص الترخيص لحزمة لا يتطابق معرفها الفريد (الحزمة أو زوج معرف المستخدم) مع التطبيق مقدم الطلب. | لا | عدم إعادة محاولة التحقّق من الترخيص
يحدث هذا عادةً بسبب خطأ في التطوير. |
|
ERROR_NOT_MARKET_MANAGED |
3 |
خطأ في الخادم - لم يتعرّف Google Play على التطبيق (اسم الحزمة). | لا | عدم إعادة محاولة التحقّق من الترخيص
يمكن أن تشير إلى أنّ التطبيق لم يتم نشره من خلال Google Play أو إلى حدوث خطأ في التطوير في تنفيذ الترخيص. |
ملاحظة: كما هو موثق في إعداد بيئة الاختبار، يمكن إلغاء رمز الاستجابة يدويًا لمطوِّر التطبيق وأي مستخدمي اختبار مسجَّلين عبر Google Play Console.
ملاحظة: في السابق، كان بإمكانك اختبار أحد التطبيقات من خلال تحميل إصدار "مسودّة" غير منشور. لم تعُد هذه الوظيفة متاحة، وبدلاً من ذلك، عليك نشرها على قناة التوزيع ألفا أو التجريبية. لمزيد من المعلومات، يُرجى الاطّلاع على مسودّة التطبيقات لم تعُد متوافقة.
الإضافات الإضافية لاستجابة الخادم
لمساعدة تطبيقك في إدارة الوصول إلى التطبيق خلال فترة ردّ أموال التطبيق وتوفير معلومات أخرى، يضمّن خادم الترخيص عدة أجزاء من المعلومات في ردود الترخيص. وعلى وجه التحديد، توفّر الخدمة القيم المقترَحة لفترة صلاحية ترخيص التطبيق وفترة السماح لإعادة المحاولة والحد الأقصى لعدد مرات إعادة المحاولة المسموح به وغير ذلك من الإعدادات. إذا كان تطبيقك يستخدم ملفات توسيع APK، ستتضمّن الاستجابة أيضًا أسماء الملفات وأحجامها وعناوين URL. ويُلحق الخادم الإعدادات كأزواج المفتاح/القيمة في حقل "إضافية" لاستجابة الترخيص.
يمكن لأي عملية تنفيذ للسمة Policy
استخراج إعدادات الإضافات من استجابة الترخيص واستخدامها حسب الحاجة. إنّ آلية تنفيذ Policy
التلقائية في LVL، ServerManagedPolicy
، هي بمثابة طريقة تنفيذ عملية ورسم توضيحي لكيفية الحصول على الإعدادات وتخزينها واستخدامها.
المزيد! | الوصف |
---|---|
VT |
الطابع الزمني لصلاحية الترخيص تحدد التاريخ/الوقت الذي تنتهي عنده استجابة الترخيص الحالي (المخزَّن مؤقتًا) ويجب إعادة التحقّق منها على خادم الترخيص. يُرجى الاطّلاع على القسم أدناه حول فترة صلاحية الترخيص. |
GT |
الطابع الزمني لفترة السماح تحدّد هذه السياسة نهاية الفترة التي قد تسمح السياسة خلالها
بالوصول إلى التطبيق، حتى إذا كانت حالة الاستجابة هي
RETRY . يدير الخادم القيمة، لكن القيمة المعتادة تكون 5 أيام أو أكثر. يُرجى الاطِّلاع على القسم أدناه حول فترة إعادة المحاولة والحد الأقصى لعدد إعادة المحاولة. |
GR |
الحدّ الأقصى لعدد عمليات إعادة المحاولة تحدِّد هذه السياسة عدد عمليات التحقّق المتتالية المتعلّقة بتراخيص RETRY
التي يجب أن يسمح بها Policy ، وذلك قبل منع المستخدم من الوصول إلى التطبيق.
يدير الخادم القيمة، لكن القيمة النموذجية تكون "10" أو أعلى. يُرجى الاطِّلاع على القسم أدناه حول فترة إعادة المحاولة والحد الأقصى لعدد إعادة المحاولة. |
UT |
الطابع الزمني للتحديث. تحدد اليوم/الوقت الذي تم فيه تحميل
آخر تحديث لهذا التطبيق ونشره. يعرض الخادم هذه البيانات الإضافية فقط لردود |
FILE_URL1 أو FILE_URL2 |
عنوان URL لملف توسيع (1 هو للملف الرئيسي، 2 هو ملف التصحيح). استخدِم هذا الخيار لتنزيل الملف عبر بروتوكول HTTP. |
FILE_NAME1 أو FILE_NAME2 |
اسم ملف التوسيع (1 هو للملف الرئيسي، 2 هو ملف التصحيح). يجب استخدام هذا الاسم عند حفظ الملف على الجهاز. |
FILE_SIZE1 أو FILE_SIZE2 |
حجم الملف بالبايت (1 هو الملف الرئيسي، 2 هو ملف التصحيح). واستخدم هذا التطبيق للمساعدة في التنزيل والتأكد من توفّر مساحة كافية على موقع التخزين المشترك للجهاز قبل التنزيل. |
مدة صلاحية الترخيص
يضبط خادم الترخيص في Google Play مدة صلاحية الترخيص لجميع التطبيقات التي تم تنزيلها. وتعبِّر الفترة عن الفترة الزمنية التي يجب خلالها اعتبار حالة ترخيص التطبيق غير متغيرة وقابلة للتخزين المؤقت من خلال Policy
للترخيص في التطبيق. يعرض خادم الترخيص
مدة الصلاحية استجابةً لجميع فحوصات التراخيص، مع إلحاق طابع زمني
لانتهاء الصلاحية بالاستجابة كمدة إضافية ضمن المفتاح VT
. يمكن لـ
Policy
استخراج قيمة مفتاح VT واستخدامها للسماح بالوصول المشروط إلى التطبيق
بدون إعادة التحقّق من الترخيص، وذلك إلى أن تنتهي صلاحية
مدة الصلاحية.
تشير صلاحية الترخيص إلى Policy
للترخيص عندما يكون مطلوبًا منه إعادة التحقّق من حالة الترخيص مع خادم الترخيص. ولا يهدف إلى الإشارة ضمنًا إلى
ما إذا كان التطبيق مرخصًا للاستخدام أم لا. وهذا لا يعني أنّه عند انتهاء صلاحية فترة صلاحية ترخيص التطبيق، لا يعني ذلك أنّ التطبيق لم يعُد مرخَّصًا للاستخدام، بل يشير فقط إلى أنّه على Policy
إعادة التحقّق من حالة الترخيص مع الخادم. بناءً على ذلك،
ما دامت مدة صلاحية الترخيص لم تنتهِ، يُسمح لـ
Policy
بتخزين حالة الترخيص الأولية مؤقتًا على الجهاز وعرض حالة الترخيص المُخزَّنة مؤقتًا
بدلاً من إرسال فحص ترخيص جديد إلى الخادم.
ويدير خادم الترخيص مدة الصلاحية كوسيلة لمساعدة التطبيق في تنفيذ الترخيص على نحو سليم خلال فترة رد الأموال التي يوفرها Google Play للتطبيقات المدفوعة. تحدّد مدة الصلاحية استنادًا إلى ما إذا كان تم شراء التطبيق أم لا، وإذا كان الأمر كذلك، كانت المدة التي تسبقه. وعلى وجه التحديد، يضبط الخادم فترة الصلاحية على النحو التالي:
- بالنسبة إلى التطبيق المدفوع، يضبط الخادم مدة صلاحية الترخيص الأولية حتى تظل استجابة الترخيص صالحة ما دام التطبيق قابلاً للاسترداد. قد يخزن
Policy
للترخيص في التطبيق مؤقتًا نتيجة الفحص الأولي للترخيص ولا يحتاج إلى إعادة التحقق من الترخيص حتى تنتهي مدة الصلاحية. - عندما لا يمكن استرداد المبلغ المدفوع في التطبيق، يحدد الخادم فترة صلاحية أطول، تكون عادةً عددًا من الأيام.
- بالنسبة إلى أي تطبيق مجاني، يضبط الخادم مدة الصلاحية على قيمة عالية جدًا (
long.MAX_VALUE
). وهذا يضمن أنه شريطة أن يخزّنPolicy
الطابع الزمني للصلاحية مؤقتًا محليًا، لن يحتاج إلى إعادة التحقق من حالة ترخيص التطبيق في المستقبل.
في عملية تنفيذ ServerManagedPolicy
، يتم استخدام الطابع الزمني المستخرَج
(mValidityTimestamp
) كشرط أساسي لتحديد ما إذا كان يجب
إعادة التحقّق من حالة الترخيص مع الخادم قبل السماح للمستخدم بالوصول
إلى التطبيق.
فترة إعادة المحاولة والحد الأقصى لعدد إعادة المحاولة
في بعض الحالات، قد تمنع شروط النظام أو الشبكة فحص ترخيص التطبيق من الوصول إلى خادم الترخيص أو تمنع استجابة الخادم من الوصول إلى تطبيق عميل Google Play. على سبيل المثال، قد يشغِّل المستخدم تطبيقًا في حال عدم توفّر شبكة خلوية أو اتصال بيانات، كما هو الحال عند التواجد على متن طائرة، أو عندما يكون اتصال الشبكة غير مستقر أو عندما تكون إشارة شبكة الجوّال ضعيفة.
عندما تمنع مشاكل في الشبكة فحص الترخيص أو تقاطعه، يرسل برنامج Google Play إشعارًا إلى التطبيق من خلال عرض رمز استجابة RETRY
لطريقة processServerResponse()
في Policy
. في حال حدوث مشاكل في النظام، مثلاً عندما يتعذّر على التطبيق الربط بتطبيق
ILicensingService
في Google Play، تطلب مكتبة LicenseChecker
نفسها من طريقة
السياسة processServerResponse()
باستخدام رمز الاستجابة RETRY
.
وبشكل عام، يشير رمز الاستجابة RETRY
إلى التطبيق بحدوث
خطأ، ما أدى إلى منع اكتمال عملية التحقّق من الترخيص.
يساعد خادم Google Play أحد التطبيقات في إدارة الترخيص في ظل شروط الخطأ من خلال ضبط "فترة السماح" لإعادة المحاولة والحد الأقصى لعدد المحاولات المسموح بها. يضمِّن الخادم هذه القيم في جميع استجابات فحص الترخيص،
وإلحاقها كقيم إضافية ضمن المفتاحين GT
وGR
.
يمكن للتطبيق Policy
استخراج الإضافة GT
وGR
واستخدامها للسماح بالوصول إلى التطبيق بشكل مشروط، على النحو التالي:
- بالنسبة إلى عملية التحقّق من الترخيص التي تؤدي إلى ظهور استجابة
RETRY
، يجب أن تخزن علامةPolicy
مؤقتًا رمز الاستجابةRETRY
وأن تزيد من عدد ردودRETRY
. - من المفترض أن تسمح
Policy
للمستخدم بالوصول إلى التطبيق، بشرط أن لا تزال فترة السماح لإعادة المحاولة نشطة أو لم يتم الوصول إلى الحد الأقصى لعدد عمليات إعادة المحاولة.
وتستخدم السمة ServerManagedPolicy
قيم GT
وGR
التي يوفّرها الخادم كما هو موضّح أعلاه. يوضّح المثال أدناه المعالجة المشروطة لردود إعادة المحاولة في طريقة allow()
. يتم الاحتفاظ بعدد RETRY
من الردود
في طريقة processServerResponse()
، ولا يتم عرضه.
Kotlin
fun allowAccess(): Boolean { val ts = System.currentTimeMillis() return when(lastResponse) { LICENSED -> { // Check if the LICENSED response occurred within the validity timeout. ts <= validityTimestamp // Cached LICENSED response is still valid. } RETRY -> { ts < lastResponseTime + MILLIS_PER_MINUTE && // Only allow access if we are within the retry period // or we haven't used up our max retries. (ts <= retryUntil || retryCount <= maxRetries) } else -> false } }
Java
public boolean allowAccess() { long ts = System.currentTimeMillis(); if (lastResponse == LicenseResponse.LICENSED) { // Check if the LICENSED response occurred within the validity timeout. if (ts <= validityTimestamp) { // Cached LICENSED response is still valid. return true; } } else if (lastResponse == LicenseResponse.RETRY && ts < lastResponseTime + MILLIS_PER_MINUTE) { // Only allow access if we are within the retry period // or we haven't used up our max retries. return (ts <= retryUntil || retryCount <= maxRetries); } return false; }