هشدار: وقتی برنامه شما فرآیند تأیید مجوز را در سمت مشتری انجام میدهد، برای مهاجمان احتمالی آسانتر است که منطق مرتبط با این فرآیند تأیید را اصلاح یا حذف کنند.
به همین دلیل، قویاً شما را تشویق میکنیم که به جای آن تأیید مجوز سمت سرور را انجام دهید .
پس از راهاندازی حساب ناشر و محیط توسعه ( به تنظیم برای صدور مجوز مراجعه کنید)، آماده هستید تا تأیید مجوز را با کتابخانه تأیید مجوز (LVL) به برنامه خود اضافه کنید.
افزودن تأیید مجوز با LVL شامل این وظایف است:
- افزودن مجوز مجوز به مانیفست برنامه شما.
- پیاده سازی یک خط مشی - می توانید یکی از پیاده سازی های کامل ارائه شده در LVL را انتخاب کنید یا خودتان ایجاد کنید.
- در حال پیاده سازی Obfuscator ، اگر
Policy
شما داده های پاسخ مجوز را در حافظه پنهان کند. - افزودن کد برای بررسی مجوز در فعالیت اصلی برنامه شما.
- پیاده سازی 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
:
- آخرین پاسخ مجوز موفق در ذخیره سازی دائمی محلی را پنهان می کند (و به درستی مبهم می کند).
- پاسخ ذخیره شده در حافظه پنهان را برای همه بررسی های مجوز، تا زمانی که پاسخ ذخیره شده در حافظه پنهان معتبر است، به جای درخواست به سرور مجوز، برمی گرداند. تنظیم اعتبار پاسخ با توجه به
VT
اضافی ارائه شده توسط سرور بسیار توصیه می شود. برای اطلاعات بیشتر به موارد اضافی پاسخ سرور مراجعه کنید. - از یک دوره عقب نشینی نمایی استفاده می کند، در صورتی که تلاش مجدد هر درخواستی منجر به خطا شود. توجه داشته باشید که سرویس گیرنده Google Play بهطور خودکار درخواستهای ناموفق را دوباره امتحان میکند، بنابراین در بیشتر موارد نیازی نیست
Policy
شما دوباره آنها را امتحان کند. - یک "دوره مهلت" را ارائه می دهد که به کاربر اجازه می دهد به برنامه شما برای مدت زمان محدود یا تعداد استفاده دسترسی داشته باشد، در حالی که یک بررسی مجوز دوباره در حال انجام است. دوره مهلت با اجازه دادن به دسترسی تا زمانی که بررسی مجوز بعدی با موفقیت تکمیل شود به نفع کاربر است و با قرار دادن محدودیت سخت برای دسترسی به درخواست شما در زمانی که پاسخ مجوز معتبری در دسترس نیست، به نفع شماست.
طراحی 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
رمزگذاری را با استفاده از سه فیلد داده ارائه شده توسط برنامه ایجاد می کند:
- نمک - آرایه ای از بایت های تصادفی برای استفاده برای هر (غیر) مبهم سازی.
- یک رشته شناسه برنامه، معمولاً نام بسته برنامه.
- یک رشته شناسه دستگاه، که تا حد امکان از منابع خاص دستگاه مشتق شده است تا آن را منحصر به فرد کند.
برای استفاده از 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
شما انجام می شود.
برای افزودن بررسی مجوز و رسیدگی به پاسخ، باید:
- واردات را اضافه کنید
- LicenseCheckerCallback را به عنوان یک کلاس داخلی خصوصی پیاده سازی کنید
- یک Handler برای ارسال از LicenseCheckerCallback به رشته UI ایجاد کنید
- LicenseChecker و LicenseCheckerCallback را به صورت آنی اجرا کنید
- برای شروع بررسی مجوز ، checkAccess() را فراخوانی کنید
- کلید عمومی خود را برای صدور مجوز جاسازی کنید
- برای بستن اتصالات 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» را در اختیار کاربر قرار دهید، که ممکن است به دلیل در دسترس نبودن سرویس در طول درخواست اتفاق افتاده باشد.
نمودار بالا نحوه انجام یک بررسی مجوز معمولی را نشان می دهد:
- کد موجود در فعالیت اصلی برنامه، اشیاء
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
شما ارسال می کند.همچنین، هر دو متد callback
allow()
وdontAllow()
یک آرگومانreason
دریافت می کنند. دلیل متدallow()
معمولاPolicy.LICENSED
یاPolicy.RETRY
و دلیلdontAllow()
معمولاPolicy.NOT_LICENSED
یاPolicy.RETRY
است. این مقادیر پاسخ مفید هستند، بنابراین میتوانید پاسخ مناسبی را برای کاربر نشان دهید، مانند ارائه یک دکمه "Retry" زمانی کهdontAllow()
باPolicy.RETRY
پاسخ میدهد، که ممکن است به دلیل در دسترس نبودن سرویس باشد. - در صورت بروز خطای برنامه، مانند زمانی که برنامه سعی می کند مجوز نام بسته نامعتبر را بررسی کند،
LicenseChecker
یک پاسخ خطا را به متد LicenseCheckerCallback'sapplicationError()
ارسال می کند.
توجه داشته باشید که، علاوه بر شروع بررسی مجوز و رسیدگی به نتیجه، که در بخشهای زیر توضیح داده شده است، برنامه شما همچنین باید یک پیادهسازی خطمشی و اگر 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
شما را از رشته پس زمینه فراخوانی می کند.
برای برنامه شما، این بدان معنی است که:
- روش های
LicenseCheckerCallback
شما در بسیاری از موارد از یک رشته پس زمینه فراخوانی می شوند. - این روشها نمیتوانند وضعیت را بهروزرسانی کنند یا پردازشی را در رشته 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 پاسخ را دریافت می کند، از کلید عمومی ارائه شده توسط برنامه برای تأیید امضای پاسخ مجوز استفاده می کند.
برای افزودن مجوز به یک برنامه، باید کلید عمومی برنامه خود را برای صدور مجوز دریافت کرده و آن را در برنامه خود کپی کنید. در اینجا نحوه یافتن کلید عمومی برنامه خود برای صدور مجوز آورده شده است:
- به کنسول Google Play بروید و وارد شوید. مطمئن شوید که به حسابی وارد شدهاید که برنامهای که از آن مجوز میدهید منتشر شده است (یا منتشر خواهد شد).
- در صفحه جزئیات برنامه، پیوند Services & APIs را پیدا کرده و روی آن کلیک کنید.
- در صفحه 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 هستید. مراحل عادی را برای تهیه ، امضا و سپس انتشار برنامه دنبال کنید.
از کجا پشتیبانی کنید
اگر هنگام اجرای یا استقرار انتشار در برنامه های خود ، سؤال دارید یا با مشکل روبرو هستید ، لطفاً از منابع پشتیبانی ذکر شده در جدول زیر استفاده کنید. با هدایت سؤالات خود به انجمن صحیح ، می توانید پشتیبانی مورد نیاز خود را سریعتر دریافت کنید.
نوع پشتیبانی | منبع | دامنه مباحث |
---|---|---|
مسائل مربوط به توسعه و آزمایش | Google Groups: توسعه دهندگان Android | بارگیری و ادغام LVL ، پروژه های کتابخانه ، سؤالات Policy ، ایده های تجربه کاربر ، رسیدگی به پاسخ ها ، Obfuscator ، IPC ، تنظیم محیط آزمایش |
سرریز پشته: http://stackoverflow.com/questions/tagged/android | ||
حسابها ، انتشارات و اعزام | انجمن راهنما Google Play | حساب های ناشر ، مجوز جفت کلید ، حساب های تست ، پاسخ سرور ، پاسخ های آزمون ، استقرار برنامه و نتایج |
سؤالات متداول در مورد مجوز بازار | ||
ردیاب شماره LVL | ردیاب شماره پروژه بازاریابی | گزارش های مربوط به اشکال و انتشار به طور خاص به کلاس های کد منبع LVL و پیاده سازی های رابط |
برای کسب اطلاعات کلی در مورد نحوه ارسال به گروه های ذکر شده در بالا ، به بخش منابع جامعه در صفحه منابع پشتیبانی توسعه دهنده مراجعه کنید.
منابع اضافی
برنامه نمونه گنجانده شده با LVL نمونه کاملی از نحوه شروع بررسی مجوز و رسیدگی به نتیجه ، در کلاس MainActivity
را ارائه می دهد.