編輯:關於Android編程
以前寫過很多次音樂播放器,但是總有一些問題出現,例如:
1,音樂長時間播放問題(即便是放在service中去播放,依然會被殺死);
2,音樂的播放進度如何掌握?(如何利用mediaplayer.getCurrentPosition()來有效的通知界面變更進度?);
3,在我以往的經驗中,音樂播放完畢下一曲時候,經常出現當前音樂播放還差幾秒鐘的時候就下一曲了的情況。
從網上找到教程中,通常都是一個播放器的demo,簡單的直接把MediaPlayer放在了一個Activity中去操作,稍有良心的教程把MediaPlayer放在了Servic中,但是這是遠遠不夠的。
最好的教程還是谷歌官方的Training和API Guides,盡管很久以前就簡單粗暴的讀過有關service的文檔,但是,古人都說溫故而知新嘛,經過這次溫故,對比以前的代碼經驗,覺得可以有更好的方式來實現一個音樂播放器。遂決定重新寫一個音樂播放器。
如果有大神有更好 方案,還望知會我。
注意:這篇文章,不適合對MediaPlayer不了解的同學,假定看這篇文章的,都是已經會初步使用Service的同學。
一,音樂列表的讀取。
關於音樂列表的讀取,不同的音樂播放器都會有不同的方案,有的是有多重方案並用。例如說,全盤掃描音樂格式文件等,但是Android本身有媒體庫,可以讀取本地媒體庫的數據,來快速獲知設備上的音樂。
首先我封裝了一個Audio類來存儲讀取的音頻信息。
public class Audio {
private String mTitle,
mTitleKey,
mArtist,
mArtistKey,
mComposer,
mAlbum,
mAlbumKey,
mDisplayName,
mMimeType,
mPath;
private int mId,
mArtistId,
mAlbumId,
mYear,
mTrack;
private int mDuration = 0,
mSize = 0;
private boolean isRingtone = false,
isPodcast = false,
isAlarm = false,
isMusic = false,
isNotification = false;
public Audio (Bundle bundle) {
mId = bundle.getInt(MediaStore.Audio.Media._ID);
mTitle = bundle.getString(MediaStore.Audio.Media.TITLE);
mTitleKey = bundle.getString(MediaStore.Audio.Media.TITLE_KEY);
mArtist = bundle.getString(MediaStore.Audio.Media.ARTIST);
mArtistKey = bundle.getString(MediaStore.Audio.Media.ARTIST_KEY);
mComposer = bundle.getString(MediaStore.Audio.Media.COMPOSER);
mAlbum = bundle.getString(MediaStore.Audio.Media.ALBUM);
mAlbumKey = bundle.getString(MediaStore.Audio.Media.ALBUM_KEY);
mDisplayName = bundle.getString(MediaStore.Audio.Media.DISPLAY_NAME);
mYear = bundle.getInt(MediaStore.Audio.Media.YEAR);
mMimeType = bundle.getString(MediaStore.Audio.Media.MIME_TYPE);
mPath = bundle.getString(MediaStore.Audio.Media.DATA);
mArtistId = bundle.getInt(MediaStore.Audio.Media.ARTIST_ID);
mAlbumId = bundle.getInt(MediaStore.Audio.Media.ALBUM_ID);
mTrack = bundle.getInt(MediaStore.Audio.Media.TRACK);
mDuration = bundle.getInt(MediaStore.Audio.Media.DURATION);
mSize = bundle.getInt(MediaStore.Audio.Media.SIZE);
isRingtone = bundle.getInt(MediaStore.Audio.Media.IS_RINGTONE) == 1;
isPodcast = bundle.getInt(MediaStore.Audio.Media.IS_PODCAST) == 1;
isAlarm = bundle.getInt(MediaStore.Audio.Media.IS_ALARM) == 1;
isMusic = bundle.getInt(MediaStore.Audio.Media.IS_MUSIC) == 1;
isNotification = bundle.getInt(MediaStore.Audio.Media.IS_NOTIFICATION) == 1;
}
public int getId() {
return mId;
}
public String getMimeType () {
return mMimeType;
}
public int getDuration () {
return mDuration;
}
public int getSize () {
return mSize;
}
public boolean isRingtone () {
return isRingtone;
}
public boolean isPodcast () {
return isPodcast;
}
public boolean isAlarm () {
return isAlarm;
}
public boolean isMusic () {
return isMusic;
}
public boolean isNotification () {
return isNotification;
}
public String getTitle () {
return mTitle;
}
public String getTitleKey () {
return mTitleKey;
}
public String getArtist () {
return mArtist;
}
public int getArtistId () {
return mArtistId;
}
public String getArtistKey () {
return mArtistKey;
}
public String getComposer () {
return mComposer;
}
public String getAlbum () {
return mAlbum;
}
public int getAlbumId () {
return mAlbumId;
}
public String getAlbumKey () {
return mAlbumKey;
}
public String getDisplayName () {
return mDisplayName;
}
public int getYear () {
return mYear;
}
public int getTrack () {
return mTrack;
}
public String getPath () {
return mPath;
}
}
以上類來封裝音樂媒體信息,一些變量看名字也能看出來是什麼,例如說title,duration此類,無非就是歌曲名稱,時長之類的信息,有些變量名字單詞認識,但是並不知道干什麼用,其實我也不知道是什麼信息,雖然打印出來過,但是並不懂到底哪裡能用到,反正一股腦都讀出來了先,以後再打印輸出看看都是些什麼。
其次,一個讀取媒體音頻的方法:
public class MediaUtils {
public static final String[] AUDIO_KEYS = new String[]{
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.TITLE_KEY,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ARTIST_ID,
MediaStore.Audio.Media.ARTIST_KEY,
MediaStore.Audio.Media.COMPOSER,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.ALBUM_KEY,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.SIZE,
MediaStore.Audio.Media.YEAR,
MediaStore.Audio.Media.TRACK,
MediaStore.Audio.Media.IS_RINGTONE,
MediaStore.Audio.Media.IS_PODCAST,
MediaStore.Audio.Media.IS_ALARM,
MediaStore.Audio.Media.IS_MUSIC,
MediaStore.Audio.Media.IS_NOTIFICATION,
MediaStore.Audio.Media.MIME_TYPE,
MediaStore.Audio.Media.DATA
};
public static List getAudioList(Context context) {
List audioList = new ArrayList();
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
AUDIO_KEYS,
null,
null,
null);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
Bundle bundle = new Bundle ();
for (int i = 0; i < AUDIO_KEYS.length; i++) {
final String key = AUDIO_KEYS[i];
final int columnIndex = cursor.getColumnIndex(key);
final int type = cursor.getType(columnIndex);
switch (type) {
case Cursor.FIELD_TYPE_BLOB:
break;
case Cursor.FIELD_TYPE_FLOAT:
float floatValue = cursor.getFloat(columnIndex);
bundle.putFloat(key, floatValue);
break;
case Cursor.FIELD_TYPE_INTEGER:
int intValue = cursor.getInt(columnIndex);
bundle.putInt(key, intValue);
break;
case Cursor.FIELD_TYPE_NULL:
break;
case Cursor.FIELD_TYPE_STRING:
String strValue = cursor.getString(columnIndex);
bundle.putString(key, strValue);
break;
}
}
Audio audio = new Audio (bundle);
audioList.add(audio);
}
cursor.close();
return audioList;
}
}
如此返回一個Audio的List,現在我們可以用這個List做一個列表展示。

android private libraries 中的包源代碼添加方法
先上圖:這裡以添加 afinal_0.5.1_bin.jar 為例。第一步:添加jar包到libs裡面,系統自動把jar加載到android private librar
java/android 設計模式學習筆記(2)---觀察者模式
這篇來講一下觀察者模式,觀察者模式在實際項目中使用的也是非常頻繁的,它最常用的地方是GUI系統、訂閱——發布系統等。因為這個模式的一個重要作用就是
Android與JS之間跨平台異步調用實例詳解
Android與JS之間跨平台異步調用 為什麼突然要搞這個問題呢? 在開發浏覽器的時候遇到這個狗血的問題,花了將近1天的時間才想到這個解決方案,Androi
android代碼簽名和混淆打包
研究了一下android的apk的簽名和代碼的混淆打包,如果不混淆打包,那麼apk可以直接被人反編譯出來查看源碼,混淆打包雖然還是能看懂,但是沒有那麼好懂了,至少要話費些