首页 > 其他分享 >2024-07-16升级问题:调用自带软件打开文件时 android.os.FileUriExposedException

2024-07-16升级问题:调用自带软件打开文件时 android.os.FileUriExposedException

时间:2024-07-16 16:54:16浏览次数:12  
标签:context java 07 16 Intent file intent android os

2024-07-16升级问题:调用手机自带软件打开文件时,出现以下问题:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: rs.tabletcropland, PID: 10997
    android.os.FileUriExposedException: file:///storage/emulated/0/arcgis/%E7%9F%B3%E7%8B%AE%E5%B8%82/Attachment/%E7%9F%B3%E7%8B%AE%E5%B8%82%E8%AE%BE%E6%96%BD%E5%86%9C%E4%B8%9A%E5%A4%A7%E6%A3%9A%E8%B0%83%E6%9F%A5%E6%95%B0%E6%8D%AE.xlsx exposed beyond app through Intent.getData()
        at android.os.StrictMode.onFileUriExposed(StrictMode.java:2210)
        at android.net.Uri.checkFileUriExposed(Uri.java:2419)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:11812)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:11764)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1765)
        at android.app.Activity.startActivityForResult(Activity.java:5730)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
        at android.app.Activity.startActivityForResult(Activity.java:5654)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
        at android.app.Activity.startActivity(Activity.java:6152)
        at android.app.Activity.startActivity(Activity.java:6105)
        at com.FJDZYG.GIS.Tools.Base.OpenFileUtil.openFile(OpenFileUtil.java:107)
        at com.FJDZYG.GIS.Common.homePage.view.SearchFileActivity.openfile(SearchFileActivity.java:68)
        at com.FJDZYG.GIS.Common.homePage.view.SearchFileActivity.access$300(SearchFileActivity.java:33)
        at com.FJDZYG.GIS.Common.homePage.view.SearchFileActivity$6.false}
    lifecycleStateRequest PauseActivityItem{finished=true,userLeaving=false,configChanges=0,dontReport=false}
I/Process: Sending signal. PID: 10997 SIG: 9
Process 10997 terminated.

        这个错误是因为在Android 7.0及以上版本中,直接使用file://URI可能会导致FileUriExposedException。为了解决这个问题,你可以将文件路径转换为content://URI,然后使用Intent来打开文件。

解决步骤:

1、在AndroidManifest.xml中添加FileProvider

        在你的AndroidManifest.xml文件中添加一个<provider>元素,用于声明FileProvider和其相关的元数据。这里需要注意的是android:authorities属性的值:

<application ... >
    ...
    <!--authorities="你的包名+fileprovider" -->
    <provider
        android:authorities="${applicationId}.fileprovider"
        android:name="android.support.v4.content.FileProvider"
        android:grantUriPermissions="true"
        android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths"/>
    </provider>
    ...
</application>

如果是AndroidX的库,则可以如下:

        <!--authorities="你的包名+fileprovider" -->
        <provider
            android:authorities="${applicationId}.fileprovider"
            android:name="androidx.core.content.FileProvider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"/>
        </provider>

2、创建file_paths.xml文件

        在你的Android项目的res/xml目录下创建一个名为file_paths.xml的文件(如果xml文件夹不存在,则需要创建它)。在这个文件中,你可以定义共享文件的路径。例如,以下代码表示共享外部存储根目录下的所有文件:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="." />
</paths>

完整的:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- external-path:sd ;path:你的应用保存文件的根目录;name随便定义-->
    <!-- root-path 手机存储根目录 -->
    <root-path path="" name="arcgis" />
    <external-path name="external_files" path="." />

    <files-path name="picture" path="internal/pic/"/>
    <files-path name="database" path="internal/db/"/>
    <external-files-path name="picture" path="picture/"/>
</paths>

3、在代码中使用FileProvider 

 在需要构建文件Uri的地方,使用FileProvider来构建Uri,而不是直接使用Uri.fromFile()。

完整代码:

