افزودن تأیید مجوز سمت مشتری به برنامه شما

هشدار: وقتی برنامه شما فرآیند تأیید مجوز را در سمت مشتری انجام می‌دهد، برای مهاجمان احتمالی آسان‌تر است که منطق مرتبط با این فرآیند تأیید را اصلاح یا حذف کنند.

به همین دلیل، قویاً شما را تشویق می‌کنیم که به جای آن تأیید مجوز سمت سرور را انجام دهید .

پس از راه‌اندازی حساب ناشر و محیط توسعه ( به تنظیم برای صدور مجوز مراجعه کنید)، آماده هستید تا تأیید مجوز را با کتابخانه تأیید مجوز (LVL) به برنامه خود اضافه کنید.

افزودن تأیید مجوز با LVL شامل این وظایف است:

  1. افزودن مجوز مجوز به مانیفست برنامه شما.
  2. پیاده سازی یک خط مشی - می توانید یکی از پیاده سازی های کامل ارائه شده در LVL را انتخاب کنید یا خودتان ایجاد کنید.
  3. در حال پیاده سازی Obfuscator ، اگر Policy شما داده های پاسخ مجوز را در حافظه پنهان کند.
  4. افزودن کد برای بررسی مجوز در فعالیت اصلی برنامه شما.
  5. پیاده سازی 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 هنگام پردازش پاسخ از سرور مجوز فراخوانی می‌شوند. همچنین یک enum به نام LicenseResponse را اعلام می‌کند که مقدار پاسخ مجوز ارسال شده در فراخوانی processServerResponse() را مشخص می‌کند.

  • processServerResponse() به شما امکان می‌دهد تا داده‌های پاسخ خام دریافتی از سرور مجوز را پیش پردازش کنید، قبل از تعیین اینکه آیا اجازه دسترسی را بدهید یا خیر.

    یک پیاده‌سازی معمولی برخی یا همه فیلدها را از پاسخ مجوز استخراج می‌کند و داده‌ها را به صورت محلی در یک فروشگاه دائمی، مانند ذخیره‌سازی SharedPreferences ذخیره می‌کند تا اطمینان حاصل شود که داده‌ها در سراسر فراخوانی برنامه‌ها و چرخه‌های قدرت دستگاه قابل دسترسی هستند. برای مثال، یک Policy به جای بازنشانی مقادیر هر بار که برنامه راه‌اندازی می‌شود، مهر زمانی آخرین بررسی موفق مجوز، تعداد تلاش مجدد، دوره اعتبار مجوز و اطلاعات مشابه را در یک فروشگاه دائمی حفظ می‌کند.

    هنگام ذخیره داده‌های پاسخ به صورت محلی، Policy باید اطمینان حاصل کند که داده‌ها مبهم هستند ( به پیاده‌سازی Obfuscator در زیر مراجعه کنید).

  • allowAccess() بر اساس هرگونه داده پاسخ مجوز موجود (از سرور مجوز یا از حافظه پنهان) یا سایر اطلاعات خاص برنامه تعیین می کند که آیا به کاربر اجازه دسترسی به برنامه شما را بدهد. به عنوان مثال، اجرای شما از allowAccess() می‌تواند معیارهای دیگری مانند استفاده یا سایر داده‌های بازیابی شده از یک سرور پشتیبان را در نظر بگیرد. در همه موارد، پیاده‌سازی allowAccess() تنها در صورتی باید true برگرداند که کاربر مجوز استفاده از برنامه را داشته باشد، همانطور که سرور مجوز تعیین می‌کند، یا اگر مشکلی در شبکه یا سیستم گذرا وجود داشته باشد که از تکمیل بررسی مجوز جلوگیری کند. در چنین مواردی، پیاده‌سازی شما می‌تواند تعداد پاسخ‌های سعی مجدد را حفظ کند و تا زمانی که بررسی مجوز بعدی کامل شود، موقتاً اجازه دسترسی را می‌دهد.

برای ساده‌سازی فرآیند افزودن مجوز به برنامه‌تان و ارائه تصویری از نحوه طراحی یک Policy ، LVL شامل دو پیاده‌سازی کامل Policy است که می‌توانید بدون تغییر استفاده کنید یا با نیازهای خود تطبیق دهید:

  • ServerManagedPolicy ، یک Policy انعطاف‌پذیر که از تنظیمات ارائه‌شده توسط سرور و پاسخ‌های حافظه پنهان برای مدیریت دسترسی در شرایط مختلف شبکه استفاده می‌کند.
  • StrictPolicy ، که هیچ داده پاسخی را در حافظه پنهان ذخیره نمی‌کند و تنها در صورتی اجازه دسترسی به سرور را می‌دهد که یک پاسخ دارای مجوز را برگرداند.

برای اکثر برنامه ها، استفاده از ServerManagedPolicy به شدت توصیه می شود. ServerManagedPolicy پیش فرض LVL است و با برنامه نمونه LVL یکپارچه شده است.

دستورالعمل برای سیاست های سفارشی

در اجرای مجوز خود، می توانید از یکی از خط مشی های کامل ارائه شده در LVL (ServerManagedPolicy یا StrictPolicy) استفاده کنید یا می توانید یک خط مشی سفارشی ایجاد کنید. برای هر نوع خط مشی سفارشی، چندین نکته مهم طراحی وجود دارد که باید در پیاده سازی خود به آنها توجه کنید.

سرور مجوز برای محافظت در برابر استفاده بیش از حد از منابع که می تواند منجر به انکار سرویس شود، محدودیت های درخواست عمومی را اعمال می کند. هنگامی که یک برنامه از حد درخواست فراتر می رود، سرور صدور مجوز یک پاسخ 503 را برمی گرداند که به عنوان یک خطای کلی سرور به برنامه شما ارسال می شود. این بدان معنی است که تا زمانی که محدودیت بازنشانی نشود، هیچ پاسخ مجوزی برای کاربر در دسترس نخواهد بود، که می تواند برای مدت نامحدودی کاربر را تحت تأثیر قرار دهد.

