5

我正在尝试实现android 应用内更新。我正在按照官方门户中给出的教程进行操作,但是调用 startUpdateflow 方法时未显示该对话框。请在下面找到我正在执行的代码块。

final AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(this);
    Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
    appUpdateInfoTask.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
        @Override
        public void onSuccess(AppUpdateInfo appUpdateInfo) {
            try {
                Toast.makeText(getApplicationContext(),"Success.", Toast.LENGTH_SHORT).show();
                appUpdateManager.startUpdateFlowForResult(
                        appUpdateInfo,
                        AppUpdateType.FLEXIBLE,
                        SplashScreenActivity.this,
                        APP_UPDATE_REQUEST_CODE
                );
            } catch (IntentSender.SendIntentException e) {
                Toast.makeText(getApplicationContext(),"Exception received", Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        }
    });

我可以看到成功吐司和线路

appUpdateManager.startUpdateFlowForResult() is called

但这没有显示门户中显示的带有“不感谢”和“更新”按钮的更新对话框。我也尝试过使用FakeAppUpdateManager但这也没有帮助。

在这里请求帮助!

4

4 回答 4

6

这是我注意到的;换句话说,您的里程可能会有所不同。

应用内更新如宣传的那样工作,但为了让它按您期望的方式工作,有一些事情需要准备好。

  1. 您需要从 Google Play 安装您的测试应用;如果您只是从 Android Studio 安装它,它将无法正常工作。

  2. 从 Google Play 安装它可以通过“开放测试”、“封闭测试”或“内部测试”来完成,但是(我认为)这些轨道只允许发布版本(即不能设置断点),所以我建议你开始与“内部应用程序共享”。只需将您的.apk或上传.aabhttps://play.google.com/console/internal-app-sharing。唯一似乎不起作用的是在“内部应用共享”中设置更新优先级。我想听听其他人是如何处理的。

  3. FakeAppUpdateManager不显示更新对话框。您只需通过发出命令来模拟 Google Play 会做什么,例如fakeAppUpdateManager.downloadStarts(),但不会有任何对话框。参考这个

  4. 更新可以同时FLEXIBLE进行IMMEDIATE。换句话说,如果您检查appUpdateInfo.isUpdateTypeAllowed(FLEXIBLE)appUpdateInfo.isUpdateTypeAllowed(IMMEDIATE),它们可以都是true。您可以根据更新的优先级来决定此时要做什么。

这些是我采取的步骤。

  1. 设置versionCode为 2,构建.apk.aab(在调试版本中),并将其上传到“内部应用共享”。记下其下载 URL。

  2. 设置versionCode为 1,与步骤 1 相同。

  3. 从手机打开第 2 步中的 URL(即版本 1)。它将打开 Google Play 并要求您下载该应用程序。下载并打开它。

  4. 从手机打开步骤 1(即版本 2)的 URL,但不要点击“更新”按钮;只需将应用程序版本 1 带到前台即可。

  5. 在应用程序运行时,附加调试器(Android Studio -> 运行 -> 将调试器附加到 Android 进程)。

  6. 检查更新 ( appUpdateManager.appUpdateInfo.addOnSuccessListener {...})、启动更新 ( appUpdateManager.startUpdateFlowForResult(...)) 等。

于 2021-01-31T19:51:10.287 回答
4

我面临着同样的问题。我在 com.google.android.play.core.appupdate.AppUpdateManager 类的方法 startUpdateFlowForResult 的文档中找到了这个

每个 {@link com.google.android.play.core.appupdate.AppUpdateInfo AppUpdateInfo} 实例只能在对该方法的一次调用中使用。如果您需要多次调用它 - 例如,在失败的情况下重试启动流程时,您需要从 {@link 获取新的 {@link com.google.android.play.core.appupdate.AppUpdateInfo AppUpdateInfo} #getAppUpdateInfo()}。

因此,在取消或更新失败后获取新实例就可以了

于 2020-01-22T10:35:06.597 回答
1

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

约束:应用内更新仅适用于运行 Android 5.0(API 级别 21)或更高版本的设备

第一步: 添加依赖:

dependencies {

    implementation 'com.google.android.play:core:1.5.0'
    ...
}

第 2 步:检查更新可用性并在可用时开始

创建 AppUpdateManagerFactory 的实例

 appUpdateManager = AppUpdateManagerFactory.create(context);

为 FLEXIBLE 更新请求的响应注册监听器

        appUpdateManager.registerListener(listener);

之后得到 appUpdateInfo

Task<AppUpdateInfo> appUpdateInfo = appUpdateManager.getAppUpdateInfo();

            appUpdateInfo.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
                @Override
                public void onSuccess(AppUpdateInfo appUpdateInfo) {
                    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
                        if (appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
                            Log.d("App update A", "Flexible");
                            int updateType = FLEXIBLE;
                            requestUpdate(appUpdateInfo, updateType);
                        } else if (appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
                            Log.d("App update B", "IMMEDIATE");
                            int updateType = IMMEDIATE;
                            requestUpdate(appUpdateInfo, updateType);
                        }
                    }
                }
            });

