项目名称:音乐播放器
开发语言:java
开发环境:Eclipse、android SDK
项目简介:音乐播放器是一款实现了音乐播放,音乐切换,音乐后台播放等一系列功能的软件。
1. 音乐列表
使用递归的算法从手机的SDK里面遍历音乐文件,显示到界面。
2. 音乐上一首,下一首切换
实现了音乐的上一首,下一首切换,当切换的时候就重新去获取音乐路径
3. 后台音乐播放
为了用户更好的体验,实现了当退出音乐界面的时候,音乐在后台继续播放,采用的是服务的技术
4. 通知
当退出界面的时候,怎么控制后台服务的音乐播放和暂停,就是发送一个通知,实现通知和服务的通讯
实现播放功能
/**
* 初始化音乐资源,进行播放
*
* @param musicFile
*/
private void initMusic(String musicFile) {
try {
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
}
// if(mMediaPlayer.isPlaying()){
// mMediaPlayer.reset();
// }
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.setDataSource(musicFile);
mMediaPlayer.prepare();
playerMusic();
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 音乐播放或暂停
*/
private boolean playerMusic() {
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
notificationMusicPlayer();
return true;
} else {
mMediaPlayer.pause();
notificationMusicPlayer();
return false;
}
}
实现上一首下一首功能,所以我们从音乐列表界面获取的就不是一首歌德路径而是一个列表数组
// =========获取音乐播放列表资源=============
Intent intent = getIntent();
ArrayList<MusicBean> mMusicList = intent
.getParcelableArrayListExtra("MUSIC_LIST");
int mCurrentPostion = intent.getIntExtra("CURRENT_POSTION", 0);
Intent service = new Intent(this, MusicPlayerService.class);
service.putParcelableArrayListExtra("MUSIC_LIST", mMusicList);
service.putExtra("CURRENT_POSTION", mCurrentPostion);
startService(service);
bindService(service, mServiceConnection, BIND_AUTO_CREATE);
mPlayerBtn.setImageResource(R.drawable.landscape_player_btn_pause_normal);
new Thread(new UpdateUIThread()).start();
/**
* 播放下一首音乐
*/
private void playerNextMusic() {
if (++mCurrentPostion < mMusicList.size()) {
playerNewMusic(mCurrentPostion);
} else {
mCurrentPostion = mMusicList.size() - 1;
Toast.makeText(this, "已到最后一首", Toast.LENGTH_SHORT).show();
}
}
/**
* 播放上一首音乐
*/
private void playerPreMusic() {
if (--mCurrentPostion >= 0) {
playerNewMusic(mCurrentPostion);
} else {
mCurrentPostion = 0;
Toast.makeText(this, "已到第一首", Toast.LENGTH_SHORT).show();
}
}
/**
* 释放MediaPlayer资源
*/
@Override
public void onDestroy() {
super.onDestroy();
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer = null;
}
}
因为我们要实现在后台服务播放所以要实现服务和Activity的通讯
// =======第一步定义接口里面定义实现业务逻辑的方法=========//
interface IPlayerMusicServicer {
public boolean iPlayerMusic();
public void iPlayerNextMusic();
public void iPlayerPreMusic();
public int iPlayerDuration();
public int iPlayerCurrentPostion();
}
//==========第二步定义一个类实现接口==============//
class MusicServiceBinder extends Binder implements IPlayerMusicServicer {
public boolean iPlayerMusic() {
return playerMusic();
}
@Override
public void iPlayerNextMusic() {
playerNextMusic();
}
@Override
public void iPlayerPreMusic() {
playerPreMusic();
}
@Override
public int iPlayerDuration() {
if (mMediaPlayer != null) {
return mMediaPlayer.getDuration();
} else {
return 0;
}
}
@Override
public int iPlayerCurrentPostion() {
if (mMediaPlayer != null) {
return mMediaPlayer.getCurrentPosition();
} else {
return 0;
}
}
}
// ====实例化接口类通过这个类可以实现业务逻辑===============//
private MusicServiceBinder mMusicServiceBinder = new MusicServiceBinder();
public IBinder onBind(Intent intent) {
Log.i("111", "返回对象:.>>" + mMusicServiceBinder);
return mMusicServiceBinder;
}
通过服务的public IBinder onBind(Intent intent) {
Log.i("111", "返回对象:.>>" + mMusicServiceBinder);
return mMusicServiceBinder;
}
返回接口
在Activity里面接收接口
private IPlayerMusicServicer mIPlayerMusicServicer;
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
}
public void onServiceConnected(ComponentName name, IBinder service) {
mIPlayerMusicServicer = (IPlayerMusicServicer) service;
// 多态的体现,其实返回的是mMusicServiceBinder继承自Biner类的实例对象,通过 onBind返回的
}
};
在需要实现功能的地方去调用接口的方法
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.playerpag_control_player_btn:
boolean isPlayer = mIPlayerMusicServicer.iPlayerMusic();
if (isPlayer) {
mPlayerBtn
.setImageResource(R.drawable.landscape_player_btn_pause_normal);
} else {
mPlayerBtn
.setImageResource(R.drawable.landscape_player_btn_play_press);
}
break;
case R.id.playerpag_control_previous_btn:
mIPlayerMusicServicer.iPlayerPreMusic();
break;
case R.id.playerpag_control_next_btn:
mIPlayerMusicServicer.iPlayerNextMusic();
break;
}
}
然后就是通知控制播放
private void notificationMusicPlayer() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
this);
builder.setSmallIcon(R.drawable.m03);
builder.setTicker("音乐播放开始");
// =========通过RemoteViews吧自定义布局文件转化成通知用的View==================//
RemoteViews views = new RemoteViews(getPackageName(),
R.layout.notification);
views.setTextViewText(R.id.title, mCurrentMusicName);
views.setTextViewText(R.id.text, "未知音乐家");
views.setImageViewResource(R.id.image, R.drawable.m11);
if (!mMediaPlayer.isPlaying()) {
views.setImageViewResource(R.id.iv_pause,
R.drawable.webview_forward_hover);
} else {
views.setImageViewResource(R.id.iv_pause, R.drawable.nc_pause);
}
//======接受广播=========//
Intent pauseIntent = new Intent(ACTION_PAUSE);
PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 1,pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.iv_pause, pausePendingIntent);
builder.setContent(views);// 把自定义布局view设置给通知
// =========通知的点击事件,当点击通知的时候就跳转到音乐播放界面===============//
// ==通知的跳转是个特例。所以需要pendingIntent,pendingIntent可以获取跳转到服务,界面等,通过他的get方法获取====//
Intent intent = new Intent(this, PlayerpagerActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
// =========发送通知,要通过NotificationManager这个类来发送==========//
NotificationManager manger = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
int id = 1000;
Notification notification = builder.build();
manger.notify(id, notification);
}
/**
* 定义广播接收者
*/
BroadcastReceiver musicPlayerReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_PAUSE)) {
playerMusic();
} else if (action.equals(ACTION_PRE)) {
playerPreMusic();
} else if (action.equals(ACTION_NEXT)) {
playerNextMusic();
}
}
};