Mediaplayer實現音樂播放器,支援後臺播放
mediaplayer是Android開發中常見的播放音訊檔案的類。這個demo主要實現掃描本地的mp3音訊檔案並支援後臺播放,廢話不多說,直接上程式碼
1,佈局檔案:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.activity.MusicActivity"
android:fitsSystemWindows="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#2aa0fa"
android:padding="10dp">
<TextView
android:id="@+id/tv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/back"
android:drawablePadding="6dp"
android:text="返回"
android:textColor="#fff"
android:textSize="22sp"/>
</RelativeLayout>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:layout_gravity="center_vertical"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#2aa0fa">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="3"
android:orientation="vertical"
android:layout_height="match_parent">
<TextView
android:textSize="16sp"
android:text="帶你去旅行"
android:singleLine="true"
android:textColor="#fff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:marqueeRepeatLimit="marquee_forever"
android:ellipsize="marquee"
android:scrollHorizontally="true"
android:focusableInTouchMode="true"
android:focusable="true"
android:id="@+id/playSong"/>
<TextView
android:id="@+id/playName"
android:textSize="14sp"
android:textColor="#f0f0f0"
android:text="校長"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView
android:paddingLeft="10dp"
android:id="@+id/preview"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:src="@drawable/ic_skip_previous_white_48dp"/>
<ImageView
android:id="@+id/pause"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:src="@drawable/uamp_ic_pause_white_48dp"
android:layout_centerInParent="true"/>
<ImageView
android:id="@+id/next"
android:layout_weight="2"
android:paddingRight="10dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/ic_skip_next_white_48dp"
android:layout_alignParentRight="true"/>
</LinearLayout>
</LinearLayout>
2,播放的類musicactivity
public class MusicActivity extends Activity implements AdapterView.OnItemClickListener, View.OnClickListener {
private static final String TAG = MusicActivity.class.getName();
private bindServiceConn mConn;
private ListView mListView;
private static TextView mPlaySong;
private static TextView mPlayName;
private static ImageView mPause;
private static Bitmap mPauseBitmap;
private static Bitmap mPlayBitmap;
private static ArrayList<SongBean> mList;
private IMusicService mService;
private int mCurrentPosition = -1;
public static final int PLAY_MUSIC = 1;
public static final int PAUSE_MUSIC = 2;
public static final int PREVIOUS_MUSIC = 3;
public static final int NEXT_MUSIC = 4;
private static SharedPreferences sp;
public static Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case PLAY_MUSIC:
int position = msg.arg1;
SongBean songBean = mList.get(position);
mPlaySong.setText(songBean.getTitle());
mPlayName.setText(songBean.getArtist());
sp.edit().putString("song", songBean.getTitle()).apply();
sp.edit().putString("artist", songBean.getArtist()).apply();
sp.edit().putInt("position", position).apply();
mPause.setImageBitmap(mPlayBitmap);
break;
case PAUSE_MUSIC:
boolean pause = (boolean) msg.obj;
if (pause) {
mPause.setImageBitmap(mPauseBitmap);
} else {
mPause.setImageBitmap(mPlayBitmap);
}
break;
case PREVIOUS_MUSIC:
mPause.setImageBitmap(mPlayBitmap);
break;
case NEXT_MUSIC:
mPause.setImageBitmap(mPlayBitmap);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_music);
StatusBarUtil.setStatusBarColor(this);
sp = getSharedPreferences("MusicInfo", MODE_PRIVATE);
Intent intent = new Intent();
intent.setClass(this, MusicService.class);
startService(intent);
mConn = new bindServiceConn();
bindService(intent, mConn, BIND_AUTO_CREATE);
initView();
new musicAsyncTask().execute();
}
private void initView() {
mPauseBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.uamp_ic_play_arrow_white_48dp);
mPlayBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.uamp_ic_pause_white_48dp);
mPlaySong = (TextView) findViewById(R.id.playSong);
mPlayName = (TextView) findViewById(R.id.playName);
mPause = (ImageView) findViewById(R.id.pause);
findViewById(R.id.pause).setOnClickListener(this);
findViewById(R.id.preview).setOnClickListener(this);
findViewById(R.id.next).setOnClickListener(this);
mListView = (ListView) findViewById(R.id.listView);
mListView.setOnItemClickListener(this);
String song = sp.getString("song", "");
String artist = sp.getString("artist", "");
mCurrentPosition = sp.getInt("position", -1);
mPlaySong.setText(song);
mPlayName.setText(artist);
findViewById(R.id.tv_back).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
public void onClick(View view) {
if (mList.size() == 0) {
Toast.makeText(this, getString(R.string.has_no_music_file), Toast.LENGTH_SHORT).show();
return;
}
switch (view.getId()) {
case R.id.preview:
mService.previous(mCurrentPosition, mList);
break;
case R.id.next:
mService.next(mCurrentPosition, mList);
break;
case R.id.pause:
mService.pause(mCurrentPosition, mList);
break;
}
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
mCurrentPosition = i;
mPause.setImageBitmap(mPlayBitmap);
mService.play(mCurrentPosition, mList);
}
class bindServiceConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mService = (IMusicService) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
class musicAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
mList = new ArrayList<>();
}
@Override
protected Void doInBackground(Void... voids) {
mList = MediaUtil.getAllSongs(MusicActivity.this);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Logger.i(TAG, mList.toString());
mListView.setAdapter(new MusicAdapter(mList));
}
}
class MusicAdapter extends BaseAdapter {
private ArrayList<SongBean> songList;
public MusicAdapter(ArrayList<SongBean> songList) {
this.songList = songList;
}
@Override
public int getCount() {
return songList == null ? 0 : songList.size();
}
@Override
public Object getItem(int i) {
return songList.get(i);
}
@Override
public long getItemId(int i) {
return songList.get(i).getId();
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
viewHolder holder = null;
if (view == null) {
view = LayoutInflater.from(MusicActivity.this).inflate(R.layout.item_song_information, null);
holder = new viewHolder();
holder.singerName = (TextView) view.findViewById(R.id.singerName);
holder.songName = (TextView) view.findViewById(R.id.songName);
view.setTag(holder);
} else {
holder = (viewHolder) view.getTag();
}
holder.songName.setText(mList.get(i).getTitle());
holder.singerName.setText(mList.get(i).getArtist());
return view;
}
}
static class viewHolder {
public TextView songName;
public TextView singerName;
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mConn);
}
}
3,定義暫停,播放,上一首,下一首的介面
public interface IMusicService {
void previous(int position, ArrayList<SongBean> list);
void pause(int position, ArrayList<SongBean> list);
void next(int position, ArrayList<SongBean> list);
void play(int position, ArrayList<SongBean> list);
}
4,支援後臺的service
public class MusicService extends Service {
private MediaPlayer mPlayer;
private int currentPosition = -1;
private boolean isPause = false;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
@Override
public void onCreate() {
super.onCreate();
if(mPlayer!=null){
mPlayer=new MediaPlayer();
}
}
private void playMusic(int position, final ArrayList<SongBean> list) {
Message message = Message.obtain();
message.what= MusicActivity.PLAY_MUSIC;
message.arg1=position;
MusicActivity.mHandler.sendMessage(message);
SongBean songBean = list.get(position);
if (mPlayer == null) {
mPlayer = new MediaPlayer();
}
if (mPlayer.isPlaying()) {
mPlayer.stop();
mPlayer = new MediaPlayer();
}
try {
mPlayer.reset();
mPlayer.setDataSource(songBean.getUrl());
mPlayer.prepare();
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.i("test", "onPrepared");
mPlayer.start();
isPause = false;
}
});
//音樂播放完成的監聽
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
Log.i("test", "onCompletion");
currentPosition = currentPosition + 1;
if(currentPosition==list.size()){
currentPosition=0;
}
playMusic(currentPosition,list);
}
});
Log.i("test", "duration====" + mPlayer.getDuration());
} catch (Exception e) {
e.printStackTrace();
}
}
public void callPause(ArrayList<SongBean> list){
Message message = Message.obtain();
message.what=MusicActivity.PAUSE_MUSIC;
if (currentPosition == -1) {
currentPosition = 0;
playMusic(currentPosition,list);
} else if (mPlayer.isPlaying()) {
mPlayer.pause();
isPause = true;
} else {
mPlayer.start();
isPause = false;
}
message.obj=isPause;
MusicActivity.mHandler.sendMessage(message);
}
public void callPrevious(ArrayList<SongBean> list){
if (isPause) {
mPlayer.start();
Message message = Message.obtain();
message.what=MusicActivity.PREVIOUS_MUSIC;
MusicActivity.mHandler.sendMessage(message);
}
if (currentPosition == 0) {
currentPosition = list.size() - 1;
playMusic(currentPosition,list);
} else if (currentPosition == -1) {
currentPosition = 0;
playMusic(currentPosition,list);
} else {
currentPosition = currentPosition - 1;
playMusic(currentPosition,list);
}
}
public void callNext(ArrayList<SongBean> list){
if (isPause) {
mPlayer.start();
Message message = Message.obtain();
message.what=MusicActivity.NEXT_MUSIC;
MusicActivity.mHandler.sendMessage(message);
}
if (currentPosition == list.size() - 1) {
currentPosition = 0;
playMusic(currentPosition,list);
} else if (currentPosition == -1) {
currentPosition = 0;
playMusic(currentPosition,list);
} else {
currentPosition = currentPosition + 1;
playMusic(currentPosition,list);
}
}
class MyBinder extends Binder implements IMusicService{
@Override
public void previous(int position ,ArrayList<SongBean> list) {
callPrevious(list);
}
@Override
public void pause(int position ,ArrayList<SongBean> list) {
callPause(list);
}
@Override
public void next(int position,ArrayList<SongBean> list) {
callNext(list);
}
@Override
public void play(int position, ArrayList<SongBean> list) {
currentPosition=position;
playMusic(position,list);
}
}
5,獲取本地音訊檔案工具類MediaUtil
public class MediaUtil {
private static final Uri albumArtUri = Uri.parse("content://media/external/audio/albumart");
public static ArrayList<SongBean> getAllSongs(Context context) {
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
ArrayList<SongBean> mp3Infos = new ArrayList<SongBean>();
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
SongBean mp3Info = new SongBean();
long id = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media._ID));
String title = cursor.getString((cursor
.getColumnIndex(MediaStore.Audio.Media.TITLE)));
String artist = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String album = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String displayName = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
long albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
long duration = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.DURATION));
long size = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.SIZE));
String url = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA));
int isMusic = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));
if (isMusic != 0 && displayName.endsWith(".mp3")) {
mp3Info.setId(id);
mp3Info.setTitle(title);
mp3Info.setArtist(artist);
mp3Info.setAlbum(album);
mp3Info.setDisplayName(displayName);
mp3Info.setAlbumId(albumId);
mp3Info.setDuration(duration);
mp3Info.setSize(size);
mp3Info.setUrl(url);
mp3Infos.add(mp3Info);
}
}
return mp3Infos;
}
}
6,獲取音樂資訊的songbean
public class SongBean {
@Override
public String toString() {
return "SongBean{" +
"mId=" + mId +
", mTitle='" + mTitle + '\'' +
", mArtist='" + mArtist + '\'' +
", mAlbum='" + mAlbum + '\'' +
", mDisplayName='" + mDisplayName + '\'' +
", mAlbumId=" + mAlbumId +
", mDuration=" + mDuration +
", mSize=" + mSize +
", mUrl='" + mUrl + '\'' +
'}';
}
public long getId() {
return mId;
}
private long mId;
private String mTitle;
private String mArtist;
private String mAlbum;
private String mDisplayName;
private long mAlbumId;
private long mDuration;
private long mSize;
private String mUrl;
public void setId(long id) {
mId = id;
}
public void setTitle(String title) {
mTitle = title;
}
public void setArtist(String artist) {
mArtist = artist;
}
public void setAlbum(String album) {
mAlbum = album;
}
public void setDisplayName(String displayName) {
mDisplayName = displayName;
}
public void setAlbumId(long albumId) {
mAlbumId = albumId;
}
public void setDuration(long duration) {
mDuration = duration;
}
public void setSize(long size) {
mSize = size;
}
public void setUrl(String url) {
mUrl = url;
}
public String getTitle() {
return mTitle;
}
public String getArtist() {
return mArtist;
}
public String getAlbum() {
return mAlbum;
}
public String getDisplayName() {
return mDisplayName;
}
public long getAlbumId() {
return mAlbumId;
}
public long getDuration() {
return mDuration;
}
public long getSize() {
return mSize;
}
public String getUrl() {
return mUrl;
}
}