تحذير: عندما يُجري تطبيقك عملية التحقّق من الترخيص على من جانب العميل، يصبح من الأسهل على المهاجمين المحتملين تعديل المنطق المرتبط بعملية التحقق هذه.
ولهذا السبب، نشجّعك بشدة على تنفيذ عملية من جانب الخادم إثبات صحة الترخيص بدلاً من ذلك.
بعد إعداد حساب الناشر وبيئة التطوير (راجع الإعداد للترخيص)، تكون مستعدًا لإضافة عملية التحقق من الترخيص إلى تطبيقك مع "مكتبة التحقّق من التراخيص" (LVL).
تتضمن إضافة التحقق من الترخيص مع LVL المهام التالية:
- إضافة إذن الترخيص في بيان تطبيقك
- تنفيذ سياسة: يمكنك اختيار إحدى عمليات التنفيذ الكاملة الواردة في LVL أو إنشاء عمليات التنفيذ الخاصة بك.
- تنفيذ مُبهج، إذا كان
Policy
يخزِّن أيًّا منها في ذاكرة التخزين المؤقت وبيانات استجابة الترخيص. - إضافة رمز للتحقق من الترخيص في الملف الرئيسي لتطبيقك النشاط.
- Implementing a DeviceLimiter (اختياريّة ولا يُنصح باستخدامها) معظم التطبيقات).
تصف الأقسام أدناه هذه المهام. عند الانتهاء من يجب أن تتمكن من تجميع تطبيقك بنجاح بدء الاختبار كما هو موضح في قسم إعداد الاختبار البيئة:
للحصول على نظرة عامة على المجموعة الكاملة من ملفات المصدر المضمنة في LVL، يمكنك الاطلاع على ملخص فئات LVL والواجهات:
إضافة إذن الترخيص
لاستخدام تطبيق Google Play لإرسال فحص الترخيص إلى
الخادم، فيجب أن يطلب التطبيق الإذن المناسب،
com.android.vending.CHECK_LICENSE
إذا كان تطبيقك لا
عدم الإفصاح عن إذن الترخيص ولكنّه يحاول بدء فحص للترخيص
ينتج عن LVL استثناء أمني.
لطلب إذن الترخيص في تطبيقك، يجب الإفصاح عن <uses-permission>
.
كعنصر ثانوي في <manifest>
على النحو التالي:
<uses-permission
android:name="com.android.vending.CHECK_LICENSE" />
على سبيل المثال، إليك الطريقة التي يعرِّف بها تطبيق LVL النموذجي للإذن:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" ..."> <!-- Devices >= 3 have version of Google Play that supports licensing. --> <uses-sdk android:minSdkVersion="3" /> <!-- Required permission to check licensing. --> <uses-permission android:name="com.android.vending.CHECK_LICENSE" /> ... </manifest>
ملاحظة: في الوقت الحالي، لا يمكنك الإفصاح عن
CHECK_LICENSE
في بيان مشروع مكتبة LVL،
لأنّ أدوات SDK لن تدمجها في ملفات البيانات الخاصة
التطبيقات. وبدلاً من ذلك، يجب الإفصاح عن الإذن في كل فئة تابعة.
بيان التطبيق.
تنفيذ سياسة
لا تحدد خدمة الترخيص في Google Play بنفسها ما إذا كان
يجب منح مستخدم لديه ترخيص معيّن إمكانية الوصول إلى تطبيقك.
وإنما تُترك هذه المسؤولية على عاتق تنفيذ Policy
الذي تقدمه.
في تطبيقك.
السياسة هي واجهة تم تعريفها من قِبل LVL مصممة للاحتفاظ بـ
منطق التطبيق للسماح للمستخدم بالوصول أو منعه، بناءً على النتيجة
للتحقق من الترخيص. ولاستخدام LVL، يجب أن يوفّر تطبيقك
تنفيذ Policy
.
تعرض الواجهة Policy
طريقتين، هما allowAccess()
processServerResponse()
، والتي يتم استدعاؤها بواسطة LicenseChecker
مثال عند معالجة رد من خادم الترخيص. كما تعلن أيضًا عن
تعداد يُسمى LicenseResponse
، يحدد استجابة الترخيص
القيمة التي تم تمريرها في المكالمات إلى processServerResponse()
.
- يتيح لك
processServerResponse()
إجراء معالجة مسبقة للاستجابة الأولية. البيانات الواردة من خادم الترخيص، قبل تحديد ما إذا كان ينبغي منح الوصول إليه.ستؤدي عملية التنفيذ النموذجية إلى استخراج بعض الحقول أو جميعها من الترخيص. والاستجابة وتخزين البيانات محليًا في مخزن دائم، على سبيل المثال من خلال مساحة تخزين بسعة
SharedPreferences
، لضمان أن تكون البيانات يمكن الوصول إليه عبر استدعاءات التطبيقات ودورات تشغيل الجهاز. على سبيل المثال: سيحتفظPolicy
بالطابع الزمني لآخر عملية تحقق ناجحة للترخيص، وعدد مرات إعادة المحاولة ومدة صلاحية الترخيص ومعلومات مماثلة في بدلاً من إعادة تعيين القيم في كل مرة يتم فيها تشغيل التطبيق إطلاق المنتج.عند تخزين بيانات الاستجابة محليًا، يجب أن يتأكّد
Policy
من أنّ البيانات تتضمن تشويشًا (راجِع تنفيذ أداة إخفاء مفاتيح فك التشفير، أدناه). - يحدِّد تطبيق "
allowAccess()
" ما إذا كان سيتم منح المستخدم إذن الوصول إلى المحتوى. تطبيقك، استنادًا إلى أي بيانات متاحة للرد على الترخيص (من من خادم الترخيص أو من ذاكرة التخزين المؤقت) أو معلومات أخرى خاصة بالتطبيق. بالنسبة على سبيل المثال، يمكن أن يأخذ تنفيذallowAccess()
في على مستوى الحساب الإضافية، كالاستخدام أو البيانات الأخرى المأخوذة من خادم الخلفية. في جميع الحالات، لا يمكن تنفيذallowAccess()
يجب عرضtrue
فقط إذا كان المستخدم لديه ترخيص لاستخدام كما يحدده خادم الترخيص أو إذا كانت هناك مهلة مؤقتة مشكلة في الشبكة أو النظام تمنع اكتمال عملية فحص الترخيص. ضِمن مثل هذه الحالات، يمكن أن يحافظ تنفيذك على عدد من الردود على مرات إعادة المحاولة للسماح بالوصول بشكل مؤقت إلى أن تكتمل عملية التحقق التالية من الترخيص.
لتبسيط عملية إضافة الترخيص إلى تطبيقك
توضيح لكيفية تصميم Policy
، يتضمن LVL
عمليتي تنفيذ Policy
كاملتين يمكنك استخدامهما بدون تعديل أو
التكيف مع احتياجاتك:
- Server ManagedPolicy، وسياسة
Policy
المرنة تستخدم الإعدادات المقدَّمة من الخادم والردود المخزّنة مؤقتًا لإدارة إمكانية الوصول إلى البيانات وظروف الشبكة المتنوعة - شديدة، التي لا تخزّن أي استجابة مؤقتًا إلى البيانات وتسمح بالوصول فقط إذا قام الخادم بإرجاع ملف الاستجابة.
بالنسبة إلى معظم التطبيقات، غالبًا ما يكون استخدام ServerManagedPolicy الموصى بها. إن ServerManagedPolicy هو الإعداد التلقائي لـ LVL ويتم دمجه مع نموذج تطبيق LVL.
إرشادات السياسات المخصصة
عند تنفيذ الترخيص، يمكنك استخدام إحدى السياسات الكاملة المقدمة في LVL (ServerManagedPolicy أو StrictPolicy) أو يمكنك إنشاء سياسة مخصصة. بالنسبة إلى أي نوع من السياسات المخصصة، هناك العديد من مبادئ التصميم نقاط فهمها وأخذها في الاعتبار في عملية التنفيذ.
يطبِّق خادم الترخيص حدود الطلبات العامة للحماية من الاستخدام الزائد. من الموارد التي قد تؤدي إلى الحرمان من الخدمة. في حال تجاوز أحد التطبيقات حد الطلب، يعرض خادم الترخيص استجابة 503، إلى التطبيق على أنه خطأ عام في الخادم. هذا يعني عدم وجود استجابة الترخيص ستكون متاحة للمستخدم حتى تتم إعادة تعيين الحد، والذي يمكن أن يؤثر على المستخدم لفترة غير محددة.
في حال وضع سياسة مخصّصة، ننصحك بما يلي: Policy
:
- تخزّن ذاكرة التخزين المؤقت لأحدث استجابة للترخيص ناجحة (وتُخفي مفاتيح فك التشفير بشكل صحيح) في التخزين الدائم المحلي.
- عرض الاستجابة المخزّنة مؤقتًا لجميع عمليات التحقق من الترخيص، طوال ما دامت
تكون الاستجابة المخزّنة مؤقتًا صالحة، بدلاً من تقديم طلب إلى خادم الترخيص.
جارٍ ضبط صلاحية الاستجابة وفقًا لسياسة
VT
التي يوفّرها الخادم يوصى بشدة باستخدام المزيد. راجِع الإضافات لاستجابة الخادم لمزيد من المعلومات. - تستخدم فترة تراجع أسي، إذا كانت إعادة محاولة أي طلبات النتيجة في
الأخطاء. ملاحظة: تعذَّر على برنامج Google Play إعادة المحاولة تلقائيًا
لذلك، في معظم الحالات، لن تحتاج إلى إعادة المحاولة من خلال
Policy
. - توفر "فترة السماح" تتيح للمستخدم الوصول إلى لفترة محدودة أو لعدد محدود من الاستخدامات، بينما يتم التحقق من الترخيص تمت إعادة المحاولة. تعود فترة السماح بالنفع على المستخدم من خلال السماح بالوصول حتى فحص الترخيص بنجاح، وستفيدك من خلال وضع أقصى حد للوصول إلى تطبيقك في حال عدم وجود استجابة صالحة للترخيص المتوفرة.
يُعدّ تصميم Policy
وفقًا للإرشادات المذكورة أعلاه أمرًا بالغ الأهمية،
لأنه يضمن أفضل تجربة ممكنة للمستخدمين مع منحك
تحكمًا فعالاً في تطبيقك حتى في ظروف الخطأ.
يُرجى ملاحظة أنّه يمكن لأي Policy
استخدام الإعدادات التي يوفّرها خادم الترخيص لتنفيذ ما يلي:
المساعدة في إدارة الصلاحية والتخزين المؤقت وإعادة محاولة فترة السماح والمزيد. يمكن أن يؤدي استخراج
الإعدادات التي يوفرها الخادم واضحة ويسهل استخدامها بشكل كبير
الموصى بها. يُرجى الاطّلاع على تنفيذ سياسة ServerManagedPolicy للحصول على مثال عن كيفية
لاستخراج العناصر الإضافية واستخدامها. للحصول على قائمة بإعدادات الخادم ومعلومات حول
كيفية استخدامها، راجع استجابة الخادم
الميزات الإضافية
سياسة مُدارة للخادم
يشمل LVL التنفيذ الكامل والمقترَح لـ Policy
.
تسمى Server ManagedPolicy. يتم دمج التنفيذ مع
صفوف LVL وهي بمثابة Policy
التلقائية في المكتبة.
يوفّر خادم ServerManagedPolicy كل المعالجة للترخيص ويعيد المحاولة.
الردود. فهي تخزِّن جميع بيانات الاستجابة مؤقتًا محليًا في
ملف SharedPreferences
، مع إخفاء مفاتيح فك التشفير
تنفيذ Obfuscator
للتطبيق. يضمن ذلك استجابة الترخيص
البيانات آمنة وتستمر في جميع دورات الطاقة للجهاز. سياسة مُدارة للخادم
التطبيقات الملموسة لطرق الواجهة
processServerResponse()
وallowAccess()
وكذلك
مجموعة من الطرق وأنواع الدعم لإدارة التراخيص
الردود.
والأهم من ذلك، فإن إحدى الميزات الرئيسية لـ ServerManagedPolicy هي
الإعدادات التي يوفّرها الخادم كأساس لإدارة الترخيص في
فترة استرداد الأموال المدفوعة ومن خلال ظروف الشبكة والأخطاء المختلفة.
وعند اتصال أحد التطبيقات بخادم Google Play للتحقق من الترخيص،
يضيف الخادم العديد من الإعدادات كأزواج المفتاح/القيمة في حقل الوظائف الإضافية
أنواع استجابة الترخيص. على سبيل المثال، يقدم الخادم القيم المقترحة
مدة صلاحية ترخيص التطبيق، وفترة السماح لإعادة المحاولة، والحد الأقصى المسموح به
عدد إعادة المحاولة، من بين أساليب أخرى. يستخرج خادم ServerManagedPolicy القيم من
استجابة الترخيص بطريقة processServerResponse()
وعمليات الفحص
في طريقة allowAccess()
الخاصة بها. للحصول على قائمة بالعناوين
الإعدادات المستخدمة من قِبل ServerManagedPolicy، راجع استجابة الخادم
الميزات الإضافية
تسهيل الاستخدام وتحقيق أفضل أداء والاستفادة من إعدادات الترخيص
من خادم Google Play، باستخدام ServerManagedPolicy
يُنصح بشدة باستخدام الترخيص Policy
.
إذا كنت قلقًا بشأن أمان بيانات استجابة الترخيص
تم تخزينه محليًا في SharedPreferences
، يمكنك استخدام تشويش أقوى
أو تصمّم Policy
أكثر صرامة لا تخزِّن بيانات الترخيص. المستوى
مثال على Policy
، يمكنك الاطّلاع على StrictPolicy للحصول على مزيد من المعلومات.
لاستخدام ServerManagedPolicy، ما عليك سوى استيراده إلى "نشاطك" ثم أنشئ
وتمرير إشارة إلى المثيل عند إنشاء
LicenseChecker
راجع Instantiate LicenseChecker و
يُرجى الانتقال إلى LicenseCheckerCallback للاطّلاع على مزيد من المعلومات.
السياسة المتشددة
يتضمّن LVL طريقة تنفيذ كاملة بديلة لواجهة Policy
.
تسمى StrictPolicy. يوفر تنفيذ السياسة المتشددة نهجًا أكثر تقييدًا
أكثر من Server ManagedPolicy، حيث إنها لا تسمح للمستخدم بالوصول إلى
التطبيق ما لم يتم تلقي استجابة ترخيص من الخادم في
وقت الوصول الذي يشير إلى أن المستخدم مرخص.
تكمن الميزة الأساسية لسياسة StrictPolicy في أنها لا تخزن أي
بيانات استجابة الترخيص محليًا في متجر دائم. نظرًا لعدم تخزين أي بيانات،
لا يتم تتبُّع طلبات إعادة المحاولة ولا يمكن استخدام الردود المخزّنة مؤقتًا لتنفيذها
عمليات فحص التراخيص. لا يسمح Policy
بالوصول إلا في الحالات التالية:
- يتم تلقّي استجابة الترخيص من خادم الترخيص
- تشير استجابة الترخيص إلى أن المستخدم مرخص له الوصول إلى التطبيق.
من المناسب استخدام السياسة المتشددة إذا كانت مهمتك الأساسية هي التأكد من في جميع الحالات المحتملة، لن يتم السماح لأي مستخدم بالدخول إلى التطبيق ما لم أن يتم التأكد من أن المستخدم حاصل على ترخيص في وقت الاستخدام. بالإضافة إلى ذلك، توفّر هذه السياسة مستوى أمان أعلى إلى حد ما من Server ManagedPolicy — حيث لا توجد بيانات مخزنة مؤقتًا محليًا، فلا توجد طريقة يمكن بها لأي مستخدم ضار العبث بـ باستخدام البيانات المخزنة مؤقتًا والحصول على حق الوصول إلى التطبيق.
وفي الوقت نفسه، تمثل Policy
تحديًا للمستخدمين العاديين، نظرًا لأنها
يعني أنهم لن يتمكنوا من الدخول إلى التطبيق عند عدم وجود شبكة
يتوفر اتصال (شبكة جوّال أو Wi-Fi). من الآثار الجانبية الأخرى أن
إرسال المزيد من طلبات فحص الترخيص إلى الخادم، نظرًا لاستخدام
النسخة المخزنة مؤقتًا من الاستجابة غير ممكنة.
بشكل عام، تمثّل هذه السياسة درجة من الراحة للمستخدمين
للحصول على الأمان المطلق والتحكم في الوصول. التفكير في المقايضة بعناية
قبل استخدام Policy
.
ولاستخدام StrictPolicy، ما عليك سوى استيرادها إلى نشاطك وإنشاء مثيل،
ووجِّه إشارة إليه عند إنشاء LicenseChecker
. عرض
Instantiate LicenseChecker و LicenseCheckerCallback
لمزيد من المعلومات.
يحتاج تنفيذ Policy
النموذجي إلى حفظ بيانات استجابة الترخيص لـ
تطبيق إلى متجر دائم، بحيث يمكن الوصول إليه عبر
استدعاءات التطبيقات ودورات تشغيل الجهاز. على سبيل المثال، ستعرض السمة Policy
بالطابع الزمني لآخر فحص ناجح للترخيص وعدد مرات إعادة المحاولة
ومدة صلاحية الترخيص ومعلومات مماثلة في متجر دائم،
بدلاً من إعادة تعيين القيم في كل مرة يتم فيها تشغيل التطبيق. تشير رسالة الأشكال البيانية
تم تضمين Policy
التلقائي في LVL، وServerManagedPolicy، ويخزّن استجابة الترخيص.
البيانات في مثال SharedPreferences
، لضمان أن
البيانات دائمة.
لأنّ Policy
سيستخدم بيانات استجابة الترخيص المُخزَّنة لتحديد ما إذا كان
للسماح بالوصول إلى التطبيق أو منعه، يجب التأكد من أن أي
تكون البيانات المخزنة آمنة ولا يمكن إعادة استخدامها أو معالجتها من قبل المستخدم الجذر
الخاص بك. وعلى وجه التحديد، على Policy
دائمًا تشويش البيانات قبل تخزينها.
باستخدام مفتاح فريد للتطبيق والجهاز. التشويش باستخدام
مفتاح خاص بالتطبيق وخاص بالجهاز، نظرًا لأن ذلك
فإنها تمنع مشاركة البيانات المشبوهة بين التطبيقات
الأجهزة.
ويساعد LVL التطبيق في تخزين بيانات استجابة الترخيص في
بطريقة آمنة ومستمرة. أولاً، توفّر الميزة Obfuscator
تسمح لتطبيقك بتقديم خوارزمية التشويش
للبيانات المخزنة. بناءً على ذلك، توفر LVL الفئة المساعدة
PreferenceObfuscator، الذي يعالج معظم عمل استدعاء الدالة
في Obfuscator
للتطبيق وقراءة البيانات المشفَّرة وكتابتها في
مثيل واحد (SharedPreferences
)
يوفر LVL تنفيذ Obfuscator
كاملاً يسمى
أداة AESObfuscator التي تستخدم تشفير AES لتشويش البيانات يمكنك
استخدام AESObfuscator في تطبيقك بدون أي تعديل أو
تكييفه مع احتياجاتك. في حالة استخدام Policy
(مثل
Server ManagedPolicy) التي تخزّن بيانات استجابة الترخيص في ذاكرة التخزين المؤقت باستخدام أداة AESObfuscator
الأساسي عند تنفيذ Obfuscator
.
لمزيد من المعلومات، يُرجى الاطّلاع على القسم التالي.
أداة AESObfuscator
يشمل LVL التنفيذ الكامل والمقترَح لـ Obfuscator
.
تسمى AESObfuscator. يتم دمج التنفيذ مع
نموذج تطبيق LVL ويعمل كنموذج Obfuscator
التلقائي في المكتبة.
توفّر أداة AESObfuscator إمكانية تشويش البيانات بأمان باستخدام تشفير AES
تشفير البيانات وفك تشفيرها عند كتابتها أو قراءتها من وحدة التخزين.
يبدأ Obfuscator
التشفير باستخدام ثلاثة حقول بيانات متوفّرة.
من خلال التطبيق:
- القيمة العشوائية هي مصفوفة من وحدات البايت العشوائية لاستخدامها لكل عملية إخفاء مفاتيح فك التشفير.
- سلسلة معرف التطبيق، وعادةً ما تكون اسم حزمة التطبيق.
- سلسلة معرّف الجهاز، مشتقة من أكبر عدد ممكن من المصادر الخاصة بالأجهزة قدر الإمكان، حتى تجعلها فريدة من نوعها.
لاستخدام AESObfuscator، يجب أولاً استيراده إلى "نشاطك". إعلان جلسة خاصة الصفيفة النهائية الثابتة للاحتفاظ بوحدات البايت الملحة وإعدادها على 20 بشكل عشوائي وحدات البايت التي تم إنشاؤها.
Kotlin
// Generate 20 random bytes, and put them here. private val SALT = byteArrayOf( -46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95, -45, 77, -117, -36, -113, -11, 32, -64, 89 )
Java
... // Generate 20 random bytes, and put them here. private static final byte[] SALT = new byte[] { -46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95, -45, 77, -117, -36, -113, -11, 32, -64, 89 }; ...
بعد ذلك، عليك تعريف متغيّر يتضمّن معرّف الجهاز وإنشاء قيمة
بأي طريقة مطلوبة. على سبيل المثال، قد يتم تضمين نموذج التطبيق المضمّن في LVL
إلى إعدادات النظام
android.Settings.Secure.ANDROID_ID
، ويكون فريدًا لكل جهاز.
لاحظ أنه بناءً على واجهات برمجة التطبيقات التي تستخدمها، قد يحتاج التطبيق إلى
طلب أذونات إضافية للحصول على معلومات خاصة بالجهاز.
على سبيل المثال، للاستعلام عن TelephonyManager
للحصول على
رمز IMEI للجهاز أو البيانات ذات الصلة، سيحتاج التطبيق أيضًا إلى طلب
إذن android.permission.READ_PHONE_STATE
في ملف البيان.
قبل طلب أذونات جديدة لالغرض الوحيد من الحصول على الأذونات
المعلومات الخاصة بالجهاز لاستخدامها في Obfuscator
، يُرجى مراعاة
كيفية تأثير ذلك في تطبيقك أو على الفلترة المتعلّقة به على Google Play
(لأنّ بعض الأذونات قد تؤدي إلى إضافة أدوات إنشاء حزمة تطوير البرامج (SDK)
<uses-feature>
المرتبط).
وأخيرًا، أنشئ مثيلاً لـ AESObfuscator لتمرير الملح
ومعرّف التطبيق ومعرّف الجهاز. يمكنك إنشاء المثيل
مباشرةً، أثناء إنشاء Policy
وLicenseChecker
. مثلاً:
Kotlin
... // Construct the LicenseChecker with a Policy. private val checker = LicenseChecker( this, ServerManagedPolicy(this, AESObfuscator(SALT, packageName, deviceId)), BASE64_PUBLIC_KEY ) ...
Java
... // Construct the LicenseChecker with a Policy. checker = new LicenseChecker( this, new ServerManagedPolicy(this, new AESObfuscator(SALT, getPackageName(), deviceId)), BASE64_PUBLIC_KEY // Your public licensing key. ); ...
للحصول على مثال كامل، يُرجى الاطّلاع على MainActivity في نموذج تطبيق LVL.
التحقّق من الترخيص من نشاط
بعد تنفيذ Policy
لإدارة الوصول إلى تطبيقك،
الخطوة التالية هي إضافة عملية فحص للترخيص إلى تطبيقك، والتي تؤدي إلى بدء طلب
إلى خادم الترخيص إذا لزم الأمر، ويدير الوصول إلى التطبيق استنادًا إلى
استجابة الترخيص. كل أعمال إضافة التحقق من الترخيص ومعالجتها
تحدث الاستجابة في ملف مصدر Activity
الرئيسي.
لإضافة عملية التحقّق من الترخيص والتعامل مع الردّ، عليك إجراء ما يلي:
- إضافة عمليات استيراد
- تنفيذ LicenseCheckerCallback كفصل داخلي خاص
- إنشاء معالج للنشر من LicenseCheckerCallback إلى سلسلة واجهة المستخدم
- Instantiate LicenseChecker و LicenseCheckerCallback
- Call checkAccess() لبدء عملية البحث عن الترخيص
- تضمين مفتاحك العام للحصول على ترخيص
- استدعاء طريقة onDestroy() من LicenseChecker لإغلاق اتصالات IPC.
تصف الأقسام أدناه هذه المهام.
نظرة عامة على التحقّق من الترخيص والردّ عليه
في معظم الحالات، عليك إضافة فحص الترخيص إلى قسم
Activity
، بطريقة onCreate()
. هذا النمط
ويضمن فحص الترخيص عندما يشغّل المستخدم تطبيقك مباشرةً
على الفور. في بعض الحالات، يمكنك إضافة عمليات فحص للترخيص في
المواقع أيضًا. على سبيل المثال، إذا كان تطبيقك يتضمن أنشطة متعددة
التي يمكن للتطبيقات الأخرى تشغيلها من خلال Intent
،
يمكنك إضافة عمليات فحص للتراخيص في تلك الأنشطة.
يتألّف التحقّق من الترخيص من إجراءَين أساسيَّين:
- إن الاتصال بطريقة بدء فحص الترخيص - في LVL، هو
استدعاء لطريقة
checkAccess()
لكائنLicenseChecker
الذي التي تبنيها. - يشير ذلك المصطلح إلى معاودة الاتصال تعرض نتيجة فحص الترخيص. في LVL، هذا هو
واجهة
LicenseCheckerCallback
تنفّذها تشير رسالة الأشكال البيانية تُعلن عن طريقتين، هماallow()
dontAllow()
، التي تم استدعاءها بواسطة المكتبة بناءً على نتيجة فحص الترخيص. يمكنك تنفيذ هاتين الطريقتين بأي منطق الذي تحتاج إليه، للسماح للمستخدم بالدخول إلى تطبيقك أو منعه. لاحظ أن هذه الطرق لا تحدد ما إذا كنت تريد السماح بالوصول أم لا تقع على عاتق تنفيذPolicy
مسؤولية اتخاذ القرار. بدلاً من ذلك، توفير سلوكيات التطبيق ببساطة بخصوص كيفية السماح منع الوصول (ومعالجة أخطاء التطبيق).تقدّم الطريقتان
allow()
وdontAllow()
"سببًا". لاستجابتهم، والتي يمكن أن تكون من قيمPolicy
،LICENSED
،NOT_LICENSED
أوRETRY
وعلى وجه الخصوص، ينبغي لك التعامل مع الحالة التي تتلقّى الطريقة استجابةRETRY
بشأنdontAllow()
وتزوّد المستخدم "إعادة المحاولة" الذي قد يكون بسبب عدم توفر الخدمة أثناء طلبك.
يوضح المخطّط أعلاه كيفية إجراء عملية التحقّق من الترخيص النموذجية:
- ينشئ الرمز في النشاط الرئيسي للتطبيق مثيلاً لـ
LicenseCheckerCallback
وLicenseChecker
كائنين. عند إنشاءLicenseChecker
، يمر الرمز فيContext
، وعملية تنفيذPolicy
المطلوب استخدامها، المفتاح العام لحساب الناشر للترخيص كمعلمات. - يستدعي الرمز بعد ذلك الطريقة
checkAccess()
في كائنLicenseChecker
. تطلب طريقة تنفيذ الطريقةPolicy
لتحديد ما إذا كانت هناك استجابة ترخيص صالحة ومخزنة مؤقتًا محليًا فيSharedPreferences
- في هذه الحالة، سيطلب تنفيذ "
checkAccess()
"allow()
- بخلاف ذلك، تبدأ
LicenseChecker
طلب فحص الترخيص الذي يتم إرساله. لخادم الترخيص.
ملاحظة: يعود خادم الترخيص دائمًا
LICENSED
عند إجراء فحص لترخيص تطبيق. - في هذه الحالة، سيطلب تنفيذ "
- عند تلقّي ردّ، ينشئ "
LicenseChecker
" أداة LicenseValidator. يتحقّق من بيانات الترخيص المُوقَّعة ويستخرج حقول الرد، إلى "Policy
" لتقييمها بشكل أكبر.- إذا كان الترخيص صالحًا، يخزِّن
Policy
الرد مؤقتًاSharedPreferences
مع إعلام المدقق، الذي يستدعي بعد ذلك الطريقةallow()
في الكائنLicenseCheckerCallback
. - إذا لم يكن الترخيص صالحًا، سترسل أداة
Policy
إشعارًا إلى أداة التدقيق التي تطلب طريقةdontAllow()
علىLicenseCheckerCallback
.
- إذا كان الترخيص صالحًا، يخزِّن
- في حالة حدوث خطأ محلي أو خطأ في الخادم، كما هو الحال عند إنشاء
غير متاح لإرسال الطلب، يمرر
LicenseChecker
ردRETRY
إلى طريقةprocessServerResponse()
للكائنPolicy
.بالإضافة إلى ذلك، تتلقّى كل من طريقة معاودة الاتصال
allow()
وdontAllow()
رسالة الوسيطةreason
. يكون سبب طريقةallow()
عادةًPolicy.LICENSED
أوPolicy.RETRY
والسببdontAllow()
عادةًPolicy.NOT_LICENSED
أوPolicy.RETRY
. قيم الرد هذه مفيدة حتى تتمكن من إظهار رد مناسب للمستخدم، مثل تقديم زر "إعادة المحاولة" زر عند استجابةdontAllow()
باستخدامPolicy.RETRY
، وقد يرجع ذلك إلى أن الخدمة كانت غير متاح. - في حالة حدوث خطأ في التطبيق، مثلاً عند محاولة التطبيق
التحقّق من ترخيص اسم الحزمة غير صالح، حيث يتجاوز
LicenseChecker
خطأ الردّ علىapplicationError()
الخاصة بـ LicenseCheckerCallback .
لاحظ أنه بالإضافة إلى بدء فحص الترخيص والتعامل مع
والموضحة في الأقسام أدناه، يحتاج تطبيقك أيضًا
تقديم تنفيذ السياسة، وفي حال كانت السمة Policy
وتخزِّن بيانات الاستجابة (مثل ServerManagedPolicy)، وهي تنفيذ Obfuscator.
إضافة عمليات استيراد
أولاً، افتح ملف الفئة الخاص بالنشاط الرئيسي للتطبيق واستورد
LicenseChecker
وLicenseCheckerCallback
من حزمة LVL.
Kotlin
import com.google.android.vending.licensing.LicenseChecker import com.google.android.vending.licensing.LicenseCheckerCallback
Java
import com.google.android.vending.licensing.LicenseChecker; import com.google.android.vending.licensing.LicenseCheckerCallback;
إذا كنت تستخدم طريقة تنفيذ Policy
التلقائية المقدّمة مع LVL،
في Server ManagedPolicy، قم باستيرادها أيضًا مع AESObfuscator. إذا كنت
باستخدام Policy
أو Obfuscator
مخصّص، يمكنك استيرادهما بدلاً من ذلك.
Kotlin
import com.google.android.vending.licensing.ServerManagedPolicy import com.google.android.vending.licensing.AESObfuscator
Java
import com.google.android.vending.licensing.ServerManagedPolicy; import com.google.android.vending.licensing.AESObfuscator;
تنفيذ LicenseCheckerCallback كفئة داخلية خاصة
LicenseCheckerCallback
هي واجهة يوفّرها LVL للتعامل مع المنتج.
نتيجة فحص الترخيص. لإتاحة الترخيص باستخدام LVL، يجب:
تنفيذ LicenseCheckerCallback
طرقه للسماح أو عدم السماح بالوصول إلى التطبيق.
وتكون نتيجة فحص الترخيص دائمًا الاتصال بأحد
LicenseCheckerCallback
طريقة تم إنشاؤها استنادًا إلى التحقّق من صحة الردّ
والحمولة ورمز استجابة الخادم نفسه وأي معالجة إضافية مقدمة
من "Policy
" ويمكن لتطبيقك تنفيذ الطرق بأي طريقة مطلوبة. ضِمن
بشكل عام، من الأفضل إبقاء الطرق بسيطة، وقصرها على إدارة واجهة المستخدم
والحالة والوصول إلى التطبيق. إذا أردت إضافة إجراءات معالجة إضافية للترخيص
عن طريق الاتصال بخادم الخلفية أو تطبيق قيود مخصصة،
ننصحك بتضمين هذا الرمز في Policy
بدلاً من
من خلال إضافتها إلى طرق LicenseCheckerCallback
.
في معظم الحالات، يجب الإفصاح عن تنفيذك
LicenseCheckerCallback
كصف خاص داخل التطبيق الرئيسي
صف النشاط.
تنفيذ الطريقتين allow()
وdontAllow()
على النحو التالي
احتاجت. لتبدأ، يمكنك استخدام سلوكيات بسيطة للتعامل مع النتائج في
مثل عرض الترخيص في مربّع حوار. يساعدك هذا في
تشغيل تطبيقك بشكل أسرع ويمكن أن يساعد في تصحيح الأخطاء. لاحقًا، بعد
السلوكيات التي تريدها بالضبط، يمكنك إضافة معالجة أكثر تعقيدًا.
بعض الاقتراحات للتعامل مع الردود غير المرخّصة في
تشمل dontAllow()
ما يلي:
- عرض رسالة "إعادة المحاولة" للمستخدم، بما في ذلك زر لبدء
ويتحقّق من الترخيص الجديد إذا كان
reason
المقدّم هوPolicy.RETRY
. - عرض عبارة "شراء هذا التطبيق" مربع حوار، بما في ذلك الزر المستخدم للوصول إلى صفحة تفاصيل التطبيق على Google Play، والتي من خلال استخدام التطبيق لشراء التطبيق. لمزيد من المعلومات حول كيفية إعداد مثل ، راجع الربط بمنتجاتك.
- اعرض إشعار إشعار منبثق يشير إلى أن ميزات محدود لأنه غير مرخّص.
يوضح المثال أدناه كيفية تنفيذ نموذج LVL
LicenseCheckerCallback
، بالطرق التي تعرض عملية التحقّق من الترخيص
.
Kotlin
private inner class MyLicenseCheckerCallback : LicenseCheckerCallback { override fun allow(reason: Int) { if (isFinishing) { // Don't update UI if Activity is finishing. return } // Should allow user access. displayResult(getString(R.string.allow)) } override fun dontAllow(reason: Int) { if (isFinishing) { // Don't update UI if Activity is finishing. return } displayResult(getString(R.string.dont_allow)) if (reason == Policy.RETRY) { // If the reason received from the policy is RETRY, it was probably // due to a loss of connection with the service, so we should give the // user a chance to retry. So show a dialog to retry. showDialog(DIALOG_RETRY) } else { // Otherwise, the user isn't licensed to use this app. // Your response should always inform the user that the application // isn't licensed, but your behavior at that point can vary. You might // provide the user a limited access version of your app or you can // take them to Google Play to purchase the app. showDialog(DIALOG_GOTOMARKET) } } }
Java
private class MyLicenseCheckerCallback implements LicenseCheckerCallback { public void allow(int reason) { if (isFinishing()) { // Don't update UI if Activity is finishing. return; } // Should allow user access. displayResult(getString(R.string.allow)); } public void dontAllow(int reason) { if (isFinishing()) { // Don't update UI if Activity is finishing. return; } displayResult(getString(R.string.dont_allow)); if (reason == Policy.RETRY) { // If the reason received from the policy is RETRY, it was probably // due to a loss of connection with the service, so we should give the // user a chance to retry. So show a dialog to retry. showDialog(DIALOG_RETRY); } else { // Otherwise, the user isn't licensed to use this app. // Your response should always inform the user that the application // isn't licensed, but your behavior at that point can vary. You might // provide the user a limited access version of your app or you can // take them to Google Play to purchase the app. showDialog(DIALOG_GOTOMARKET); } } }
بالإضافة إلى ذلك، يجب تنفيذ applicationError()
.
التي تستدعيها LVL للسماح لتطبيقك بمعالجة الأخطاء غير
يمكن إعادة المحاولة. للحصول على قائمة بمثل هذه الأخطاء، يمكنك مراجعة الخادم
رموز الاستجابة في مرجع الترخيص يمكنك تنفيذ
الطريقة بأي طريقة مطلوبة. في معظم الحالات،
إلى تسجيل رمز الخطأ واستدعاء dontAllow()
.
إنشاء معالج للنشر من LicenseCheckerCallback إلى سلسلة واجهة المستخدم
أثناء فحص الترخيص، تمرر LVL الطلب إلى Google Play
الذي يعالج الاتصال بخادم الترخيص. المستوى
يمرر الطلب عبر IPC غير المتزامن (باستخدام Binder
) لذا
فإن الاتصال بالشبكة والمعالجة الفعلية لا يتم في سلسلة محادثات
تتم إدارتها من خلال تطبيقك. وبالمثل، عند تطبيق تطبيق Google Play
تتلقى النتيجة، فإنها تستدعي طريقة استدعاء عبر IPC، والتي بدورها
في مجموعة سلاسل IPC في عملية التطبيق.
تدير فئة LicenseChecker
اتصال IPC لتطبيقك من خلال
تطبيق Google Play، بما في ذلك المكالمة التي ترسل الطلب
رد الاتصال الذي يتلقى الرد. يتم أيضًا تتبُّع الترخيص المفتوح من قِبل "LicenseChecker
".
الطلبات وإدارة المهلات.
حتى يتمكن من التعامل مع المهلات بشكل صحيح ومعالجة الاستجابات الواردة أيضًا
بدون التأثير في سلسلة واجهة المستخدم في تطبيقك، يؤدي LicenseChecker
إلى ظهور
مؤشر ترابط الخلفية عند إنشاء مثيل. في سلسلة المحادثات، تتم معالجة كل
نتائج التحقّق من الترخيص، سواء كانت النتيجة ردًا تم تلقّيه من الخادم
أو خطأ انتهاء المهلة. وفي ختام المعالجة، تستدعي LVL
LicenseCheckerCallback
طريقة من سلسلة المحادثات في الخلفية
ويعني ذلك ما يلي في تطبيقك:
- سيتم استدعاء طرق
LicenseCheckerCallback
، في كثير من الحالات، من سلسلة محادثات في الخلفية. - ولن تتمكّن هذه الطرق من تعديل الحالة أو استدعاء أي معالجة في سلسلة واجهة المستخدم، ما لم تنشئ معالجًا في سلسلة واجهة المستخدم وكان لديك رد الاتصال المنشورة على المعالج.
إذا أردت تعديل سلسلة محادثات واجهة المستخدم في طُرق LicenseCheckerCallback
، اتّبِع الخطوات التالية:
إنشاء مثيل لـ Handler
في النشاط الرئيسي
طريقة onCreate()
،
كما هو موضح أدناه. في هذا المثال، يمثل نموذج واجهة برمجة تطبيقات LVL
تطلب LicenseCheckerCallback
طريقة (انظر أعلاه) من displayResult()
تحديث مؤشر ترابط واجهة المستخدم من خلال إعدادات
طريقة post()
Kotlin
private lateinit var handler: Handler override fun onCreate(savedInstanceState: Bundle?) { ... handler = Handler() }
Java
private Handler handler; @Override public void onCreate(Bundle savedInstanceState) { ... handler = new Handler(); }
بعد ذلك، يمكنك استخدام طرق المعالِج من خلال طُرق LicenseCheckerCallback
لتنفيذ ما يلي:
نشر كائنات قابلة للتنفيذ أو كائنات رسالة إلى المعالج. إليك كيفية عمل النموذج
تطبيق مضمن في LVL ينشر قسمًا قابلاً للتشغيل إلى معالج في مؤشر ترابط واجهة المستخدم
لعرض حالة الترخيص.
Kotlin
private fun displayResult(result: String) { handler.post { statusText.text = result setProgressBarIndeterminateVisibility(false) checkLicenseButton.isEnabled = true } }
Java
private void displayResult(final String result) { handler.post(new Runnable() { public void run() { statusText.setText(result); setProgressBarIndeterminateVisibility(false); checkLicenseButton.setEnabled(true); } }); }
إنشاء نسخة فورية من LicenseChecker و LicenseCheckerCallback
في علامة تبويب "النشاط"
طريقة واحدة (onCreate()
)،
إنشاء مثيلات خاصة من LicenseCheckerCallback وLicenseChecker
. يجب
إنشاء مثيل LicenseCheckerCallback
أولاً، لأنّك تحتاج إلى تمرير مرجع
إلى هذه الحالة عند استدعاء الدالة الإنشائية لـ LicenseChecker
.
عند إنشاء مثيل LicenseChecker
، عليك تمرير هذه المَعلمات:
- تطبيق "
Context
" - مرجع إلى تنفيذ
Policy
لاستخدامه في التحقّق من الترخيص ضِمن في معظم الحالات، قد تستخدم طريقة تنفيذPolicy
التلقائية التي يوفّرها LVL سياسة الخادم المُدار. - يشير متغير السلسلة الذي يتضمن المفتاح العام لحساب الناشر إلى الترخيص.
إذا كنت تستخدم ServerManagedPolicy، لن تحتاج إلى الوصول إلى الفئة
إذًا، يمكنك إنشاء مثيل لها في الدالة الإنشائية LicenseChecker
،
كما هو موضح في المثال أدناه. لاحظ أنك بحاجة إلى تمرير مرجع إلى
مثيل أداة Obfuscator عند إنشاء ServermanagedPolicy.
يوضح المثال أدناه إنشاء مثيل لـ LicenseChecker
LicenseCheckerCallback
من طريقة onCreate()
لنشاط
الصف.
Kotlin
class MainActivity : AppCompatActivity() { ... private lateinit var licenseCheckerCallback: LicenseCheckerCallback private lateinit var checker: LicenseChecker override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... // Construct the LicenseCheckerCallback. The library calls this when done. licenseCheckerCallback = MyLicenseCheckerCallback() // Construct the LicenseChecker with a Policy. checker = LicenseChecker( this, ServerManagedPolicy(this, AESObfuscator(SALT, packageName, deviceId)), BASE64_PUBLIC_KEY // Your public licensing key. ) ... } }
Java
public class MainActivity extends Activity { ... private LicenseCheckerCallback licenseCheckerCallback; private LicenseChecker checker; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... // Construct the LicenseCheckerCallback. The library calls this when done. licenseCheckerCallback = new MyLicenseCheckerCallback(); // Construct the LicenseChecker with a Policy. checker = new LicenseChecker( this, new ServerManagedPolicy(this, new AESObfuscator(SALT, getPackageName(), deviceId)), BASE64_PUBLIC_KEY // Your public licensing key. ); ... } }
تجدر الإشارة إلى أنّ LicenseChecker
يستدعي طرق LicenseCheckerCallback
من واجهة المستخدم.
سلسلة المحادثات فقط إذا كانت هناك استجابة ترخيص صالحة تم تخزينها مؤقتًا محليًا. إذا كانت
إرسال فحص الترخيص إلى الخادم، فإن عمليات معاودة الاتصال تبدأ دائمًا من
أو سلسلة التعليمات في الخلفية، حتى في حال حدوث أخطاء في الشبكة.
يمكنك طلب CheckAccess() لبدء عملية فحص الترخيص.
في "نشاطك الرئيسي"، أضِف طلبًا إلى طريقة checkAccess()
في
مثيل واحد (LicenseChecker
) في المكالمة، مرِّر إشارة إلى
مثيل LicenseCheckerCallback
كمعلَمة. إذا كنت بحاجة إلى التعامل مع
التأثيرات الخاصة لواجهة المستخدم أو إدارة الحالة قبل المكالمة، قد تجدها مفيدة
لاستدعاء checkAccess()
من طريقة تضمين. على سبيل المثال، يتناسب LVL
أمثلة على طلبات التطبيق checkAccess()
من
طريقة برنامج تضمين doCheck()
:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... // Call a wrapper method that initiates the license check doCheck() ... } ... private fun doCheck() { checkLicenseButton.isEnabled = false setProgressBarIndeterminateVisibility(true) statusText.setText(R.string.checking_license) checker.checkAccess(licenseCheckerCallback) }
Java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... // Call a wrapper method that initiates the license check doCheck(); ... } ... private void doCheck() { checkLicenseButton.setEnabled(false); setProgressBarIndeterminateVisibility(true); statusText.setText(R.string.checking_license); checker.checkAccess(licenseCheckerCallback); }
تضمين مفتاحك العام للترخيص
بالنسبة إلى كل تطبيق، يتم تلقائيًا ينشئ مفتاحَي التشفير العام/الخاص RSA بحجم 2048 بت يُستخدم الترخيص والفوترة داخل التطبيقات. يرتبط مفتاحا التشفير بشكل فريد التطبيق. وعلى الرغم من ارتباطهما بالتطبيق، فإن مفتاحَي التشفير ليس هو نفسه المفتاح الذي تستخدمه لتوقيع تطبيقاتك (أو مشتقًا منه).
تكشف أداة Google Play Console عن المفتاح العام للترخيص لأي مستخدم سجّل المطوِّر الدخول إلى Play Console ولكنه يحتفظ بالمفتاح الخاص مخفيًا عن جميع المستخدمين في موقع آمن. عندما يطلب أحد التطبيقات فحص الترخيص لتطبيق منشور في حسابك، أو خادم الترخيص ويوقّع على استجابة الترخيص باستخدام المفتاح الخاص لمفتاحي تشفير التطبيق. عندما يتلقى LVL الرد، فإنه يستخدم المفتاح العام الذي يوفره التطبيق للتحقق من توقيع استجابة الترخيص.
لإضافة ترخيص إلى تطبيق، يجب أن تحصل على ترخيص مفتاح عام للترخيص ونسخه في تطبيقك. إليك كيفية العثور على المفتاح العام لتطبيقك للترخيص:
- انتقِل إلى Google Play Console وسجِّل الدخول. تأكد من تسجيل الدخول إلى الحساب الذي تستخدمه في التطبيق أن يكون الترخيص منشورًا (أو سيتم نشره).
- في صفحة تفاصيل التطبيق، حدد مكان الخدمات واجهات برمجة التطبيقات الرابط وانقر عليه.
- في قسم الخدمات واجهات برمجة التطبيقات (APIs)، حدد موقع الترخيص قسم الفوترة داخل التطبيق مفتاحك العام لـ في مفتاح الترخيص لهذا التطبيق.
لإضافة المفتاح العام إلى تطبيقك، ما عليك سوى نسخ سلسلة المفتاح ولصقها
من الحقل إلى تطبيقك كقيمة لمتغير السلسلة
BASE64_PUBLIC_KEY
عند النسخ، تأكد من أن لديك
سلسلة المفتاح بالكامل، دون حذف أي أحرف.
في ما يلي مثال من نموذج تطبيق LVL:
Kotlin
private const val BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... " //truncated for this example class LicensingActivity : AppCompatActivity() { ... }
Java
public class MainActivity extends Activity { private static final String BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... "; //truncated for this example ... }
يمكنك استدعاء طريقة onDestroy() من LicenseChecker. لإغلاق اتصالات IPC
أخيرًا، اسمح لـ LVL بإصلاحه قبل تقديم طلبك
تم تغيير "Context
"، يُرجى إضافة مكالمة إلى "LicenseChecker
".
طريقة واحدة (onDestroy()
) من طريقة نشاطك
تنفيذ onDestroy()
. يتسبب الاتصال في
LicenseChecker
لإغلاق أي اتصال IPC مفتوح على Google Play بشكل صحيح
ILicensingService للتطبيق وإزالة أي مراجع محلية للخدمة
والمعالج.
تعذّر استدعاء طريقة onDestroy()
المستخدمة في LicenseChecker
إلى حدوث مشاكل طوال دورة حياة طلبك. على سبيل المثال، إذا كانت قيمة
يغير المستخدم اتجاه الشاشة عندما يكون التحقق من الترخيص نشطًا، يغير التطبيق
تمت إتلاف Context
. إذا لم يكن تطبيقك
إغلاق اتصال IPC لـ LicenseChecker
بشكل صحيح، سيتعطّل تطبيقك
عند تلقي الرد. وبالمثل، إذا خرج المستخدم من تطبيقك
أثناء فحص الترخيص، سيتعطّل تطبيقك عند
ما لم يتم طلب الاستجابة
طريقة onDestroy()
التي يستخدمها LicenseChecker
لإلغاء الربط بالخدمة.
وفي ما يلي مثال من نموذج تطبيق مضمن في LVL، حيث
mChecker
هو مثيل LicenseChecker
:
Kotlin
override fun onDestroy() { super.onDestroy() checker.onDestroy() ... }
Java
@Override protected void onDestroy() { super.onDestroy(); checker.onDestroy(); ... }
في حال تمديد مهلة LicenseChecker
أو تعديلها، قد تحتاج أيضًا إلى الاتصال بـ
طريقة finishCheck()
في LicenseChecker
لتنظيف أي IPC مفتوح
الاتصالات.
تنفيذ محدد الجهاز
وفي بعض الحالات، قد تحتاج إلى الحدّ من الحدّ الأقصى المسموح به لقيمة "Policy
"
الأجهزة المسموح لها باستخدام ترخيص واحد. سيؤدي هذا إلى منع المستخدم
بدءًا من نقل تطبيق مرخص إلى عدد من الأجهزة واستخدام
التطبيق على هذه الأجهزة التي لها رقم تعريف الحساب نفسه. كما أنه سيمنع
المستخدم من "المشاركة" التطبيق من خلال تقديم معلومات الحساب
المرتبطة بالترخيص لأفراد آخرين، يمكنهم بعد ذلك تسجيل الدخول إلى ذلك
على أجهزتهم والوصول إلى ترخيص التطبيق.
وتدعم LVL الترخيص لكل جهاز من خلال توفير
DeviceLimiter
، التي تشير إلى طريقة واحدة،
allowDeviceAccess()
عندما يتعامل LicenseValidator مع الرد
من خادم الترخيص، يتّصل بـ allowDeviceAccess()
ويمرر
سلسلة رقم تعريف المستخدم المستخرَجة من الردّ.
إذا كنت لا تريد فرض قيود على الأجهزة، ليس هناك أي واجب
مطلوب - يستخدم الصف LicenseChecker
فئة تلقائية تلقائيًا
عملية تنفيذ تسمى NullDeviceLimiter. كما يشير الاسم، NullDeviceLimiter
"خطأ" الفئة التي تعرض طريقة allowDeviceAccess()
لها ببساطة
استجابة LICENSED
لجميع المستخدمين والأجهزة.
تنبيه: لا يُنصح بالترخيص لكل جهاز مع لمعظم الطلبات للأسباب التالية:
- يتطلب ذلك توفير خادم خلفية لإدارة المستخدمين والأجهزة ورسم الخرائط
- وقد يؤدي ذلك بدون قصد إلى منع المستخدم من الوصول إلى تطبيقًا اشتروه بشكل شرعي على جهاز آخر.
إخفاء التعليمات البرمجية
لضمان أمان تطبيقك، وخاصةً إذا كان تطبيقك تطبيق يستخدم الترخيص و/أو القيود والحماية المخصصة، فمن الأفضل أن للتشويش على رمز التطبيق. يؤدي التشويش على تجعل من الصعب على المستخدم الضار فك تشفير محتوى بايت، قم بتعديله — عن طريق إزالة التحقق من الترخيص مثلاً — ثم إعادة تجميعها.
تتوفَّر العديد من برامج إخفاء مفاتيح فك التشفير لتطبيقات Android، بما في ذلك ProGuard، الذي يوفر أيضًا بميزات تحسين الترميز. يشير هذا المصطلح إلى استخدام ProGuard أو برنامج مشابه للتشويش ننصح بشدة باستخدام الرمز لجميع التطبيقات التي تستخدم Google ترخيص Play:
نشر تطبيق مرخَّص
عند الانتهاء من اختبار تنفيذ الترخيص، ستكون جاهزًا لما يلي: نشر التطبيق على Google Play. اتّبِع الخطوات العادية لإعداد التطبيق وتوقيعه، ثم نشره.
كيفية الحصول على الدعم
إذا كانت لديك أسئلة أو واجهت مشاكل أثناء التنفيذ أو النشر النشر في تطبيقاتك، فيرجى استخدام موارد الدعم المدرجة في الجدول أدناه. من خلال توجيه استفساراتك إلى المنتدى الصحيح، يمكنك الحصول على والدعم الذي تحتاجه بسرعة أكبر.
نوع الدعم | المورد | نطاق المواضيع |
---|---|---|
مشكلات التطوير والاختبار | مجموعات Google: android-developers | تنزيل ودمج LVL، مشاريع المكتبة، Policy
أسئلة، أفكار تجربة المستخدم، التعامل مع الردود، Obfuscator ، IPC، اختبار
إعداد البيئة |
Stack Overflow: http://stackoverflow.com/questions/marker/android | ||
مشاكل الحسابات والنشر والنشر | Google Play منتدى المساعدة | حسابات الناشرين، مفتاحَي الترخيص، وحسابات الاختبار، والخادم الاستجابات واستجابات الاختبار ونشر التطبيقات والنتائج |
السوق الأسئلة الشائعة حول الدعم المتعلق بالترخيص | ||
أداة تتبُّع مشاكل LVL | التسويق أداة تتبُّع المشاكل في المشروع | تقارير الأخطاء والمشاكل المرتبطة تحديدًا بفئات رموز المصدر LVL وعمليات تنفيذ الواجهة |
للحصول على معلومات عامة حول كيفية النشر في المجموعات المذكورة أعلاه، يمكنك الاطّلاع على قسم موارد المنتدى. في صفحة موارد دعم المطوّرين.
مراجع إضافية
ويقدم تطبيق النموذج المضمن مع LVL مثالاً كاملاً على كيفية
لبدء فحص الترخيص والتعامل مع النتيجة، في
صف واحد (MainActivity
).