פתרון בעיות ב-Play Games Services במשחקי Android

בדף הזה מוסבר איך לפתור בעיות שעלולות לקרות במהלך פיתוח משחקי Android באמצעות Google Play Games Services.

רישום

כדי לפתור בעיות במשחק, אפשר להפעיל רישום מפורט ביומן במכשיר באמצעות הפקודה adb shell. אחר כך תוכלו להציג את הודעות היומן של Google Play Games Services באמצעות logcat.

הפעלת רישום

כדי להפעיל את הרישום ביומן במכשיר הבדיקה:

  1. מחברים את המכשיר למחשב שמותקן בו Android SDK.

  2. פותחים טרמינל ומריצים את הפקודה הבאה:

    adb shell setprop log.tag.Games VERBOSE
  3. מריצים את המשחק במכשיר ומשחזרים את הבעיה שרוצים לנפות.

  4. צפייה ביומנים:

    adb logcat

השבתת הרישום ביומן

כדי להשבית את הרישום המפורט ביומן של Play Games Services במכשיר ולחזור להתנהגות המקורית של רישום ביומן, מריצים את הפקודה הבאה:

adb shell setprop log.tag.Games INFO

לא ניתן לאמת

אם אין לך אפשרות לאמת שחקנים במשחק, קודם צריך לוודא שפעלת לפי ההוראות ליצירת מזהי לקוח והגדרת שירותי משחקים. אם אתם עדיין נתקלים בשגיאות אימות, כדאי לבדוק את הפריטים הבאים כדי לוודא שהמשחק מוגדר בצורה נכונה.

בדיקת תגי המטא נתונים

ה-AndroidManifest.xml צריך להכיל תג מטא-נתונים של משחקים. כדי לוודא שתגי המטא-נתונים מוגדרים בצורה נכונה:

  1. פותחים את AndroidManifest.xml ומוודאים שהוא מכיל תג meta-data כמו שמוצג בהמשך:

    <meta-data android:name="com.google.android.gms.games.APP_ID"
        android:value="@string/app_id" />
    
  2. מאתרים את ההגדרה של משאב @string/app_id. הוא מוגדר בדרך כלל בקובץ XML שנמצא בספרייה res/xml, לדוגמה res/xml/strings.xml או res/xml/ids.xml.

  3. מוודאים שהערך של רכיב @string/app_id זהה למזהה המספרי של האפליקציה. הערך של המשאב הזה צריך להכיל רק ספרות. לדוגמה:

    <string name="app_id">123456789012</string>
    

בדיקת שם החבילה

שם החבילה של המשחק צריך להיות זהה לשם החבילה שמופיע במזהה הלקוח. כדי לאמת את שם החבילה:

  1. פותחים את AndroidManifest.xml ומוודאים ששם החבילה של המשחק נכון. שם החבילה הוא הערך של המאפיין package בתג manifest.

  2. צריך לוודא ששם החבילה שסיפקתם כשיצרתם את מזהה הלקוח נכון. כדי לאמת את שם החבילה ב-Google Play Console, עוברים אל Play Console ולוחצים על הרשומה שמתאימה למשחק שלכם.

  3. עוברים לכרטיסייה אפליקציות מקושרות ובודקים את רשימת מזהי הלקוחות. ברשימה הזו צריכה להופיע אפליקציה ל-Android שמקושרת לחשבון, ושם החבילה שלה זהה לשם החבילה ב-AndroidManifest.xml. אם יש אי התאמה, צריך ליצור מזהה לקוח חדש עם שם החבילה הנכון ולנסות לבצע אימות מחדש.

בדיקת טביעת האצבע של האישור

האישור שבו אתם מאמתים את המשחק צריך להיות זהה לטביעת האצבע של האישור שמשויכת למזהה הלקוח. כדי לאמת את זה, קודם צריך לבדוק את טביעת האצבע של אישור SHA1 באופן הבא:

  1. מוצאים את קובץ האישור ומקבלים את טביעת האצבע שלו מסוג SHA1. כדי לקבל את טביעת האצבע של SHA1, מריצים את הפקודה הבאה:

    keytool -exportcert -alias your-key-name -keystore /path/to/your/keystore/file -list -v
    
  2. שימו לב לרצף הספרות ההקסדצימליות שמסומן בתווית SHA1: בפלט. זו טביעת האצבע של האישור.