اگر در حال طراحی یک خط مشی سفارشی هستید، توصیه می کنیم که این Policy :

  1. آخرین پاسخ مجوز موفق در ذخیره سازی دائمی محلی را پنهان می کند (و به درستی مبهم می کند).
  2. پاسخ ذخیره شده در حافظه پنهان را برای همه بررسی های مجوز، تا زمانی که پاسخ ذخیره شده در حافظه پنهان معتبر است، به جای درخواست به سرور مجوز، برمی گرداند. تنظیم اعتبار پاسخ با توجه به VT اضافی ارائه شده توسط سرور بسیار توصیه می شود. برای اطلاعات بیشتر به موارد اضافی پاسخ سرور مراجعه کنید.
  3. از یک دوره عقب نشینی نمایی استفاده می کند، در صورتی که تلاش مجدد هر درخواستی منجر به خطا شود. توجه داشته باشید که سرویس گیرنده Google Play به‌طور خودکار درخواست‌های ناموفق را دوباره امتحان می‌کند، بنابراین در بیشتر موارد نیازی نیست Policy شما دوباره آنها را امتحان کند.
  4. یک "دوره مهلت" را ارائه می دهد که به کاربر اجازه می دهد به برنامه شما برای مدت زمان محدود یا تعداد استفاده دسترسی داشته باشد، در حالی که یک بررسی مجوز دوباره در حال انجام است. دوره مهلت با اجازه دادن به دسترسی تا زمانی که بررسی مجوز بعدی با موفقیت تکمیل شود به نفع کاربر است و با قرار دادن محدودیت سخت برای دسترسی به درخواست شما در زمانی که پاسخ مجوز معتبری در دسترس نیست، به نفع شماست.

طراحی Policy خود بر اساس دستورالعمل های ذکر شده در بالا بسیار مهم است، زیرا بهترین تجربه ممکن را برای کاربران تضمین می کند و در عین حال کنترل مؤثری بر برنامه خود حتی در شرایط خطا به شما می دهد.

توجه داشته باشید که هر Policy می‌تواند از تنظیمات ارائه‌شده توسط سرور صدور مجوز برای کمک به مدیریت اعتبار و حافظه پنهان، امتحان مجدد دوره مهلت و موارد دیگر استفاده کند. استخراج تنظیمات ارائه شده توسط سرور ساده است و استفاده از آنها به شدت توصیه می شود. برای مثالی از نحوه استخراج و استفاده از موارد اضافی، اجرای ServerManagedPolicy را ببینید. برای فهرستی از تنظیمات سرور و اطلاعات مربوط به نحوه استفاده از آنها، به موارد اضافی پاسخ سرور مراجعه کنید.

سیاست مدیریت سرور

LVL شامل اجرای کامل و توصیه شده رابط Policy به نام ServerManagedPolicy است. پیاده سازی با کلاس های LVL یکپارچه شده و به عنوان Policy پیش فرض در کتابخانه عمل می کند.

ServerManagedPolicy تمام مدیریت را برای پاسخ‌های مجوز و امتحان مجدد فراهم می‌کند. تمام داده های پاسخ را به صورت محلی در یک فایل SharedPreferences ذخیره می کند و آن را با اجرای Obfuscator برنامه مبهم می کند. این تضمین می کند که داده های پاسخ مجوز ایمن هستند و در چرخه های برق دستگاه باقی می مانند. ServerManagedPolicy پیاده سازی های مشخصی از روش های واسط processServerResponse() و allowAccess() ارائه می دهد و همچنین شامل مجموعه ای از روش ها و انواع پشتیبانی کننده برای مدیریت پاسخ های مجوز می باشد.

نکته مهم، یکی از ویژگی های کلیدی ServerManagedPolicy استفاده از تنظیمات ارائه شده توسط سرور به عنوان مبنایی برای مدیریت مجوز در طول دوره بازپرداخت برنامه و از طریق شبکه و شرایط خطای متفاوت است. هنگامی که یک برنامه کاربردی برای بررسی مجوز با سرور Google Play تماس می گیرد، سرور چندین تنظیمات را به عنوان جفت کلید-مقدار در قسمت اضافی انواع پاسخ مجوز خاص اضافه می کند. به عنوان مثال، سرور مقادیر توصیه شده را برای مدت اعتبار مجوز برنامه، دوره مهلت امتحان مجدد و حداکثر تعداد مجاز تکرار مجدد و موارد دیگر ارائه می دهد. ServerManagedPolicy مقادیر را از پاسخ مجوز در متد processServerResponse() خود استخراج می کند و آنها را در متد allowAccess() بررسی می کند. برای فهرستی از تنظیمات ارائه شده توسط سرور که توسط ServerManagedPolicy استفاده می‌شود، به موارد اضافی پاسخ سرور مراجعه کنید.

برای راحتی، بهترین عملکرد و مزایای استفاده از تنظیمات مجوز از سرور Google Play، استفاده از ServerManagedPolicy به عنوان Policy صدور مجوز اکیداً توصیه می‌شود .

اگر نگران امنیت داده‌های پاسخ مجوزی هستید که به صورت محلی در SharedPreferences ذخیره می‌شوند، می‌توانید از یک الگوریتم مبهم‌سازی قوی‌تر استفاده کنید یا Policy سخت‌گیرانه‌تری طراحی کنید که داده‌های مجوز را ذخیره نمی‌کند. LVL شامل نمونه ای از چنین Policy است - برای اطلاعات بیشتر به StrictPolicy مراجعه کنید.

برای استفاده از ServerManagedPolicy، کافی است آن را به Activity خود وارد کنید، یک نمونه ایجاد کنید، و هنگام ساخت LicenseChecker ، یک مرجع به نمونه ارسال کنید. برای اطلاعات بیشتر به Instantiate LicenseChecker و LicenseCheckerCallback مراجعه کنید.

