Android中,SD卡上的媒體文件(圖片、視頻)的改變與通知

MediaProvider相當於一個數據中心,SD卡上所有的數據在這裏都有記錄,而Gallery的什用就是展示和操作這個數據中心,每次用戶啓動Gallery時,Gallery只是讀取MediaProvider裏面的記錄並顯示用戶。如果用戶在Gallery裏刪除一個媒體時,Gallery通過調用MediaProvider開放的接口來實現。

MediaProvider和Gallery的大致關係就是這樣的了。我現在碰到的問題要解決的話,必須要搞清楚一件事才能繼續往下走:

因爲Gallery啓動時是不會給MediaProvider發送命令讓它掃描全盤的。那麼,當SD卡上的數據有更新時(比如通過藍牙接收一個媒體、從網上下載一個媒體、刪除一個媒體等操作),MediaProvider如何知道這些變化然後更新自己的數據庫的呢?

在這裏不考慮用戶通過PC上的USB傳輸到SD卡上的問題。因爲SD卡重新掛載時,MediaProvider會自動掃描SD卡上的媒體來更新媒體數據庫的。

 

那麼只有一個答案了,誰更新了SD卡上的媒體,誰通知MediaProvider把更新了的媒體同步到MediaProvider的媒體數據庫中。有兩種方式,恰好藍牙和下載器分別使用了這兩種方式,這裏就以它們兩個程序來說明一下。

 

1、MediaScannerConnection,藍牙傳輸文件時就是用的這種方式,每當接收到新的媒體文件,都會通過這種方式告訴MediaProvider同步媒體數據庫。

建立連接

mConnection = new MediaScannerConnection(mContext, this);

因爲建立連接是一個異步過程,所以,在建立連接時需要加入一個監聽器。這樣,連接建立後就可以得到通知,並進行下一步。

 

更新媒體數據庫

mConnection.scanFile(mInfo.mFilename, mInfo.mMimetype);

這也是一個異步過程,更新完畢後,監聽器中得到通知,並斷開連接。

 

斷開連接

mConnection.disconnect();

 

詳細代碼參考/packages/apps/Bluetooth下面BluetoothOppService.java中的MediaScannerNotifier這個類。

 

 

2、MediaScannerService,下載器DownloadProvider就是用的這種方式,當一個媒體文件下載完成後,直接綁定到MediaScannerService上,並調用mMediaScannerService.scanFile(info.mFileName, info.mMimeType);

這種方式比起上面的方式來,有兩個缺點:

1、無法設置監聽器。

2、scanFile本身是同步方法,掃描完成後纔會返回,因此需要自己開一個新的線程來調用。

 

詳細代碼可以參考/packages/providers/DownloadProvider中DownloadService.java

 

 

任何一個應用程序,如果會更新SD卡上的媒體的話,都要記得使用上面兩種方式中的一種來通知MediaProvider更新數據庫。否則的話,用戶打開Gallery是看不到我們的更新的。

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