MediaSession框架使用、源码分析以及实战

最近在和某音乐App合作项目中使用到,特此进行整理分析。

需求是需要获取某音乐播放的状态以及歌曲封面等内容。

整理后基本上分成三部分来写吧。

前言
本文系列主要分成三部分。
1. MediaSession框架使用.
2. MediaSession框架源码分析.
3. MediaSession框架实战App.

本文主要讲MediaSession框架使用。

MediaSession框架使用

很多同学在学习安卓的时候,可能会完成一个音乐播放器的项目,因为音乐播放器项目会贯穿安卓的四大组件。在项目中,大家一定会在服务中使用MediaPlayer去播放音乐,但是界面如何控制服务进行音乐的更换、改变播放进度,大家往往会使用发送广播或者启动service的方式去通知服务,同时,服务可以发送广播通知界面播放进度的变化,或者使用EventBug之类的去通知。

这时候问题来了:
1、有更高效的方式嘛?

在Android 5.0中,谷歌推出了MediaSession框架专门解决媒体播放时界面和服务通讯问题。
要理解MediaSession框架,分别看看Media和Session:首先Media是媒体的意思,也就是说这个框架用于音视频媒体;而Session呢,翻译成中文就是会话的意思。一个会话,肯定是涉及两方或以上;为了保证受控端和控制端不串号(想象一个遥控器可以遥控同一型号的多台电视),就有了SessionToken的概念,相当于我们在连接蓝牙设备时的配对码,这样就保证了不串号。

下面我们参考ANdroid开发者文档来更好的理解MediaSession框架。

媒体应用架构概览

本部分内容参考:媒体应用架构概览.

使用媒体会话

本部分内容参考:使用媒体会话.

开发音频应用

音频应用概览

本部分内容参考:音频应用概览.

构建媒体浏览器服务

本部分内容参考:构建媒体浏览器服务.

构建媒体浏览器客户端

本部分内容参考:构建媒体浏览器客户端.

媒体会话回调

本部分内容参考:媒体会话回调.

MediaSession框架

一、 基础用法

首先,我们先来看一下MediaSession主要类和对象的构成,如下图:
在这里插入图片描述
这个图只是用来对整个框架进行梳理和回顾,相信在看完后面的使用方法后就会觉得很简单了。

简单描述一下:

  • MediaBrowser:媒体浏览器,用来连接服务,在连接成功的结果回调后,获取token(配对令牌),并以此获得MediaController媒体控制器。同时,有订阅并设置订阅信息回调的功能。
  • MediaController:媒体控制器,可以用mMediaController.getMetadata()等方法来主动获取媒体信息,也可以使用形如mMediaController.getTransportControls().skipToNext()来发送控制指令。其次一般需要注册MediaController.Callback回调进行客户端更新。
  • MediaBrowserService:浏览器服务,实现具体的媒体逻辑。一般在onCreate()中用setSessionToken(…)来设置token。在重写的onGetRoot(…)中判断是否允许连接,在onLoadChildren(…)中处理订阅信息。
  • MediaSession:设置MediaSession.Callback,这里就是客户端指令送达的地方。在媒体信息或状态改变后,使用形如mediaSession.setMetadata(mediaMetadata)来通知客户端。

下面是具体的使用:

1.连接,并建立联系

先来看客户端,我们需要做的是建立连接,并且在连接成功后设置回调。

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
        //第二个参数是ComponetName,有多种构造方法,指向要连接的服务
        //第三个参数是连接结果的回调connectionCallback,第四个参数为Bundle
        mMediaBrowser = new MediaBrowser(this,
                new ComponentName(this, MediaService.class), connectionCallback, null);
        mMediaBrowser.connect();
        ...
    }

	//连接结果的回调
	 private MediaBrowser.ConnectionCallback connectionCallback 
	 							= new MediaBrowser.ConnectionCallback() {
   
	     //如果服务端接受连接,就会调此方法表示连接成功,否则回调onConnectionFailed();
		 public void 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
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值