سیاست سختگیرانه

LVL شامل یک اجرای کامل جایگزین از رابط Policy به نام StrictPolicy است. پیاده‌سازی StrictPolicy خط‌مشی محدودتری نسبت به ServerManagedPolicy ارائه می‌کند، زیرا به کاربر اجازه دسترسی به برنامه را نمی‌دهد مگر اینکه در زمان دسترسی، پاسخ مجوز از سرور دریافت شود که نشان می‌دهد کاربر دارای مجوز است.

ویژگی اصلی StrictPolicy این است که هیچ داده پاسخ مجوز را به صورت محلی، در یک فروشگاه دائمی ذخیره نمی کند. از آنجایی که هیچ داده‌ای ذخیره نمی‌شود، درخواست‌های امتحان مجدد ردیابی نمی‌شوند و پاسخ‌های حافظه پنهان نمی‌توانند برای انجام بررسی‌های مجوز استفاده شوند. این Policy فقط در موارد زیر اجازه دسترسی را می‌دهد:

  • پاسخ مجوز از سرور صدور مجوز دریافت می شود و
  • پاسخ مجوز نشان می دهد که کاربر مجوز دسترسی به برنامه را دارد.

استفاده از StrictPolicy در صورتی مناسب است که نگرانی اصلی شما اطمینان از این باشد که در تمام موارد ممکن، هیچ کاربری اجازه دسترسی به برنامه را نداشته باشد مگر اینکه مجوز کاربر در زمان استفاده تأیید شود. علاوه بر این، این خط مشی امنیت کمی بیشتر از ServerManagedPolicy ارائه می دهد - از آنجایی که هیچ داده ای در حافظه پنهان محلی وجود ندارد، هیچ راهی وجود ندارد که یک کاربر مخرب بتواند داده های ذخیره شده را دستکاری کند و به برنامه دسترسی پیدا کند.

در عین حال، این Policy چالشی را برای کاربران عادی ایجاد می‌کند، زیرا به این معنی است که وقتی اتصال شبکه (سلولی یا Wi-Fi) در دسترس نباشد، نمی‌توانند به برنامه دسترسی پیدا کنند. یکی دیگر از عوارض جانبی این است که برنامه شما درخواست های بررسی مجوز بیشتری را به سرور ارسال می کند، زیرا استفاده از پاسخ ذخیره شده در حافظه پنهان امکان پذیر نیست.

به طور کلی، این خط‌مشی نشان‌دهنده میزانی از راحتی کاربر برای امنیت مطلق و کنترل دسترسی است. قبل از استفاده از این Policy ، مبادله را به دقت در نظر بگیرید.

برای استفاده از StrictPolicy، به سادگی آن را به Activity خود وارد کنید، یک نمونه ایجاد کنید، و هنگام ساخت LicenseChecker ، یک مرجع به آن ارسال کنید. برای اطلاعات بیشتر به Instantiate LicenseChecker و LicenseCheckerCallback مراجعه کنید.

یک پیاده‌سازی Policy معمولی باید داده‌های پاسخ مجوز برای یک برنامه کاربردی را در یک فروشگاه دائمی ذخیره کند، به طوری که در سراسر فراخوانی برنامه‌ها و چرخه‌های قدرت دستگاه قابل دسترسی باشد. برای مثال، یک Policy به جای بازنشانی مقادیر هر بار که برنامه راه‌اندازی می‌شود، مهر زمانی آخرین بررسی موفق مجوز، تعداد تلاش مجدد، دوره اعتبار مجوز و اطلاعات مشابه را در یک فروشگاه دائمی حفظ می‌کند. Policy پیش‌فرض موجود در LVL، ServerManagedPolicy، داده‌های پاسخ مجوز را در یک نمونه SharedPreferences ذخیره می‌کند تا اطمینان حاصل شود که داده‌ها پایدار هستند.

از آنجایی که Policy از داده‌های پاسخ مجوز ذخیره‌شده برای تعیین اجازه یا عدم اجازه دسترسی به برنامه استفاده می‌کند، باید اطمینان حاصل کند که هر داده ذخیره‌شده ایمن است و نمی‌تواند توسط یک کاربر ریشه در دستگاه استفاده مجدد یا دستکاری شود. به طور خاص، Policy همیشه باید داده ها را قبل از ذخیره کردن، با استفاده از کلیدی که برای برنامه و دستگاه منحصر به فرد است، مبهم کند. مبهم سازی با استفاده از کلیدی که هم مختص برنامه و هم دستگاه خاص است بسیار مهم است، زیرا از اشتراک گذاری داده های مبهم بین برنامه ها و دستگاه ها جلوگیری می کند.

LVL به برنامه کمک می کند تا داده های پاسخ مجوز خود را به شیوه ای ایمن و مداوم ذخیره کند. اول، یک رابط Obfuscator را فراهم می کند که به برنامه شما اجازه می دهد الگوریتم مبهم سازی انتخابی خود را برای داده های ذخیره شده ارائه دهد. بر اساس آن، LVL کلاس کمکی PreferenceObfuscator را فراهم می کند، که بیشتر کارهای فراخوانی کلاس Obfuscator برنامه و خواندن و نوشتن داده های مبهم در یک نمونه SharedPreferences را انجام می دهد.

LVL یک پیاده سازی کامل Obfuscator به نام AESObfuscator را ارائه می دهد که از رمزگذاری AES برای مبهم کردن داده ها استفاده می کند. شما می توانید از AESObfuscator در برنامه خود بدون تغییر استفاده کنید یا می توانید آن را با نیازهای خود تطبیق دهید. اگر از یک Policy (مانند ServerManagedPolicy) استفاده می کنید که داده های پاسخ مجوز را در حافظه پنهان ذخیره می کند، استفاده از AESObfuscator به عنوان پایه ای برای اجرای Obfuscator بسیار توصیه می شود. برای اطلاعات بیشتر، بخش بعدی را ببینید.

