Android AppUpdateManager未初始化自动更新。

huangapple go评论75阅读模式
英文:

Android AppUpdateManager not initializing the auto update

问题

在每次发布更新时,我想立即更新我的应用程序。我按照官方Android文档中关于如何测试自动更新功能的说明进行了操作,但没有任何反应。我在代码中添加了一些日志以检查这些函数是否初始化,但是Logcat也没有显示任何内容。这是我的语法问题,还是我应该将这些函数放在其他地方?目前,所有的更新代码都写在应用程序的主要启动类中。

在类的onCreate方法中:

private static final int REQUEST_APP_UPDATE = 560;
private AppUpdateManager appUpdateManager;
private InstallStateUpdatedListener installStateUpdatedListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    appUpdateManager = AppUpdateManagerFactory.create(this);

    installStateUpdatedListener = new InstallStateUpdatedListener() {
        @Override
        public void onStateUpdate(InstallState state) {
            if (state.installStatus() == InstallStatus.DOWNLOADED) {
                // 当下载完成时的处理
            } else if (state.installStatus() == InstallStatus.INSTALLED) {
                if (appUpdateManager != null) {
                    appUpdateManager.unregisterListener(installStateUpdatedListener);
                }
            } else {
                Log.i(TAG, "InstallStateUpdatedListener: state: " + state.installStatus());
            }
        }
    };

    appUpdateManager
            .getAppUpdateInfo()
            .addOnSuccessListener(appUpdateInfo -> {
                Log.d("TAG", "here");

                // 检查平台是否允许指定类型的更新
                if ((appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE)
                        && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
                    // 请求更新
                    try {
                        Log.d("TAG", "here");
                        appUpdateManager.startUpdateFlowForResult(
                                appUpdateInfo,
                                AppUpdateType.IMMEDIATE,
                                this,
                                REQUEST_APP_UPDATE);
                    } catch (IntentSender.SendIntentException e) {
                        e.printStackTrace();
                    }
                }
            });

    appUpdateManager.registerListener(installStateUpdatedListener);
    // ...
}

在onResume和onStop处理方法中:

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

    appUpdateManager
            .getAppUpdateInfo()
            .addOnSuccessListener(appUpdateInfo -> {
                if (appUpdateInfo.updateAvailability()
                        == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
                    // 如果应用内更新已经在运行,继续更新
                    try {
                        appUpdateManager.startUpdateFlowForResult(
                                appUpdateInfo,
                                AppUpdateType.IMMEDIATE,
                                this,
                                REQUEST_APP_UPDATE);
                    } catch (IntentSender.SendIntentException e) {
                        e.printStackTrace();
                    }
                }
            });
}

@Override
protected void onStop() {
    super.onStop();
    if (appUpdateManager != null) {
        appUpdateManager.unregisterListener(installStateUpdatedListener);
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_APP_UPDATE) {
        if (resultCode != RESULT_OK) {
            Log.d("TAG", "Update flow failed! Result code: " + resultCode);
            // 如果更新被取消或失败,
            // 您可以请求重新开始更新。
        }
    }
}
英文:

I want to update my app immediately every time I publish an update. I followed the instructions from the official android documentation on how to test the auto update feature , but nothing happens. I placed some logs in order to check whether these functions initialize, but the logcat shows nothing either. Is this a problem in my syntax, or should I place these functions somewhere else? Currently, all my update code is written inside the main, starting class of the app.

On create method of the class

