項目中可能有這樣的需求:下載或導入、導出的圖片、音樂等媒體文件,需要馬上能在圖庫或本地視屏播放器中顯示出來,或者要能在媒體數據庫中查詢到媒體文件的相關信息,這時我們就得主動通知系統掃描新的媒體文件了。我整理了一個掃描的工具類,分享下。
具體代碼:
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)); } } }
如果有掃描問題歡迎反饋。