AESObfuscator

LVL شامل اجرای کامل و توصیه شده رابط Obfuscator به نام AESObfuscator است. پیاده سازی با برنامه نمونه LVL یکپارچه شده است و به عنوان Obfuscator پیش فرض در کتابخانه عمل می کند.

AESObfuscator با استفاده از AES برای رمزگذاری و رمزگشایی داده ها هنگام نوشتن یا خواندن از ذخیره سازی، مبهم سازی ایمن داده ها را فراهم می کند. Obfuscator رمزگذاری را با استفاده از سه فیلد داده ارائه شده توسط برنامه ایجاد می کند:

  1. نمک - آرایه ای از بایت های تصادفی برای استفاده برای هر (غیر) مبهم سازی.
  2. یک رشته شناسه برنامه، معمولاً نام بسته برنامه.
  3. یک رشته شناسه دستگاه، که تا حد امکان از منابع خاص دستگاه مشتق شده است تا آن را منحصر به فرد کند.

برای استفاده از AESObfuscator، ابتدا آن را به Activity خود وارد کنید. یک آرایه نهایی ثابت خصوصی برای نگه داشتن بایت های نمکی اعلام کنید و آن را به 20 بایت تولید شده به طور تصادفی مقداردهی کنید.

کاتلین

// 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
)

جاوا

...
    // 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 جستجو می کند که برای هر دستگاه منحصر به فرد است.

توجه داشته باشید که بسته به API هایی که استفاده می کنید، ممکن است برنامه شما برای به دست آوردن اطلاعات خاص دستگاه نیاز به درخواست مجوزهای اضافی داشته باشد. برای مثال، برای درخواست از TelephonyManager برای به دست آوردن IMEI دستگاه یا داده‌های مرتبط، برنامه همچنین باید مجوز android.permission.READ_PHONE_STATE را در مانیفست خود درخواست کند.

قبل از درخواست مجوزهای جدید برای تنها هدف به دست آوردن اطلاعات خاص دستگاه برای استفاده در Obfuscator خود، در نظر بگیرید که چگونه انجام این کار ممکن است بر برنامه شما یا فیلتر آن در Google Play تأثیر بگذارد (زیرا برخی از مجوزها می توانند باعث شوند که ابزارهای ساخت SDK به <uses-feature> مربوطه اضافه کند. <uses-feature> ).

در نهایت، یک نمونه از AESObfuscator بسازید و نمک، شناسه برنامه و شناسه دستگاه را ارسال کنید. شما می توانید به طور مستقیم نمونه را بسازید، در حالی که Policy و LicenseChecker خود را می سازید. به عنوان مثال:

کاتلین

    ...
    // Construct the LicenseChecker with a Policy.
    private val checker = LicenseChecker(
            this,
            ServerManagedPolicy(this, AESObfuscator(SALT, packageName, deviceId)),
            BASE64_PUBLIC_KEY
    )
    ...

جاوا

    ...
    // 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 شما انجام می شود.

برای افزودن بررسی مجوز و رسیدگی به پاسخ، باید:

  1. واردات را اضافه کنید
  2. LicenseCheckerCallback را به عنوان یک کلاس داخلی خصوصی پیاده سازی کنید
  3. یک Handler برای ارسال از LicenseCheckerCallback به رشته UI ایجاد کنید
  4. LicenseChecker و LicenseCheckerCallback را به صورت آنی اجرا کنید
  5. برای شروع بررسی مجوز ، checkAccess() را فراخوانی کنید
  6. کلید عمومی خود را برای صدور مجوز جاسازی کنید
  7. برای بستن اتصالات IPC ، متد onDestroy() LicenseChecker خود را فراخوانی کنید .

بخش های زیر این وظایف را شرح می دهند.

بررسی اجمالی مجوز و پاسخ

در بیشتر موارد، باید بررسی مجوز را به Activity اصلی برنامه خود در متد onCreate() اضافه کنید. این تضمین می کند که وقتی کاربر برنامه شما را مستقیماً راه اندازی می کند، بررسی مجوز بلافاصله فراخوانی می شود. در برخی موارد، می توانید چک های مجوز را در مکان های دیگر نیز اضافه کنید. به عنوان مثال، اگر برنامه شما شامل چندین مؤلفه Activity است که سایر برنامه‌ها می‌توانند توسط Intent شروع به کار کنند، می‌توانید بررسی‌های مجوز را در آن فعالیت‌ها اضافه کنید.

بررسی مجوز شامل دو عمل اصلی است:

  • فراخوانی روشی برای شروع بررسی مجوز - در LVL، این فراخوانی به متد checkAccess() یک شی LicenseChecker است که شما می سازید.
  • یک تماس برگشتی که نتیجه بررسی مجوز را برمی گرداند. در LVL، این یک رابط LicenseCheckerCallback است که شما پیاده سازی می کنید. رابط دو متد allow() و dontAllow() را اعلام می کند که توسط کتابخانه بر اساس نتیجه بررسی مجوز فراخوانی می شوند. شما این دو روش را با هر منطقی که نیاز دارید پیاده سازی می کنید تا به کاربر اجازه دسترسی یا عدم دسترسی به برنامه شما را بدهید. توجه داشته باشید که این روش‌ها تعیین نمی‌کنند که آیا اجازه دسترسی داده می‌شود یا خیر - این تعیین مسئولیت اجرای Policy شما است. در عوض، این روش‌ها به سادگی رفتارهای برنامه کاربردی را برای نحوه اجازه و غیرمجاز کردن دسترسی (و رسیدگی به خطاهای برنامه) ارائه می‌کنند.

    متدهای allow() و dontAllow() یک "دلیل" برای پاسخ خود ارائه می دهند که می تواند یکی از مقادیر Policy ، LICENSED ، NOT_LICENSED ، یا RETRY باشد. به طور خاص، شما باید حالتی را که در آن متد پاسخ RETRY برای dontAllow() دریافت می‌کند رسیدگی کنید و دکمه «Retry» را در اختیار کاربر قرار دهید، که ممکن است به دلیل در دسترس نبودن سرویس در طول درخواست اتفاق افتاده باشد.

