Android 7.0(API24)下SD卡图片删除异常问题求助
搞定Android 7.0媒体文件删除的三个坑
嘿,我太懂你遇到这些问题的抓狂了!Android 7.0的存储权限和媒体扫描机制确实有不少坑,我来逐个帮你拆解解决:
一、仅删MediaStore条目,重启后图片又回来?
这是因为你只更新了系统的媒体数据库,实际的图片文件根本没删掉!系统重启后,媒体扫描器会重新遍历存储,发现这个遗留的文件,就自动把它加回MediaStore了。
正确操作步骤:
- 先通过ContentResolver查到图片对应的真实文件路径(从
MediaStore.Images.Media.DATA字段获取) - 手动删除这个物理文件
- 再调用ContentResolver删除MediaStore里的数据库条目
给你个示例代码片段:
// 先查文件路径 String[] projection = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query(targetUri, projection, null, null, null); if (cursor != null && cursor.moveToFirst()) { String filePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); cursor.close(); // 删除物理文件 File imageFile = new File(filePath); if (imageFile.exists() && imageFile.delete()) { Log.d("Delete", "物理文件删除成功"); } } // 删MediaStore条目 getContentResolver().delete(targetUri, null, null);
二、外置SD卡路径(/storage/4ED7-7F17/...)无法写入/删除?
Android 7.0开始,对**外置SD卡(二级存储)**的访问权限做了严格限制:
Environment.getExternalStorage...系列方法只能访问内部共享存储(就是/storage/emulated/0/)- 普通的
WRITE_EXTERNAL_STORAGE权限管不到外置SD卡的私有目录,所以直接用File对象调用canWrite()会返回false
两种解决方案:
方案1:用MediaStore API操作外置SD卡的媒体文件
不管是内部还是外置存储的媒体文件,都通过MediaStore来查询和操作,别硬编码路径。比如要找外置SD卡Camera目录下的图片,可以通过VOLUME_NAME筛选(就是你路径里的4ED7-7F17):
// 筛选条件:指定存储卷 + 相对路径匹配Camera目录 String selection = MediaStore.Images.Media.VOLUME_NAME + " = ? AND " + MediaStore.Images.Media.RELATIVE_PATH + " LIKE ?"; String[] selectionArgs = {"4ED7-7F17", "DCIM/Camera/%"}; Cursor cursor = getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA}, selection, selectionArgs, null );
拿到对应的Uri和文件路径后,按照第一个问题的步骤删文件+删MediaStore条目就行。
方案2:通过SAF获取外置SD卡的访问权限
如果需要批量操作SD卡文件,让用户通过系统文件选择器授权访问SD卡目录,之后用DocumentFile来操作:
- 启动SAF选择目录:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); startActivityForResult(intent, REQUEST_CODE_SAF_AUTH);
- 处理授权结果,持久化权限并操作文件:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_SAF_AUTH && resultCode == RESULT_OK && data != null) { Uri treeUri = data.getData(); // 持久化权限,重启后依然有效 getContentResolver().takePersistableUriPermission( treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION ); // 找到DCIM/Camera目录 DocumentFile rootDir = DocumentFile.fromTreeUri(this, treeUri); DocumentFile dcimDir = rootDir.findFile("DCIM"); DocumentFile cameraDir = dcimDir != null ? dcimDir.findFile("Camera") : null; if (cameraDir != null && cameraDir.exists()) { // 删除目标文件 DocumentFile targetFile = cameraDir.findFile("test.jpg"); if (targetFile != null && targetFile.delete()) { Log.d("Delete", "SD卡文件删除成功"); } } } }
关键提醒:
别硬编码外置SD卡的挂载路径!不同设备的SD卡路径可能不一样,通过MediaStore的VOLUME_NAME字段识别才是可靠的方式。
内容的提问来源于stack exchange,提问作者andytimmy
相关产品推荐
相关产品推荐

