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

Android SDK33下载文件夹CSV文件无法删除问题求助

Android 10下DownloadManager下载文件无法删除的解决方案

问题分析

你的场景是应用通过DownloadManager下载CSV文件到外部存储,处理后删除失败,两种尝试方案均无效,原因如下:

  • 方案1(File.delete()失败):Android 10引入Scoped Storage机制,即使申请了WRITE_EXTERNAL_STORAGE权限,直接通过File对象操作公共下载目录的文件也会因权限限制失败,系统返回删除失败(false)。
  • 方案2(MediaStore删除失败):DownloadManager的下载ID和MediaStore.Downloads._ID并非同一标识,用该条件无法匹配到对应的文件记录,因此删除行数为0。

正确解决方案

方法1:通过DownloadManager获取文件Uri后删除

利用DownloadManager.getUriForDownloadedFile()获取下载文件的Content Uri,再通过ContentResolver执行删除操作,这是适配Scoped Storage的标准方式:

// 在下载完成的广播接收器中处理
val downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1L)
if (downloadId != -1L) {
    val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    val fileUri = downloadManager.getUriForDownloadedFile(downloadId)
    
    if (fileUri != null) {
        val deletedRows = context.contentResolver.delete(fileUri, null, null)
        logD("删除行数:$deletedRows")
        if (deletedRows > 0) {
            logD("文件删除成功")
        } else {
            logD("文件删除失败,请检查权限或文件状态")
        }
    } else {
        logE("无法获取下载文件的Uri,文件可能已被删除或下载失败")
    }
}

方法2:优化下载逻辑适配Scoped Storage

为避免路径权限问题,建议修改EasyDownloadManager的下载路径设置方式,使用系统提供的公共目录API,而非手动拼接路径:

修改下载方法

object EasyDownloadManager {
    fun startDowload(context: Context, fileName: String, url: String){
        val request = DownloadManager.Request(Uri.parse(url))
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE or DownloadManager.Request.NETWORK_WIFI)
        // 直接指定系统下载目录下的文件
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)

        val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
        downloadManager.enqueue(request)
    }

    // 保留原有的getFileFromId方法
    fun getFileFromId(context: Context, id: Long) : InputStreamReader {
        val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
        val uri: Uri = downloadManager.getUriForDownloadedFile(id)
        val inputStream = context.contentResolver.openInputStream(uri) ?: throw IOException("无法打开文件输入流")
        return InputStreamReader(inputStream)
    }
}

调用下载的代码调整

val fileName = "${season.code}${season.period}.csv"
EasyDownloadManager.startDowload(context, fileName, season.dataUrl)
context.registerReceiver(downloadBroadcastReceiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))

权限补充说明

  • 若应用targetSdk为33,MANAGE_EXTERNAL_STORAGE是特殊权限,需引导用户到系统设置页面授权,但该权限仅适用于文件管理类应用,普通应用不建议依赖,优先使用Scoped Storage兼容方案。
  • 确保动态申请了READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限(Android 10+中WRITE_EXTERNAL_STORAGE权限仅用于访问自己创建的文件,公共目录需通过ContentResolver操作)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 06:53:20