Android 音乐播放器,Service后台管理播放

来源:互联网 发布:小企业免费会计软件 编辑:程序博客网 时间:2024/05/16 20:42

新手笔记:

由于刚学习安卓开发,还没接触Service,所以之前的音乐播放器都是在Activity上完成的,可能功能还不够复杂,所以看不到坏处,不过很多声音说,音乐播放这块最好是放在Service中完成,因为即使用户退出该程序,但后台依然会播放音乐等。

下面讲实现的方法:

1、定义一个继承Service的子类,为MusicService,基本框架为

public class MusicService extends Service {public void playMusic(List<Mp3Info> mlist,int index){        }public class MyReceiver extends BroadcastReceiver{@Overridepublic 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){}}@Overridepublic IBinder onBind(Intent intent){System.out.println("Service is Binded");return binder;}@Overridepublic 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----");}@Overridepublic int onStartCommand(Intent intent,int flags,int startId){        return super.onStartCommand(intent, flags, startId);  }@Overridepublic boolean onUnbind(Intent intent){System.out.println("Service is Unbinded");return true;}@Overridepublic 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 {//声明@Overrideprotected 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{@Overridepublic 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;}}}// 开一条线程改变seekbarHandler handler = new Handler();Runnable runnable = new Runnable(){@Overridepublic void run(){if(!isChanging) mSeekbarPlay.setProgress(binder.getMpCurrentPosition()); mCurrentPosition.setText(toConvert.convertLength(binder.getMpCurrentPosition())); handler.postDelayed(runnable,500);}};private class SeekBarListener implements OnSeekBarChangeListener{@Overridepublic void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {if(fromUser==true){binder.setSeekTo(progress);   //通过binder改变service播放进度}}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {isChanging = true;}@Overridepublic void onStopTrackingTouch(SeekBar arg0) {isChanging = false;}}private ServiceConnection conn = new ServiceConnection(){//当该Activity 与 Service 连接成功时回调该方法@Overridepublic void onServiceConnected(ComponentName name,IBinder service){System.out.println("---Service Connected---");//获取Service 的 onBind方法所返回的MyBinder对象binder = (MusicService.MyBinder) service;binder.getMusicList(mlist);}@Overridepublic 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(){@Overridepublic 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);}});}@Overridepublic 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的播放状态,如下一首,播放停止,点歌,更改播放模式等等。现在做的这个播放器还是半成品,抱着学习的心态,将不断完善,还有很多不足的地方需要更改。



原创粉丝点击