由于最近工作需求的原因,有一个功能就是将webView里面的照片保存到本地,并且能够直接在相册中有一个及时的反馈。
项目中,具体是实现流程是这样的设计webview点击交互事件,当点击webview中的图片的时候抓取到图片的url地址;当需要保存图片的时候,通过nohttp下载图片并将图片保存到本地,然后更新相册。
在这里,抓取url地址和下载图片的方案有很多,这里就不在赘述,这里是说明一下如何更新相册,因为这里是一个坑,我一共遇到过两个方案:
方案一:
发送广播通知系统更新相册。
在网上大部分时候是这样做的,为什么呢?因为简单,只需要发送一个广播就OK了。但是这个方法是一个坑,坑在哪里,一会在说,这里先说一个怎么实现:
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(url.webviewImagePath+"/image.jpg"))); File file= (File) object; Uri uri = Uri.fromFile(file); intent.setData(uri); ShowImageActivity.this.sendBroadcast(intent);
上面代码就是发送广播中的方式,其中url.webviewImagePath+"/image.jpg"是保存到本地的地址和图片格式,file是把下载到图片的对象object转换为file。之后发送广播通知系统更新相册就好。
那么现在问题来了,坑在哪里。主要是下面两个问题:
1、相册更新很慢
这是因为我们向系统发送广播通知,却不能告知系统刷新特定的文件,所以系统会刷新整个sd卡。这样一来,自然相册更新会很慢。
2、部分安卓版本相册无法更新,重启手机后会更新
这是因为在部分安卓版本中,考虑到系统安全的问题,是不允许app向系统发送广播,这样一来自然无法更新相册,而另一个方面,手机重新启动,会重新挂载sd卡,这样就会刷新sd开所有东西。
那么问题来了,既然通过广播的方式刷新相册有这么多坑,那么有没有什么好的方式呢?这就是第二种方式:
方案二:
使用MediaScanner
什么是MediaScanner?MediaScanner完成Android中的多媒体文件的扫描工作。例如,mediascanner扫描系统内存和SD卡文件之后,会将扫描的结果加载在数据库中,在Music这个应用程序中看到的显示在activity 的list列表上歌曲专辑名,流派,歌曲时长等信息,都是扫描后的结果放在数据库中,最后读到的数据库中的信息。这里可以明白的一点是:多媒体数据库中的信息是由MediaScanner添加的。下面就是使用的方式:
class SannerClient implements MediaScannerConnection.MediaScannerConnectionClient { public void onMediaScannerConnected() { if (mFile == null) { return; } scan(mFile, mMimeType); } public void onScanCompleted(String path, Uri uri) { mConn.disconnect(); } private void scan(File file, String type) { if (file.isFile()) { mConn.scanFile(file.getAbsolutePath(), null); return; } //该方法可以遍历多个文件,这里不需要 File[] files = file.listFiles(); if (files == null) { return; } for (File f : file.listFiles()) { scan(f, type); } } } public void scanFile(File file, String mimeType) { mFile = file; mMimeType = mimeType; mConn.connect(); }
在我们需要添加照片到相册的地方,这几调用scanFile就可以了,其中两个参数:file是指添加的文件,mimeType是扫描文件的格式。这样我们可以直接扫描添加特定的文件。提高了速度
不是闷骚的程序员算不上程序员。我的微信公众号“那点鼻事”,在这里周一到周五每天一篇文章,与技术无关,只哈牛逼。