Android Media——使用MediaController实现音乐播放

        首先是客户端代,我们需要做的是建立连接,并且在连接成功后设置回调,客户端再Activity中实现:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
	...
	//媒体浏览器
    private MediaBrowser mMediaBrowser;
    //媒体控制器
    private MediaController mMediaController;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //新建MediaBrowser,第一个参数是context
        //第二个参数是CompoentName,有多种构造方法,指向要连接的服务
        //第三个参数是连接结果的回调connectionCallback,第四个参数为Bundle
        mMediaBrowser = new MediaBrowser(this,
                new ComponentName(this, MediaService.class), connectionCallback, null);
        mMediaBrowser.connect();
        ...
    }


	//连接结果的回调
	 private MediaBrowser.ConnectionCallback connectionCallback 
	 							= new MediaBrowser.ConnectionCallback() {
	 
		 public void onConnected() {
		     	//如果服务端接受连接,就会调此方法表示连接成功,否则回调onConnectionFailed();
	           Log.d(TAG, "onConnected: ");
	           //获取配对令牌
	           MediaSession.Token token = mMediaBrowser.getSessionToken();
	           //通过token,获取MediaController,第一个参数是context,第二个参数为token
	           mMediaController = new MediaController(getBaseContext(), token);
			
			   //mediaController注册回调,callback就是媒体信息改变后,服务给客户端的回调
	           mMediaController.registerCallback(mMediaCallBack);
		     }
		       
		    public void onConnectionSuspended() {
		         //与服务断开回调(可选)
		     }
		     
		    public void onConnectionFailed() {
		         //连接失败回调(可选)
		     }
	 }


	//服务对客户端的信息回调。
 	private MediaController.Callback mMediaCallBack = new MediaController.Callback() {
		//回调函数的方法都是选择性重写的,这里不列举全,具体可查询文章末尾的表格
		  @Override
        public void onMetadataChanged(MediaMetadata metadata) {
            super.onMetadataChanged(metadata);
			//服务端运行mediaSession.setMetadata(mediaMetadata)就会到达此处,以下类推.


         	//歌曲信息回调,更新。MediaMetadata在文章后面会提及
			MediaDescription description = metadata.getDescription();
			//获取标题
			String title = description.getTitle().toString();
			//获取作者
			String author = description.getSubtitle().toString();
			//获取专辑名
            String album = description.getDescription().toString();
			//获取总时长
			long duratime = mediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
			...
        }
        
		 @Override
        public void onPlaybackStateChanged(PlaybackState state) {
            super.onPlaybackStateChanged(state);
			//播放状态信息回调,更新。PlaybackState在文章后面会提及
			 if (state.getState() == PlaybackState.STATE_PLAYING) {
          		//正在播放
          	 } 
          	 ...	
			//获取当前播放进度
			 long position = state.getPosition()
		     ....
        }


		@Override
        public void onQueueChanged(List<MediaSession.QueueItem> queue) {
            super.onQueueChanged(queue);
			//播放列表信息回调,QueueItem在文章后面会提及
			....
        }	


		@Override
        public void onSessionEvent(String event, Bundle extras) {
            super.onSessionEvent(event, extras);
            //自定义的事件回调,满足你各种自定义需求
            ...
        }


        @Override
        public void onExtrasChanged(Bundle extras) {
            super.onExtrasChanged(extras);
            //额外信息回调,可以承载播放模式等信息
        }
        .....
	}
}

        接下来看服务端,我们要做的是同意客户端连接,响应客户端的控制命令,并且在信息改变时通知回调给客户端,服务端再Service中实现:

public class MediaService extends MediaBrowserService{


	...
	//媒体会话,受控端
	private MediaSession mediaSession;


	@Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: ");
        //初始化,第一个参数为context,第二个参数为String类型tag,这里就设置为类名了
        mediaSession = new MediaSession(this, "MediaService");
        //设置token
        setSessionToken(mediaSession.getSessionToken());
        //设置callback,这里的callback就是客户端对服务指令到达处
        mediaSession.setCallback(mCallback);
    }


	//mediaSession设置的callback,也是客户端控制指令所到达处
	private MediaSession.Callback mCallback = new MediaSession.Callback() {
	//重写的方法都是选择性重写的,不完全列列举,具体可以查询文章末尾表格
		@Override
        public void onPlay() {
            super.onPlay();
			//客户端mMediaController.getTransportControls().play()就会调用到这里,以下类推
			//处理播放逻辑
			...
			//处理完成后通知客户端更新,这里就会回调给客户端的MediaController.Callback
			
			mediaSession.setPlaybackState(playbackState);
        }
		
        @Override
        public void onPause() {
            super.onPause();
            //暂停
            ....
        }


        @Override
        public void onSkipToNext() {
            super.onSkipToNext();
            //下一首
            .....
            //通知媒体信息改变
            mediaSession.setMetadata(mediaMetadata);
        }


        @Override
        public void onCustomAction(String action, Bundle extras) {
            super.onCustomAction(action, extras);
			//自定义指令发送到的地方
			//对应客户端 mMediaController.getTransportControls().sendCustomAction(...)


        }
		....
	}
	
	//自己写的方法,用于改变播放列表
	private void changePlayList(){
		....
		
		//通知播放队列改变
		mediaSession.setQueue(queueItems);
	}


	 @Override
    public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
		//MediaBrowserService必须重写的方法,第一个参数为客户端的packageName,第二个参数为Uid
		//第三个参数是从客户端传递过来的Bundle。
		//通过以上参数来进行判断,若同意连接,则返回BrowserRoot对象,否则返回null;


		//构造BrowserRoot的第一个参数为rootId(自定义),第二个参数为Bundle;
        return new BrowserRoot("MyMedia", null);
    }


	 @Override
    public void onLoadChildren(String parentId, 
    				MediaBrowserService.Result<List<MediaBrowser.MediaItem>> result) {
	//MediaBrowserService必须重写的方法,用于处理订阅信息,文章后面会提及
	....
	}


	....
}

        在客户端与服务端建立连接后,就可以调用mMediaController的播放、暂停、上下首、跳转某个时间点方法了,如:在客户端Activity的播放按键onClick回调时调用mMediaController.getTransportControls().play(),这时在服务端的MediaSession.Callback() 的onPlay()方法就会被调用,我们可以在onPlay方法中调用MediaPlay的start方法。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值