مرجع الترخيص

فئات وواجهات LVL

يسرد الجدول 1 جميع الملفات المصدر في عملية "التحقّق من الترخيص" المكتبة (LVL) المتاحة من خلال حزمة تطوير البرامج (SDK) لنظام التشغيل Android جميع الملفات جزء من حزمة com.android.vending.licensing.

الجدول 1. ملخص مكتبة LVL والفئات والواجهات.

الفئة الاسم الوصف
التحقّق من الترخيص ونتائجه أداة التحقّق من التراخيص الفئة التي تنشئ مثيلاً لها (أو فئة فرعية) لبدء فحص الترخيص.
LicenseCheckerCallback الواجهة التي تنفّذها لمعالجة نتائج فحص الترخيص.
السياسة السياسة الواجهة التي تنفّذها لتحديد ما إذا كان يجب السماح الوصول إلى التطبيق، استنادًا إلى استجابة الترخيص.
سياسة مُدارة للخادم عملية تنفيذ "Policy" التلقائية يتم استخدام الإعدادات التي توفّرها لإدارة التخزين المحلي لبيانات الترخيص وصلاحية الترخيص إعادة المحاولة.
السياسة المتشددة تنفيذ Policy بديل. يفرض الترخيص استنادًا إلى استجابة الترخيص من الخادم فقط. لا حاجة للتخزين المؤقت أو طلب إعادة المحاولة.
تشويش البيانات
(اختياري)
أداة إخفاء مفاتيح فك التشفير تنفِّذها إذا كنت تستخدم Policy (مثل Server ManagedPolicy) التي تخزّن بيانات استجابة الترخيص مؤقّتًا في متجر دائم. تطبيق خوارزمية إخفاء مفاتيح فك التشفير لتشفير وفك ترميز البيانات التي تتم كتابتها أو تَقْرَأ
أداة AESObfuscator تنفيذ أداة إخفاء مفاتيح فك التشفير التلقائية التي تستخدم تشفير/فك تشفير AES للتشويش على البيانات أو إلغاء تشويشها.
تقييد الأجهزة
(اختياري)
Devicelimiter الواجهة التي تنفذها إذا كنت تريد تقييد استخدام التطبيق على جهاز محدد. تم طلب الإذن من LicenseValidator. التنفيذ لا يُنصح باستخدام تطبيق DeviceLimiter مع معظم التطبيقات لأنّه يتطلب إضافة. خادم الخلفية وقد يتسبب في فقدان المستخدم لإمكانية الوصول إلى التطبيقات المرخصة، ما لم يتم تصميمها بعناية.
محدد الجهاز Null تطبيق Devicelimiteder التلقائي الذي لا يمكن تنفيذه (يسمح بالوصول إلى جميع الأجهزة).
مكتبة أساسية، لا حاجة للدمج بيانات الاستجابة فئة تتضمن حقول استجابة الترخيص.
مدقّق الترخيص الصف الذي يفك تشفير الردود التي تم تلقّيها من الترخيص ويتحقّق منها الخادم.
التحقق من الاستثناء فئة تشير إلى الأخطاء التي تحدث عند التحقق من سلامة البيانات التي يديرها مُبهج.
أداة PreferenceObfuscator فئة الأداة التي تكتب/تقرأ البيانات المُشفَّرة إلى متجر "SharedPreferences"
ILicensingService واجهة IPC أحادية الاتجاه التي يتم من خلالها تمرير طلب فحص الترخيص إلى Google Play.
ILicenseResultListener تنفيذ استدعاء IPC أحادي الاتجاه الذي يتلقى التطبيق من خلاله استجابة غير متزامنة من خادم الترخيص

استجابة الخادم

يسرد الجدول 2 جميع حقول استجابة الترخيص التي تم إرجاعها بواسطة خادم ترخيص.

الجدول 2. ملخّص حقول استجابة الترخيص يعرضها خادم Google Play.

الحقل الوصف
responseCode رمز الاستجابة الذي يعرضه خادم الترخيص. رموز الاستجابة هي موضح في رموز استجابة الخادم.
signedData تسلسل سلسلة تحتفظ بالبيانات التي يعرضها خادم الترخيص، على النحو التالي: responseCode|nonce|packageName|versionCode|userId|timestamp:extras
  • responseCode: رمز الاستجابة الذي يعرضه خادم الترخيص
  • nonce: معرّف الرقم الخاص بالطلب
  • packageName: اسم حزمة التطبيق المطلوب التحقّق من ترخيصه
  • versionCode: رمز إصدار التطبيق المطلوب التحقّق من الترخيص له
  • userId: معرّف فريد للمستخدم لكل تطبيق، حيث يحصل المستخدم نفسه على معرّف مختلف لتطبيق مختلف.
  • timestamp: عدد المللي ثانية التي تعود إلى حقبة 1970-01-01 00:00:00 بالتوقيت العالمي المنسق (UTC) للطلب.
  • extras: معلومات إضافية للمساعدة في إدارة التراخيص من التطبيق. الحقول الإضافية مبينة في الميزات الإضافية لاستجابة الخادم
signature توقيع signedData باستخدام مفتاح خاص بالتطبيق.

رموز استجابة الخادم

