新手mp3播放器心得(一)---- 獲取所有歌曲(遍歷檔案獲取、媒體庫獲取)
阿新 • • 發佈:2019-02-01
(一)遍歷檔案獲取
我在一開始是想著遍歷所有檔案,然後獲取所有歌曲的路徑,而在獲取路徑前涉及到獲取記憶體卡的根路徑,下面就說一下關於獲取記憶體卡根路徑的內容
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; }
(二)媒體庫獲取在遍歷檔案獲取歌曲後,發現只能獲取歌曲路徑,還需要自己計算時長,處理路徑名稱,還需要獲得歌手名字和專輯圖片,所以上面的方法是行不通的。所以通過檢視文件和百度,發現可以通過媒體庫來獲取所有歌曲,MediaPlayer在每次開機和記憶體卡拔插後,都會重新掃描檔案,所以很方便,不多說直接上程式碼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>} }
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>