最近做的一个需求是:将拍照或相册的图片上传服务器后删除对应的本地图片。在实现这个简单的需求的过程中却碰到了两个意想不到的问题。
这两个问题源自于删除本地图片时选用的两个不同的方法
file.delete
很明显,图片也是File的一种,所以完全可以使用file.delete方法来删除本地图片。
public static void deletePicture(String localPath) {
if(!TextUtils.isEmpty(localPath)){
File file = new File(localPath);
if (file.exists()) {
file.delete();
}
}
}
但是,很快就发现,file.delete方法在删除记录在媒体数据库里面的图片时会有个明显的问题:删除不干净。即使file.delete方法执行返回ture提示删除成功,在图库或者其他图片选择库里面还是会显示该图片的缩略图(或者空白图)。这是因为使用file.delete方法只是删除了本的图片,但并没有通知媒体数据库删除该图片的缩略图。
contentResolver.delete
contentResolver.delete可以解决上面所说的问题,删除图片的缩略图不再在图库或者其他图片选择库里显示。
public static void deletePicture(String localPath, Context context) {
if(!TextUtils.isEmpty(localPath)){
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver contentResolver = context.getContentResolver();
String url = MediaStore.Images.Media.DATA + "=?";
contentResolver.delete(uri, url, new String[]{localPath});
}
}
但是,在删除经过自己裁剪压缩处理后保存起来的图片时却发现:不能删除这些图片,contentResolver.delete方法返回值为0。
出现这个问题的原因是:因为图片创建时并没有通知(插入到)媒体数据库,所以contentResolver查询时没有找到这张图片,当然就无法删除了,这时候反过来可以使用file.delete方法删除。
结合contentResolver.delete和file.delete
综上所述,可以结合contentResolver.delete和file.delete实现本地图片的删除。
public static void deletePicture(String localPath, Context context) {
if(!TextUtils.isEmpty(localPath)){
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver contentResolver = context.getContentResolver();
String url = MediaStore.Images.Media.DATA + "=?";
int deleteRows = contentResolver.delete(uri, url, new String[]{localPath});
if (deleteRows == 0) {//当生成图片时没有通知(插入到)媒体数据库,那么在图库里面看不到该图片,而且使用contentResolver.delete方法会返回0,此时使用file.delete方法删除文件
File file = new File(localPath);
if (file.exists()) {
file.delete();
}
}
}
}