Android 10 - 使用PackageManager安装新版本的apk而不是Intents实际上不起作用



我的apk当前更新的方式是通过新apk在旧apk上安装自身(同时不覆盖本地数据库或设置(。

因此,由于Android 10(API 29(ACTION_VIEW已被弃用,因此这不再起作用:

Intent intent = new Intent(Intent.ACTION_VIEW);
//output file is the apk downloaded earlier
intent.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-archive");
startActivity(intent);

在我通过互联网找到的不同答案之后,我需要开始使用PackageInstaller。看看在 Android 文档中找到的演示,我得到了这个:

Intent intent = new Intent(PSMentorActivity.this,InstallApkSessionApi.class);
intent.putExtra("apkFile",outputFile);
this.startActivity(intent);

其中 InstallApkSessionApi 包含一个按钮,按下该按钮时应启动安装窗口:

PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new 
PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(params);
session = packageInstaller.openSession(sessionId);
addApkToInstallSession(file, session);
// Create an install status receiver.
Context context = InstallApkSessionApi.this;
Intent intent = new Intent(context, InstallApkSessionApi.class);
intent.setAction(PACKAGE_INSTALLED_ACTION);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.getIntentSender();
// Commit the session (this will start the installation workflow).
session.commit(statusReceiver);

足够简单,尽管与过去相比更复杂。我在NewIntent中得到的回应总是:

case PackageInstaller.STATUS_FAILURE:
Toast.makeText(this, "Install failed!10 " + status + ", " + message,
Toast.LENGTH_SHORT).show();
break;

其中,状态和消息采用以下值:status=1, message= "INSTALL_FAILED_INTERNAL_ERROR: Permission denied"

所以我认为这是权限问题。我已经拥有读取和写入存储的权限。其他相关权限包括:INSTALL_PACKAGESREQUEST_INSTALL_PACKAGES我无法使用,因为前者不打算用于第三方使用,而后者是签名级别。

是否有我非常缺少的东西,或者没有办法在不通过谷歌播放的情况下更新我的 Apk?

我遇到了同样的问题,并像你一样尝试了相同的方式(包安装程序(。它不起作用。 所以,这是给你的解决方案,

if(android.os.Build.VERSION.SDK_INT >= 29){
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(Uri.fromFile(outputFile));
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);   
}else{
Intent intent = new Intent(Intent.ACTION_VIEW);
//output file is the apk downloaded earlier
intent.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package- 
archive");
startActivity(intent);
}

我已经在Android 10(谷歌Pixel 2,One + 7,Samsung s10(中进行了测试,它工作正常。如果您仍然遇到任何问题,请告诉我。注意:您的版本代码必须大于旧版本代码。

因此,经过帮助和更多搜索伟大的互联网,我已经能够使这两种方法都适合我。我仍然不明白是什么导致了这个问题。以前,我直接使用Uri.fromFile(file)从文件创建意图中使用的 Uri。这适用于 Android 10 下的任何内容。我处理此问题的新方法是使用提供程序并使用它获取文件。

  1. 当前的方法,要使用一段时间,直到我可以正确实现 PackageManager 安装(仍然有一些问题需要修复(。
Uri urlapk = FileProvider.getUriForFile(this,BuildConfig.APPLICATION_ID+".fileProvider",outputFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(urlapk, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
  1. 按照我的问题中指定的那样使用包管理器,但有以下区别(输入流现在正在从 Uri 构建(:
private void addApkToInstallSession(Uri uri, PackageInstaller.Session session)
throws IOException {
try (OutputStream packageInSession = session.openWrite("package", 0, -1);
InputStream is = getContentResolver().openInputStream(uri)) {
byte[] buffer = new byte[16384];
int n;
while ((n = is.read(buffer)) >= 0) {
packageInSession.write(buffer, 0, n);
}
}
}

我对 PackageManager 的主要问题是它在安装时关闭我的应用程序,不向用户提供默认反馈。所以我想我将不得不"做出"这种反馈。我将继续讨论包管理器,因为 apk 已弃用ACTION_VIEW。

最新更新