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
相关产品推荐
相关产品推荐

