软件更新,启动 apk,致命异常:Activity 未找到处理意图(使用前缀 file://),使用 getExternalFilesDir 时遇到问题

Sofware update, start apk, FATAL EXCEPTION: Activity not found to handle intent (Working with prefix file://), Having issue using getExternalFilesDir

我正在创建应用程序自定义更新程序,我从这里找到了很多帮助,但不是针对这个问题。

我可以像这样使用 AsyncTask 下载 update.apk:

output = new FileOutputStream(context.getFilesDir()+"/update.apk");

下载成功,然后尝试运行apk更新软件,如下:

编辑: 这部分已按照 ligi 的建议进行了更正。 ("file://")

Intent promptInstall = new Intent(Intent.ACTION_VIEW)
    .setDataAndType(Uri.parse("file://"+context.getFilesDir()+"/update.apk"),
                            "application/vnd.android.package-archive");

promptInstall.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
promptInstall.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(promptInstall);

在添加前缀之前,应用因上述错误而崩溃。

FATAL EXCEPTION: main
android.content.ActivityNotFoundException: 
    No Activity found to handle Intent { 
        act=android.intent.action.VIEW dat=/data/data/com.my.app/files/update.apk 
        typ=application/vnd.android.package-archive flg=0x10000001 
    }

编辑:

按照建议,我尝试这样做并得到错误:

/strorage/emulated/0/Android/data/com.my.app/files 打开失败:EISDIR

String PATH = context.getExternalFilesDir(null) + "/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "update.apk");
output = new FileOutputStream(file);

并尝试按照建议开始安装

File file = new File(context.getExternalFilesDir(null) + "/update.apk");
file.setReadable(true, false);
Intent promptInstall = new Intent(Intent.ACTION_VIEW);
promptInstall.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
promptInstall.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
promptInstall.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(promptInstall);

我做错了什么?

编辑:解决方案

我忘记添加从外部存储读取的权限,将此行添加到

AndroidManifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

AsyncTask

@Override
protected String doInBackground (String...sUrl){
    ......
    File sd = Environment.getExternalStorageDirectory();
    File outputFile = new File(sd, "/download/update.apk");
    output = new FileOutputStream(outputFile);
    ......
}


@Override
protected void onPostExecute(String result) {
    ......
    File sd = Environment.getExternalStorageDirectory();
    File inputFile = new File(sd, "/download/update.apk");

    Intent promptInstall = new Intent(Intent.ACTION_VIEW);
    promptInstall.setDataAndType(Uri.fromFile(inputFile), "application/vnd.android.package-archive");

    promptInstall.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    promptInstall.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(promptInstall);
    ......
}

您需要为架构添加前缀 ( file:// )

首先,对文件使用 Uri.fromFile(),而不是 Uri.parse(),以避免 ligi 引用的 file:/// 方案问题。

其次,安装程序无法访问 APK,因为您将其放在内部存储中。您必须将 APK 文件放在外部存储设备上(例如 getExternalFilesDir())。