博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 7.0系统代码调用安装apk时报错FileUriExposedException完美解决
阅读量:6962 次
发布时间:2019-06-27

本文共 2593 字,大约阅读时间需要 8 分钟。

项目更新遇到问题

  Android项目开发中经常遇到下载更新的需求,以前调用系统安装器执行安装操作代码如下:

Intent intent = new Intent();intent.setAction(android.content.Intent.ACTION_VIEW);intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");context.startActivity(intent);

  如果Android系统为7.0及以上时则会报异常FileUriExposedException,这是由于安卓官方为了提高私有文件的安全性,面向 Android 7.0 或更高版本的应用私有目录被限制访问 (0700)。此设置可防止私有文件的元数据泄漏,如它们的大小或存在性。传递file:// URI 可能给接收器留下无法访问的路径。因此,尝试传递 file:// URI 会触发 FileUriExposedException。因此需要使用 FileProvider。

Android7.0系统使用FileProvider安装apk安装步骤:

1.manifest.xml文件配置:定义一个FileProvider

2.添加可用权限的文件目录

  在项目res路径下新建名为xml的路径,在xml路径下新建名为file_paths.xml的文件,在file_paths.xml文件中增加如下内容指定分享的路径:

3.使用provider直接安装apk:

Intent intent = new Intent();intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", new File(path));intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.setDataAndType(contentUri, context.getContentResolver().getType(contentUri));//指定打开文件所调用的Activity,若不指定,则会弹出打开方式选择框,intent.setClassName("com.android.packageinstaller","com.android.packageinstaller.PackageInstallerActivity");context.startActivity(intent);

完美适配所有系统版本进行apk安装的方式

  如上代码虽然可以在Android7.0系统中正常安装apk,但是在低于Android7.0的系统中则不起作用,所以对apk安装调用方法进行封装,完美适配所有系统版本进行apk的安装调用。

/**     * 安装apk     *      * @param context Application对象     * @param path     *            apk路径     */    public static void InstallApk(Context context, String path) {        Intent intent = new Intent();        if (Build.VERSION.SDK_INT >= 24) {//Android 7.0以上            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", new File(path));            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);            intent.setDataAndType(contentUri, context.getContentResolver().getType(contentUri));            //指定打开文件所调用的Activity            intent.setClassName("com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");        } else {            intent.setAction(android.content.Intent.ACTION_VIEW);            intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");        }        context.startActivity(intent);    }

注意事项:

  清单文件配置的authorities的值必须与FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", new File(path));方法中第二个参数一致。

转载于:https://www.cnblogs.com/walker-world/p/7517364.html

你可能感兴趣的文章
yii2使用多个数据库的案例
查看>>
[LintCode/LeetCode] Search Insert Position
查看>>
Node处理http跨域请求
查看>>
Gradle for Android 第五篇( 多模块构建 )
查看>>
框架 也可以这样用 easy
查看>>
LCUI 1.1.0 Beta 发布,C 的图形界面库
查看>>
Base64
查看>>
MariaDB(mysql)之半同步复制及复制过滤器的使用
查看>>
WCF Ria Service 理解制图版本【待续】
查看>>
【IOS】高仿糗事百科客户端(基本实现了除注册,评论之外的功能)
查看>>
puppet之模块详解
查看>>
shell脚本
查看>>
python 模块
查看>>
Flash Builder生成asdoc格式的帮助文档
查看>>
分享实录 | 第四范式程晓澄:机器学习在推荐系统中的应用
查看>>
测试服务器响应时间
查看>>
xm console无法联接guest问题的解决
查看>>
一步一步SharePoint 2007之一:安装SharePoint
查看>>
Server Develop (七) Linux 守护进程
查看>>
Android requires compiler compliance level 5.0. Please fix project properties.错误
查看>>