לאחר מכן, בודקים שכלי הבנייה משתמש באישור הזה:

  1. יוצרים את קובץ ה-APK של המשחק באמצעות כלי הבנייה וחותמים עליו באמצעות האישור הרצוי. מעתיקים את ה-APK שנוצר לתיקייה זמנית.
  2. בספרייה הזמנית, מריצים את הפקודה הבאה כדי לחלץ את קובץ ה-APK.

    unzip YourGame.apk
    
  3. יצירת מפתח פרטי באמצעות קובץ אישור RSA:

    keytool -printcert -file META-INF/CERT.RSA
    

    לחלופין, אפשר ליצור את המפתח הפרטי באמצעות קובץ אישור DSA:

    keytool -printcert -file META-INF/CERT.DSA
    
  4. שימו לב לרצף הספרות ההקסדצימליות בשורה עם התווית SHA1:.

    רצף הספרות הזה צריך להיות זהה לטביעת האצבע של האישור מהשלב הקודם. אם יש אי התאמה, כלי הבנייה או המערכת לא מוגדרים לחתימה על האפליקציה באמצעות האישור. במקרה כזה, צריך לעיין במסמכי התיעוד של סביבת הבנייה כדי להבין איך להגדיר אותה בצורה נכונה ולנסות לבצע אימות מחדש.

לאחר מכן, בודקים אם טביעת האצבע של האישור זהה לטביעת האצבע שהוגדרה במזהה הלקוח. ככה עושים את זה:

  1. פותחים את Play Console ועוברים למשחק.
  2. בדף פרטי המשחק, גוללים לתחתית ולוחצים על הקישור לפרויקט המקושר ב-Google Cloud Platform.
  3. בוחרים את הפרויקט.
  4. בסרגל הצד שמימין, לוחצים על APIs & auth (ממשקי API והרשאות). מוודאים שהסטטוס של Google Play games services API הוא ON ברשימת ממשקי ה-API שמוצגת.
  5. בסרגל הצד שמימין, בוחרים באפשרות אפליקציות רשומות.
  6. מרחיבים את הקטע 'מזהה לקוח OAuth 2.0' ורושמים את טביעת האצבע של האישור (SHA1).

אם טביעת האצבע הזו לא תואמת לטביעת האצבע של האישור מהשלבים הקודמים, צריך ליצור מזהה לקוח חדש עם טביעת האצבע הנכונה של האישור. צריך ליצור את מזהה הלקוח החדש ב-Play Console ולא בפרויקט Google Cloud Platform.

בדיקה שהחשבונות לבדיקה מופעלים

לפני פרסום משחק, צריך להגדיר את החשבון שבו נוצר המשחק ב-Play Console כחשבון של בודק. כדי לוודא שההגדרה הזו בוצעה בצורה נכונה:

  1. פותחים את Play Console ועוברים למשחק.
  2. פותחים את הכרטיסייה בדיקה.
  3. בודקים שהחשבון שאיתו מנסים לבצע אימות מופיע ברשימת הבודקים.

אם החשבון שאתם מנסים לבצע איתו אימות לא מופיע ברשימה, מוסיפים אותו לרשימה, מחכים כמה דקות ומנסים לבצע אימות שוב.

בעיות ב-Proguard

אם אתם משתמשים ב-Proguard ומוצגות שגיאות ב-APK המוסתר, בדקו את רמת ה-API לטירגוט ב-AndroidManifest.xml. חשוב להגדיר את הגרסה ל-17 ומעלה.

סיבות אחרות לבעיות בהגדרה

כדאי לבדוק סיבות נפוצות אחרות לשגיאות:

  • אם המשחק פורסם, צריך לוודא שהגדרות המשחק פורסמו גם כן (אפשר לפרסם את האפליקציה בלי לפרסם את הגדרות המשחק). כדי לעשות זאת, עוברים אל Google Play Console, נכנסים לאפליקציה ובודקים שהתיבה לצד שם המשחק מסומנת, מה שמציין שהמשחק פורסם. אם מצוין שהמשחק נמצא במצב אחר, כמו 'מוכן לפרסום' או 'מוכן לבדיקה', לוחצים על התיבה ובוחרים באפשרות פרסום המשחק.
  • אם אתם לא מצליחים לפרסם את המשחק, צריך לוודא שרק לאחד ממזהי הלקוח מופעלת האפשרות האפליקציה הזו מועדפת להתקנות חדשות.

מאזינים אנונימיים

אל תשתמשו במאזינים אנונימיים. מאזינים אנונימיים הם הטמעות של ממשק מאזין שמוגדרות בשורה, כמו בדוגמה שלמטה.

    ImageManager im = ...;

    // Anonymous listener -- dangerous:
    im.loadImage(new ImageManager.OnImageLoadedListener() {
        @Override
        public void onImageLoaded(Uri uri, Drawable drawable) {
            // ...code...
        }
    }

המאזינים האנונימיים לא אמינים כי Play Games SDK שומר אותם כהפניות חלשות, מה שאומר שאוסף הג'אנק עשוי לאסוף אותם לפני שהם מופעלים. במקום זאת, צריך להטמיע את ה-listener באמצעות אובייקט מתמשך כמו Activity.

    public class MyActivity extends Activity
            implements ImageManager.OnImageLoadedListener {

        private void loadOurImages() {
            ImageManager im = ...;
            im.loadImage(this);
        }

        @Override
        public void onImageLoaded(Uri uri, Drawable drawable) {
            // ...code...
        }
    }