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进行操作:
- 查询目标文件的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; }
- 删除文件:
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
相关产品推荐
相关产品推荐