/**
     * 打开文件
     * 兼容7.0
     * @param context     activity
     * @param file        File
     * @param contentType 文件类型如:文本(text/html)
     *                    当手机中没有一个app可以打开file时会抛ActivityNotFoundException
     */
    public static void startActionFile(Context context, File file, String contentType) throws ActivityNotFoundException {
        if (context == null) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//打开只要读取的权限就够了。写的权限会导致失败
        intent.setDataAndType(getUriForFile(context, file), contentType);
        if (!(context instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        context.startActivity(intent);
    }
/***
     * Android7.0以上文件在应用间打开方式
     * @param context
     * @param file
     */
    public static void openFile_new(Context context, File file) {
        try {
            if (context == null) {
                return;
            }
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//打开只要读取的权限就够了。写的权限会导致失败
            String contentType = getMIMEType(file);
            intent.setDataAndType(getUriForFile(context, file), contentType);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            context.startActivity(intent);
        }
        catch (ActivityNotFoundException e) {
            // TODO: handle exception
            Toast.makeText(context, "sorry附件不能打开,请下载相关软件!", Toast.LENGTH_LONG).show();
        }
    }

    public static Uri getUriForFile(Context context, File file) {
        if (context == null || file == null) {
            throw new NullPointerException();
        }
        Uri uri;
        if (Build.VERSION.SDK_INT >= 24) {
            uri = FileProvider.getUriForFile(context.getApplicationContext(), context.getPackageName()+".fileprovider", file);
        } else {
            uri = Uri.fromFile(file);
        }
        return uri;
    }

至此,问题解决。

标签:context,java,07,16,Intent,file,intent,android,os
From: https://blog.csdn.net/sig321/article/details/140470540

相关文章

  • iOS开发基础104-正向代理和反向代理
    正向代理和反向代理是计算机网络中两种重要的技术,它们在网络请求的传递和管理上扮演着不同的角色。下面将详细介绍这两者的概念、优缺点,并探讨它们在iOS开发中的应用。一、正向代理1.概念正向代理是一种代理服务器,客户端向代理服务器发送请求,由代理服务器转发请求到目标服务器......
  • iOS开发基础103-APP之间跳转
    iOS提供了多种方式来实现应用之间的相互跳转。其中,URLSchemes和UniversalLinks是两种主要的方法。下面详细介绍这两种方法,并提供相应的示例代码,同时对它们的优缺点进行分析。一、URLSchemes1.什么是URLSchemesURLSchemes是一种基于URL的通讯方式,允许一个应用通过指定的UR......
  • iOS开发基础102-后台保活方案
    iOS系统在后台执行程序时,有严格的限制,为了更好地管理资源和电池寿命,iOS会限制应用程序在后台的运行时间。然而,iOS提供了一些特定的策略和技术,使得应用程序可以在特定场景下保持后台运行(即“后台保活”)。以下是iOS中几种常见的后台保活方案,并附上示例代码:一、后台任务利用beginBa......
  • 【HarmonyOS开发】Tabs使用封装
    背景在写Tabs时,会使用很多个TabContent来实现不同页面的展示内容,但是如果TabContent数量很多时,会导致Tabs代码量大而且很臃肿,因此想着尝试去封装Tabs的使用,可以让界面整洁和对内容界面的解耦。主要依托于wrapBuilder:封装全局@Builder的方法使用。需要注意从API11才开始......
  • ROS源码学习分享_6_ConnectionManager
        在上一章中,我们观察了PollManager节点背后的一些行为逻辑,但还有一些地方与本章有一些关联而没有讲到,这次我们就补上这些拼图。(本文章源自作者对于源码的观察理解以及其他资料的学习结合后的产物,仅用于自我复习,如有错误敬请见谅)    按照惯例我们先看一下......
  • iOS开发基础101-指纹和面部识别
    在iOS开发中,使用FaceID和TouchID可以为用户提供安全的生物识别认证,而手势识别(GestureRecognition)可以增加用户交互的便利性和灵活性。下面将详细介绍这三种技术,并给出如何封装一个统一的工具类来供外部使用。一、FaceID与TouchID1.设置与配置在使用FaceID和TouchID之前,需要在......
  • python中os.stat().st_size、os.path.getsize()获取文件大小
    一、os.stat().st_sizeos.stat(filePath)返回读取指定文件的相关属性,然后利用stat模块进行处理。importosos.stat('data_feather_ys.feather')#os.stat_result(st_mode=33206,st_ino=3659174697257342,st_dev=2829373452,st_nlink=1,st_uid=0,st_gid=0,st_size=400......
  • postMessageXss续2
      原文地址如下:https://research.securitum.com/art-of-bug-bounty-a-way-from-js-file-analysis-to-xss/  在19年我写了一篇文章,是基于postMessageXss漏洞的入门教学:https://www.cnblogs.com/piaomiaohongchen/p/14727871.html   这几天浏览mXss技术的时候,看到了一......
  • 2024-07-16 代码高亮插件highlight.js安装使用以及排错日志
    highlight.js—— 一个开源语法高亮库,用于在网页上对源代码进行语法高亮显示。安装npmihighlight.jsyarnaddhighlight.js引入//main.jsimport{createApp}from'vue';importAppfrom"./App.vue";importhljsfrom"highlight.js";//代码高亮插件import......
  • PX4学习日志四:PositionControl.cpp代码解读
    首先看boolPositionControl::update(constfloatdt)函数,该函数先进行有效性判断。跳转到_positionControl函数if(valid){_positionControl();分析_positionControl函数3.1通过P控制实现速度调节Vector3fvel_sp_position=(_pos_sp-_pos).emult(_gain_pos_p);......