最近在项目开发过程中遇到文件使用完需要删除掉,一般我们都这么删除:
/**
* 删除单个文件
*
* @param filePath 被删除文件的文件名
*/
public static void deleteSingleFile(String filePath) {
File file = new File(filePath);
if (file.isFile() && file.exists()) {
file.delete();
}
}
天真的以为这样就够了?
还是太嫩了啊,打开相册你会发现它依旧默默躺在,微微对着你笑.....
原因是系统会自动给文件存一张缩略图,上面 file.delete 仅仅删除了本地文件,并没有同步去删除媒体库中的缩略图。因为Android系统在启动的时候会启动 MediaScannerService 扫描系统上的多媒体文件,然后将这些多媒体文件的信息加入到多媒体数据库中,应用程序要取得这些多媒体信息就是从这个多媒体数据库里面去取的,并不是从SD卡中取。也就是说,如果开机后增加或删除了一些多媒体,这个多媒体数据库是不会自动刷新的。下面介绍两种方式让你清理掉这个缩略图:
刷新媒体库
网上常用的方法是通过广播发送消息给系统,让系统自动更新一次媒体库,但是发送 Intent.ACTION_MEDIA_MOUNTED 广播只在 4.4 版本之前好使,因为官方开发文档指出:4.4开始,不再允许非系统应用发送系统消息。
为了兼容问题,伪造系统广播是没法使用了,只能另辟蹊径,刚刚我们也说了,android系统在启动的时候会启动 MediaScannerService 扫描系统上的多媒体文件,那么,我们如果在查看相册之前,手动扫描一次多媒体文件,是不是可以呢?
直接上代码:
/**
* @param filename 文件全名,包括后缀
*/
private void updateMedia(String filename) {
MediaScannerConnection.scanFile(this, new String[]{filename}, null, new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("TAG", "Scanned " + path + ":");
Log.i("TAG", "-> uri=" + uri);
}
});
}
上述代码是对添加的图像文件进行扫描,由于只是扫描了我们添加的文件,并非对整个媒体库文件进行扫描,因此,并不会影响效率。
ContentResolver 定位删除缩略图
ContentProviders 存储和检索数据,通过它可以让所有的应用程序访问到,我们也可以使用系统提供的 ContentProvider 去操作媒体库:
/**
* @param filename 文件全名,包括后缀
*/
public void updateMedia(Context context, String path){
context.getcontentresolver.delete(Media.EXTERNAL_CONTENT_URI,Media.DATA + "=?",path);
//MediaStore.Audio.Media.EXTERNAL_CONTENT_URI数据库表所在路径
//这里用到了后面的参数,第二个表示delete判断的条件,MediaStore.Audio.Media._ID表示
Log.i("TAG", "path = " + path);
}
最后
经测试,上述方法可以完美解决媒体库更新的难题!