شکل 1. بررسی اجمالی یک تعامل بررسی مجوز معمولی.

نمودار بالا نحوه انجام یک بررسی مجوز معمولی را نشان می دهد:

  1. کد موجود در فعالیت اصلی برنامه، اشیاء LicenseCheckerCallback و LicenseChecker را نشان می دهد. هنگام ساخت LicenseChecker ، کد در Context ، یک اجرای Policy برای استفاده، و کلید عمومی حساب ناشر برای صدور مجوز به عنوان پارامتر ارسال می شود.
  2. سپس کد متد checkAccess() را در شی LicenseChecker فراخوانی می کند. پیاده‌سازی روش، Policy فراخوانی می‌کند تا مشخص کند که آیا یک پاسخ مجوز معتبر در حافظه پنهان محلی، در SharedPreferences وجود دارد یا خیر.
    • اگر چنین است، فراخوانی اجرای checkAccess() allow() .
    • در غیر این صورت، LicenseChecker یک درخواست بررسی مجوز را آغاز می کند که به سرور مجوز ارسال می شود.

    توجه: هنگامی که شما یک برنامه پیش‌نویس را بررسی می‌کنید، سرور صدور مجوز همیشه LICENSED را برمی‌گرداند.

  3. هنگامی که یک پاسخ دریافت می شود، LicenseChecker یک LicenseValidator ایجاد می کند که داده های مجوز امضا شده را تأیید می کند و فیلدهای پاسخ را استخراج می کند، سپس آنها را برای ارزیابی بیشتر به Policy شما منتقل می کند.
    • اگر مجوز معتبر باشد، Policy پاسخ را در SharedPreferences ذخیره می‌کند و اعتباردهنده را مطلع می‌کند، که سپس متد allow() در شی LicenseCheckerCallback فراخوانی می‌کند.
    • اگر مجوز معتبر نباشد، Policy به اعتباردهنده اطلاع می‌دهد که متد dontAllow() را در LicenseCheckerCallback فراخوانی می‌کند.
  4. در صورت بروز خطای محلی یا سرور قابل بازیابی، مانند زمانی که شبکه برای ارسال درخواست در دسترس نیست، LicenseChecker یک پاسخ RETRY را به متد processServerResponse() شی Policy شما ارسال می کند.

    همچنین، هر دو متد callback allow() و dontAllow() یک آرگومان reason دریافت می کنند. دلیل متد allow() معمولا Policy.LICENSED یا Policy.RETRY و دلیل dontAllow() معمولا Policy.NOT_LICENSED یا Policy.RETRY است. این مقادیر پاسخ مفید هستند، بنابراین می‌توانید پاسخ مناسبی را برای کاربر نشان دهید، مانند ارائه یک دکمه "Retry" زمانی که dontAllow() با Policy.RETRY پاسخ می‌دهد، که ممکن است به دلیل در دسترس نبودن سرویس باشد.

  5. در صورت بروز خطای برنامه، مانند زمانی که برنامه سعی می کند مجوز نام بسته نامعتبر را بررسی کند، LicenseChecker یک پاسخ خطا را به متد LicenseCheckerCallback's applicationError() ارسال می کند.

توجه داشته باشید که، علاوه بر شروع بررسی مجوز و رسیدگی به نتیجه، که در بخش‌های زیر توضیح داده شده است، برنامه شما همچنین باید یک پیاده‌سازی خط‌مشی و اگر Policy داده‌های پاسخ (مانند ServerManagedPolicy) را ذخیره می‌کند، یک اجرای Obfuscator را نیز ارائه کند.

واردات را اضافه کنید

ابتدا فایل کلاس Activity اصلی برنامه را باز کنید و LicenseChecker و LicenseCheckerCallback را از بسته LVL وارد کنید.

کاتلین

import com.google.android.vending.licensing.LicenseChecker
import com.google.android.vending.licensing.LicenseCheckerCallback

جاوا

import com.google.android.vending.licensing.LicenseChecker;
import com.google.android.vending.licensing.LicenseCheckerCallback;

اگر از اجرای Policy پیش‌فرض ارائه شده با LVL، ServerManagedPolicy استفاده می‌کنید، آن را نیز همراه با AESObfuscator وارد کنید. اگر از یک Policy یا Obfuscator سفارشی استفاده می کنید، به جای آن آن ها را وارد کنید.

کاتلین

import com.google.android.vending.licensing.ServerManagedPolicy
import com.google.android.vending.licensing.AESObfuscator

جاوا

import com.google.android.vending.licensing.ServerManagedPolicy;
import com.google.android.vending.licensing.AESObfuscator;

LicenseCheckerCallback را به عنوان یک کلاس داخلی خصوصی پیاده سازی کنید

LicenseCheckerCallback رابطی است که توسط LVL برای رسیدگی به نتایج بررسی مجوز ارائه شده است. برای پشتیبانی از صدور مجوز با استفاده از LVL، باید LicenseCheckerCallback و روش های آن را پیاده سازی کنید تا دسترسی به برنامه را مجاز یا غیرمجاز کنید.

نتیجه بررسی مجوز همیشه تماس با یکی از روش‌های LicenseCheckerCallback است که بر اساس تأیید بار پاسخ، کد پاسخ سرور و هرگونه پردازش اضافی ارائه شده توسط Policy شما انجام می‌شود. برنامه شما می تواند روش ها را به هر شکلی که لازم است پیاده سازی کند. به طور کلی، بهتر است روش ها را ساده نگه دارید و آنها را به مدیریت وضعیت رابط کاربری و دسترسی برنامه محدود کنید. اگر می‌خواهید پردازش بیشتر پاسخ‌های مجوز را اضافه کنید، مانند تماس با یک سرور پشتیبان یا اعمال محدودیت‌های سفارشی، باید به جای قرار دادن آن در روش‌های LicenseCheckerCallback ، آن کد را در Policy خود بگنجانید.

