java - 在 Android 中放置应用内更新实现的位置

标签 java android in-app-update

我正在尝试在我的应用中实现应用内更新,但我查看的文档/教程与实际的最终实现之间存在脱节。

我遵循了以下的各种代码教程:

https://developer.android.com/guide/playcore/in-app-updates/kotlin-java#start-update https://www.section.io/engineering-education/android-application-in-app-update-using-android-studio/ https://medium.com/android-news/implement-in-app-update-in-android-68892bd11e35 https://www.raywenderlich.com/8034025-in-app-updates-getting-started

代码本身相当简单。

但我发现所有这些教程中缺少的是如何实际调用应用程序内更新。这些教程似乎都在做一个专门的应用内更新 Activity 。如何从我的主要 Activity 中启动此应用内更新 Activity ?或者,我如何将应用内更新代码合并到我现有的主要 Activity 中?

我假设我想要某种异步启动应用程序内更新监听器或类似的东西,但我似乎无法理解集成所有应用程序内更新代码的最后一步/在-应用更新 Activity 到我的应用中。

编辑:这是我尝试过的示例

public class MainActivity extends AppCompatActivity implements RegionViewAdapter.ItemClickListener {
    private InstallStateUpdatedListener installStateUpdatedListener;
    private static final int FLEXIBLE_APP_UPDATE_REQ_CODE = 123;
    // if you change this value, you must also change it in the app build.gradle
    private final String currentVersion = "2021.06.6";

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

        appUpdateManager = AppUpdateManagerFactory.create(this);

        installStateUpdatedListener = state -> {
            if (state.installStatus() == InstallStatus.DOWNLOADED) {
                popupSnackbarForCompleteUpdate();
            } else if (state.installStatus() == InstallStatus.INSTALLED) {
                removeInstallStateUpdateListener();
            } else {
                Toast.makeText(getApplicationContext(), "InstallStateUpdatedListener: state: " + state.installStatus(), Toast.LENGTH_LONG).show();
            }
        };

    ...
    }
...
    public void checkUpdate() {

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

        // Checks that the platform will allow the specified type of update.
        appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
            if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
                    && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
                startUpdateFlow(appUpdateInfo);
            } else if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
                popupSnackbarForCompleteUpdate();
            }
        });

    }

    // Displays the snackbar notification and call to action.
    private void popupSnackbarForCompleteUpdate() {
        Snackbar snackbar =
                Snackbar.make(
                        findViewById(R.id.my_drawer_layout),
                        "An update has just been downloaded.",
                        Snackbar.LENGTH_INDEFINITE);
        snackbar.setAction("RESTART", view -> appUpdateManager.completeUpdate());
        snackbar.setActionTextColor(
                getResources().getColor(R.color.snackbar_action_text_color));
        snackbar.show();
    }

    private void startUpdateFlow(AppUpdateInfo appUpdateInfo) {
        try {
            appUpdateManager.startUpdateFlowForResult(appUpdateInfo, AppUpdateType.FLEXIBLE, this, FLEXIBLE_APP_UPDATE_REQ_CODE);
        } catch (IntentSender.SendIntentException e) {
            e.printStackTrace();
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == FLEXIBLE_APP_UPDATE_REQ_CODE) {
            if (resultCode == RESULT_CANCELED) {
                Toast.makeText(getApplicationContext(), "Update canceled by user! Result Code: " + resultCode, Toast.LENGTH_LONG).show();
            } else if (resultCode == RESULT_OK) {
                Toast.makeText(getApplicationContext(),"Update success! Result Code: " + resultCode, Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getApplicationContext(), "Update Failed! Result Code: " + resultCode, Toast.LENGTH_LONG).show();
                checkUpdate();
            }
        }
    }

    private void removeInstallStateUpdateListener() {
        if (appUpdateManager != null) {
            appUpdateManager.unregisterListener(installStateUpdatedListener);
        }
    }


    // Checks that the update is not stalled during 'onResume()'.
    // However, you should execute this check at all app entry points.
    @Override
    protected void onResume() {
        super.onResume();

        appUpdateManager
                .getAppUpdateInfo()
                .addOnSuccessListener(appUpdateInfo -> {
                    // If the update is downloaded but not installed,
                    // notify the user to complete the update.
                    if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
                        popupSnackbarForCompleteUpdate();
                    }
                });
    }

}

最佳答案

这个答案是一个黑客!

我在应用程序更新方面遇到了很多麻烦。问题是这个库是为那些留在调用 startUpdateFlowForResult 的同一 Activity 中的用户创建的,然后每当用户做一些意想不到的事情,比如检查 whatsapp 或去下一个 Activity 时,一切都会崩溃,并且更新没有完成。并且您可以尝试使用无穷无尽的样板来修复它,但是由于调用与 Activity 无关的 snackbar 非常复杂,这至少会花费您一些白发并留下可能仍然有些错误的精致代码。

替代方案

我最终放弃并决定将我的用户直接重定向到 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,但并不像看起来那么糟糕。我发现用户体验仍然很好,用户可以跳过您的更新或在初始化更新后返回应用。

关于java - 在 Android 中放置应用内更新实现的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68596439/

相关文章:

java - 检查数字是偶数还是奇数

android - TableRow 高度不会根据 android TableLayout 中的内容增加吗?

android - 如何从 Android Things 使用 Google API(日历、Gmail 等)

android - 当我在谷歌播放控制台中更新应用程序时,如何设置更新类型 "In App Update"?

java - 在 Java 中,在哪里保存正在扩展为另一个类的类?

java - 单击按钮更改jsp

java - 当用户单击 RecyclerView 中的项目时如何关闭 BottomSheetDialog?

android - OpenSL es- 操作音频缓冲区队列

android - 如何在 Android 中手动测试 In App Update

java - AppUpdateManager.startUpdateFlowForResult 导致 IntentSender$SendIntentException