提示 Android 应用用户更新应用(如果当前版本<>市场版本)

2022-09-01 12:30:11

假设我的Android应用程序版本0.1当前安装在用户的手机上。每次他们启动我的应用程序时,我都想检查Android市场中是否有不同的版本可用,假设这个版本是0.2。如果这两个版本之间存在不匹配,我想显示一个对话框,提示用户升级应用程序。

我完全理解Android Market本身存在向用户发出通知程序,但就我的分析数据而言,它在提醒用户升级到新版本的应用程序方面不是很有效。

任何见解都将非常有帮助。谢谢StackOverflowers,你们摇滚!


答案 1

自 2019 年起,更新应用的最佳方式是使用 Play Core 库 (1.5.0+) 提供的应用内更新。它适用于棒棒糖和更新,但公平地说,Kit-Kat在今天还不到7%,很快就会永远消失。您可以在Kit-Kat上安全地运行此代码而无需进行版本检查,它不会崩溃。

官方文件:https://developer.android.com/guide/app-bundle/in-app-updates

有两种类型的应用内更新:灵活即时

Flexible会在对话窗口中很好地询问您:enter image description here

“即时”将要求您更新应用程序,以便继续使用带有全屏消息的操作(此页面可以关闭):

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. 使用发布证书为您的应用签名,然后将其上传到开发者 Play 管理中心中应用版本(Alpha/Beta/其他自定义封闭式跟踪)下的发布跟踪之一。

  2. 在版本跟踪页面的“管理测试人员”部分,创建并添加测试人员列表,并确保选中该复选框!- 此步骤是可选的,因为您的开发人员帐户电子邮件也是测试人员帐户,您可以使用它进行测试。

  3. 在测试人员列表下,您会找到“选择加入网址” - 复制此网址并将其提供给您的测试人员或自行打开。转到该页面并接受提案进行测试。将有一个指向该应用的链接(您将无法在Play商店中搜索该应用,因此请将其添加为书签)

  4. 通过该链接在您的设备上安装该应用程序。

  5. 在增量版本和构建另一个签名的apk构建>生成签名捆绑包/ APK...并将其上传到您的发布轨道。build.gradledefaultConfig { versionCode k+1 }

  6. 俟。。。1小时?2小时?或更多,然后才会在赛道上发布。

  7. 清除设备上Play商店应用的缓存。问题在于 Play 应用会缓存有关已安装应用及其可用更新的详细信息,因此您需要清除缓存。为此,需要两个步骤:

7.1. 转到“设置”>应用>Google PLay商店>存储>清除缓存。

7.2. 打开Play商店应用>打开主菜单>我的应用和游戏>,您应该会看到您的应用有新的更新。

如果您没有看到它,请确保您的新更新已在轨道上发布(转到已添加书签的页面,然后使用它打开Play商店上的应用列表,以查看其中显示的版本)。此外,当您的更新生效时,您会在开发者 Play 管理中心的右上角看到一条通知(铃铛图标上有一个红点)。

希望它有帮助。


答案 2

Android Market是一个封闭的系统,只有一个非官方的API,可能会在任何时间点中断。

您最好的选择是在您的Web服务器上托管一个文件(xml,json或简单文本),其中您只需要在将应用程序发布到市场上时更新该应用程序的当前版本即可。

然后,你的应用只需在启动时获取该文件,检查当前安装的应用是否具有较低的版本号,并显示一个对话框来警告用户他滞后了。


推荐