در بیشتر موارد، شما باید اجرای LicenseCheckerCallback خود را به عنوان یک کلاس خصوصی در کلاس Activity اصلی برنامه خود اعلام کنید.

در صورت نیاز متدهای allow() و dontAllow() را پیاده سازی کنید. برای شروع، می توانید از رفتارهای ساده مدیریت نتایج در روش ها استفاده کنید، مانند نمایش نتیجه مجوز در یک گفتگو. این به شما کمک می کند تا برنامه خود را زودتر اجرا کنید و می تواند به رفع اشکال کمک کند. بعداً، پس از اینکه رفتارهای دقیقی را که می خواهید مشخص کردید، می توانید مدیریت پیچیده تری را اضافه کنید.

برخی از پیشنهادات برای مدیریت پاسخ‌های بدون مجوز در dontAllow() عبارتند از:

  • یک گفتگوی "دوباره امتحان کنید" را به کاربر نمایش دهید، از جمله دکمه ای برای شروع بررسی مجوز جدید اگر reason ارائه شده Policy.RETRY باشد.
  • یک گفتگوی «خرید این برنامه» را نمایش دهید، از جمله دکمه‌ای که کاربر را به صفحه جزئیات برنامه در Google Play پیوند می‌دهد و کاربر می‌تواند از آن برنامه را خریداری کند. برای اطلاعات بیشتر در مورد نحوه تنظیم چنین پیوندهایی، به پیوند به محصولات شما مراجعه کنید.
  • نمایش یک اعلان Toast که نشان می دهد ویژگی های برنامه محدود است زیرا مجوز ندارد.

مثال زیر نشان می دهد که چگونه برنامه نمونه LVL LicenseCheckerCallback را با روش هایی که نتیجه بررسی مجوز را در یک گفتگو نمایش می دهد، پیاده سازی می کند.

کاتلین

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)
        }
    }
}

جاوا

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() را فراخوانی کند.

یک Handler برای ارسال از LicenseCheckerCallback به رشته UI ایجاد کنید

در طول بررسی مجوز، LVL درخواست را به برنامه Google Play ارسال می کند، که ارتباط با سرور صدور مجوز را مدیریت می کند. LVL درخواست را از طریق IPC ناهمزمان (با استفاده از Binder ) ارسال می کند، بنابراین پردازش واقعی و ارتباطات شبکه در رشته ای که توسط برنامه شما مدیریت می شود انجام نمی شود. به طور مشابه، زمانی که برنامه Google Play نتیجه را دریافت می‌کند، یک روش پاسخ به تماس را از طریق IPC فراخوانی می‌کند، که به نوبه خود در یک مخزن رشته IPC در فرآیند برنامه شما اجرا می‌شود.

کلاس LicenseChecker ارتباط IPC برنامه شما با برنامه Google Play را مدیریت می کند، از جمله تماسی که درخواست را ارسال می کند و تماسی که پاسخ را دریافت می کند. LicenseChecker همچنین درخواست های مجوز باز را ردیابی می کند و تایم اوت های آنها را مدیریت می کند.

برای اینکه بتواند زمان‌بندی‌ها را به درستی مدیریت کند و همچنین پاسخ‌های دریافتی را بدون تأثیر بر رشته رابط کاربری برنامه شما پردازش کند، LicenseChecker در همان ابتدا یک رشته پس‌زمینه ایجاد می‌کند. در رشته، تمام پردازش نتایج بررسی مجوز را انجام می دهد، خواه نتیجه یک پاسخ دریافت شده از سرور باشد یا یک خطای مهلت زمانی. در پایان پردازش، LVL روش های LicenseCheckerCallback شما را از رشته پس زمینه فراخوانی می کند.

برای برنامه شما، این بدان معنی است که:

  1. روش های LicenseCheckerCallback شما در بسیاری از موارد از یک رشته پس زمینه فراخوانی می شوند.
  2. این روش‌ها نمی‌توانند وضعیت را به‌روزرسانی کنند یا پردازشی را در رشته UI فراخوانی کنند، مگر اینکه یک Handler در رشته UI ایجاد کنید و روش‌های پاسخ به تماس خود را به Handler ارسال کنید.

اگر می‌خواهید روش‌های LicenseCheckerCallback شما رشته رابط کاربری را به‌روزرسانی کند، یک Handler در متد onCreate() Activity اصلی، مانند شکل زیر، نمونه‌سازی کنید. در این مثال، روش‌های LicenseCheckerCallback برنامه نمونه LVL (به بالا مراجعه کنید) displayResult() برای به‌روزرسانی رشته رابط کاربری از طریق متد Handler's post() فراخوانی می‌کند.

کاتلین

    private lateinit var handler: Handler

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        handler = Handler()
    }

جاوا

    private Handler handler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        handler = new Handler();
    }

سپس، در روش های LicenseCheckerCallback خود، می توانید از روش های Handler برای ارسال اشیاء قابل اجرا یا پیام به Handler استفاده کنید. در اینجا آمده است که چگونه برنامه نمونه موجود در LVL یک Runnable را برای یک Handler در رشته UI ارسال می کند تا وضعیت مجوز را نمایش دهد.

کاتلین

private fun displayResult(result: String) {
    handler.post {
        statusText.text = result
        setProgressBarIndeterminateVisibility(false)
        checkLicenseButton.isEnabled = true
    }
}

جاوا

private void displayResult(final String result) {
        handler.post(new Runnable() {
            public void run() {
                statusText.setText(result);
                setProgressBarIndeterminateVisibility(false);
                checkLicenseButton.setEnabled(true);
            }
        });
    }

