Android 音乐播放器,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;
			}
		}
	}
	
	// 开一条线程改变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的播放状态,如下一首,播放停止,点歌,更改播放模式等等。现在做的这个播放器还是半成品,抱着学习的心态,将不断完善,还有很多不足的地方需要更改。



  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值