Java Android 10-使用PackageManager安装新版本的apk而不是Intents不';真的不行
我的apk当前的更新方式是通过新的apk在旧的apk上安装自身(同时不覆盖本地数据库或设置) 因此,由于Android 10(API 29)Java Android 10-使用PackageManager安装新版本的apk而不是Intents不';真的不行,java,android,android-intent,android-10.0,Java,Android,Android Intent,Android 10.0,我的apk当前的更新方式是通过新的apk在旧的apk上安装自身(同时不覆盖本地数据库或设置) 因此,由于Android 10(API 29)ACTION\u VIEW已被弃用,因此这项功能不再有效: Intent intent = new Intent(Intent.ACTION_VIEW); //output file is the apk downloaded earlier intent.setDataAndType(Uri.fromFile(outputFile), "applicati
ACTION\u 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);
很简单,尽管比过去复杂。我在onNewIntent中得到的答复总是:
case PackageInstaller.STATUS_FAILURE:
Toast.makeText(this, "Install failed!10 " + status + ", " + message,
Toast.LENGTH_SHORT).show();
break;
其中状态和消息采用以下值:status=1,message=“安装失败\u内部错误:权限被拒绝”
所以我认为这是权限的问题。我已经拥有了对存储器的读写权限。其他相关权限包括:INSTALL\u PACKAGES
和REQUEST\u INSTALL\u PACKAGES
,我无法使用这些权限,因为第一个权限不是供第三方使用的,后者是签名级别的
是否有什么东西我非常缺少,或者没有一种方法可以让我在不通过google play的情况下更新我的Apk 我也遇到过同样的问题,也尝试过同样的方法(PackageInstaller),就像你一样。它不起作用。 所以,这里有一个解决方案
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);
}
我已经在安卓10(谷歌像素2,1+7,三星s10)上进行了测试,它运行良好。如果你仍然面临任何问题,请告诉我。
注意:您的版本代码必须大于旧版本。因此,经过帮助和更多搜索伟大的互联网,我已经能够使这两种方法都适用于我。我还是不太明白是什么导致了这个问题。之前,我使用
Uri.fromFile(file)
直接从文件创建意图中使用的Uri。这适用于Android 10下的任何东西。我处理这个问题的新方法是使用提供程序并使用它获取文件
PackageManager的主要问题是,它在安装时关闭我的应用程序,而不向用户提供默认反馈。所以我想我必须“做出”这样的反馈。我将转到PackageManager,因为APK不推荐使用ACTION_视图。欢迎使用stack overflow。数学显然对你的生活产生了影响:积极的,消极的,谁知道呢。我来这里已经三年了。第一次遇到问题,我就找不到解决办法。很高兴来到这里,我希望我的问题不会太多。好吧,至少你的问题还不错,这对新撰稿人来说是一个值得欢迎的变化-希望你能找到一个答案来演示如何使用
PackageInstaller
,并且它在Android 10上运行良好。您的问题没有显示addApkToInstallSession()
,这可能是您的问题所在。这在Kotlin中。我发现有一个应用程序演示,但最初由于无法正确处理文件而无法适应。我还是不明白,但我会弄明白的。我的addApkToInstallSession()与我在演示中找到的(Java中的)完全相同。我发送给addApk的输出文件肯定在那里,因为当我在一个较旧的Android上测试更新时,它确实起了作用。它向我抛出了一个“找不到处理意图的活动”,并且崩溃了,没有成功。在安卓10模拟器和小米9T Pro上测试。有什么我需要添加到清单中吗?是的,在检查了Android文档之后,这个常量似乎在29年也被弃用了。文档页面甚至建议使用PackageInstaller,我已经尝试过使用,但没有成功。它还指定任何超过25个的目标都需要\u安装\u软件包,即签名级别的权限。您是否调试并检查了在Uri.fromFile(path)中传递的文件路径?这就是我在“Uri apkUri=FileProvider.getUriForFile(context,BuildConfig.APPLICATION_ID+”.FileProvider,file);”中所做的。如何在清单文件中定义该提供程序?我曾经保存apk,然后调用Uri.fromFile(outputFile))。
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);
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);
}
}
}