Подтвердить что ты не робот

Запросить приложение Android для обновления приложения, если текущая версия <> рыночная версия

Допустим, что приложение Android App версии 0.1 установлено на телефоне пользователя. Каждый раз, когда они запускают мое приложение, я хочу проверить, есть ли другая версия, доступная в Android Market, скажем, что эта версия 0.2. Если есть несоответствие между этими двумя версиями, я хочу показать диалоговое окно с предложением обновить приложение.

Я полностью понимаю, что для пользователей существует процедура уведомления от Android Market, но, насколько это касается моих данных Analytics, не очень эффективно напоминать пользователям обновляться до новой версии приложения.

Любое понимание было бы очень полезно. Спасибо StackOverflowers, вы, ребята, рок!

4b9b3361

Ответ 1

Начиная с 2019 года, лучший способ обновления вашего приложения - использовать обновления внутри приложения, предоставляемые библиотекой Play Core (1.5. 0+). Это работает для Lollipop и новее, но, честно говоря, Kit-Kat на сегодня составляет менее 7% и скоро исчезнет навсегда. Вы можете безопасно запустить этот код на Kit-Kat без проверки версий, он не будет аварийно завершен.

Официальная документация: https://developer.android.com/guide/app-bundle/in-app-updates

Существует два типа обновлений в приложении: гибкие и немедленные.

Гибко спросит вас приятно в диалоговом окне: enter image description here

в то время как Immediate потребует от вас обновить приложение, чтобы продолжить использовать его с полноэкранным сообщением (эту страницу можно закрыть):

enter image description here

Важно: на данный момент вы не можете выбрать тип обновления для развертывания в разделе "Выпуск приложения" на консоли разработчика Play. Но, по-видимому, они скоро дадут нам такую возможность. Из того, что я тестировал, в настоящее время мы получаем оба типа в onSuccessListener.

Итак, давайте реализуем оба типа в нашем коде.

В модуле build.gradle добавьте следующую зависимость:

dependencies {
    implementation 'com.google.android.play:core:1.6.1'//for new version updater
}

В MainActivity.class:

private static final int REQ_CODE_VERSION_UPDATE = 530;
private AppUpdateManager appUpdateManager;
private InstallStateUpdatedListener installStateUpdatedListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

   checkForAppUpdate();
}

@Override
protected void onResume() {
    super.onResume();
    checkNewAppVersionState();
}

@Override
public void onActivityResult(int requestCode, final int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    switch (requestCode) {

        case REQ_CODE_VERSION_UPDATE:
            if (resultCode != RESULT_OK) { //RESULT_OK / RESULT_CANCELED / RESULT_IN_APP_UPDATE_FAILED
                L.d("Update flow failed! Result code: " + resultCode);
                // If the update is cancelled or fails,
                // you can request to start the update again.
                unregisterInstallStateUpdListener();
            }

            break;
    }
}

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


private void checkForAppUpdate() {
    // Creates instance of the manager.
    appUpdateManager = AppUpdateManagerFactory.create(AppCustom.getAppContext());

    // Returns an intent object that you use to check for an update.
    Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();

    // Create a listener to track request state updates.
    installStateUpdatedListener = new InstallStateUpdatedListener() {
        @Override
        public void onStateUpdate(InstallState installState) {
            // Show module progress, log state, or install the update.
            if (installState.installStatus() == InstallStatus.DOWNLOADED)
                // After the update is downloaded, show a notification
                // and request user confirmation to restart the app.
                popupSnackbarForCompleteUpdateAndUnregister();
        }
    };

    // Checks that the platform will allow the specified type of update.
    appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
        if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
            // Request the update.
            if (appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {

                // Before starting an update, register a listener for updates.
                appUpdateManager.registerListener(installStateUpdatedListener);
                // Start an update.
                startAppUpdateFlexible(appUpdateInfo);
            } else if (appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) ) {
                // Start an update.
                startAppUpdateImmediate(appUpdateInfo);
            }
        }
    });
}

