Android 音乐播放器,Service后台管理播放
2017-05-21 10:48
246 查看
新手笔记:
由于刚学习安卓开发,还没接触Service,所以之前的音乐播放器都是在Activity上完成的,可能功能还不够复杂,所以看不到坏处,不过很多声音说,音乐播放这块最好是放在Service中完成,因为即使用户退出该程序,但后台依然会播放音乐等。
下面讲实现的方法:
1、定义一个继承Service的子类,为MusicService,基本框架为
这里解释一下:
IBinder onBind(Intent intent):该方法是必须实现的,返回一个IBinder对象,Activity可通这个对象与Service进行通信,在这里,Service要获取或者更新播放列表,播放模式,以及跳转某时刻播放,和Activity要获取当前播放的位置以及播放时长,都用IBinder对象进行通信。但其实这里也可以用广播来通信,暂时不清楚哪种方式比较好,基于学习的需要,两种方法我都用上了,下面有写到用广播来通知Activity更新UI。
void onCreate:第一次创建Service会回调该方法。在这里,我们写入需要初始化的操作,创建BroadcastReceiver和IntentFilter,注册监听器,实例化一个MediaPlayer对象。
2、在AndroidManifest,xml文件配置该Service,为
相应的,在Activity,我们需要通过IBinder对象,发送或者更新播放列表、播放模式、跳转的时刻等等到Service,也需要获取播放的位置以及播放时长以更新UI等。大概的框架如下:
public class MainActivity extends Activity implements OnClickListener {
//声明
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initViews();
initDatas();
initEvents();
initList();
}
public class ActivityReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context,Intent intent){
int update = intent.getIntExtra("update", -1);
int current = intent.getIntExtra("current", -1);
if (current >= 0) {
mSeekbarPlay.setMax(binder.getMpDuration());
mDuration.setText( toConvert.convertLength(binder.getMpDuration()));
handler.post(runnable);
mSeekbarPlay.setOnSeekBarChangeListener(new SeekBarListener());
mPlayingTitle.setText(mlist.get(current).getTitle());
Bitmap bm = getmusics.getArtworkFromFile(MainActivity.this, mlist.get(current).getId(), mlist.get(current).getAlbumId());
mAlbumImg.setImageBitmap(bm);
toConvert.convertImg(mAlbumImg, getmusics);
Bitmap bmblur = toConvert.fastBlurBitmap(bm,MainActivity.this);
BitmapDrawable bd= new BitmapDrawable(getResources(), bmblur);
playing3.setBackground(bd);
}
switch(update){
case 0x11: mBtnPlay.setImageResource(R.drawable.icon_stop);break;
case 0x22: mBtnPlay.setImageResource(R.drawable.icon_play);break;
}
}
}
// 开一
4000
条线程改变seekbar
Handler handler = new Handler();
Runnable runnable = new Runnable(){
@Override
public void run(){
if(!isChanging) mSeekbarPlay.setProgress(binder.getMpCurrentPosition());
mCurrentPosition.setText(toConvert.convertLength(binder.getMpCurrentPosition()));
handler.postDelayed(runnable,500);
}
};
private class SeekBarListener implements OnSeekBarChangeListener{
@Override
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
if(fromUser==true){
binder.setSeekTo(progress); //通过binder改变service播放进度
}
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
isChanging = true;
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
isChanging = false;
}
}
private ServiceConnection conn = new ServiceConnection(){
//当该Activity 与 Service 连接成功时回调该方法
@Override
public void onServiceConnected(ComponentName name,IBinder service){
System.out.println("---Service Connected---");
//获取Service 的 onBind方法所返回的MyBinder对象
binder = (MusicService.MyBinder) service;
binder.getMusicList(mlist);
}
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("---Service Disconnected---");
}
};
public void initList()
{
//获取音乐文件列表对象mlist
}
public void setMusicList(List<Mp3Info> mlist)
{
//初始化播放列表UI的类
}
private void initViews(){
//获取View相关的对象及初始化等操作
}
private void initDatas() {
//创建BroadcastReceiver和IntentFilter,注册监听器,创建启动Service的Intent,以及绑定Service
//初始化ViewPager的适配器
//设置ViewPager的适配器
}
private void initEvents(){
//设置监听点击事件
mTabMine.setOnClickListener(this);
mTabPlay.setOnClickListener(this);
mPlayingMode.setOnClickListener(this);
mBtnPlay.setOnClickListener(this);
mBtnNext.setOnClickListener(this);
mBtnPrev.setOnClickListener(this);
// ViewPager监听事件
MusicList.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id){
mViewpager.setCurrentItem(1); //点击播放列表会自动跳转到播放页
intent = new Intent(CTL_ACTION);
intent.putExtra("musicindex", position);
intent.putExtra("control", 1);
sendBroadcast(intent);
}
});
}
@Override
public void onClick(View v) {
intent = new Intent(CTL_ACTION);
switch (v.getId()) {
case R.id.id_tab_mine:
//设置viewPager的当前Tab
mViewpager.setCurrentItem(0);
break;
case R.id.id_tab_play:
mViewpager.setCurrentItem(1);
break;
case R.id.id_btn_playingmode:{
ModeNum++;
if(ModeNum > 2) ModeNum = 0;
switch(ModeNum){
case 0:
mPlayingMode.setImageResource(R.drawable.icon_shunxu); break;
case 1:
mPlayingMode.setImageResource(R.drawable.icon_suiji);break;
case 2:
mPlayingMode.setImageResource(R.drawable.icon_danqu);break;
}
intent.putExtra("modenum", ModeNum);
sendBroadcast(intent);
break;
}
case R.id.id_btn_play:
intent.putExtra("control", 1);
break;
case R.id.id_btn_next:
intent.putExtra("control", 2);
break;
case R.id.id_btn_prev:
intent.putExtra("control", 3);
break;
}
sendBroadcast(intent);
}
@Override //按下系统返回键效果同home键
public void onBackPressed() {
Intent setIntent = new Intent(Intent.ACTION_MAIN);
setIntent.addCategory(Intent.CATEGORY_HOME);
setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(setIntent);
}
}
Activity启动之后,完成所有的初始化,包括启动Service,接下来就只剩下,UI界面与用户的交互,然后监听到的操作通过广播与Service通信,改变Service的播放状态,如下一首,播放停止,点歌,更改播放模式等等。现在做的这个播放器还是半成品,抱着学习的心态,将不断完善,还有很多不足的地方需要更改。
由于刚学习安卓开发,还没接触Service,所以之前的音乐播放器都是在Activity上完成的,可能功能还不够复杂,所以看不到坏处,不过很多声音说,音乐播放这块最好是放在Service中完成,因为即使用户退出该程序,但后台依然会播放音乐等。
下面讲实现的方法:
1、定义一个继承Service的子类,为MusicService,基本框架为
public class MusicService extends Service { public void playMusic(List<Mp3Info> mlist,int index){ } public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context,Intent intent) { } } private void completionPlayNext(int i){ } private void PlayNext(){ } private void PlayPrev(){ } private void PlayorPause(){ } // 继承Binder来实现IBinder类 public class MyBinder extends Binder{ public void getMusicList(List<Mp3Info> list){ } public void getModeNum(int num){ } public int getMpCurrentPosition(){ } public int getMpDuration(){ } public void setSeekTo(int progress){ } } @Override public IBinder onBind(Intent intent){ System.out.println("Service is Binded"); return binder; } @Override public void onCreate(){ super.onCreate(); serviceReceiver = new MyReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(CTL_ACTION); registerReceiver(serviceReceiver, filter); mp = new MediaPlayer(); System.out.println("Service---onCreate----"); } @Override public int onStartCommand(Intent intent,int flags,int startId){ return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent){ System.out.println("Service is Unbinded"); return true; } @Override public void onDestroy(){ super.onDestroy(); } }
这里解释一下:
IBinder onBind(Intent intent):该方法是必须实现的,返回一个IBinder对象,Activity可通这个对象与Service进行通信,在这里,Service要获取或者更新播放列表,播放模式,以及跳转某时刻播放,和Activity要获取当前播放的位置以及播放时长,都用IBinder对象进行通信。但其实这里也可以用广播来通信,暂时不清楚哪种方式比较好,基于学习的需要,两种方法我都用上了,下面有写到用广播来通知Activity更新UI。
void onCreate:第一次创建Service会回调该方法。在这里,我们写入需要初始化的操作,创建BroadcastReceiver和IntentFilter,注册监听器,实例化一个MediaPlayer对象。
2、在AndroidManifest,xml文件配置该Service,为
<service android:name="com.example.my_music.MusicService" android:exported="false"/>
相应的,在Activity,我们需要通过IBinder对象,发送或者更新播放列表、播放模式、跳转的时刻等等到Service,也需要获取播放的位置以及播放时长以更新UI等。大概的框架如下:
public class MainActivity extends Activity implements OnClickListener {
//声明
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initViews();
initDatas();
initEvents();
initList();
}
public class ActivityReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context,Intent intent){
int update = intent.getIntExtra("update", -1);
int current = intent.getIntExtra("current", -1);
if (current >= 0) {
mSeekbarPlay.setMax(binder.getMpDuration());
mDuration.setText( toConvert.convertLength(binder.getMpDuration()));
handler.post(runnable);
mSeekbarPlay.setOnSeekBarChangeListener(new SeekBarListener());
mPlayingTitle.setText(mlist.get(current).getTitle());
Bitmap bm = getmusics.getArtworkFromFile(MainActivity.this, mlist.get(current).getId(), mlist.get(current).getAlbumId());
mAlbumImg.setImageBitmap(bm);
toConvert.convertImg(mAlbumImg, getmusics);
Bitmap bmblur = toConvert.fastBlurBitmap(bm,MainActivity.this);
BitmapDrawable bd= new BitmapDrawable(getResources(), bmblur);
playing3.setBackground(bd);
}
switch(update){
case 0x11: mBtnPlay.setImageResource(R.drawable.icon_stop);break;
case 0x22: mBtnPlay.setImageResource(R.drawable.icon_play);break;
}
}
}
// 开一
4000
条线程改变seekbar
Handler handler = new Handler();
Runnable runnable = new Runnable(){
@Override
public void run(){
if(!isChanging) mSeekbarPlay.setProgress(binder.getMpCurrentPosition());
mCurrentPosition.setText(toConvert.convertLength(binder.getMpCurrentPosition()));
handler.postDelayed(runnable,500);
}
};
private class SeekBarListener implements OnSeekBarChangeListener{
@Override
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
if(fromUser==true){
binder.setSeekTo(progress); //通过binder改变service播放进度
}
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
isChanging = true;
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
isChanging = false;
}
}
private ServiceConnection conn = new ServiceConnection(){
//当该Activity 与 Service 连接成功时回调该方法
@Override
public void onServiceConnected(ComponentName name,IBinder service){
System.out.println("---Service Connected---");
//获取Service 的 onBind方法所返回的MyBinder对象
binder = (MusicService.MyBinder) service;
binder.getMusicList(mlist);
}
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("---Service Disconnected---");
}
};
public void initList()
{
//获取音乐文件列表对象mlist
}
public void setMusicList(List<Mp3Info> mlist)
{
//初始化播放列表UI的类
}
private void initViews(){
//获取View相关的对象及初始化等操作
}
private void initDatas() {
//创建BroadcastReceiver和IntentFilter,注册监听器,创建启动Service的Intent,以及绑定Service
//初始化ViewPager的适配器
//设置ViewPager的适配器
}
private void initEvents(){
//设置监听点击事件
mTabMine.setOnClickListener(this);
mTabPlay.setOnClickListener(this);
mPlayingMode.setOnClickListener(this);
mBtnPlay.setOnClickListener(this);
mBtnNext.setOnClickListener(this);
mBtnPrev.setOnClickListener(this);
// ViewPager监听事件
MusicList.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id){
mViewpager.setCurrentItem(1); //点击播放列表会自动跳转到播放页
intent = new Intent(CTL_ACTION);
intent.putExtra("musicindex", position);
intent.putExtra("control", 1);
sendBroadcast(intent);
}
});
}
@Override
public void onClick(View v) {
intent = new Intent(CTL_ACTION);
switch (v.getId()) {
case R.id.id_tab_mine:
//设置viewPager的当前Tab
mViewpager.setCurrentItem(0);
break;
case R.id.id_tab_play:
mViewpager.setCurrentItem(1);
break;
case R.id.id_btn_playingmode:{
ModeNum++;
if(ModeNum > 2) ModeNum = 0;
switch(ModeNum){
case 0:
mPlayingMode.setImageResource(R.drawable.icon_shunxu); break;
case 1:
mPlayingMode.setImageResource(R.drawable.icon_suiji);break;
case 2:
mPlayingMode.setImageResource(R.drawable.icon_danqu);break;
}
intent.putExtra("modenum", ModeNum);
sendBroadcast(intent);
break;
}
case R.id.id_btn_play:
intent.putExtra("control", 1);
break;
case R.id.id_btn_next:
intent.putExtra("control", 2);
break;
case R.id.id_btn_prev:
intent.putExtra("control", 3);
break;
}
sendBroadcast(intent);
}
@Override //按下系统返回键效果同home键
public void onBackPressed() {
Intent setIntent = new Intent(Intent.ACTION_MAIN);
setIntent.addCategory(Intent.CATEGORY_HOME);
setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(setIntent);
}
}
Activity启动之后,完成所有的初始化,包括启动Service,接下来就只剩下,UI界面与用户的交互,然后监听到的操作通过广播与Service通信,改变Service的播放状态,如下一首,播放停止,点歌,更改播放模式等等。现在做的这个播放器还是半成品,抱着学习的心态,将不断完善,还有很多不足的地方需要更改。
相关文章推荐
- Android-Service (基本知识,生命周期,实例-startService 启动的服务音乐播放器后台服务播放)
- android的service学习案例------自己做的音乐播放器,让service后台播放mp3文件(是burning.mp3哦!)
- Android-Service (基本知识,生命周期,实例-startService 启动的服务音乐播放器后台服务播放)
- 【Android】简易音乐播放器(介绍使用Service和Broadcast播放音乐文件)
- Android通过Service实现音乐后台播放
- Android 音乐播放器的开发教程(六)service的运用及音乐列表点击播放 ----- 小达
- Android使用本地Service实现后台播放音乐
- Android 超简单音乐播放器(六)播放暂停音乐,更换播放模式,上下歌曲切换(service)
- Android service学习总结和利用service实现的后台音乐播放功能
- 【Android】Service+Seek Bar实现后台音乐播放器小呆萌
- 【Android】简易音乐播放器(介绍使用Service和Broadcast播放音乐文件)
- Android控制后台音乐播放器暂停,播放
- Android 开启后台Service播放Mediaplayer
- Android 利用AudioManager控制后台音乐播放器暂停,播放
- Android四大组件--Service,后台播放背景音乐
- android组件Service控制后台音乐播放
- 深入剖析Android四大组件(六)——相对完美的后台Service实现播放音乐功能
- ANDROID管理多个音乐播放器同时播放问题参考文章
- Android实现后台播放音乐(Service方式)
- android音乐后台播放需要用到Service