Nano Hash - криптовалюты, майнинг, программирование

Таблица лидеров Android не работает после публикации с ошибкой RESULT_APP_MISCONFIGURED

Я добавил таблицу лидеров в свое приложение (игру). Он отлично работает, пока я запускаю приложение прямо на своем телефоне из студии Android. Но после загрузки приложения с альфа-тестирования в googleplay не работает таблица лидеров.

Он показывает ошибку неправильной настройки приложения.

RESULT_APP_MISCONFIGURED

Я правильно добавил ключ SHA1 в консоль разработчика Google. Я снова проверил ключ SHA1 и обнаружил, что ключ правильный.

Я просмотрел эти темы в stackoverflow, но не смог найти подходящего решения моей проблемы. Я также проверил это решение, но это не решает проблему.

Пожалуйста, посмотрите на скриншоты ниже, которые я сделал из консоли разработчика Google. Я стер имя пакета/ключ sha1 и другие личные вещи со снимков экрана в целях безопасности.

  1. Связанное приложение Связанное приложение

  2. Таблица лидеров Доска лидеров

  3. Консоль разработчика Консоль разработчика

Ниже приведен вспомогательный класс игры, который я использовал в своем коде.

    class GameHelperUtils {
    public static final int R_UNKNOWN_ERROR = 0;
    public static final int R_SIGN_IN_FAILED = 1;
    public static final int R_APP_MISCONFIGURED = 2;
    public static final int R_LICENSE_FAILED = 3;

    private final static String[] FALLBACK_STRINGS = {
            "*Unknown error.",
            "*Failed to sign in. Please check your network connection and try again.",
            "*The application is incorrectly configured. Check that the package name and signing certificate match the client ID created in Developer Console. Also, if the application is not yet published, check that the account you are trying to sign in with is listed as a tester account. See logs for more information.",
            "*License check failed."
    };

    private final static int[] RES_IDS = {
            R.string.gamehelper_unknown_error, R.string.gamehelper_sign_in_failed,
            R.string.gamehelper_app_misconfigured, R.string.gamehelper_license_failed
    };

    static String activityResponseCodeToString(int respCode) {
        switch (respCode) {
            case Activity.RESULT_OK:
                return "RESULT_OK";
            case Activity.RESULT_CANCELED:
                return "RESULT_CANCELED";
            case GamesActivityResultCodes.RESULT_APP_MISCONFIGURED:
                return "RESULT_APP_MISCONFIGURED";
            case GamesActivityResultCodes.RESULT_LEFT_ROOM:
                return "RESULT_LEFT_ROOM";
            case GamesActivityResultCodes.RESULT_LICENSE_FAILED:
                return "RESULT_LICENSE_FAILED";
            case GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED:
                return "RESULT_RECONNECT_REQUIRED";
            case GamesActivityResultCodes.RESULT_SIGN_IN_FAILED:
                return "SIGN_IN_FAILED";
            default:
                return String.valueOf(respCode);
        }
    }

    static String errorCodeToString(int errorCode) {
        switch (errorCode) {
            case ConnectionResult.DEVELOPER_ERROR:
                return "DEVELOPER_ERROR(" + errorCode + ")";
            case ConnectionResult.INTERNAL_ERROR:
                return "INTERNAL_ERROR(" + errorCode + ")";
            case ConnectionResult.INVALID_ACCOUNT:
                return "INVALID_ACCOUNT(" + errorCode + ")";
            case ConnectionResult.LICENSE_CHECK_FAILED:
                return "LICENSE_CHECK_FAILED(" + errorCode + ")";
            case ConnectionResult.NETWORK_ERROR:
                return "NETWORK_ERROR(" + errorCode + ")";
            case ConnectionResult.RESOLUTION_REQUIRED:
                return "RESOLUTION_REQUIRED(" + errorCode + ")";
            case ConnectionResult.SERVICE_DISABLED:
                return "SERVICE_DISABLED(" + errorCode + ")";
            case ConnectionResult.SERVICE_INVALID:
                return "SERVICE_INVALID(" + errorCode + ")";
            case ConnectionResult.SERVICE_MISSING:
                return "SERVICE_MISSING(" + errorCode + ")";
            case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
                return "SERVICE_VERSION_UPDATE_REQUIRED(" + errorCode + ")";
            case ConnectionResult.SIGN_IN_REQUIRED:
                return "SIGN_IN_REQUIRED(" + errorCode + ")";
            case ConnectionResult.SUCCESS:
                return "SUCCESS(" + errorCode + ")";
            default:
                return "Unknown error code " + errorCode;
        }
    }

    static void printMisconfiguredDebugInfo(Context ctx) {
        Log.w("GameHelper", "****");
        Log.w("GameHelper", "****");
        Log.w("GameHelper", "**** APP NOT CORRECTLY CONFIGURED TO USE GOOGLE PLAY GAME SERVICES");
        Log.w("GameHelper", "**** This is usually caused by one of these reasons:");
        Log.w("GameHelper", "**** (1) Your package name and certificate fingerprint do not match");
        Log.w("GameHelper", "****     the client ID you registered in Developer Console.");
        Log.w("GameHelper", "**** (2) Your App ID was incorrectly entered.");
        Log.w("GameHelper", "**** (3) Your game settings have not been published and you are ");
        Log.w("GameHelper", "****     trying to log in with an account that is not listed as");
        Log.w("GameHelper", "****     a test account.");
        Log.w("GameHelper", "****");
        if (ctx == null) {
            Log.w("GameHelper", "*** (no Context, so can't print more debug info)");
            return;
        }

        Log.w("GameHelper", "**** To help you debug, here is the information about this app");
        Log.w("GameHelper", "**** Package name         : " + ctx.getPackageName());
        Log.w("GameHelper", "**** Cert SHA1 fingerprint: " + getSHA1CertFingerprint(ctx));
        Log.w("GameHelper", "**** App ID from          : " + getAppIdFromResource(ctx));
        Log.w("GameHelper", "****");
        Log.w("GameHelper", "**** Check that the above information matches your setup in ");
        Log.w("GameHelper", "**** Developer Console. Also, check that you're logging in with the");
        Log.w("GameHelper", "**** right account (it should be listed in the Testers section if");
        Log.w("GameHelper", "**** your project is not yet published).");
        Log.w("GameHelper", "****");
        Log.w("GameHelper", "**** For more information, refer to the troubleshooting guide:");
        Log.w("GameHelper", "****   http://developers.google.com/games/services/android/troubleshooting");
    }

    static String getAppIdFromResource(Context ctx) {
        try {
            Resources res = ctx.getResources();
            String pkgName = ctx.getPackageName();
            int res_id = res.getIdentifier("app_id", "string", pkgName);
            return res.getString(res_id);
        } catch (Exception ex) {
            ex.printStackTrace();
            return "??? (failed to retrieve APP ID)";
        }
    }

    static String getSHA1CertFingerprint(Context ctx) {
        try {
            Signature[] sigs = ctx.getPackageManager().getPackageInfo(
                    ctx.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
            if (sigs.length == 0) {
                return "ERROR: NO SIGNATURE.";
            } else if (sigs.length > 1) {
                return "ERROR: MULTIPLE SIGNATURES";
            }
            byte[] digest = MessageDigest.getInstance("SHA1").digest(sigs[0].toByteArray());
            StringBuilder hexString = new StringBuilder();
            for (int i = 0; i < digest.length; ++i) {
                if (i > 0) {
                    hexString.append(":");
                }
                byteToString(hexString, digest[i]);
            }
            return hexString.toString();

        } catch (PackageManager.NameNotFoundException ex) {
            ex.printStackTrace();
            return "(ERROR: package not found)";
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
            return "(ERROR: SHA1 algorithm not found)";
        }
    }

    static void byteToString(StringBuilder sb, byte b) {
        int unsigned_byte = b < 0 ? b + 256 : b;
        int hi = unsigned_byte / 16;
        int lo = unsigned_byte % 16;
        sb.append("0123456789ABCDEF".substring(hi, hi + 1));
        sb.append("0123456789ABCDEF".substring(lo, lo + 1));
    }

    static String getString(Context ctx, int whichString) {
        whichString = whichString >= 0 && whichString < RES_IDS.length ? whichString : 0;
        int resId = RES_IDS[whichString];
        try {
            return ctx.getString(resId);
        } catch (Exception ex) {
            ex.printStackTrace();
            Log.w(GameHelper.TAG, "*** GameHelper could not found resource id #" + resId + ". " +
                "This probably happened because you included it as a stand-alone JAR. " +
                "BaseGameUtils should be compiled as a LIBRARY PROJECT, so that it can access " +
                "its resources. Using a fallback string.");
            return FALLBACK_STRINGS[whichString];
        }
    }
}

Пожалуйста, помогите мне решить эту проблему. Заранее спасибо.


  • Возможный дубликат Google Play Games – Приложение проходит альфа- и бета-тестирование – Ошибка 10004 при входе в систему РЕЗУЛЬТАТ ПРИЛОЖЕНИЕ НЕ НАСТРОЕНО 07.04.2016
  • Я уже проверил это решение. Но, к сожалению, это не решает мою проблему. :( 07.04.2016
  • Вы также заметили комментарий Воя? Или это не относится к вашей ситуации? 07.04.2016
  • да я это заметил. Но никакие другие машины не используются для выпуска приложения, кроме моего. И я снова проверил ключ SHA1. И не нашел ничего плохого в этом ключе. Спасибо за ваши предложения. :) 07.04.2016
  • Извини. Но можете ли вы предоставить более подробную информацию? Потому что, как я вижу, помимо того факта, что вы проверили SHA1 (что верно, поэтому никаких изменений не было внесено), ваш пост является возможным дубликатом того, что прокомментировано выше. Можете ли вы предоставить более подробную информацию? Согласно документам: Код результата отправляется обратно в вызывающую активность, когда игра неправильно настроена для доступа к сервису Games. Для получения дополнительной информации разработчикам следует проверить журналы. 07.04.2016
  • Я отредактировал свой вопрос. Добавлен код и скриншоты. Пожалуйста, посмотрите выше. Спасибо за вашу поддержку. :) 07.04.2016
  • Намного лучше. Дополнительная информация для сообщества. А логи есть? Вы также видели/делали то, что рекомендуется в этом ответе раньше? 07.04.2016
  • Извините, логов нет, только ошибка RESULT_APP_MISCONFIGURED. Да, я попробовал совет, указанный в этом ответе. 07.04.2016
  • Вы также тестировали это на нескольких устройствах? 08.04.2016
  • Да, я тестировал на нескольких устройствах, а также на нескольких производителях (например, Samsung/Sony/HTC/Motorla). но таблица лидеров не работает ни на одном из устройств, если apk загружен из магазина игр. Все устройства отлично работают при работе непосредственно из студии Android. 08.04.2016

Ответы:


1

Это может быть возможным источником ошибки:

«Вы должны создать два идентификатора клиента, один с отпечатком сертификата выпуска, а другой с отпечатком сертификата отладки. Обязательно используйте одно и то же имя пакета для обоих. Это позволяет игровым сервисам Google Play распознавать вызовы из ваших связанных APK, которые подписаны с помощью либо сертификат. Дополнительные сведения о подписании сертификата для Android см. в разделе «Подписание приложения».

Поэтому «Отмените публикацию вашей игры» в Game Services. Затем «Удалить таблицу лидеров», и после того, как вы опубликуете свою игру, также опубликуйте таблицу лидеров игрового сервиса. Не устанавливайте apk-файл на телефон до публикации игры!

20.09.2019
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..