private void startAppUpdateImmediate(AppUpdateInfo appUpdateInfo) {
    try {
        appUpdateManager.startUpdateFlowForResult(
                appUpdateInfo,
                AppUpdateType.IMMEDIATE,
                // The current activity making the update request.
                this,
                // Include a request code to later monitor this update request.
                MainActivity.REQ_CODE_VERSION_UPDATE);
    } catch (IntentSender.SendIntentException e) {
        e.printStackTrace();
    }
}

private void startAppUpdateFlexible(AppUpdateInfo appUpdateInfo) {
    try {
        appUpdateManager.startUpdateFlowForResult(
                appUpdateInfo,
                AppUpdateType.FLEXIBLE,
                // The current activity making the update request.
                this,
                // Include a request code to later monitor this update request.
                MainActivity.REQ_CODE_VERSION_UPDATE);
    } catch (IntentSender.SendIntentException e) {
        e.printStackTrace();
        unregisterInstallStateUpdListener();
    }
}

/**
 * Displays the snackbar notification and call to action.
 * Needed only for Flexible app update
 */
private void popupSnackbarForCompleteUpdateAndUnregister() {
    Snackbar snackbar =
            Snackbar.make(drawerLayout, getString(R.string.update_downloaded), Snackbar.LENGTH_INDEFINITE);
    snackbar.setAction(R.string.restart, new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            appUpdateManager.completeUpdate();
        }
    });
    snackbar.setActionTextColor(getResources().getColor(R.color.action_color));
    snackbar.show();

    unregisterInstallStateUpdListener();
}

/**
 * Checks that the update is not stalled during 'onResume()'.
 * However, you should execute this check at all app entry points.
 */
private void checkNewAppVersionState() {
    appUpdateManager
            .getAppUpdateInfo()
            .addOnSuccessListener(
                    appUpdateInfo -> {
                        //FLEXIBLE:
                        // If the update is downloaded but not installed,
                        // notify the user to complete the update.
                        if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
                            popupSnackbarForCompleteUpdateAndUnregister();
                        }

                        //IMMEDIATE:
                        if (appUpdateInfo.updateAvailability()
                                == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
                            // If an in-app update is already running, resume the update.
                            startAppUpdateImmediate(appUpdateInfo);
                        }
                    });

}

/**
 * Needed only for FLEXIBLE update
 */
private void unregisterInstallStateUpdListener() {
    if (appUpdateManager != null && installStateUpdatedListener != null)
        appUpdateManager.unregisterListener(installStateUpdatedListener);
}

И мы сделали!

Тестирование. Пожалуйста, прочитайте документы, чтобы вы знали, как правильно его протестировать с помощью тестовых треков в Google Play.

Короче:

  1. Подпишите свое приложение сертификатом выпуска и загрузите его на один из треков публикации в Developer Play Console в разделе "Релизы приложений" (альфа/бета/другой пользовательский закрытый трек).

  2. На странице отслеживания релиза в разделе "Управление тестерами" создайте и добавьте список тестеров и убедитесь, что вы установили флажок ! - этот шаг не является обязательным, поскольку адрес электронной почты вашей учетной записи разработчика также является учетной записью тестеров, и вы можете использовать ее для тестирования.

  3. В списке тестировщиков вы найдете "URL-адрес подтверждения" - скопируйте этот URL-адрес и дайте его своим тестировщикам или откройте его самостоятельно. Перейдите на эту страницу и примите предложение для тестирования. Там будет ссылка на приложение. (Вы не сможете найти приложение в Play Store, поэтому добавьте его в закладки)

  4. Установите приложение на свое устройство по этой ссылке.

  5. В build.gradle версию defaultConfig { versionCode k+1 } и создайте еще один подписанный apk Build> Generate Signed Bundle/APK... и загрузите его на свой трек публикации.

  6. Подождите... 1 час? два часа? или больше, прежде чем он будет опубликован на треке.

  7. ОЧИСТИТЕ КЕЙШ приложения Play Store на вашем устройстве. Проблема заключается в том, что приложение Play кэширует сведения об установленных приложениях и их доступных обновлениях, поэтому вам необходимо очистить кэш. Для этого сделайте два шага:

