Android无法从Download文件夹获取文档,报FileNotFoundException求助
解决
java.io.FileNotFoundException路径错误问题 你遇到的核心问题是路径拼接时缺少了关键的斜杠,导致系统找不到正确的文件位置。从错误信息/storage/emulated/0/DownloadReact-native commands.pdf就能一眼看出——Download文件夹名和文件名React-native commands.pdf直接连在一起了,正确的路径应该是/storage/emulated/0/Download/React-native commands.pdf。
问题代码的出错点:
你在拼接路径时,Download后面没有加上分隔斜杠/:
val path = Environment.getExternalStorageDirectory().toString() +"/Download" + fileName val ss = Environment.getExternalStoragePublicDirectory("").toString()+"/Download" + fileName
这两行里的"/Download"必须改成"/Download/",否则文件名会被当成Download文件夹名的一部分,形成一个不存在的路径。
修复后的完整代码:
if (isDownloadsDocument(uri)) { Log.d("build_version_one", Build.VERSION.SDK_INT.toString()) Log.d("build_version_two", Build.VERSION_CODES.M.toString()) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val id: String var cursor: Cursor? = null try { cursor = context.contentResolver.query(uri, arrayOf(MediaStore.MediaColumns.DISPLAY_NAME), null, null, null) if (cursor != null && cursor.moveToFirst()) { val fileName = cursor.getString(0) // 修复路径拼接:给Download后添加斜杠 val path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName val ss = Environment.getExternalStoragePublicDirectory("").toString() + "/Download/" + fileName Log.d("orginal_path","one"+path) Log.d("orginal_path","two"+ss) if (!TextUtils.isEmpty(path)) { Log.d("orginal_path","working") return path } } } finally { cursor?.close() } id = DocumentsContract.getDocumentId(uri) if (!TextUtils.isEmpty(id)) { if (id.startsWith("raw:")) { return id.replaceFirst("raw:".toRegex(), "") } val contentUriPrefixesToTry = arrayOf( "content://downloads/public_downloads", "content://downloads/my_downloads" ) for (contentUriPrefix in contentUriPrefixesToTry) { return try { val contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), java.lang.Long.valueOf(id)) Log.d("orginal_content_uri", contentUri.toString()) getDataColumn(context, contentUri, null, null) } catch (e: NumberFormatException) { //In Android 8 and Android P the id is not a number uri.path.replaceFirst("^/document/raw:", "").replaceFirst("^raw:", "") } } } } }
额外优化建议:
为了彻底避免这类手动拼接的错误,推荐使用File类来构建路径,它会自动适配系统的路径分隔符:
val downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) val targetFile = File(downloadDir, fileName) val path = targetFile.absolutePath
这种方式更安全,也不需要手动处理斜杠,能兼容不同Android版本的路径规则。
内容的提问来源于stack exchange,提问作者jithin prvak
相关产品推荐
相关产品推荐

