(一)遍历文件获取
我在一开始是想着遍历所有文件,然后获取所有歌曲的路径,而在获取路径前涉及到获取内存卡的根路径,下面就说一下关于获取内存卡根路径的内容
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>