项目中可能有这样的需求:下载或导入、导出的图片、音乐等媒体文件,需要马上能在图库或本地视屏播放器中显示出来,或者要能在媒体数据库中查询到媒体文件的相关信息,这时我们就得主动通知系统扫描新的媒体文件了。我整理了一个扫描的工具类,分享下。
具体代码:
public class MediaScanner { private volatile static MediaScanner instance; private MediaScanner(){ } public static MediaScanner getInstace(){ synchronized (MediaScanner.class){ if(instance == null){ instance = new MediaScanner(); } } return instance; } /** * 扫描一个媒体文件 * @param filePath 要扫描的媒体文件 */ public void scanFile(Context context, ScanFile filePath) { List<ScanFile> filePaths = new ArrayList<ScanFile>(1); filePaths.add(filePath); scanFiles(context, filePaths); } /** * 扫描多个媒体文件 * @param filePaths 要扫描的文件列表 */ public void scanFiles(Context context, List<ScanFile> filePaths){ SannerClient client = new SannerClient(context, filePaths); client.connectAndScan(); } /** * 媒体文件扫描对象构造器 */ public static class ScanFile{ /** * 要扫描的媒体文件路劲或包含媒体文件的文件夹路径 */ public String filePaths; /** * 要扫描的媒体文件类型 eg: audio/mp3 media/* application/ogg * image/jpeg image/png video/mpeg video/3gpp * ...... */ public String mineType; public ScanFile(String filePaths, String mineType) { this.filePaths = filePaths; this.mineType = mineType; } } public class SannerClient implements MediaScannerConnection.MediaScannerConnectionClient { /** * 要扫描的文件或文件夹 */ private List<ScanFile> scanFiles = null; /** * 实际要扫描的单个文件集合 */ private List<ScanFile> filePaths = null; private MediaScannerConnection mediaScanConn; public SannerClient(Context context, List<ScanFile> scanFiles) { this.scanFiles = scanFiles; mediaScanConn = new MediaScannerConnection(context, this); } /** * 连接MediaScanner并开始扫描 */ public void connectAndScan(){ if(scanFiles != null && !scanFiles.isEmpty()){ this.filePaths = new ArrayList<ScanFile>(); //遍历取得单个文件集合 for(ScanFile sf : scanFiles){ findFile(sf); } mediaScanConn.connect(); } } private void findFile(ScanFile file){ File f = new File(file.filePaths); if(f.isFile()){ filePaths.add(file); }else{ File[] fs = f.listFiles(); if(fs != null && fs.length > 0){ for(File cf : fs){ findFile(new ScanFile(cf.getAbsolutePath(), file.mineType)); } } } } private void scanNext(){ if(filePaths != null && !filePaths.isEmpty()){ ScanFile sf = filePaths.remove(filePaths.size() - 1); mediaScanConn.scanFile(sf.filePaths, sf.mineType); }else{ mediaScanConn.disconnect(); } } @Override public void onMediaScannerConnected() { scanNext(); } @Override public void onScanCompleted(String path, Uri uri) { // TODO Auto-generated method stub scanNext(); //媒体扫描完成可以配合EventBus等消息通讯工具发出通知,也可接收Intent.ACTION_MEDIA_SCANNER_FINISHED的广播 //EventBus.getDefault().post(new EventMediaScanCompleted(path)); } } }
如果有扫描问题欢迎反馈。