private static final int REQUEST_APP_UPDATE = 560;
private AppUpdateManager appUpdateManager;
private InstallStateUpdatedListener installStateUpdatedListener;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
appUpdateManager = AppUpdateManagerFactory.create(this);
installStateUpdatedListener = new
InstallStateUpdatedListener() {
@Override
public void onStateUpdate(InstallState state) {
if (state.installStatus() == InstallStatus.DOWNLOADED){
} else if (state.installStatus() == InstallStatus.INSTALLED){
if (appUpdateManager != null){
appUpdateManager.unregisterListener(installStateUpdatedListener);
}
} else {
Log.i(TAG, "InstallStateUpdatedListener: state: " + state.installStatus());
}
}
};
appUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener(
appUpdateInfo -> {
Log.d("TAG", "here");
// Checks that the platform will allow the specified type of update.
if ((appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE)
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE))
{
// Request the update.
try {
Log.d("TAG", "here");
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.IMMEDIATE,
this,
REQUEST_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
appUpdateManager.registerListener(installStateUpdatedListener);
...

On resume and on stop handling methods:

 @Override
protected void onResume() {
super.onResume();
appUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener(
appUpdateInfo -> {
if (appUpdateInfo.updateAvailability()
== UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
// If an in-app update is already running, resume the update.
try {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.IMMEDIATE,
this,
REQUEST_APP_UPDATE);
Log.d("TAG", "tu");
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onStop() {
super.onStop();
if (appUpdateManager != null) {
appUpdateManager.unregisterListener(installStateUpdatedListener);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_APP_UPDATE) {
if (resultCode != RESULT_OK) {
Log.d("TAG", "Update flow failed! Result code: " + resultCode);
// If the update is cancelled or fails,
// you can request to start the update again.
}
}
}

答案1

得分: 1

我建议您将所有关于AppUpdateInfo的获取操作移动到onResume()中,因为这是一个更可靠的活动入口点(例如,如果活动已进入后台,然后由用户再次打开)。onCreate方法仅在活动被销毁后调用,因此,如果应用程序被最小化,重新打开时可能看不到更新对话框。

@Override
public void onResume() {
    super.onResume();
    appUpdateManager.getAppUpdateInfo().addOnSuccessListener(info -> {
        boolean isStalledUpdate = info.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS;
        boolean isReadyForUpdate = 
            info.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
            && info.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE);

        if (isReadyForUpdate || isStalledUpdate) {
            appUpdateManager.startUpdateFlowForResult(
                info, 
                AppUpdateType.IMMEDIATE, 
                this, 
                REQ_CODE
            );
        }
    });
}

有时应用程序不会自动与Play Store的更新同步,因此您需要执行以下操作:

确保手动可用更新 - 转到Play Store,检查更新,并确保您的应用程序有可用更新。
之后打开您的应用程序(调用onResume中的更新管理器的活动),您将看到立即更新对话框。

另外,给您一个提示 - 让您的Activity实现InstallStateUpdateListener并覆盖onStateUpdate方法来处理不同的事件。

@Override
public void onResume() {
    // 所有之前的逻辑 
    // 如果更新可用或已停滞,请调用此方法
    appUpdateManager.registerListener(this);
}

@Override
public void onStateUpdate(InstallState state) {
    if (state == null) return;
    switch (state.installStatus()) {
        case InstallStatus.INSTALLED: 
            appUpdateManager.unregisterListener(this);
            return;
        case InstallStatus.FAILED:
            appUpdateManager.unregisterListener(this);
            return;
        case InstallStatus.CANCELED:
            appUpdateManager.unregisterListener(this);
            return;
        default:
            // 提供您自己的逻辑
            return;
    }
}

这将帮助您避免在活动生命周期方法中调用单独的监听器实例。

英文:

I suggest you to move all your AppUpdateInfo retrieving to onResume() since it is more reliable entry point of an activity (for example, if Activity has came to background and then was opened again by user). OnCreate method will be called only if activity was destroyed, since that, you may not see update dialog after reopening application if it was minimized.

@Override
public void onResume() {
super.onResume();
appUpdateManager.getAppUpdateInfo().addOnSuccessListener( info -> {
boolean isStalledUpdate = info.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS;
boolean isReadyForUpdate = 
info.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& info.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE;
if (isReadyForUpdate || isStalledUpdate) {
appUpdateManager.startUpdateFlowForResult(
info, 
AppUpdateType.IMMEDIATE, 
this, 
REQ_CODE
);
}
}

Sometimes app is not automatically synchronized with Play Store updates, so you need to do the following:

Make sure you have an update available manually - go to Play Store, check for updates and make sure that you have an update available for your application.
After that open your app (your activity, that calls update manager in onResume) and you will see immediate update dialog.

Also, one tip for you - make your Activity implement InstallStateUpdateListener and override method onStateUpdate like this to handle different events.

@Override
public void onResume() {
// All previous logic 
// If update is available or was stalled call this
appUpdateManager.registerListener(this);
}
@Override
public void onStateUpdate(InstallState state) {
if (state == null) return;
switch (state.installStatus()) {
case InstallStatus.INSTALLED: 
appUpdateManager.unregisterListener(this)
return;
case InstallStatus.FAILED:
appUpdateManager.unregisterListener(this)
return;
case InstallStatus.CANCELED:
appUpdateManager.unregisterListener(this)
return;
default:
// provide your own logic
return;
}
}

This will help you to avoid calling separate instance of listener in activity lifecycle methods.

答案2

得分: 1

我提供的代码是有效的,不更新的问题是设备本身不知道是否有更新的问题。在Play商店刷新更新列表后,应用程序更新管理器在启动应用程序时初始化了自动更新窗口。

英文:

The code that I provided was working, the problem of not updating was a matter of the device itself not knowing whether an update is available. After refreshing the update list on the Play Store, the app update manager initialized the auto update window when starting the app.

huangapple
  • 本文由 发表于 2020年8月24日 18:56:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63559661.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定