Java Android 10-使用PackageManager安装新版本的apk而不是Intents不';真的不行

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

我的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), "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,但有以下区别(inputStream现在是从Uri构建的):

  • 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);
                }
            }
    }