android.os.FileUriExposedException: file:///xxxx exposed beyond app through Intent.getData()

Android 自动安装Apk的时候报错android.os.FileUriExposedException: file:///storage/emulated/0/Download/download.apk exposed beyond app through Intent.getData()

原因: Android N版本(7.0)后,从安全性出发,不能直接通过Uri的方式共享文件,而应该通过content:uri,并赋予临时访问权限,利用ContentProvider组件来进行应用间文件共享。

解决方法:

  1. 在res目录下创建xml文件夹,并创建fileproviderpath.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
   <!--因为要安装的apk是存储在sd卡的,这里的映射就相当于:
    content:虚拟路径 映射到了-> Environment.getExternalStorageDirectory()
   -->
   <external-path
       name="external_path"
       path="." />
</paths>

在这里插入图片描述

  1. 在AndroidManifest文件Application中配置FileProvider
      <provider
           android:name="androidx.core.content.FileProvider"
           android:authorities="${applicationId}.fileprovider" 
           android:exported="false"
           android:grantUriPermissions="true">
           <meta-data
               android:name="android.support.FILE_PROVIDER_PATHS"
               android:resource="@xml/fileproviderpath">
           </meta-data>
       </provider>
属性 详情
android:authorities="${applicationId}.fileprovider" Provider唯一标识符,代码中通过这个唯一标识符才可以找到该内容提供者并操作它的数据
android:exported=“false” exported代表是否能被其它应用使用此Provider,默认是true,这里必须是false
android:resource="@xml/fileproviderpath" 刚刚上一步创建的xml文件,指定content:url与实际url映射
  1. 调用该FileProvider
 /**
     * 安装应用
     *
     */
    public static void installApk(Activity activity, File apkFile) {
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        Uri uri = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        //fileprovider为上述manifest中provider所配置相同
            uri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileprovider", apkFile);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        } else {
            uri = Uri.fromFile(apkFile);
        }
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        activity.startActivity(intent);
    }
  1. 注意: 不要忘了加上安装应用权限,如果不加此权限,应用未报错,但是安装失败
 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

参考:Android7.0以上(自动安装)文件访问报异常android.os.FileUriExposedException: file:///storage/emulated/0/app/****

发布了51 篇原创文章 · 获赞 5 · 访问量 2606

猜你喜欢

转载自blog.csdn.net/qq_45453266/article/details/105181680