LicenseChecker و LicenseCheckerCallback را به صورت آنی اجرا کنید

در متد onCreate() Activity اصلی، نمونه های خصوصی LicenseCheckerCallback و LicenseChecker ایجاد کنید. ابتدا باید LicenseCheckerCallback را نمونه برداری کنید، زیرا باید هنگام فراخوانی سازنده LicenseChecker یک مرجع به آن نمونه ارسال کنید.

وقتی LicenseChecker را نمونه‌سازی می‌کنید، باید این پارامترها را پاس کنید:

  • Context برنامه
  • ارجاع به اجرای Policy برای استفاده برای بررسی مجوز. در بیشتر موارد، شما از اجرای Policy پیش‌فرض ارائه شده توسط LVL، ServerManagedPolicy استفاده می‌کنید.
  • متغیر String که کلید عمومی حساب ناشر شما را برای صدور مجوز نگه می دارد.

اگر از ServerManagedPolicy استفاده می‌کنید، نیازی به دسترسی مستقیم به کلاس ندارید، بنابراین می‌توانید آن را در سازنده LicenseChecker نمونه‌سازی کنید، همانطور که در مثال زیر نشان داده شده است. توجه داشته باشید که هنگام ساخت ServerManagedPolicy باید یک مرجع به یک نمونه Obfuscator جدید ارسال کنید.

مثال زیر نمونه سازی LicenseChecker و LicenseCheckerCallback را از متد onCreate() یک کلاس Activity نشان می دهد.

کاتلین

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.
        )
        ...
    }
}

جاوا

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() از یک متد wrapper برایتان مفید باشد. به عنوان مثال، برنامه نمونه LVL از یک متد wrapper doCheck() checkAccess() فراخوانی می کند:

کاتلین

    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)
    }

جاوا

    @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);
    }

کلید عمومی خود را برای صدور مجوز جاسازی کنید

برای هر برنامه، سرویس Google Play به طور خودکار یک جفت کلید عمومی/خصوصی RSA 2048 بیتی ایجاد می کند که برای صدور مجوز و صورتحساب درون برنامه ای استفاده می شود. جفت کلید به طور منحصر به فرد با برنامه مرتبط است. اگرچه با برنامه مرتبط است، جفت کلید با کلیدی که برای امضای برنامه های خود استفاده می کنید (یا برگرفته از آن) یکسان نیست .

کنسول Google Play کلید عمومی را برای صدور مجوز در اختیار هر توسعه‌دهنده‌ای قرار می‌دهد که به کنسول Play وارد شده باشد، اما کلید خصوصی را از همه کاربران در یک مکان امن پنهان نگه می‌دارد. هنگامی که برنامه ای درخواست بررسی مجوز برای برنامه ای منتشر شده در حساب کاربری شما می کند، سرور صدور مجوز با استفاده از کلید خصوصی جفت کلید برنامه شما، پاسخ مجوز را امضا می کند. هنگامی که LVL پاسخ را دریافت می کند، از کلید عمومی ارائه شده توسط برنامه برای تأیید امضای پاسخ مجوز استفاده می کند.

برای افزودن مجوز به یک برنامه، باید کلید عمومی برنامه خود را برای صدور مجوز دریافت کرده و آن را در برنامه خود کپی کنید. در اینجا نحوه یافتن کلید عمومی برنامه خود برای صدور مجوز آورده شده است:

  1. به کنسول Google Play بروید و وارد شوید. مطمئن شوید که به حسابی وارد شده‌اید که برنامه‌ای که از آن مجوز می‌دهید منتشر شده است (یا منتشر خواهد شد).
  2. در صفحه جزئیات برنامه، پیوند Services & APIs را پیدا کرده و روی آن کلیک کنید.
  3. در صفحه Services & APIs ، بخش Licensing & In-App Billing را پیدا کنید. کلید عمومی شما برای صدور مجوز در قسمت Your License Key For This Application داده شده است.

برای افزودن کلید عمومی به برنامه خود، کافی است رشته کلید را از فیلد در برنامه خود به عنوان مقدار متغیر رشته BASE64_PUBLIC_KEY کپی/پیست کنید. هنگام کپی کردن، مطمئن شوید که کل رشته کلید را بدون حذف هیچ کاراکتری انتخاب کرده اید.

در اینجا یک مثال از برنامه نمونه LVL آورده شده است:

کاتلین

private const val BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... " //truncated for this example
class LicensingActivity : AppCompatActivity() {
    ...
}

جاوا

public class MainActivity extends Activity {
    private static final String BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... "; //truncated for this example
    ...
}

برای بستن اتصالات IPC، متد onDestroy() LicenseChecker خود را فراخوانی کنید

در نهایت، برای اینکه اجازه دهید LVL قبل از تغییر Context برنامه شما پاک شود، یک فراخوانی به متد LicenseChecker 's onDestroy() از پیاده سازی onDestroy() Activity خود اضافه کنید. این تماس باعث می‌شود که LicenseChecker هر اتصال IPC باز را به سرویس ILicensingService برنامه Google Play به درستی ببندد و هرگونه ارجاع محلی به سرویس و کنترل‌کننده را حذف کند.

عدم فراخوانی متد LicenseChecker 's onDestroy() می تواند منجر به مشکلاتی در طول چرخه عمر برنامه شما شود. به عنوان مثال، اگر کاربر جهت صفحه نمایش را تغییر دهد در حالی که بررسی مجوز فعال است، Context برنامه از بین می رود. اگر برنامه شما به درستی اتصال IPC LicenseChecker را نبندد، برنامه شما با دریافت پاسخ از کار می افتد. به طور مشابه ، اگر کاربر در حالی که یک مجوز در حال انجام است ، از درخواست شما خارج شود ، هنگام دریافت پاسخ ، درخواست شما خراب می شود ، مگر اینکه روش onDestroy() LicenseChecker را به درستی خوانده باشد تا از این سرویس جدا شود.

