1. 程式人生 > >新手mp3播放器心得(一)---- 獲取所有歌曲(遍歷檔案獲取、媒體庫獲取)

新手mp3播放器心得(一)---- 獲取所有歌曲(遍歷檔案獲取、媒體庫獲取)

(一)遍歷檔案獲取

我在一開始是想著遍歷所有檔案,然後獲取所有歌曲的路徑,而在獲取路徑前涉及到獲取記憶體卡的根路徑,下面就說一下關於獲取記憶體卡根路徑的內容

1.一部分手機將eMMC儲存掛載到 /mnt/external_sd 、/mnt/sdcard2 等節點,而將外接的SD卡掛載到 Environment.getExternalStorageDirectory()這個結點。
此時,呼叫Environment.getExternalStorageDirectory(),則返回外接的SD的路徑。
2.而另一部分手機直接將eMMC儲存掛載在Environment.getExternalStorageDirectory()這個節點,而將真正的外接SD卡掛載到/mnt/external_sd、/mnt/sdcard2 等節點。


此時,呼叫Environment.getExternalStorageDirectory(),則返回內建的SD的路徑。

所以通過百度後,就寫了這個方法

 /**
     * 獲取所有儲存裝置的路徑
     * @return  所有儲存裝置的路徑
     */
    public List<String> getAllStoragePath()
    {
    	boolean isSame = false;
    	StorageManager sm = (StorageManager)this.getSystemService(Context.STORAGE_SERVICE);
    	List<String> list = new ArrayList<String>();//用來儲存記憶體卡路徑
    	//獲取內建記憶體卡路徑
		String enPath = Environment.getExternalStorageDirectory().getPath();
    	try {
    		//獲取所有外接記憶體裝置的路徑,包括外接記憶體卡,OTG
    		String[] paths = (String[])sm.getClass()
    				.getMethod("getVolumePaths", null).invoke(sm, null);
    		if(null != paths && paths.length != 0){
    			
    			for (int i = 0; i < paths.length; i++) {
    				//檢測路徑是否與內建記憶體卡路徑相同
    				if(enPath.equals(paths[i])){
    					isSame = true;
    				}
					list.add(paths[i]);
				}
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	//如果沒有相同的路徑就把內建記憶體卡路徑的新增進去
		if(isSame == false){
			list.add(enPath);
		}
        return list;
    }
下面上完整程式碼
package com.example.getallmusic;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.storage.StorageManager;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {

	/**
	 *  歌曲路徑集合
	 */
	private List<String> musicPathList = new ArrayList<String>();
	
	/**
	 *  所有記憶體卡路徑陣列
	 */
	private List<String> allSDCardPaths;

	
	
	private TextView allPath;//顯示所有記憶體卡路徑
	private TextView allMusic;//顯示總歌曲數目
	
	
	/**
	 * 監聽耗時操作
	 */
	private ProgressDialog progress;
	//處理耗時操作
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			progress.dismiss();
			if(null != musicPathList && musicPathList.size() != 0){
	    		String str = allMusic.getText().toString();
	    		allMusic.setText(str+musicPathList.size());
	    	}else{
	    		String str = allMusic.getText().toString();
	    		allMusic.setText(str+"無歌曲");
	    	}
		}
	};
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        allPath = (TextView) findViewById(R.id.tv_allpath);
		allMusic = (TextView) findViewById(R.id.tv_allmusic);
		
    }
    /**
     * 顯示所有記憶體卡路徑 button的onClick方法
     * @param v
     */
    public void button1(View v){
    	String SDPathStr = null;
 		allSDCardPaths = getAllStoragePath();
 		if(allSDCardPaths != null){
 			for (int i = 0; i < allSDCardPaths.size(); i++) {
 				SDPathStr = allSDCardPaths.get(i);
 				String str = allPath.getText().toString();
 				allPath.setText(str+"\n"+SDPathStr);
 			}
 		}else{
 			allPath.setText("無記憶體卡");
 		}
    }

    
    /**
     * 顯示所有歌曲 button的onClick方法
     * @param v
     */
    public void button2(View v){
    	progress = ProgressDialog.show(this, null, "查詢歌曲中……");
    	//查詢歌曲為耗時操作,必須在子執行緒中操作
    	new Thread(new Runnable() {
    		@Override
    		public void run() {
    			//將所有記憶體卡路徑中的歌曲找出
    			for (int i = 0; i < allSDCardPaths.size(); i++) {
    	    		getAllMusicPath(allSDCardPaths.get(i));
    			}
    			handler.sendEmptyMessage(0);
    		}
    	}).start();
    	
    }

    /**
     * 獲取所有儲存裝置的路徑
     * @return  所有儲存裝置的路徑
     */
    public List<String> getAllStoragePath()
    {
    	boolean isSame = false;
    	StorageManager sm = (StorageManager)this.getSystemService(Context.STORAGE_SERVICE);
    	List<String> list = new ArrayList<String>();//用來儲存記憶體卡路徑
    	//獲取內建記憶體卡路徑
		String enPath = Environment.getExternalStorageDirectory().getPath();
    	try {
    		//獲取所有外接記憶體裝置的路徑,包括外接記憶體卡,OTG
    		String[] paths = (String[])sm.getClass()
    				.getMethod("getVolumePaths", null).invoke(sm, null);
    		if(null != paths && paths.length != 0){
    			
    			for (int i = 0; i < paths.length; i++) {
    				//檢測路徑是否與內建記憶體卡路徑相同
    				if(enPath.equals(paths[i])){
    					isSame = true;
    				}
					list.add(paths[i]);
				}
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	//如果沒有相同的路徑就把內建記憶體卡路徑的新增進去
		if(isSame == false){
			list.add(enPath);
		}
        return list;
    }
    
    
    /** 通過檔案路徑獲取檔案中所有歌曲的路徑 */
	public void getAllMusicPath(String filePath) {
		
		File file = new File(filePath);
		//如果路徑不存在
		if(file == null){
			return;
		}
		//獲取該目錄下所有檔案
		File[] files = file.listFiles();

		if(files != null){
			// 將該目錄下所有歌曲路徑加入musicPathList中
			for (int i = 0; i < files.length; i++) {
				File f = files[i];
				//如果該檔案為MP3,則儲存歌曲路徑
				if(f.getName().endsWith(".mp3")){
					musicPathList.add(f.getPath());
				}
				if (f.isDirectory()) {
<span style="white-space:pre">					</span>//通過遞迴獲取該檔案路徑下的歌曲檔案路徑
<span style="white-space:pre">					</span>getAllMusicPath(f.getPath());
<span style="white-space:pre">				</span>}
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
}
(二)媒體庫獲取在遍歷檔案獲取歌曲後,發現只能獲取歌曲路徑,還需要自己計算時長,處理路徑名稱,還需要獲得歌手名字和專輯圖片,所以上面的方法是行不通的。所以通過檢視文件和百度,發現可以通過媒體庫來獲取所有歌曲,MediaPlayer在每次開機和記憶體卡拔插後,都會重新掃描檔案,所以很方便,不多說直接上程式碼
package com.example.getallmusic;

/**
 * 歌曲資訊實體類
 * @author Administrator
 *
 */
public class MusicInfo {

	/** 歌曲id */
	private int musicId;
	
	/** 歌曲名 */
	private String musicName;
	
	/** 歌曲演唱者 */
	private String musicArtist;
	
	/** 歌曲地址 */
	private String musicPath;
	
	/** 歌曲時間長度 */
	private int musicLong;
	
	
	

	public MusicInfo() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	

	public MusicInfo(int musicId, String musicName, String musicArtist,
			String musicPath, int musicLong) {
		super();
		this.musicId = musicId;
		this.musicName = musicName;
		this.musicArtist = musicArtist;
		this.musicPath = musicPath;
		this.musicLong = musicLong;
	}



	public int getMusicId() {
		return musicId;
	}

	public void setMusicId(int musicId) {
		this.musicId = musicId;
	}

	public String getMusicName() {
		return musicName;
	}

	public void setMusicName(String musicName) {
		this.musicName = musicName;
	}

	public String getMusicArtist() {
		return musicArtist;
	}

	public void setMusicArtist(String musicArtist) {
		this.musicArtist = musicArtist;
	}

	public String getMusicPath() {
		return musicPath;
	}

	public void setMusicPath(String musicPath) {
		this.musicPath = musicPath;
	}

	public int getMusicLong() {
		return musicLong;
	}

	public void setMusicLong(int misicLong) {
		this.musicLong = misicLong;
	}
	
	
}
<pre name="code" class="java">package com.example.getallmusic;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.ProgressDialog;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.View;
import android.widget.TextView;

public class MainActivity2 extends Activity {


	
	/**  全部歌曲  */
	private List<MusicInfo> list;
	
	private TextView allMusic;//顯示總歌曲數目
	
	
	/**
	 * 監聽耗時操作
	 */
	private ProgressDialog progress;
	//處理耗時操作
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			progress.dismiss();
			String str = allMusic.getText().toString();
			allMusic.setText(str+list.size());
		}
	};	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
		allMusic = (TextView) findViewById(R.id.tv_allmusic);
		
    }
    /**
     * 顯示所有記憶體卡路徑 button的onClick方法
     * @param v
     */
    public void button1(View v){
    }

    
    /**
     * 顯示所有歌曲 button的onClick方法
     * @param v
     */
    public void button2(View v){
    	progress = ProgressDialog.show(this, null, "查詢歌曲中……");
    	//查詢歌曲為耗時操作,必須在子執行緒中操作
    	new Thread(new Runnable() {
    		@Override
    		public void run() {
    			list = scanAllAudioFiles();
    			handler.sendEmptyMessage(0);
    		}
    	}).start();
    	
    }

    /** 獲取媒體庫中所有歌曲 */
	public ArrayList<MusicInfo> scanAllAudioFiles() {
		// 生成動態陣列,並且轉載資料
		ArrayList<MusicInfo> mylist = new ArrayList<MusicInfo>();

		// 查詢媒體資料庫
		Cursor cursor = getContentResolver().query(
				MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
				MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
		// 遍歷媒體資料庫
		if (cursor.moveToFirst()) {//判斷遊標是否為空

			MusicInfo info;
			int musicId;//歌曲id
			String musicName;//歌曲名
			String musicArtist;//音樂家
			int musicTime;//歌曲時長
			String musicPath;//歌曲路徑
			while (!cursor.isAfterLast()) {//遊標是否指向第最後一行的位置
				
				// 歌曲編號 :MediaStore.Audio.Media._ID
				musicId = cursor.getInt(cursor
						.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
				// 歌曲名: MediaStore.Audio.Media.TITLE
				musicName = cursor.getString(cursor
						.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
				
				// 音樂家: MediaStore.Audio.Media.ARTIST
				musicArtist = cursor.getString(cursor
						.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
				// 歌曲檔案的路徑 :MediaStore.Audio.Media.DATA
				musicPath = cursor.getString(cursor
						.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
				// 歌曲的總播放時長 :MediaStore.Audio.Media.DURATION
				musicTime = cursor
						.getInt(cursor
								.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
				// 歌曲檔案的大小 :MediaStore.Audio.Media.SIZE
				Long size = cursor.getLong(cursor
						.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));

				if (size > 1024 * 800) {// 大於800K的音樂檔案
					info = new MusicInfo();
					info.setMusicId(musicId);
					info.setMusicName(musicName);
					info.setMusicArtist(musicArtist);
					info.setMusicPath(musicPath);
					info.setMusicLong(musicTime);
					mylist.add(info);
				}
				cursor.moveToNext();//遊標移動到下一行
			}
		}
		cursor.close();
		return mylist;
	}
}
</pre><pre name="code" class="java">下面是佈局檔案
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="button1"
        android:text="顯示所有記憶體卡路徑" />


    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="button2"
        android:text="顯示所有歌曲" />


    <TextView
        android:id="@+id/tv_allpath"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:text="記憶體卡路徑有:" />


    <TextView
        android:id="@+id/tv_allmusic"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:text="歌曲共有:" />


</LinearLayout>