يسرد الجدول 3 جميع رموز استجابة الترخيص المتوافقة مع خادم ترخيص. بشكل عام، يجب أن يتعامل التطبيق مع كل هذه الاستجابات الرموز. وبشكل افتراضي، توفر فئة LicenseValidator في LVL جميع من أجل معالجة رموز الاستجابة هذه.

الجدول 3. ملخّص رموز الاستجابة يعرضها خادم Google Play في استجابة الترخيص.

رمز الاستجابة تمثيل عدد صحيح والقيمة الوصف هل تم التوقيع؟ المحتوى الإضافي التعليقات
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 خطأ محلي — طلب التطبيق فحص الترخيص لحزمة الذي لا يطابق UID الخاص به (الحزمة، زوج معرّف المستخدم) معرّف الطلب التطبيق. لا لا تعِد محاولة فحص الترخيص.

يحدث عادةً بسبب خطأ في التطوير.

ERROR_NOT_MARKET_MANAGED 3 خطأ في الخادم - لم يتمّ التعرّف على التطبيق (اسم الحزمة) من خلال Google Play. لا لا تعِد محاولة فحص الترخيص.

يمكن أن يشير إلى أنه لم يتم نشر التطبيق. من خلال Google Play أو أن هناك خطأ في التطوير في عملية الترخيص التنفيذ.

ملاحظة: كما هو موثّق في أثناء إعداد بيئة الاختبار، يمكن إدخال رمز الاستجابة يدويًا تم الإلغاء لمطوِّر التطبيق وأي مستخدمين اختباريين مسجَّلين من خلال Google Play Console

ملاحظة: كان بإمكانك في السابق اختبار أحد التطبيقات من خلال تحميل "مسودة" غير منشورة . لم تعُد هذه الوظيفة مدعوم؛ لكن يجب نشره في توزيع ألفا أو بيتا . لمزيد من المعلومات، يُرجى الاطّلاع على مسودة التطبيقات. لم تعُد متاحة.

الميزات الإضافية لاستجابة الخادم

لمساعدة تطبيقك في إدارة أذونات الوصول إلى التطبيق من خلال طلب استرداد الأموال ويقدمون معلومات أخرى، ويتضمن خادم الترخيص عدة أجزاء من المعلومات في ردود الترخيص. وعلى وجه التحديد، توفر الخدمة القيم الموصى بها فترة صلاحية ترخيص التطبيق، وفترة السماح لإعادة المحاولة، والحد الأقصى لعدد مرات إعادة المحاولة المسموح به، وغير ذلك الإعدادات. في حال كان تطبيقك يستخدم APK ملفات بيانات موسّعة، تتضمّن الاستجابة أيضًا أسماء الملفات وأحجامها وعناوين URL. يُلحق الخادم الإعدادات كأزواج المفتاح/القيمة في استجابة الترخيص "الإضافية" .

يمكن لأي تنفيذ Policy استخراج الإعدادات الإضافية من الترخيص الرد واستخدامها حسب الحاجة. تُعدّ عملية تنفيذ Policy التلقائية في LVL، ServerManagedPolicy، طريقة فعّالة ورسم توضيحي لكيفية الحصول على ملف التعريف وتخزينه واستخدامه الإعدادات.

الجدول 4. ملخّص عن إعدادات إدارة التراخيص التي يوفِّرها خادم Google Play في أحد التراخيص الاستجابة.

منشئ محتوى إضافيالوصف
VT الطابع الزمني لصلاحية الترخيص تحدد التاريخ/الوقت الذي (مخزّن مؤقتًا) تنتهي صلاحية استجابة الترخيص ويجب إعادة التحقق منها على خادم الترخيص. الاطّلاع على القسم أدناه حول فترة صلاحية الترخيص.
GT الطابع الزمني لفترة السماح تحدد نهاية الفترة التي يتم خلالها قد تسمح السياسة بالوصول إلى التطبيق، حتى إذا كانت حالة الاستجابة RETRY

يدير الخادم القيمة، إلا أن القيمة المعتادة ستكون 5. أو أكثر من ذلك. الاطّلاع على القسم أدناه حول فترة إعادة المحاولة والحد الأقصى لعدد مرات إعادة المحاولة.

GR الحد الأقصى لعدد المحاولات تحدِّد هذه السياسة عدد عمليات التحقّق المتتالية للترخيص في "RETRY". يجب أن يسمح Policy، قبل منع المستخدم من الوصول إلى التطبيق.

يدير الخادم القيمة، على الرغم من أن القيمة المعتادة ستكون "10". أو أعلى. الاطّلاع على القسم أدناه حول فترة إعادة المحاولة والحد الأقصى لعدد مرات إعادة المحاولة.

UT الطابع الزمني للتحديث. تُحدِّد اليوم/الوقت عندما يكون آخر تعديل على تم تحميل هذا التطبيق ونشره.

يعرض الخادم هذه القيمة الإضافية لردود LICENSED_OLD_KEYS فقط، للسماح لـ Policy بتحديد مقدار انقضى وقت طويل منذ نشر تحديث باستخدام مفاتيح ترخيص جديدة قبل يرفض دخول المستخدم إلى التطبيق.

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، تستدعي مكتبة 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;
}