我最近遇到了一种可能由Google Play提供的新版应用更新流程。我喜欢无缝流程来更新Android应用程序。我在Hotstar应用程序中观察了下面提到的步骤。
我怎样才能做到这一点?必须有一种与Google Play进行通信的方式。我经历了很多博客。但是,没有找到任何解决方案。如果用户禁用了自动应用更新,这对于开发人员来说可能是一个很棒的功能。
官方文件:https://developer.android.com/guide/app-bundle/in-app-updates
约束:应用内更新仅适用于运行Android 5.0(API级别21)或更高版本的设备
第1步:添加依赖项:
dependencies {
implementation 'com.google.android.play:core:1.5.0'
...
}
第2步:检查更新可用性并在可用时启动
mAppUpdateManager = AppUpdateManagerFactory.create(this);
mAppUpdateManager.registerListener(installStateUpdatedListener);
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)){
try {
mAppUpdateManager.startUpdateFlowForResult(
appUpdateInfo, AppUpdateType.FLEXIBLE, MainActivity.this, RC_APP_UPDATE);
}
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED){
popupSnackbarForCompleteUpdate();
} else {
Log.e(TAG, "checkForAppUpdateAvailability: something else");
}
});
第3步:收听更新状态
InstallStateUpdatedListener installStateUpdatedListener = new
InstallStateUpdatedListener() {
@Override
public void onStateUpdate(InstallState state) {
if (state.installStatus() == InstallStatus.DOWNLOADED){
popupSnackbarForCompleteUpdate();
} else if (state.installStatus() == InstallStatus.INSTALLED){
if (mAppUpdateManager != null){
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
}
} else {
Log.i(TAG, "InstallStateUpdatedListener: state: " + state.installStatus());
}
}
};
第4步:获取更新状态的回调
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_APP_UPDATE) {
if (resultCode != RESULT_OK) {
Log.e(TAG, "onActivityResult: app download failed");
}
}
}
第5步:灵活更新
private void popupSnackbarForCompleteUpdate() {
Snackbar snackbar =
Snackbar.make(
findViewById(R.id.coordinatorLayout_main),
"New app is ready!",
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("Install", view -> {
if (mAppUpdateManager != null){
mAppUpdateManager.completeUpdate();
}
});
snackbar.setActionTextColor(getResources().getColor(R.color.install_color));
snackbar.show();
}
Android正式宣布今天向所有人发布应用内更新。 https://developer.android.com/guide/app-bundle/in-app-updates
试图实现这一点,在接受的答案中引用的官方Google文档在语法上是不正确的。它花了一些研究,但我终于找到了正确的语法:
代替:
// Creates an instance of the manager.
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);
// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfo = appUpdateManager.getAppUpdateInfo();
// Checks that the platform will allow the specified type of update.
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
// For a flexible update, use AppUpdateType.FLEXIBLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Request the update.
appUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
// Or 'AppUpdateType.FLEXIBLE' for flexible updates.
AppUpdateType.IMMEDIATE,
// The current activity making the update request.
this,
// Include a request code to later monitor this update request.
MY_REQUEST_CODE);
}
做这个:
private AppUpdateManager appUpdateManager;
...
// onCreate(){
// Creates instance of the manager.
appUpdateManager = AppUpdateManagerFactory.create(mainContext);
// Don't need to do this here anymore
// Returns an intent object that you use to check for an update.
//Task<AppUpdateInfo> appUpdateInfo = appUpdateManager.getAppUpdateInfo();
appUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener(
appUpdateInfo -> {
// 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 {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.IMMEDIATE,
this,
REQUEST_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
然后,在onResume()覆盖中编码类似的代码,以防安装在此过程中挂起:
//Checks that the update is not stalled during 'onResume()'.
//However, you should execute this check at all entry points into the app.
@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);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
}
我的猜测是它由应用程序本身控制,而不是Google Play。我开发的应用程序在启动时进行API调用以读取“最新”版本号以及该版本是否为“强制”更新,并将其与正在运行的应用程序版本进行比较。如果有新版本可用,则会向用户显示一个对话框,如您显示的对话框(虽然它们更好),提醒用户可以进行更新。如果更新是“强制性”,则该消息会告知他们必须在继续之前更新应用程序。如果他们单击“更新”,则会将他们带到App Store页面,他们会照常启动下载更新并退出应用程序。如果他们点击关闭,应用程序就会退出。如果更新不是强制性的,则会询问他们是否要立即更新,或继续更新。如果他们单击“更新”,则会将他们带到App Store页面,他们会照常启动下载更新并退出应用程序。如果他们单击“继续”,那么他们只会进入应用程序的现有版本。
我不确定他们如何管理后台下载然后在退出应用程序之前启动了应用更新。这将是非常好的,但我们上面的方法也很容易,并为开发人员提供了很多功能。
Google正在测试this blog post所述的早期版本的应用内更新API。
它现在仅适用于一些早期测试合作伙伴,但它最终应该适用于所有开发人员。密切关注Android开发者博客以及Play控制台中的公告。