7.1. Перейдите в Настройки> Приложение> Google PLay Store> Хранилище> Очистить кэш.

7.2. Откройте приложение Play Store> откройте главное меню> Мои приложения и игры> и там вы увидите, что ваше приложение имеет новое обновление.

Если вы не видите, убедитесь, что ваше новое обновление уже выпущено на треке (перейдите на страницу с закладками и используйте ее, чтобы открыть список приложений в Play Store, чтобы увидеть, какая версия там показана). Кроме того, когда ваше обновление будет доступно, вы увидите уведомление в правом верхнем углу консоли разработчика Play (значок колокольчика будет иметь красную точку).

Надеюсь, поможет.

Ответ 2

Android Market является закрытой системой и имеет только неофициальные API, которые могут сломаться в любой момент времени.

Лучше всего размещать файл (xml, json или простой текст) на своем веб-сервере, на котором вам просто нужно обновить текущую версию вашего приложения при публикации в Маркете.

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

Ответ 3

Другой вариант, который вы можете использовать, если вы хотите, чтобы ваш серверный сервер не сохранил вашу текущую версию приложения, как это было предложено в принятом ответе, заключается в использовании Диспетчер тегов Google (GTM).

Если вы уже используете SDK Google Analytics, у вас есть и GTM.

В GTM вы можете определить значение в контейнере для вашего приложения, которое указывает вашу последнюю выпущенную версию. Например:

{
   "latestAppVersion": 14,
   ...
}

Затем вы можете запросить это значение при запуске приложения и показать напоминание о диалоге обновления пользователя, если есть более новая версия.

Container container = TagManager.getInstance(context).openContainer(myContainerId);
long latestVersionCode = container.getLong("latestAppVersion");

// get currently running app version code
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
long versionCode = pInfo.versionCode;

// check if update is needed
if(versionCode < latestVersionCode) {
   // remind user to update his version
}

Ответ 5

Вы можете использовать эту библиотеку Android: https://github.com/danielemaddaluno/Android-Update-Checker. Он направлен на предоставление повторно используемого инструмента для проверки асинхронно, если существует новое выпущенное обновление вашего приложения в Магазине. Он основан на использовании Jsoup (http://jsoup.org/), чтобы проверить, действительно ли существует новое обновление, анализируя страницу приложения в Google Play Store:

private boolean web_update(){
    try {       
        String curVersion = applicationContext.getPackageManager().getPackageInfo(package_name, 0).versionName; 
        String newVersion = curVersion;
        newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + package_name + "&hl=en")
                .timeout(30000)
                .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
                .referrer("http://www.google.com")
                .get()
                .select("div[itemprop=softwareVersion]")
                .first()
                .ownText();
        return (value(curVersion) < value(newVersion)) ? true : false;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

И как функция "значение", следующая (работает, если значения находятся между 0-99):

private long value(String string) {
    string = string.trim();
    if( string.contains( "." )){ 
        final int index = string.lastIndexOf( "." );
        return value( string.substring( 0, index ))* 100 + value( string.substring( index + 1 )); 
    }
    else {
        return Long.valueOf( string ); 
    }
}

Если вы хотите только проверить несоответствие между версиями, вы можете изменить:

"value (curVersion) < value (newVersion)" со значением (curVersion)!= value (newVersion) "

Ответ 6

Чтобы пригласить приложение Android App для обновления, если текущая версия не соответствует рыночной версии, вы должны сначала проверить версию приложения на рынке и сравнить ее с версией приложения на устройстве. Если они отличаются, это может быть доступное обновление. В этом посте я записал код для получения текущей версии рынка и текущей версии на устройстве и сравнил их вместе. Я также показал, как показать диалог обновления и перенаправить пользователя на страницу обновления. Перейдите по этой ссылке: fooobar.com/questions/114248/...

Ответ 7

Google выпустил In-App Updates для библиотеки Play Core.

Я реализовал облегченную библиотеку, чтобы легко реализовывать обновления в приложении.

https://github.com/dnKaratzas/android-inapp-update