在那个 requestUpdate() 方法之后,

private void requestUpdate(AppUpdateInfo appUpdateInfo, int updateType) {
        try {
            appUpdateManager.startUpdateFlowForResult(appUpdateInfo, updateType, HomeActivity.this, MY_REQUEST_CODE);
        } catch (IntentSender.SendIntentException e) {
            e.printStackTrace();
        }
    }

第三步:监听更新状态

最后是听者

InstallStateUpdatedListener listener = new InstallStateUpdatedListener() {
        @Override
        public void onStateUpdate(InstallState state) {
            Log.d("installState", state.toString());
            if (state.installStatus() == InstallStatus.DOWNLOADED) {
                // After the update is downloaded, show a notification
                // and request user confirmation to restart the app.
                // SnackBarManager.getSnackBarManagerInstance().showSnackBar(GaanaActivity.this, "An update has just been downloaded.", true);
                popupSnackbarForCompleteUpdate();
            }
        }
    };

popupSnackbarForCompleteUpdate() 方法,

private void popupSnackbarForCompleteUpdate() {
        Snackbar snackbar =
                Snackbar.make(findViewById(android.R.id.content), "An update has just been downloaded.", Snackbar.LENGTH_INDEFINITE);
        snackbar.setAction("Restart", view -> appUpdateManager.completeUpdate());
        snackbar.setActionTextColor(getResources().getColor(android.R.color.white));
        snackbar.show();
    }

第 4 步:获取更新状态的回调

您也可以捕获结果,

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == MY_REQUEST_CODE) {
            System.out.println("App Update = " + resultCode);
            if (resultCode != RESULT_OK) {
                System.out.println("Update flow failed! Result code: " + resultCode);
                // If the update is cancelled or fails,
                // you can request to start the update again.
            }
        }
    }

您还必须取消注册侦听器

@Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("installState", "destroy");
        appUpdateManager.unregisterListener(listener);
    }
于 2019-08-21T13:54:52.100 回答
0

这个答案是一个黑客!

我在应用程序更新方面遇到了很多麻烦。问题是这个库是为那些停留在startUpdateFlowForResult被调用的同一活动中的用户制作的,然后每当用户做一些意想不到的事情时,比如检查其他应用程序或进入下一个活动,一切都会崩溃并且更新没有完成。你可以尝试用无穷无尽的样板来修复它,但是因为调用一个与活动无关的小吃店是超级复杂的,这将花费你至少一些白发,并且给你留下可能仍然有些错误的精致代码。

另一种选择

我终于放弃了,决定将我的用户直接重定向到 GooglePlayStore:

if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE ) { //maybe you could add some additional checks like priority level here
                makeUpdateDialog(mContext).show();
}

我专门使用应用内更新库来检查可用性,然后在操作按钮中显示一个包含以下代码的对话框:

try {
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(ownGooglePlayLink)));
} catch (android.content.ActivityNotFoundException anfe) {
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(ownWebLink)));
}

public static final String ownGooglePlayLink="market://details?id=com.my.package.name";
public static final String ownWebLink="https://play.google.com/store/apps/details?id=com.my.package.name";

诚然,这非常hacky,但并不像看起来那么糟糕。我发现用户体验仍然很好,用户可以跳过您的更新或在初始化更新后返回应用程序。这样更新由谷歌直接处理,你不必照顾它。

如果谷歌提供第二个对话框让用户决定是否要安装应用程序而不是繁琐的小吃店方法,那就太好了

于 2021-10-20T05:13:52.600 回答