我最近遇到了Google Play提供的一种新的应用更新流程。我喜欢无缝流程来更新Android应用程序。我在Hotstar应用程序中观察到以下提到的步骤。
我该如何实现?必须有一种与Google Play交流的方式。我浏览了许多博客。但是,没有找到任何解决方案。如果用户禁用了自动应用程序更新,这对于开发人员来说可能是一个很棒的功能。
答案 0 :(得分:3)
正式文档: https://developer.android.com/guide/app-bundle/in-app-updates
约束:应用内更新仅适用于运行Android 5.0(API级别21)或更高版本的设备
步骤1:添加依赖项:
let interval = CMTime(value: 1, timescale: 2)
player?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: { (progressTime) in
let seconds = CMTimeGetSeconds(progressTime)
let secondString = String(format: "%02d", Int(seconds) % 60)
let minutString = String(format: "%02d", Int(seconds) / 60)
self.currentTimeLabel.text = "\(minutString):\(secondString)"
第2步:检查更新的可用性,并开始检查是否可用
dependencies {
implementation 'com.google.android.play:core:1.5.0'
...
}
第3步:收听更新状态
mAppUpdateManager = AppUpdateManagerFactory.create(this);
mAppUpdateManager.registerListener(installStateUpdatedListener);
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)){
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");
}
});
第4步:获取更新状态的回调
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());
}
}
};
第5步:灵活更新
@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");
}
}
}
答案 1 :(得分:2)
Android今天正式向所有人宣布了应用内更新。 https://developer.android.com/guide/app-bundle/in-app-updates
答案 2 :(得分:1)
尝试执行此操作,在接受的答案中引用的官方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();
}
}
});
}
答案 3 :(得分:1)
请尝试一次。
步骤1:在build.gradle文件中,添加以下库
implementation 'com.google.android.play:core:1.6.4'
第2步:在类(Ex MainActivity.java)中声明以下变量
private AppUpdateManager mAppUpdateManager;
private int RC_APP_UPDATE = 999;
private int inAppUpdateType;
private com.google.android.play.core.tasks.Task<AppUpdateInfo> appUpdateInfoTask;
private InstallStateUpdatedListener installStateUpdatedListener;
步骤3:在onCreate()方法中,添加以下代码(初始化变量)
// Creates instance of the manager.
mAppUpdateManager = AppUpdateManagerFactory.create(this);
// Returns an intent object that you use to check for an update.
appUpdateInfoTask = mAppUpdateManager.getAppUpdateInfo();
//lambda operation used for below listener
//For flexible update
installStateUpdatedListener = installState -> {
if (installState.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
};
mAppUpdateManager.registerListener(installStateUpdatedListener);
第4步:在活动的onDestroy()方法中,只需取消注册侦听器
@Override
protected void onDestroy() {
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
super.onDestroy();
}
第5步:在onResume()中,我们需要通过以下代码监听“灵活”更新和“立即更新”。
@Override
protected void onResume() {
try {
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() ==
UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
// If an in-app update is already running, resume the update.
try {
mAppUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
inAppUpdateType,
this,
RC_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
//For flexible update
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
});
} catch (Exception e) {
e.printStackTrace();
}
super.onResume();
}
步骤6:在onActivityResult()中,我们需要处理用户点击操作(仅用于灵活更新)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_APP_UPDATE) {
//when user clicks update button
if (resultCode == RESULT_OK) {
Toast.makeText(MainActivity.this, "App download starts...", Toast.LENGTH_LONG).show();
} else if (resultCode != RESULT_CANCELED) {
//if you want to request the update again just call checkUpdate()
Toast.makeText(MainActivity.this, "App download canceled.", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_IN_APP_UPDATE_FAILED) {
Toast.makeText(MainActivity.this, "App download failed.", Toast.LENGTH_LONG).show();
}
}
}
第7步:创建一种方法来检查更新是否可用并开始更新(立即更新)
private void inAppUpdate() {
try {
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
@Override
public void onSuccess(AppUpdateInfo appUpdateInfo) {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
// For a flexible update, use AppUpdateType.FLEXIBLE
&& appUpdateInfo.isUpdateTypeAllowed(inAppUpdateType)) {
// Request the update.
try {
mAppUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
// Or 'AppUpdateType.FLEXIBLE' for flexible updates.
inAppUpdateType,
// The current activity making the update request.
MainActivity.this,
// Include a request code to later monitor this update request.
RC_APP_UPDATE);
} catch (IntentSender.SendIntentException ignored) {
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
第8步:精细地创建一个小吃对话框或任何警报,以向用户显示已下载弹性更新并准备进行更新(需要使用操作来启动更新-仅用于弹性更新)
private void popupSnackbarForCompleteUpdate() {
try {
Snackbar snackbar =
Snackbar.make(
findViewById(R.id.id_of_root_loyout),
"An update has just been downloaded.\nRestart to update",
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("INSTALL", view -> {
if (mAppUpdateManager != null){
mAppUpdateManager.completeUpdate();
}
});
snackbar.setActionTextColor(getResources().getColor(R.color.install_color));
snackbar.show();
} catch (Resources.NotFoundException e) {
e.printStackTrace();
}
}
第9步:现在,无论您要开始检查更新的位置如何,都可以使用应用内更新类型(灵活或立即)来调用该方法。
//For Immediate
inAppUpdateType = AppUpdateType.IMMEDIATE; //1
inAppUpdate();
//For Flexible
inAppUpdateType = AppUpdateType.FLEXIBLE; //0
inAppUpdate();
要记住的要点:
该灵活更新将首先下载,然后会通知用户下载已完成,然后用户必须开始更新(以上第8步中给出的选项)。
Google Play控制台中有一个选项可以测试应用内共享,只需我们可以上传常规apk(无需签名的apk)进行测试即可。 https://support.google.com/googleplay/android-developer/answer/9303479?hl=en
需要在测试设备Play商店应用中启用应用内共享选项。 How to Enable Internal App Sharing for Android?
仍然,Play商店中的任何问题,只需清除缓存并清除数据,然后重新启动设备一次即可。
答案 4 :(得分:0)
我的猜测是,它是由应用本身而非Google Play控制的。我已经开发了一些应用程序,这些应用程序在启动时会进行API调用,以读取“最新”版本号以及该版本是否为“强制性”更新,并将其与正在运行的应用程序版本进行比较。如果有新版本可用,则向用户显示一个对话框,类似于您显示的对话框(尽管他们的对话框要好得多),提醒用户有可用的更新。如果更新为“强制性”,则该消息告诉他们必须先更新应用程序,然后才能继续。如果他们单击“更新”,则会将他们带到“应用程序商店”页面,在该页面上,他们将照常启动下载更新,然后退出该应用程序。如果他们单击“关闭”,则该应用程序将退出。如果该更新不是强制性的,则询问他们是否要立即更新或继续。如果他们单击“更新”,则会将他们带到“应用程序商店”页面,在该页面上,他们将照常启动下载更新,然后退出该应用程序。如果他们单击“继续”,则它们将被带入该应用程序的现有版本中。
我不确定他们如何管理后台下载,然后在退出应用程序之前启动了应用程序更新。那将非常好,但是我们上面的方法也非常简单,并且为开发人员提供了很多功能。
答案 5 :(得分:0)
Google正在测试this blog post中所述的应用内更新API的早期版本。
目前仅对某些早期测试合作伙伴可用,但最终应对所有开发人员可用。请密切关注Android开发者博客以及Play控制台中的公告。
答案 6 :(得分:0)