در اینجا نمونه ای از برنامه نمونه موجود در LVL ، جایی که mChecker نمونه LicenseChecker است:

کاتلین

    override fun onDestroy() {
        super.onDestroy()
        checker.onDestroy()
        ...
    }

جاوا

    @Override
    protected void onDestroy() {
        super.onDestroy();
        checker.onDestroy();
        ...
    }

اگر شما در حال گسترش یا اصلاح LicenseChecker در حال اصلاح یا اصلاح هستید ، ممکن است برای تمیز کردن هرگونه اتصالات باز IPC نیز نیاز به تماس با روش finishCheck() LicenseChecker داشته باشید.

پیاده سازی DeviceLimiter

در بعضی موارد ، شما ممکن است بخواهید Policy شما تعداد دستگاه های واقعی را که مجاز به استفاده از یک مجوز واحد هستند ، محدود کند. این امر باعث می شود کاربر از یک برنامه دارای مجوز بر روی تعدادی از دستگاه ها و استفاده از برنامه در آن دستگاه ها تحت همان شناسه حساب استفاده کند. همچنین این امر باعث می شود كه کاربر با ارائه اطلاعات حساب مربوط به مجوز به افراد دیگر ، كه می توانند در دستگاه های خود به آن حساب وارد شوند و به مجوز به برنامه دسترسی پیدا كنند ، "به اشتراک گذاری" برنامه را از "به اشتراک گذاری" برنامه جلوگیری كند.

LVL با تهیه یک رابط DeviceLimiter ، که یک روش واحد را اعلام می کند ، allowDeviceAccess() از مجوزهای هر دستگاه پشتیبانی می کند. هنگامی که یک مجوز validator در حال پاسخگویی از سرور مجوز است ، آن را allowDeviceAccess() می نامد و یک رشته شناسه کاربر را که از پاسخ استخراج شده است ، عبور می دهد.

اگر نمی خواهید از محدودیت دستگاه پشتیبانی کنید ، هیچ کاری لازم نیست - کلاس LicenseChecker به طور خودکار از یک اجرای پیش فرض به نام nulldevicelimiter استفاده می کند. همانطور که از نام آن پیداست ، NullDeviceLimiter یک کلاس "NO-OP" است که روش allowDeviceAccess() به سادگی یک پاسخ LICENSED برای همه کاربران و دستگاه ها را برمی گرداند.

احتیاط: صدور مجوز در هر دستگاه برای اکثر برنامه ها توصیه نمی شود زیرا:

  • برای مدیریت نقشه برداری کاربران و دستگاه ها ، سرور پس زمینه ای را ارائه می دهد ، و
  • این می تواند سهواً منجر به عدم دسترسی کاربر به برنامه ای شود که آنها به طور قانونی در دستگاه دیگری خریداری کرده اند.

کد کردن کد شما

برای اطمینان از امنیت درخواست شما ، به ویژه برای یک برنامه پرداخت شده که از محدودیت ها و یا حفاظت از مجوز و/یا سفارشی استفاده می کند ، استفاده از کد برنامه خود بسیار مهم است. به درستی از بین بردن کد شما برای یک کاربر مخرب مشکل را برای خاموش کردن کد برنامه کاربردی دشوارتر می کند ، آن را اصلاح کنید - مانند حذف چک مجوز - و سپس دوباره آن را مجدداً تنظیم کنید.

چندین برنامه Obfuscator برای برنامه های Android از جمله Proguard در دسترس است که همچنین ویژگی های بهینه سازی کد را ارائه می دهد. استفاده از Proguard یا یک برنامه مشابه برای خنثی کردن کد شما برای کلیه برنامه هایی که از مجوز Google Play استفاده می کنند ، به شدت توصیه می شود.

انتشار یک برنامه دارای مجوز

پس از اتمام آزمایش اجرای مجوز خود ، شما آماده انتشار برنامه در Google Play هستید. مراحل عادی را برای تهیه ، امضا و سپس انتشار برنامه دنبال کنید.

از کجا پشتیبانی کنید

اگر هنگام اجرای یا استقرار انتشار در برنامه های خود ، سؤال دارید یا با مشکل روبرو هستید ، لطفاً از منابع پشتیبانی ذکر شده در جدول زیر استفاده کنید. با هدایت سؤالات خود به انجمن صحیح ، می توانید پشتیبانی مورد نیاز خود را سریعتر دریافت کنید.

جدول 2. منابع پشتیبانی توسعه دهنده خدمات صدور مجوز Google Play.

نوع پشتیبانی منبع دامنه مباحث
مسائل مربوط به توسعه و آزمایش Google Groups: توسعه دهندگان Android بارگیری و ادغام LVL ، پروژه های کتابخانه ، سؤالات Policy ، ایده های تجربه کاربر ، رسیدگی به پاسخ ها ، Obfuscator ، IPC ، تنظیم محیط آزمایش
سرریز پشته: http://stackoverflow.com/questions/tagged/android
حسابها ، انتشارات و اعزام انجمن راهنما Google Play حساب های ناشر ، مجوز جفت کلید ، حساب های تست ، پاسخ سرور ، پاسخ های آزمون ، استقرار برنامه و نتایج
سؤالات متداول در مورد مجوز بازار
ردیاب شماره LVL ردیاب شماره پروژه بازاریابی گزارش های مربوط به اشکال و انتشار به طور خاص به کلاس های کد منبع LVL و پیاده سازی های رابط

برای کسب اطلاعات کلی در مورد نحوه ارسال به گروه های ذکر شده در بالا ، به بخش منابع جامعه در صفحه منابع پشتیبانی توسعه دهنده مراجعه کنید.

منابع اضافی

برنامه نمونه گنجانده شده با LVL نمونه کاملی از نحوه شروع بررسی مجوز و رسیدگی به نتیجه ، در کلاس MainActivity را ارائه می دهد.