最近做了一個android音樂播放器,個人感覺最難的就是“後台播放”以及有關“播放清單”的部分,但是總算是找到了實現的方式。不同的人實現的方式可能不一樣,這裡我就分享一下自己對“播放清單”這個模組的一些實現方法,“後台播放”會在下一篇博文中進行介紹,希望大家也能分享一下自己的一些思路。
android使用ContentProvider來支援不同應用程式的資料共用,為了方便其他應用程式對sdcard中的資料進行操作,sdcard也提供了ContentProvider介面,這裡就以訪問音頻檔案為例,視頻以及圖片的操作也類似,這裡就不在贅述。
訪問sdcard中的音頻檔案的URI為MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,為了使播放清單顯示所以音樂檔案的資訊,這裡需要查詢sdcard裡的音頻檔案,並把查詢到的資訊儲存在Cursor中,具體代碼如下:
Cursor c = this.getContentResolver().
query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
/*這個字串數組表示要查詢的列*/
new String[]{MediaStore.Video.Media.TITLE,//音樂名MediaStore.Audio.Media.DURATION,//音樂的總時間MediaStore.Audio.Media.ARTIST,//藝術家MediaStore.Audio.Media._ID,//id號MediaStore.Audio.Media.DISPLAY_NAME,//音樂檔案名稱MediaStore.Audio.Media.DATA //音樂檔案的路徑}, null, //查詢條件,相當於sql中的where語句null, //查詢條件中使用到的資料null); //查詢結果的排序方式
通過MediaStore.Audio.Media.XXX來訪問音樂檔案的一些資訊,這裡只列出了一部分,可以根據需要進行增添和刪除。
至此,Cursor c就已經儲存了sdcard內所以音頻檔案的資訊,下面的操作就是圍繞這個Cursor展開的。
首先定義三個數組:
private int[] _ids; //存放音樂檔案的id數組private String[] _titles; //存放音樂檔案的標題數組private String[] _path; //存放音樂檔案的路徑
_ids儲存了所有音樂檔案的_ID,用來確定到底要播放哪一首歌曲,_titles存放音樂名,用來顯示在播放介面,而_path存
放音樂檔案的路徑(刪除檔案時會用到)。
接下來再定義一個變數,用來定位選擇的是哪一首音樂:
private int pos;
接下來將音樂檔案的資訊存放在相應的數組中:
c.moveToFirst();_ids = new int[c.getCount()];_titles = new String[c.getCount()];_path = new String[c.getCount()];for(int i=0;i<c.getCount();i++){_ids[i] = c.getInt(3); _titles[i] = c.getString(0);_path[i] = c.getString(5).substring(4);c.moveToNext();}
有人可能會問為什麼擷取路徑的格式是_path[i]=c.geString(5).substring(4)?因為MediaStore.Audio.Media.DATA
得到的內容格式為/mnt/sdcard/[子檔案夾名/]音樂檔案名稱,而我們想要得到的是/sdcard/[子檔案夾名]音樂檔案名稱,
所以要做相應的裁剪操作。
接下來把Cursor中的資訊顯示到listview中:
MusicListAdapter adapter = new MusicListAdapter(this, c);listview.setAdapter(adapter);
MusicListAdapter是一個自訂的Adapter,繼承自BaseAdapter,這裡只貼出代碼,不做講解。
package com.alex.video;import android.content.Context;import android.database.Cursor;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;public class MusicListAdapter extends BaseAdapter{private Context myCon;private Cursor myCur;private int pos=-1;public MusicListAdapter(Context con,Cursor cur){this.myCon = con;this.myCur = cur;}@Overridepublic int getCount() {return this.myCur.getCount();}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {convertView = LayoutInflater.from(myCon).inflate(R.layout.musiclist,null);myCur.moveToPosition(position);TextView videoTitle = (TextView)convertView.findViewById(R.id.musictitle);if (myCur.getString(0).length()>24){try {String musicTitle = bSubstring(myCur.getString(0).trim(),24);videoTitle.setText(musicTitle);} catch (Exception e) {e.printStackTrace();}}else {videoTitle.setText(myCur.getString(0).trim());}TextView videoArtist = (TextView)convertView.findViewById(R.id.musicartist);if (myCur.getString(2).equals("<unknown>")){videoArtist.setText("未知藝術家");}else{videoArtist.setText(myCur.getString(2));}TextView videoTime = (TextView)convertView.findViewById(R.id.musictime);videoTime.setText(toTime(myCur.getInt(1)));ImageView videoItem = (ImageView)convertView.findViewById(R.id.musicitem);videoItem.setImageResource(R.drawable.item);return convertView;}/*時間格式轉換*/public String toTime(int time) {time /= 1000;int minute = time / 60;int hour = minute / 60;int second = time % 60;minute %= 60;return String.format("%02d:%02d", minute, second);}/*字串裁剪*/public static String bSubstring(String s, int length) throws Exception { byte[] bytes = s.getBytes("Unicode"); int n = 0; // 表示當前的位元組數 int i = 2; // 要截取的位元組數,從第3個位元組開始 for (; i < bytes.length && n < length; i++) { // 奇數位置,如3、5、7等,為UCS2編碼中兩個位元組的第二個位元組 if (i % 2 == 1) { n++; // 在UCS2第二個位元組時n加1 } else { // 當UCS2編碼的第一個位元組不等於0時,該UCS2字元為漢字,一個漢字算兩個位元組 if (bytes[i] != 0) { n++; } } } // 如果i為奇數時,處理成偶數 if (i % 2 == 1) { // 該UCS2字元是漢字時,去掉這個截一半的漢字 if (bytes[i - 1] != 0) i = i - 1; // 該UCS2字元是字母或數字,則保留該字元 else i = i + 1; } return new String(bytes, 0, i, "Unicode"); } }
這樣,音樂的資訊就顯示在了列表中了
下一節將講解更新列表的操作。