MediaScanner 分析


MediaScanner

之所以拿MediaScanner開刀 因爲想借用系統的Media Scan 工具  通過Intent直接調用系統的

[步驟]

1. 下載並安裝Git 過程略 網絡上很多

2. 得到該功能的模塊地址並使用Git下載之   地址:git://android.git.kernel.org/platform/packages/providers/MediaProvider.git

3.  分析源代碼:

- AndroidManifest.xml :  各組件屬性描述文件

- MediaProvider : extends ContentProvider  使用SQLiteDatabase 保存查詢數據 action="content://media"

- MediaScannerCursor.java

- MediaScannerReceiver : extends BroadcastReceiver   用於接收指定Broadcast: BOOT_COMPLETED MEDIA_MOUNTED MEDIA_SCANNER_SCAN_FILE 並啓動 MediaScannerService 開始掃描

- MediaScannerService : extends Service   執行具體的掃描工作

- MediaThumbRequest

4. 鑑於 並不打算自行實現多媒體掃描 因此 此次重點研究對象:MediaScannerReceiver

5. MediaScannerReceiver 代碼

Java代碼 
  1. public class MediaScannerReceiver extends BroadcastReceiver  
  2. {  
  3.     private final static String TAG = "MediaScannerReceiver";  
  4.   
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         String action = intent.getAction();  
  8.         Uri uri = intent.getData();  
  9.         String externalStoragePath = Environment.getExternalStorageDirectory().getPath();  
  10.   
  11.         if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {  
  12.             // scan internal storage  
  13.             scan(context, MediaProvider.INTERNAL_VOLUME);  
  14.         } else {  
  15.             if (uri.getScheme().equals("file")) {  
  16.                 // handle intents related to external storage  
  17.                 String path = uri.getPath();  
  18.                 if (action.equals(Intent.ACTION_MEDIA_MOUNTED) &&   
  19.                         externalStoragePath.equals(path)) {  
  20.                     scan(context, MediaProvider.EXTERNAL_VOLUME);  
  21.                 } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&  
  22.                         path != null && path.startsWith(externalStoragePath + "/")) {  
  23.                     scanFile(context, path);  
  24.                 }  
  25.             }  
  26.         }  
  27.     }  
  28.   
  29.     private void scan(Context context, String volume) {  
  30.         Bundle args = new Bundle();  
  31.         args.putString("volume", volume);  
  32.         context.startService(  
  33.                 new Intent(context, MediaScannerService.class).putExtras(args));  
  34.     }      
  35.   
  36.     private void scanFile(Context context, String path) {  
  37.         Bundle args = new Bundle();  
  38.         args.putString("filepath", path);  
  39.         context.startService(  
  40.                 new Intent(context, MediaScannerService.class).putExtras(args));  
  41.     }      
  42. }  

6.   根據以上代碼得知:

-  當系統啓動完畢 會掃描一次

-  當 ACTION_MEDIA_MOUNTED ACTION_MEDIA_SCANNER_SCAN_FILE 也會掃描

7.  如何調用系統MediaScanner 進行掃描

- 通過 Intent.ACTION_MEDIA_MOUNTED 進行全掃描

Java代碼 
  1. public void allScan(){  
  2.         sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"  
  3.                 + Environment.getExternalStorageDirectory())));  
  4.     }  

-  通過 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE 掃描某個文件 

Java代碼 
  1. public void fileScan(String fName){  
  2.         Uri data = Uri.parse("file:///"+fName);  
  3.         sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, data));  
  4.     }  

補充: 上述方法是不支持對文件夾的 即:Uri data 必須是 文件的Uri  如果是文件夾的 其不會起作用的 切記!

- 如何掃描某文件夾下所有文件 難道就不可以麼? 當然不 藉助於Intent.ACTION_MEDIA_SCANNER_SCAN_FILE 

我們可以這麼做: 取出該文件夾下的所有子文件 如其是文件且類型符合條件 就取出該文件目錄 以 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE方式發送至MediaScannerReceiver   若其爲文件夾 則迭代查詢之    故實現爲:

Java代碼 
  1. public void fileScan(String file){  
  2.         Uri data = Uri.parse("file://"+file);  
  3.           
  4.         Log.d("TAG","file:"+file);  
  5.         sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, data));  
  6.     }  
  7.       
  8.     public void folderScan(String path){  
  9.         File file = new File(path);  
  10.           
  11.         if(file.isDirectory()){  
  12.             File[] array = file.listFiles();  
  13.               
  14.             for(int i=0;i<array.length;i++){  
  15.                 File f = array[i];  
  16.                   
  17.                 if(f.isFile()){//FILE TYPE  
  18.                     String name = f.getName();  
  19.                       
  20.                     if(name.contains(".mp3")){  
  21.                         fileScan(f.getAbsolutePath());  
  22.                     }  
  23.                 }  
  24.                 else {//FOLDER TYPE  
  25.                     folderScan(f.getAbsolutePath());  
  26.                 }  
  27.             }  
  28.         }  
  29.     }  

8. 鑑於多數人並不關心其原理 僅關係如何使用 故 總結如下:

-   掃描全部 我猜測其在效率方面可能有點副作用

Java代碼 
  1. public void systemScan(){  
  2.         sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"  
  3.                 + Environment.getExternalStorageDirectory())));  
  4.     }  

-  掃描某個文件  參數:填入該文件的路徑

Java代碼 
  1. public void fileScan(String file){  
  2.         Uri data = Uri.parse("file://"+file);  
  3.           
  4.         sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, data));  
  5.     }  

- 掃描文件夾 參數:填入該文件夾路徑

Java代碼 
  1. public void fileScan(String file){  
  2.         Uri data = Uri.parse("file://"+file);  
  3.           
  4.         sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, data));  
  5.     }  
  6.       
  7.     public void folderScan(String path){  
  8.         File file = new File(path);  
  9.           
  10.         if(file.isDirectory()){  
  11.             File[] array = file.listFiles();  
  12.               
  13.             for(int i=0;i<array.length;i++){  
  14.                 File f = array[i];  
  15.                   
  16.                 if(f.isFile()){//FILE TYPE  
  17.                     String name = f.getName();  
  18.                       
  19.                     if(name.contains(".mp3")){  
  20.                         fileScan(f.getAbsolutePath());  
  21.                     }  
  22.                 }  
  23.                 else {//FOLDER TYPE  
  24.                     folderScan(f.getAbsolutePath());  
  25.                 }  
  26.             }  
  27.         }  
  28.     } 


原文地址:   http://griffinshi.javaeye.com/blog/697492


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章