You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13中文件存在却触发FileNotFoundException问题求助

问题分析与解决方案

核心错误原因

你当前代码的关键问题是:将ActivityResult对象直接转为字符串来创建File实例。通过Intent.ACTION_GET_CONTENT选择文件后,返回的是内容URI(格式通常为content://开头),并非本地文件的绝对路径。直接用这个URI字符串创建File,系统自然找不到对应的文件,从而触发FileNotFoundException。

修正步骤与代码示例

1. 获取正确的文件URI

首先要从ActivityResult中获取真实的内容URI,并且先判断选择操作是否成功:

if (result.getResultCode() == Activity.RESULT_OK) {
    Uri uri = result.getData();
    if (uri != null) {
        // 后续读取逻辑
    }
}

2. 使用ContentResolver读取文件内容

Android中访问content://类型的URI,必须通过ContentResolver来获取输入流,而不是直接用FileInputStream。修正后的完整onActivityResult逻辑如下:

ActivityResultLauncher<Intent> startActivityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                Log.d("onActivityResult", "FileChooser works");
                // 先判断操作是否成功
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Uri uri = result.getData();
                    if (uri == null) {
                        Log.e("onActivityResult", "Uri is null");
                        return;
                    }

                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                    try (InputStream inputStream = getContentResolver().openInputStream(uri)) {
                        if (inputStream == null) {
                            Log.e("onActivityResult", "Failed to open input stream");
                            return;
                        }
                        int i;
                        while ((i = inputStream.read()) != -1) {
                            byteArrayOutputStream.write(i);
                        }
                        String s = byteArrayOutputStream.toString();
                        Log.d("FileContent", s);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

3. 权限补充说明

对于GPX这类非媒体文件:

  • Android 10及以上,通过ACTION_GET_CONTENT由用户主动选择文件,无需申请READ_EXTERNAL_STORAGE或READ_MEDIA_*权限(系统会自动授予临时访问权限)
  • 若后续需要访问其他应用创建的GPX文件,同样通过ACTION_GET_CONTENT或ACTION_OPEN_DOCUMENT即可,无需额外权限(用户主动选择的文件都能访问)

额外优化建议

  • 可以将Intent的setType改为application/gpx+xml或text/xml,更精准地筛选GPX文件:
    data.setType("application/gpx+xml");
    // 或者如果部分GPX文件被识别为文本类型,可添加额外类型
    data.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"application/gpx+xml", "text/xml"});
    
  • 使用try-with-resources语法自动关闭流(如上面代码所示),避免资源泄漏。

内容的提问来源于stack exchange,提问作者Bernd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:17:36