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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:27:32