java - 调用 completeUpdate() 时 AppUpdateManager 不安装应用程序
问题描述
我正在尝试使用 AppUpdateManager 实现 Android In App Update API。我首先尝试按照文档进行操作,如果您在这里,那么您就知道那行不通。
所以我已经阅读了十几个关于如何让它工作的教程和博客文章。我大约有 90% 在那里。对我来说,在用户接受更新后,更新已下载,我的侦听器检测到下载已完成,我会显示我自己的消息并进行回调(此时大多数教程都使用 Toast,但这不应该事情)。如果我的用户点击“重新启动”,这是我在显示的消息的 OK 方面给出的标签,然后我调用 appUpdateManager.completeUpdate()。
此时,我从 Google Play 获得了一个屏幕,其中显示了一些漂亮的动画,并在安装完成后出现安装进度条,Google 屏幕消失,然后我的应用程序重新启动。
问题是它没有安装,我可以从我的应用程序版本中看出它仍然是以前的版本,并且由于它仍然是以前的版本,所以重新创建了 appUpdateManager,当它检查 UpdateAvailability.UPDATE_AVAILABLE 时,它发现(显然)有可用的更新,并返回整个处理过程,再次下载并尝试再次重新启动应用程序。
我添加了一些日志消息并检查我是否在 onActivityResult 中收到 RESULT_IN_APP_UPDATE_FAILED,但它恢复正常。
任何人有任何帮助或建议,都会很棒。
我在 MainActivity 的开头创建了一个 appUpdateManager 句柄,如下所示:
private AppUpdateManager appUpdateManager;
我还创建了一个侦听器来监视安装状态,因为我正在努力使用 FLEXABLE AppUpdateType,例如:
private InstallStateUpdatedListener UPDATE_LISTENER = installState -> {
if (installState.installStatus() == DOWNLOADED) {
Log.d(TAG, "~UPDATE_LISTENER - installStatus is DOWNLOADED");
Utility.displayAlert(UPDATE_READY);
}
Log.d(TAG, "~Error code is: " + installState.installErrorCode());
Log.d(TAG, "~Package name is: " + installState.packageName());
};
在我的 onCreate 中,我创建了 appUpdateManager 并注册了下载侦听器,并添加了 addOnSuccessListener,如下所示:
Log.d(TAG, "~updateAppIfAvailable");
// Creates instance of the manager.
appUpdateManager = AppUpdateManagerFactory.create(this);
Log.d(TAG, "~registerListener");
appUpdateManager.registerListener(UPDATE_LISTENER);
appUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener(
appUpdateInfo -> {
// Checks that the platform will allow the specified type of update.
Log.d(TAG, "~updateAvailability is " + appUpdateInfo.updateAvailability());
if ((appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE)
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
// Request the update.
try {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.FLEXIBLE,
this,
MY_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
我的 onActivityResult 看起来像这样:@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.d(TAG, "~onActivityResult"); if (requestCode == MY_REQUEST_CODE) { switch (resultCode) { case Activity.RESULT_OK: Log.d(TAG, "~User approved update"); 休息; case Activity.RESULT_CANCELED: Log.d(TAG, "~User denied update"); 休息; case RESULT_IN_APP_UPDATE_FAILED: Log.d(TAG, "~Update failed"); 休息; } } }
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 {
Log.d(TAG, "~onResume appUpdateManager is calling startUpdateFlowForResult");
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.FLEXIBLE,
this,
MY_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
最后,当我显示我的警报时(如果您愿意,这可能是一个 Toast),我有一个取消和重新启动选项,并显示一条消息,显示“更新下载已完成”。
如果用户按下“重启”选项,那么它会调用这个 updateAndRestart() 方法:
private void updateAndRestart() {
Log.d(TAG, "~updateAndRestart");
Log.d(TAG, "~Completing app update.");
if (appUpdateManager != null) {
appUpdateManager.completeUpdate();
Log.d(TAG, "~unregisterListener");
appUpdateManager.unregisterListener(UPDATE_LISTENER);
}
}
解决方案
好的,已经一个星期了,显然我已经难倒了整个 SO 社区。:) 说真的,过去一周我一直在阅读 Android 文档和教程,但我没有其他答案,所以我只想说 Google 更新 API 还没有准备好投入生产。
我找到了一个替代解决方案。它是一个组合
- 使用此问题的答案中提到的AppUpdater库。
- 如果我收到用户点击更新的回调,那么我会使用此意图将他们带到我的 Play 商店应用列表。确保将“com.example.android”替换为您自己的应用程序 ID。这个谷歌文档页面向您展示了如何做到这一点。
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("https://play.google.com/store/apps/details?id=com.example.android")); intent.setPackage("com.android.vending"); startActivity(intent);
推荐阅读
- android - Android : 在 Github 上维护我的 Android 应用程序的多个版本
- string - 如何在bash中的连字符后提取文本
- networking - 如何查找标题数据和名称?(Python 请求)
- rust - 如何在我的代码中使用拥有的数据。借来的价值活不过来
- android - 在编辑文本中提供输入时设置按钮的可见性
- javascript - jquery - 通过 Switch 语句搜索和替换
- security - Docker 插件 - 在独立的 docker 设置中传递和存储密码
- c++ - 重载 == 运算符
- sql-server - 聚集索引和非聚集索引上的 WHERE 子句
- node.js - NodeJS + Mongoose:MissingSchemaError:模式尚未注册模型“类别”