אזהרה: כשהאפליקציה תבצע את תהליך אימות הרישיון בתאריך בצד הלקוח, קל יותר לתוקפים פוטנציאליים לשנות או להסיר הלוגיקה שמשויכת לתהליך האימות הזה.
לכן, אנחנו ממליצים מאוד ביצוע בצד השרת לבצע אימות של הרישיון.
אחרי שהגדרתם חשבון בעל תוכן דיגיטלי וסביבת פיתוח (מידע נוסף זמין במאמר הגדרה לרישוי), אתם מוכנים להוסיף את אימות הרישיון כדי לאפליקציה שלך באמצעות ספריית אימות הרישיון (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
חייב לוודא שהנתונים ערפול קוד (obfuscation) (ראו הטמעת ערפול קוד (obfuscator), למטה). allowAccess()
קובע אם להעניק למשתמש גישה אל על סמך נתוני תגובה זמינים לרישיון (מ שרת רישוי או מהמטמון) או מידע אחר שהוא ספציפי לאפליקציה. עבור לדוגמה, ההטמעה שלallowAccess()
עשויה לקחת קריטריונים נוספים בחשבון, כגון שימוש או נתונים אחרים שאוחזרו שרת עורפי. בכל המקרים, הטמעה שלallowAccess()
צריך להחזירtrue
רק אם המשתמש מורשה להשתמש כפי שנקבע על ידי שרת הרישוי, או אם קיים סטטוס זמני בעיה ברשת או במערכת שמונעת את השלמת בדיקת הרישיון. לחשבון במקרים כאלה, ההטמעה יכולה לשמור על מספר התשובות של הניסיונות החוזרים לאפשר גישה באופן זמני עד להשלמת בדיקת הרישיון הבאה.
כדי לפשט את התהליך של הוספת רישוי לאפליקציה
להמחשה של עיצוב Policy
, ה-LVL כולל
שתי הטמעות מלאות של Policy
שניתן להשתמש בהן ללא שינוי או
בהתאם לצרכים שלכם:
- ServerManagedPolicy, מדיניות גמישה של
Policy
שמשתמש בהגדרות שסופקו על ידי השרת ובתגובות שנשמרו במטמון כדי לנהל את הגישה תנאי רשת שונים, - StrictPolicy, שלא שומר תגובות במטמון ומאפשר גישה רק אם השרת מחזיר רישיון תשובה.
ברוב האפליקציות, השימוש ב-ServerManagedPolicy הוא מאוד מומלץ. ServerManagedPolicy הוא ה-LVL שמוגדר כברירת המחדל והוא משולב עם של אפליקציית ה-LVL לדוגמה.
הנחיות למדיניות מותאמת אישית
כחלק מהטמעת הרישיון, אפשר להשתמש באחת מכללי המדיניות המלאים המסופקים ב-LVL (ServerManagedPolicy או StrictPolicy) או תוכלו ליצור מדיניות מותאמת אישית. לכל סוג של מדיניות מותאמת אישית יש מספר עיצובים חשובים שחשוב להבין וליישם אותן.
שרת הרישוי מחיל מגבלות בקשות כלליות כדי להגן מפני שימוש יתר משאבים שעלולים להוביל להתקפת מניעת שירות (DoS). כשאפליקציה חורגת מגבלת הבקשות, שרת הרישוי מחזיר תגובה 503, שהועברה לאפליקציה כשגיאת שרת כללית. המשמעות היא שלא תהיה זמינה למשתמש עד שהמגבלה תתאפס, עלולות להשפיע על המשתמש לזמן בלתי מוגבל.
אם בכוונתך לעצב מדיניות מותאמת אישית, מומלץ: Policy
:
- שומר במטמון (ומערפל בצורה תקינה) את התגובה האחרונה המוצלחת של הרישיון באחסון מקומי מתמיד.
- מחזירה את התגובה שנשמרה במטמון עבור כל בדיקות הרישיונות, כל עוד
התגובה שנשמרה במטמון תקפה ולא לשלוח בקשה לשרת הרישוי.
הגדרת תוקף התגובה בהתאם ל-
VT
שסופק על ידי השרת מומלץ מאוד. למידע נוסף, ראו תוספות לתגובת שרת אפשר לקבל מידע נוסף. - משתמש בתקופת השהיה מעריכית לפני ניסיון חוזר (exponential backoff), אם מתבצע ניסיון חוזר של בקשות כלשהן התוצאה
שגיאות. לתשומת ליבך: לקוח Google Play מנסה לבצע ניסיון חוזר באופן אוטומטי
לכן ברוב המקרים אין צורך ב-
Policy
כדי לנסות שוב. - מציין 'תקופת חסד' שמאפשרת למשתמש לגשת לזמן מוגבל או למספר מוגבל של שימושים, בזמן שמתבצעת בדיקת רישיון בוצע ניסיון נוסף. תקופת החסד מועילה למשתמש מפני שהיא מאפשרת גישה עד בדיקת רישיונות תושלם בהצלחה, והיא תועיל לך על ידי הצבה הגבלה קשיחה על גישה לאפליקציה כאשר אין תגובה תקפה לרישיון זמינים.
חשוב מאוד לתכנן את הPolicy
בהתאם להנחיות שלמעלה,
כי זה מבטיח את החוויה הטובה ביותר האפשרית עבור המשתמשים, וגם
שליטה יעילה באפליקציה שלכם גם במצב של שגיאות.
לתשומת ליבך, כל Policy
יכול להשתמש בהגדרות שסופקו על ידי שרת הרישוי כדי
עוזרות לנהל את התוקף והשמירה במטמון, לבצע ניסיון חוזר של תקופת חסד ועוד. חילוץ של
ההגדרות שסופקו על ידי השרת הן פשוטות, והשימוש בהן מאוד
מומלץ. לדוגמה, אפשר לעיין בהטמעה של ServerManagedPolicy
לחלץ את התוספות ולהשתמש בהן. לרשימה של הגדרות שרת ומידע על
כיצד להשתמש בהן, ראו תגובה מהשרת
תוספות.
מדיניות מנוהלת של Server
LVL כולל הטמעה מלאה ומומלצת של Policy
ממשק שנקרא ServerManagedPolicy. ההטמעה משולבת עם
מחלקות LVL ומשמשות כ-Policy
ברירת המחדל בספרייה.
ServermanagedPolicy מספק את כל הטיפול ברישיונות ובניסיונות חוזרים
תשובות מדויקות. היא שומרת במטמון את כל נתוני התגובות באופן מקומי
SharedPreferences
, לבצע ערפול קוד (obfuscation) שלו באמצעות
יישום Obfuscator
של האפליקציה. כך אפשר לוודא שתגובת הרישיון
הנתונים מאובטחים ונשמרים בכל מחזורי ההפעלה של המכשיר. מדיניות מנוהלת של Server
מספקת הטמעות קונקרטיות של שיטות הממשק
processServerResponse()
, allowAccess()
וגם
הדוח כולל קבוצה של שיטות וסוגים תומכים לניהול רישיונות
תשובות מדויקות.
חשוב לציין שתכונה חשובה של ServerManagedPolicy היא השימוש בו
להגדרות שסופקו על ידי השרת כבסיס לניהול רישוי בכל
תקופת ההחזר הכספי של האפליקציה ובאמצעות תנאי רשת ושגיאות שונים.
כשאפליקציה יוצרת קשר עם שרת Google Play לצורך בדיקת רישיון,
השרת מצרף מספר הגדרות בתור צמדי מפתח-ערך בשדה התוספות של נתונים
סוגי התגובה לרישיונות. לדוגמה, השרת מספק ערכים מומלצים עבור
תוקף הרישיון של הבקשה, תקופת החסד של ניסיון חוזר, ותקופת החסד המקסימלית
מספר ניסיונות חוזרים, בין היתר. ServermanagedPolicy מחלץ את הערכים מה-
של הרישיון בשיטה processServerResponse()
ובבדיקות
בשיטה ה-allowAccess()
שלה. לרשימה של
ההגדרות שבהן נעשה שימוש על ידי ServerManagedPolicy, כאן אפשר לעיין בתגובת השרת
תוספות.
מטעמי נוחות, הביצועים הטובים ביותר והיתרון של השימוש בהגדרות הרישיון
משרת Google Play, באמצעות ServerManagedPolicy בתור
מומלץ מאוד להוסיף רישיון ל-Policy
.
אם יש לך חשש לגבי האבטחה של נתוני תגובה לרישיון,
מאוחסנים באופן מקומי ב-SharedPreferences
, אפשר להשתמש בערפול קוד (obfuscation) חזק יותר
או לתכנן Policy
מחמיר יותר שלא מאחסן נתוני רישיונות. LVL
כולל דוגמה ל-Policy
כזה - למידע נוסף, ראו StrictPolicy.
כדי להשתמש ב-ServerManagedPolicy, פשוט ייבא אותו לפעילות שלך, צור
ונעביר הפניה למכונה בזמן הבנייה
LicenseChecker
לפרטים נוספים, אפשר לעיין ב-Instantiate LicenseChecker
LicenseCheckerCallback לקבלת מידע נוסף.
מדיניות מחמירה
LVL כולל הטמעה מלאה חלופית של הממשק של Policy
שנקרא StrictPolicy. ההטמעה של StrictPolicy מספקת
לפי המדיניות ServerManagedPolicy, שהיא לא מאפשרת למשתמש לגשת
של האפליקציה, אלא אם התקבלה תגובת רישיון מהשרת
זמן גישה שמציין שהמשתמש מורשה.
התכונה העיקרית של StrictPolicy היא שהיא לא מאחסנת אף
לקבל רישיון באופן מקומי, בחנות קבועה. מכיוון שלא נשמרים נתונים,
לא מתבצע מעקב אחרי בקשות חוזרות ולא ניתן להשתמש בתגובות שנשמרו במטמון
את בדיקות הרישיון. Policy
מאפשרת גישה רק אם:
- תגובת הרישיון מתקבלת משרת הרישוי.
- תגובת הרישיון מציינת שהמשתמש מורשה לגשת אל תרגום מכונה.
השימוש ב-StrictPolicy מתאים אם החששות העיקריים שלכם הם להבטיח בכל המקרים האפשריים, אף משתמש לא יוכל לגשת לאפליקציה אלא אם מאושר שהמשתמש בעל רישיון בזמן השימוש. בנוסף, המדיניות מספקת אבטחה קצת יותר גבוהה מזו של ServerManagedPolicy – כי אין נתונים במטמון באופן מקומי, אין דרך שמשתמש זדוני יוכל לעשות שינויים את הנתונים שנשמרו במטמון ולקבל גישה לאפליקציה.
במקביל, Policy
מציג אתגר למשתמשים רגילים, מכיוון שהוא
פירושו שהם לא יוכלו לגשת לאפליקציה כשאין רשת
יש חיבור לרשת סלולרית או לרשת Wi-Fi. תופעת לוואי נוספת היא
ישלח לשרת בקשות נוספות לבדיקת רישיונות, מכיוון שהשתמשנו ב-
תגובה שנשמרה במטמון אינה אפשרית.
באופן כללי, המדיניות הזו מייצגת איזון של מידה מסוימת של נוחות המשתמש
לאבטחה מוחלטת ושליטה בגישה. שוקלים את הפשרה בקפידה
לפני שמשתמשים בPolicy
הזה.
כדי להשתמש ב-StrictPolicy, צריך לייבא אותו לפעילות, ליצור מכונה,
ולהעביר אליו הפניה כאשר בונים את LicenseChecker
. צפייה
Instantiate LicenseChecker ו- LicenseCheckerCallback
אפשר לקבל מידע נוסף.
הטמעה אופיינית של Policy
צריכה לשמור את נתוני התגובה לרישיון
של אפליקציה לאחסון קבוע, כדי שאפשר יהיה לגשת אליה דרך
הפעלות של אפליקציות ומחזורי הפעלה של המכשיר. לדוגמה, Policy
לשמור את חותמת הזמן של בדיקת הרישיון האחרונה שבוצעה, את מספר הניסיונות החוזרים
תקופת תוקף הרישיון ומידע דומה בחנות קבועה,
במקום לאפס את הערכים בכל פעם שהאפליקציה מופעלת.
ברירת המחדל של Policy
כלולה ב-LVL, ServerManagedPolicy, או מאחסן את התגובה
במכונה של SharedPreferences
, כדי לוודא
קבועים.
כי Policy
ישתמש בנתוני תגובה מאוחסנים של הרישיון כדי לקבוע אם
כדי לאפשר או למנוע גישה לאפליקציה, חייב לוודא
הנתונים המאוחסנים מאובטחים ולא ניתן לעשות בהם שימוש חוזר או לשנות אותם על ידי משתמש ברמה הבסיסית (root)
במכשיר. באופן ספציפי, Policy
תמיד צריך לערפל את הנתונים לפני האחסון
באמצעות מפתח ייחודי לאפליקציה ולמכשיר. ערפול קוד (obfuscation) באמצעות
מפתח שהוא ספציפי לאפליקציה וספציפי למכשיר הוא קריטי, מכיוון
הוא מונע שיתוף של הנתונים המעורפלים בין אפליקציות
מכשירים.
ה-LVL מסייע לאפליקציה לאחסן את נתוני התגובות לרישיון
בצורה מאובטחת ועקבית. קודם כול, הוא מספק Obfuscator
שמאפשר לאפליקציה לספק את האלגוריתם לערפול קוד (obfuscation)
עבור הנתונים המאוחסנים. על בסיס זה, ה-LVL מספק את המחלקה המסייעת
PreferenceObfuscator, שמטפל ברוב העבודה של הפעלת
את הכיתה Obfuscator
של האפליקציה, וקריאה וכתיבה של הנתונים המעורפלים
מופע אחד (SharedPreferences
).
ה-LVL מספק הטמעה מלאה של Obfuscator
שנקראת
AESObfuscator שמשתמש בהצפנת AES כדי להסתיר נתונים. אפשר
להשתמש ב-AESObfuscator באפליקציה ללא שינוי או שלא
להתאים אותו לצרכים שלכם. אם משתמשים ב-Policy
(כמו
ServermanagedPolicy) ששומר במטמון נתוני תגובה של רישיונות, באמצעות AESObfuscator בתור
מומלץ מאוד להטמיע את Obfuscator
.
למידע נוסף, עיינו בקטע הבא.
AESObfuscator
LVL כולל הטמעה מלאה ומומלצת של Obfuscator
שנקרא AESObfuscator. ההטמעה משולבת עם
אפליקציה לדוגמה של LVL ומשמשת כברירת המחדל של Obfuscator
בספרייה.
AESObfuscator מספק ערפול קוד (obfuscation) מאובטח של נתונים באמצעות AES כדי
להצפין ולפענח את הנתונים כשהם נכתבים באחסון או קוראים אותם.
ההצפנה מתבצעת על ידי Obfuscator
באמצעות שלושה שדות נתונים
על ידי האפליקציה:
- A salt — מערך בייטים אקראיים לשימוש לכל ערפול (obfuscation).
- מחרוזת של מזהה אפליקציה, בדרך כלל שם החבילה של האפליקציה.
- מחרוזת של מזהה מכשיר, שנגזרת מכמה מקורות ספציפיים למכשיר ככל האפשר, כדי שהיא תהיה ייחודית.
כדי להשתמש ב-AESObfuscator, קודם צריך לייבא אותו לפעילות שלך. הצהרה על פרטי מערך סופי סטטי שיכיל את בייטים ה-salt ולאתחל אותו ב-20 באופן אקראי בייטים שנוצרו על ידי AI.
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
, שהוא ייחודי לכל מכשיר.
לתשומת ליבכם: בהתאם לממשקי ה-API שבהם אתם משתמשים, ייתכן שהאפליקציה יצטרך
לבקש הרשאות נוספות כדי לקבל מידע ספציפי למכשיר.
לדוגמה, כדי לשלוח שאילתה על TelephonyManager
כדי לקבל
מספר ה-IMEI של המכשיר או נתונים קשורים, האפליקציה תצטרך גם לבקש את
ההרשאה android.permission.READ_PHONE_STATE
במניפסט.
לפני שמבקשים הרשאות חדשות למטרה הבלעדית של צירוף משתמשים
מידע ספציפי למכשיר שישמש בObfuscator
, כדאי להביא בחשבון
איך פעולה זו עשויה להשפיע על האפליקציה או על הסינון שלה ב-Google Play
(מכיוון שהרשאות מסוימות יכולות לגרום לכלי ה-build של ה-SDK להוסיף
<uses-feature>
המשויך).
לבסוף, בונים מכונה של AESObfuscator ומעבירים את ה-salt,
מזהה האפליקציה ומזהה המכשיר. אפשר ליצור את המכונה
ישירות, בזמן בניית ה-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
,
אתם יכולים להוסיף בדיקות רישיונות לפעילויות האלה.
בדיקת הרישיון מורכבת משתי פעולות עיקריות:
- קריאה ל-method להפעלת בדיקת הרישיון — ב-LVL,
קריאה ל-method
checkAccess()
של אובייקטLicenseChecker
שאתם בונים. - קריאה חוזרת (callback) שמחזירה את התוצאה של בדיקת הרישיון. ב-LVL,
ממשק
LicenseCheckerCallback
שאתם מטמיעים. הממשק כולל שתי שיטות:allow()
dontAllow()
, שמופעלים על ידי הספרייה על סמך התוצאה של בדיקת הרישיון. אתם מיישמים את שתי השיטות האלה בכל לוגיקה שהיא הדרוש לך, כדי לאפשר או לא לאפשר למשתמש גישה לאפליקציה שלך. שימו לב השיטות האלה לא קובעות אם לאפשר גישה – החלטה זו אחראית ליישום שלPolicy
. במקום זאת, methods של האפליקציות פשוט מספקות את התנהגויות האפליקציה שאיך למנוע גישה (ולטפל בשגיאות באפליקציה).השיטות
allow()
ו-dontAllow()
מספקות 'סיבה' של התשובה, שיכול להיות אחד מהערכיםPolicy
,LICENSED
,NOT_LICENSED
אוRETRY
. במיוחד, עליך לטפל במקרה שבו ה-method מקבלת את התשובהRETRY
עבורdontAllow()
ומספקת למשתמש "ניסיון חוזר" שייתכן שהסיבה לכך היא שהשירות לא היה זמין במהלך בקשה.
התרשים שלמעלה ממחיש איך מתבצעת בדיקת רישיון אופיינית:
- קוד בפעילות הראשית של האפליקציה יוצר את
LicenseCheckerCallback
ו-LicenseChecker
אובייקטים. כשיוצרים אתLicenseChecker
, הקוד מעבירContext
, הטמעתPolicy
לשימוש, וגם המפתח הציבורי של החשבון של בעל התוכן הדיגיטלי לרישוי כפרמטרים. - לאחר מכן הקוד קורא ל-method
checkAccess()
אובייקטLicenseChecker
. הטמעת השיטה מפעילה אתPolicy
כדי לקבוע האם יש תגובת רישיון חוקית ששמורה במטמון באופן מקומי,SharedPreferences
.- אם כן, לקרוא להטמעה של
checkAccess()
allow()
. - אחרת,
LicenseChecker
יוזם בקשה לבדיקת רישיון שנשלחת לשרת הרישוי.
הערה: שרת הרישוי תמיד מחזיר
LICENSED
כשמבצעים בדיקת רישיון של טיוטת בקשה. - אם כן, לקרוא להטמעה של
- כשמתקבלת תשובה,
LicenseChecker
יוצר LicenseValidator ש מאמת את הנתונים של הרישיון החתום ומחלץ את השדות בתשובה, מועברות אלPolicy
להערכה נוספת.- אם הרישיון תקף,
Policy
ישמור את התגובה במטמוןSharedPreferences
ומודיע לכלי התיקוף, ואז קורא לפונקציה השיטהallow()
באובייקטLicenseCheckerCallback
. - אם הרישיון לא תקף, נשלחת הודעה מ-
Policy
לכלי התיקוף, והפעולה הזו קוראת השיטהdontAllow()
ב-LicenseCheckerCallback
.
- אם הרישיון תקף,
- במקרה של שגיאה מקומית או שגיאה בחיבור לשרת שניתן לשחזר, למשל כאשר הרשת
לא זמין לשליחת הבקשה,
LicenseChecker
מעביר תשובתRETRY
אל באמצעות ה-methodprocessServerResponse()
של האובייקטPolicy
.כמו כן, גם אמצעי הקריאה החוזרת (callback)
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מנוהלPolicy, צריך לייבא גם אותו, יחד עם 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
שיטות, שנוצרו על סמך אימות התשובה
המטען הייעודי (payload), קוד התגובה של השרת עצמו וכל עיבוד נוסף שמסופק
על ידי Policy
. האפליקציה יכולה להטמיע את השיטות בכל דרך שנדרשת. לחשבון
באופן כללי, רצוי להשתמש בשיטות פשוטות ולהגביל אותן לניהול ממשק המשתמש
למצב וליישום. אם ברצונך להוסיף עוד עיבוד של הרישיון
על ידי יצירת קשר עם שרת עורפי או החלת אילוצים מותאמים אישית,
כדאי לשלב את הקוד הזה ב-Policy
במקום
הטמענו אותו ב-methods של LicenseCheckerCallback
.
ברוב המקרים, עליכם להצהיר על ההטמעה של
LicenseCheckerCallback
ככיתה פרטית בתוך הכיתה הראשית של האפליקציה
שיעור פעילות.
הטמעת השיטות allow()
ו-dontAllow()
בתור
הדרושים. קודם כול, אפשר להשתמש בהתנהגויות פשוטות של טיפול בתוצאות
methods, כמו הצגת תוצאת הרישיון בתיבת דו-שיח. כך אפשר לקבל
שבו האפליקציה תפעל מוקדם יותר ויכולה לסייע בניפוי באגים. מאוחר יותר, אחרי
קבעת בדיוק את הפעולות הרצויות, אפשר להוסיף טיפול מורכב יותר.
הצעות מסוימות לטיפול בתשובות ללא רישיון
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 קורא כדי לאפשר לאפליקציה לטפל בשגיאות שלא
ניתן לנסות שוב. לרשימה של שגיאות כאלה, אפשר לעיין בקטע שרת
קודי תגובה בחומר העזר בנושא רישוי. אפשר להטמיע
את השיטה הנדרשת בכל דרך שהיא. ברוב המקרים, הפרמטר
ה-method הזה צריך לתעד את קוד השגיאה ולקרוא ל-dontAllow()
.
יצירת Handler לפרסום תוכן מ- LicenseCheckerCallback לשרשור בממשק המשתמש
במהלך בדיקת רישיון, ה-LVL מעביר את הבקשה אל Google Play
שמטפל בתקשורת עם שרת הרישוי. LVL
מעביר את הבקשה דרך IPC אסינכרוני (באמצעות Binder
) כך
העיבוד והתקשורת ברשת בפועל לא מתבצעים בשרשור
שמנוהלות על ידי האפליקציה שלכם. באופן דומה, כשאפליקציית Google Play
מקבל את התוצאה, הוא מפעיל שיטת קריאה חוזרת ב-IPC, שבתורה
פועל במאגר שרשורים של IPC בתהליך האפליקציה שלכם.
המחלקה LicenseChecker
מנהלת את תקשורת ה-IPC של האפליקציה עם
אפליקציית Google Play, כולל השיחה ששולחת את הבקשה
הקריאה החוזרת שמקבלת את התשובה. LicenseChecker
עוקב גם אחרי רישיון פתוח
ומנהל את הזמן הקצוב לתפוגה שלהם.
כדי לנהל כראוי את הזמן הקצוב לתפוגה וגם לעבד תשובות נכנסות
בלי להשפיע על ה-thread של ממשק המשתמש של האפליקציה, LicenseChecker
יוצר
שרשור ברקע ביצירת מופע. בשרשור מתבצע כל העיבוד של
תוצאות בדיקת רישיונות, אם התוצאה היא תגובה שהתקבלה מהשרת
או שגיאה של תפוגת זמן קצוב. בסיום העיבוד, ה-LVL קורא לפונקציה
LicenseCheckerCallback
methods מהשרשור ברקע.
לגבי הבקשה שלך, המשמעות היא:
- במקרים רבים, השיטות של
LicenseCheckerCallback
יופעלו דרך שרשור ברקע. - השיטות האלה לא יוכלו לעדכן את המצב או להפעיל עיבוד כלשהו שרשור בממשק המשתמש, אלא אם יוצרים מטפל בשרשור של ממשק המשתמש ומקבלים קריאה חוזרת מתווספות ל-Handler.
אם רוצים שה-methods של LicenseCheckerCallback
יעדכנו את ה-thread של ממשק המשתמש,
ליצור 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
אפשר להשתמש בשיטות Handler כדי
לשלוח אובייקטים שניתנים להרצה או לשליחת הודעה ל-handler. כך עושים את זה
שכלול ב-LVL מפרסם אובייקט שניתן להריץ ל-handler בשרשור של ממשק המשתמש
כדי להציג את סטטוס הרישיון.
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); } }); }
Directiate LicenseChecker ו- LicenseCheckerCallback
בחלק של הפעילות הראשית
אמצעי תשלום אחד (onCreate()
),
יצירת מופעים פרטיים של LicenseCheckerCallback ו-LicenseChecker
. צריך
קודם כל יוצרים מופע של LicenseCheckerCallback
, כי צריך להעביר
למופע הזה כשקוראים ל-constructor של LicenseChecker
.
כשיוצרים את LicenseChecker
, צריך להעביר את הפרמטרים הבאים:
- האפליקציה
Context
- הפניה להטמעה של
Policy
שצריך להשתמש בה לבדיקת הרישיון. לחשבון ברוב המקרים, צריך להשתמש בהטמעת ברירת המחדל שלPolicy
שמסופקת על ידי ה-LVL, ServerManagedPolicy. - משתנה המחרוזת שמכיל את המפתח הציבורי של חשבון בעל האתר שלכם עבור של רישוי.
אם אתם משתמשים ב-ServerManagedPolicy, לא תצטרכו לגשת לכיתה.
ישירות, כך שאפשר ליצור אותו ב-constructor של LicenseChecker
,
כפי שאפשר לראות בדוגמה הבאה. לתשומת ליבכם: צריך להעביר הפניה אל
מופע של ערפול קוד (obfuscator) כשיוצרים ServerManagedPolicy.
הדוגמה הבאה מציגה את יצירת המופע של LicenseChecker
LicenseCheckerCallback
מה-method 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
קורא ל-methods LicenseCheckerCallback
מממשק המשתמש
thread רק אם יש תגובה תקפה של הרישיון ששמורה במטמון באופן מקומי. אם
בדיקת הרישיון נשלחת לשרת, הקריאות החוזרות תמיד מגיעות
של שרשור ברקע, גם במקרה של שגיאות רשת.
קריאה ל-checkAccess() כדי להפעיל את בדיקת הרישיון
בפעילות הראשית, מוסיפים קריאה ל-method checkAccess()
של
מופע אחד (LicenseChecker
). בשיחה, מעבירים
את המופע של LicenseCheckerCallback
כפרמטר. אם צריך לטפל במשהו
אפקטים מיוחדים בממשק המשתמש או ניהול מצב לפני השיחה, ייתכן שהם יעזרו
כדי להפעיל את checkAccess()
מ-method של wrapper. לדוגמה, טבלת ה-LVL
קריאות לדוגמה של אפליקציות מ-checkAccess()
שיטת wrapper 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); }
הטמעת המפתח הציבורי לרישוי
עבור כל אפליקציה, שירות Google Play פועל באופן אוטומטי יוצר זוג מפתחות RSA ציבורי/פרטי של 2048 ביטים שמשמש רישוי וחיוב על רכישות באפליקציות. זוג המפתחות משויך באופן ייחודי תרגום מכונה. למרות שזוג המפתחות משויך לאפליקציה, לא זהה למפתח שבו אתם משתמשים כדי לחתום על האפליקציות שלכם (או שנגזר מהן).
מערכת Google Play Console חושפת את המפתח הציבורי לצורך רישוי המפתח נכנס ל-Play Console, אבל הוא נשאר עם המפתח הפרטי מוסתר מכל המשתמשים במיקום מאובטח. כשאפליקציה מבקשת בדיקת רישיון של אפליקציה שפורסמה בחשבון שלכם, שרת הרישוי חותם על תגובת הרישיון באמצעות המפתח הפרטי של זוג המפתחות של האפליקציה. כשה-LVL מקבל את התשובה, הוא משתמש במפתח הציבורי שסופק לאימות החתימה של תגובת הרישיון.
כדי להוסיף רישיון לאפליקציה, עליך לקבל את מפתח ציבורי לרישוי ומעתיקים אותו לאפליקציה. כך מוצאים המפתח הציבורי של האפליקציה שלך לרישוי:
- עוברים אל Google Play Console ונכנסים לחשבון. צריך לוודא שנכנסתם לחשבון שממנו נשלחה האפליקציה הרישוי פורסם (או יפורסם).
- בדף הפרטים של האפליקציה, מחפשים את האפשרות Services & ממשקי API ולוחצים עליו.
- בקטע שירותים API, לאתר את רישוי בקטע 'חיוב על רכישות באפליקציות'. המפתח הציבורי שלך עבור הרישוי ניתן בשדה מפתח הרישיון שלך לאפליקציה זו.
כדי להוסיף את המפתח הציבורי לאפליקציה, פשוט מעתיקים ומדביקים את מחרוזת המפתח
מהשדה לאפליקציה בתור הערך של המשתנה String (מחרוזת)
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 של האפליקציה ומסירה כל אזכור מקומי של השירות
ו-handler.
קריאה ל-method של 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 פתוח
בחיבורים.
יישום DeviceLimiter
במקרים מסוימים, ייתכן שתרצו שה-Policy
יגביל את מספר
מכשירים שמורשים להשתמש ברישיון יחיד. זה ימנע ממשתמש
מהעברת אפליקציה מורשית למספר מכשירים ושימוש
במכשירים האלה עם אותו מספר חשבון. כמו כן, היא תמנע
משתמש מ'שיתוף' את הבקשה באמצעות פרטי החשבון
שמשויכים לרישיון לאנשים אחרים, שיכולים להיכנס לאחר מכן
החשבון במכשירים שלהם ולגשת לרישיון לאפליקציה.
LVL תומך ברישוי לכל מכשיר באמצעות
בממשק DeviceLimiter
, שמצהיר על שיטה אחת,
allowDeviceAccess()
. כאשר LicenseValidator מטפל בתגובה
משרת הרישוי הוא מבצע קריאה ל-allowDeviceAccess()
, ומעביר
מחרוזת מזהה המשתמש חולפת מהתגובה.
אם לא רוצים לתמוך בהגבלת מספר המכשירים, אין עבודה
חובה – הכיתה LicenseChecker
משתמשת באופן אוטומטי בברירת מחדל
שנקראת NullDeviceLimiter. כפי שרמז השם, NullDeviceLimiter
הוא 'לא תפעול' מחלקה שהשיטה allowDeviceAccess()
שלה פשוט מחזירה
תגובת LICENSED
לכל המשתמשים והמכשירים.
זהירות: רישוי לפי מכשיר לא מומלץ עבור רוב האפליקציות כי:
- צריך לספק שרת עורפי כדי לנהל משתמשים ומכשירים מיפוי, ו
- היא עלולה לגרום בטעות לדחיית הגישה של משתמש אל אפליקציה שהם רכשו באופן חוקי במכשיר אחר.
ערפול הקוד (obfuscation)
כדי להבטיח את אבטחת האפליקציה, במיוחד באפליקציות בתשלום המשתמשת ברישוי ו/או באילוצים והגנות מותאמים אישית, חשוב מאוד לערפל את קוד האפליקציה שלכם. ערפול קוד (obfuscation) תקין מקשה על משתמש זדוני להסיר את הידור של היישום bytecode, לשנות אותו — למשל על ידי הסרת בדיקת הרישיון — ואז להדר אותו מחדש.
יש כמה תוכניות מערפול קוד (obfuscator) זמינות לאפליקציות ל-Android, כולל ProGuard, שכולל גם לתכונות לאופטימיזציה של קוד. שימוש ב-ProGuard או בתוכנה דומה לערפול קוד (obfuscation) הקוד מומלץ מאוד לכל האפליקציות שמשתמשות ב-Google Play רישיון.
פרסום אפליקציה ברישיון
בסיום הבדיקה של הטמעת הרישיון, תהיו מוכנים לפרסם את האפליקציה ב-Google Play. פועלים לפי השלבים הרגילים כדי להכין את הבקשה, לחתום עליה ולאחר מכן לפרסם אותה.
היכן לקבל תמיכה
אם יש לך שאלות או נתקלת בבעיות במהלך הטמעה או פריסה בפרסום באפליקציות שלך, עליך להשתמש במשאבי התמיכה המפורטים בטבלה שלמטה. אם תעבירו את השאילתות לפורום המתאים, תוכלו לקבל התמיכה הנדרשת מהר יותר.
סוג התמיכה | משאב | טווח הנושאים |
---|---|---|
בעיות פיתוח ובדיקה | קבוצות Google: android-developers | הורדה ושילוב של LVL, פרויקטים של ספריות, Policy
שאלות, רעיונות לחוויית משתמש, טיפול בתשובות, Obfuscator , IPC, בדיקה
הגדרת סביבה |
Stack Overflow: http://stackoverflow.com/questions/TAG/android | ||
בעיות בחשבונות, בפרסום ובפריסה | ב-Google Play פורום העזרה | חשבונות של בעל תוכן דיגיטלי, זוג מפתחות רישוי, חשבונות בדיקה, שרת תגובות, תגובות לבדיקה, פריסת אפליקציות ותוצאות |
שוק שאלות נפוצות על תמיכה בנושא רישוי | ||
מעקב אחר בעיות LVL | רישוי מעקב אחרי בעיות בפרויקט | דוחות על באגים ובעיות שקשורים באופן ספציפי למחלקות של קוד המקור LVL והטמעות ממשקים |
למידע כללי על פרסום פוסטים בקבוצות שצוינו למעלה, ראו מקורות מידע לקהילה בדף 'משאבי תמיכה למפתחים'.
משאבים נוספים
האפליקציה לדוגמה הכלולה ב-LVL מספקת דוגמה מלאה לאופן שבו
להתחיל בדיקת רישיון ולטפל בתוצאה,
כיתה אחת (MainActivity
).