Android掃描SD卡中的文件


當android的系統啟動的時候,系統會自動掃描sdcard內的多媒體文件,並把獲得的信息保存在一個系統數據庫中,以后在其他程序中如果想要訪問多媒體文件的信息,其實就是在這個數據庫中進行的,而不是直接去sdcard中取,理解了這一點以后,問題也隨着而來:如果我在開機狀態下在sdcard內增加、刪除一些多媒體文件,系統會不會自動掃描一次呢?答案是否定的,也就是說,當你改變 sdcard內的多媒體文件時,保存多媒體信息的系統數據庫文件是不會動態更新的。
  那么如何讓多媒體數據庫中的數據更新呢?我們可以采用廣播機制來實現:在應用程序中發送一個廣播,讓android系統掃描sdcard並更新多媒體數據庫 
private void scanSdCard(){
        IntentFilter intentfilter = new IntentFilter( Intent.ACTION_MEDIA_SCANNER_STARTED);
        intentfilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
        intentfilter.addDataScheme("file");
        scanSdReceiver = new ScanSdReceiver();
        registerReceiver(scanSdReceiver, intentfilter);
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
                Uri.parse("file://" + Environment.getExternalStorageDirectory().getAbsolutePath()))); }
其中ScanSdReceiver是一個自定義的廣播接收器,繼承自 BroadCastReceiver,因為android系統開始掃描sdcard以及掃描完畢時都會發送一個系統廣播來表示當前掃描的狀態,這樣我們就可以很方便通過判斷當前的掃描狀態加一些自己的邏輯操作,ScanSdReceiver的代碼如下:
public class ScanSdReceiver extends BroadcastReceiver {
 
    private AlertDialog.Builder  builder = null;
    private AlertDialog ad = null;
    private int count1;
    private int count2;
    private int count;
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (Intent.ACTION_MEDIA_SCANNER_STARTED.equals(action)){
            Cursor c1 = context.getContentResolver()
            .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    new String[]{MediaStore.Audio.Media.TITLE,
                    MediaStore.Audio.Media.DURATION,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media._ID,
                    MediaStore.Audio.Media.DISPLAY_NAME },
                    null, null, null);
            count1 = c1.getCount();
            System.out.println("count:"+count);
            builder = new AlertDialog.Builder(context);
            builder.setMessage("正在掃描存儲卡...");
            ad = builder.create();
            ad.show();
            
        }else if(Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)){
            Cursor c2 = context.getContentResolver()
            .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    new String[]{MediaStore.Audio.Media.TITLE,
                    MediaStore.Audio.Media.DURATION,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media._ID,
                    MediaStore.Audio.Media.DISPLAY_NAME },
                    null, null, null);
            count2 = c2.getCount();
            count = count2-count1;
            ad.cancel();
            if (count>=0){
                Toast.makeText(context, "共增加" +
                        count + "首歌曲", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(context, "共減少" +
                        count + "首歌曲", Toast.LENGTH_LONG).show();
            } 
        } 
    }
}

 


 
 
 
這里我們定義了兩個Cursor對象,分別用來存儲掃描前后的多媒體信息,並給出相應的提示。  
  以前有很多朋友問過我,為什么掃描以后播放列表中的數據條數沒有發生相應的改變。要實現播放列表在掃描后更新,必須重新讀取多媒體信息到Cursor中,並且重新設置adapter,最后還要調用 XXXAdapter.notifyDataSetChanged()來通知UI更新。(可以參考第一張的內容)
  上面的操作都是手動在SDCARD中添加或着刪除多媒體文件,下面介紹如何在列表中刪除SDCARD中的多媒體文件。
  在上一篇隨筆中,我們使用了系統提供的ContentProvider來查詢sdcard中的多媒體文件,我們同樣可以使用這個ContentProvider來進行刪除操作:  
private void deleteMusic(int position){
    this.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            MediaStore.Audio.Media._ID + "=" + _ids[position],
            null);
}
 
其中“多媒體文件的ID”可以從_ids數組中取得(關於_ids數組請參考第一張的內容)。這樣,我們是否就已經從SDCARD中刪除了指定_ID的多媒體文件了呢?  其實當你打開FileExplorer時會發現,原來的文件並沒有被刪除,— —!杯具,搞了半天文件還在,我第一次遇到這個問題的時候也是糾結了老半天。。。
為什么沒有被刪除,原因是上面的刪除操作只是刪除了系統多媒體數據庫中的相應記錄,而並沒有刪除SDCAED中的文件(注意:多媒體信息數據庫和SDCARD中的多媒體文件並不會自動保持同步),這個時候如果再次掃描SDCARD,你會發現剛才從播放列表中刪除的行會再次出現。
   其實要想真正的從SDCARD中刪除多媒體文件並不難,可能有朋友會想到這樣的方法:遍歷SDCARD中的多媒體文件,然后把想要刪除的文件和其他文件逐一比較,找到文件路徑,最后進行刪除。這種方法是可以實現刪除操作的,不過效率很低,如果SDCARD中的文件夾以及文件很多,也不知道要用掉多少時間。。
  在上一張中我們從多媒體數據庫中讀出來一項很重要的信息:MediaStore.Audio.Media.DATA
並且取得里面的字串並存放在了_path數組中,最終的數據格式為:/SDCARD/[子文件夾名]文件名,又了這個路徑,我們就可以很方便的從SDCARD中刪除多媒體文件了
 
private void deleteMusicFile(int position){
    File file = new File(_path[position]);
    file.delete();
}

 

同樣,刪除文件后要想播放列表同步更新,也必須執行剛才介紹的一系列操作。  

原位地址:http://www.cnblogs.com/zchajax/archive/2011/04/27/2030709.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM