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

Android 11+中删除自建下载文件夹及文件的权限问题

解决方案

优先方案:切换到应用专属存储

Android 10(API 29)及以上,应用专属存储是官方推荐的存储方案,无需额外权限,应用可自由管理自身文件(包括后台静默删除),完全匹配你的需求。

修改下载路径代码:

// 替换原setDestinationInExternalPublicDir的调用
File appDownloadDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "Myapp/attachments");
// 确保目录存在
if (!appDownloadDir.exists()) {
    appDownloadDir.mkdirs();
}
String targetFilePath = new File(appDownloadDir, attachment.getFile().toLowerCase()).getAbsolutePath();

DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url.toString()));
// 设置文件存储路径到应用专属目录
request.setDestinationUri(Uri.fromFile(new File(targetFilePath)));
// 也可直接用setDestinationInExternalFilesDir简化写法
// request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, "Myapp/attachments/" + attachment.getFile().toLowerCase());

long refid = mDownloadManager.enqueue(request);

启动时删除目标文件夹的代码:

File targetDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "Myapp/attachments");
deleteDirectory(targetDir);

// 递归删除文件夹及内部所有文件
private boolean deleteDirectory(File dir) {
    if (dir != null && dir.isDirectory()) {
        String[] childFiles = dir.list();
        for (String child : childFiles) {
            boolean deleteSuccess = deleteDirectory(new File(dir, child));
            if (!deleteSuccess) {
                return false;
            }
        }
        return dir.delete();
    } else if (dir != null && dir.isFile()) {
        return dir.delete();
    }
    return false;
}

此方案无需申请特殊权限,后台删除操作完全静默,且符合Google Play的权限审核标准。

备选方案:操作公共Download目录的非媒体文件(仅当必须保留公共目录时)

若因业务需求必须使用公共Download目录,针对PDF这类非媒体文件,可通过MediaStore.Downloads进行操作:

  1. 查询目标文件的ContentUri:
private Uri getDownloadFileUri(Context context, String fileName) {
    String[] projection = {MediaStore.Downloads._ID};
    String selection = MediaStore.Downloads.DISPLAY_NAME + " = ?";
    String[] selectionArgs = {fileName};
    
    Cursor cursor = context.getContentResolver().query(
            MediaStore.Downloads.EXTERNAL_CONTENT_URI,
            projection,
            selection,
            selectionArgs,
            null
    );
    
    if (cursor != null && cursor.moveToFirst()) {
        long fileId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Downloads._ID));
        cursor.close();
        return ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI, fileId);
    }
    
    if (cursor != null) {
        cursor.close();
    }
    return null;
}
  1. 删除文件:
Uri fileUri = getDownloadFileUri(context, attachment.getFile().toLowerCase());
if (fileUri != null) {
    try {
        context.getContentResolver().delete(fileUri, null, null);
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

注意:该方案依赖MediaStore对文件的索引,如果DownloadManager未自动将文件加入索引,可能需要手动插入记录;且Android 13+已废弃针对非媒体文件的READ_EXTERNAL_STORAGE权限,此方案存在兼容性局限,优先推荐第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:35:31