概念性简述

MediaSession 框架是 Google 推出专门解决媒体播放时界面和服务通讯问题。这个框架可以让我们不再使用广播来控制播放器,而且也能适配耳机,蓝牙等一些其它设备,实现线控的功能

要理解MediaSession框架,分别看看Media和Session:首先Media是媒体的意思,也就是说这个框架用于音视频媒体;而Session呢,翻译成中文就是会话的意思。一个会话,肯定是涉及两方或以上;在MediaSession框架中,有受控端(一个)和控制端(可以有多个)。接下来为了保证受控端和控制端不串号(想象一个遥控器可以遥控同一型号的多台电视),就有了SessionToken的概念,相当于我们在连接蓝牙设备时的配对码,这样就保证了不串号。在MediaSession框架中,最重要的三个类的概念就这么多,


核心类

  • MediaSessionCompat
  • PlaybackStateCompat
  • MediaMetadataCompat
  • MediaSessionCompat.Callback

初始化配置

    /*** 初始化并激活 MediaSession*/private void setupMediaSession() {
//        第二个参数 tag: 这个是用于调试用的,随便填写即可mMediaSession = new MediaSessionCompat(context, TAG);//指明支持的按键信息类型mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);mMediaSession.setCallback(callback);mMediaSession.setActive(true);}

指定可以接收的来自锁屏页面的按键信息

    private static final long MEDIA_SESSION_ACTIONS =PlaybackStateCompat.ACTION_PLAY| PlaybackStateCompat.ACTION_PAUSE| PlaybackStateCompat.ACTION_PLAY_PAUSE| PlaybackStateCompat.ACTION_SKIP_TO_NEXT| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS| PlaybackStateCompat.ACTION_STOP| PlaybackStateCompat.ACTION_SEEK_TO;

5.0之后耳机物理按键的回调监听

   /*** API 21 以上 耳机多媒体按钮监听 MediaSessionCompat.Callback*/private MediaSessionCompat.Callback callback = new MediaSessionCompat.Callback() {//        接收到监听事件,可以有选择的进行重写相关方法@Overridepublic void onPlay() {super.onPlay();}@Overridepublic void onPause() {super.onPause();}@Overridepublic void onSkipToNext() {super.onSkipToNext();}@Overridepublic void onSkipToPrevious() {super.onSkipToPrevious();}@Overridepublic void onStop() {super.onStop();}@Overridepublic void onSeekTo(long pos) {super.onSeekTo(pos);}};

配置完成后,播放状态,及音乐信息的更新

    /*** 更新播放状态,播放/暂停/拖动进度条时调用*/public void updatePlaybackState() {int state = isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED;mMediaSession.setPlaybackState(new PlaybackStateCompat.Builder().setActions(MEDIA_SESSION_ACTIONS).setState(state, getCurrentPosition(), 1).build());}
    /*** 更新正在播放的音乐信息,切换歌曲时调用*/public void updateMetaData(String path) {if (!StringUtils.isReal(path)) {mMediaSession.setMetadata(null);return;}SongInfo info = mediaManager.getSongInfo(context, path);MediaMetadataCompat.Builder metaData = new MediaMetadataCompat.Builder().putString(MediaMetadataCompat.METADATA_KEY_TITLE, info.getTitle()).putString(MediaMetadataCompat.METADATA_KEY_ARTIST, info.getArtist()).putString(MediaMetadataCompat.METADATA_KEY_ALBUM, info.getAlbum()).putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, info.getArtist()).putLong(MediaMetadataCompat.METADATA_KEY_DURATION, info.getDuration()).putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, getCoverBitmap(info));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {metaData.putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, getCount());}mMediaSession.setMetadata(metaData.build());}

完整代码

package com.zdd.musicplayer.service;import android.content.Context;
import android.drm.DrmStore;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.RemoteException;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;import com.zdd.musicplayer.R;
import com.zdd.musicplayer.aidl.IPlayControl;
import com.zdd.musicplayer.manager.MediaManager;
import com.zdd.musicplayer.modle.SongInfo;
import com.zdd.musicplayer.util.StringUtils;import java.util.zip.Inflater;/*** Project: MusicPlayer* Created by Zdd on 2018/2/2.* <p>* 耳机线控* <p>* Android 5.0中新增了MediaSession类专门解决媒体播放时界面和服务通讯问题,官方说明是  允许与媒体控制器、音量键、媒体按钮和传输控件交互。* 包含了媒体控制和线控等功能* 这个框架可以让我们不再使用广播来控制播放器,而且也能适配耳机,蓝牙等一些其它设备,实现线控的功能。* <p>* 但是对于低版本上的仍需要自己控制* <p>* 参考文章 http://www.jianshu.com/p/bc2f779a5400;*/public class MediaSessionManager {private static final String TAG = "MediaSessionManager";//指定可以接收的来自锁屏页面的按键信息private static final long MEDIA_SESSION_ACTIONS =PlaybackStateCompat.ACTION_PLAY| PlaybackStateCompat.ACTION_PAUSE| PlaybackStateCompat.ACTION_PLAY_PAUSE| PlaybackStateCompat.ACTION_SKIP_TO_NEXT| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS| PlaybackStateCompat.ACTION_STOP| PlaybackStateCompat.ACTION_SEEK_TO;private final IPlayControl control;private final Context context;private MediaSessionCompat mMediaSession;private final MediaManager mediaManager;public MediaSessionManager(IPlayControl control, Context context) {this.control = control;this.context = context;this.mediaManager = MediaManager.getInstance();setupMediaSession();}/*** 初始化并激活 MediaSession*/private void setupMediaSession() {
//        第二个参数 tag: 这个是用于调试用的,随便填写即可mMediaSession = new MediaSessionCompat(context, TAG);//指明支持的按键信息类型mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);mMediaSession.setCallback(callback);mMediaSession.setActive(true);}/*** 更新播放状态, 播放/暂停/拖动进度条时调用*/public void updatePlaybackState() {int state = isPlaying() ? PlaybackStateCompat.STATE_PLAYING :PlaybackStateCompat.STATE_PAUSED;mMediaSession.setPlaybackState(new PlaybackStateCompat.Builder().setActions(MEDIA_SESSION_ACTIONS).setState(state, getCurrentPosition(), 1).build());}private long getCurrentPosition() {try {return control.getProgress();} catch (RemoteException e) {e.printStackTrace();return 0;}}/*** 是否在播放** @return*/protected boolean isPlaying() {try {return control.status() == PlayController.STATUS_PLAYING;} catch (RemoteException e) {e.printStackTrace();return false;}}/*** 更新正在播放的音乐信息,切换歌曲时调用*/public void updateMetaData(String path) {if (!StringUtils.isReal(path)) {mMediaSession.setMetadata(null);return;}SongInfo songInfo = mediaManager.getSongInfo(context, path);MediaMetadataCompat.Builder metaDta = new MediaMetadataCompat.Builder().putString(MediaMetadataCompat.METADATA_KEY_TITLE, songInfo.getTitle()).putString(MediaMetadataCompat.METADATA_KEY_ARTIST, songInfo.getArtist()).putString(MediaMetadataCompat.METADATA_KEY_ALBUM, songInfo.getAlbum()).putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, songInfo.getArtist()).putLong(MediaMetadataCompat.METADATA_KEY_DURATION, songInfo.getDuration()).putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, getCoverBitmap(songInfo));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {metaDta.putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, getCount());}mMediaSession.setMetadata(metaDta.build());}private long getCount() {try {return control.getPlayList().size();} catch (RemoteException e) {e.printStackTrace();return 0;}}private Bitmap getCoverBitmap(SongInfo info) {if (StringUtils.isReal(info.getAlbum_path())) {return BitmapFactory.decodeFile(info.getAlbum_path());} else {return BitmapFactory.decodeResource(context.getResources(), R.drawable.default_song);}}/*** 释放MediaSession,退出播放器时调用*/public void release() {mMediaSession.setCallback(null);mMediaSession.setActive(false);mMediaSession.release();}/*** API 21 以上 耳机多媒体按钮监听 MediaSessionCompat.Callback*/private MediaSessionCompat.Callback callback = new MediaSessionCompat.Callback() {//        接收到监听事件,可以有选择的进行重写相关方法@Overridepublic void onPlay() {try {control.resume();} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onPause() {try {control.pause();} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onSkipToNext() {try {control.next();} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onSkipToPrevious() {try {control.pre();} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onStop() {try {control.pause();} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onSeekTo(long pos) {try {control.seekTo((int) pos);} catch (RemoteException e) {e.printStackTrace();}}};}

参考文章

Android开源音乐播放器之播放器基本功能

音乐播放器备忘录

Android 多媒体控制 来电监听-耳机插拔监听-耳机按钮监听-MediaSession-MediaStyle

Android:MediaSession框架介绍

Android系统线控和歌曲信息屏显的那点事

android 多媒体播放 MediaSession 框架相关推荐

  1. Android 媒体播放框架MediaSession分析与实践

    版权声明:本文为博主原创文章,未经博主允许不得转载 源码:AnliaLee/BauzMusic 大家要是看到有错误的地方或者有啥好的建议,欢迎留言评论 前言 最近一直在忙着学习和研究音乐播放器,发现介 ...

  2. Android多媒体播放器源码解析(stagefright框架)

    一.android多媒体播放的调用步骤: a) android中定义一个MediaPlayer类 b) 在MediaPlayer中使用JNI技术调用的是android_media_MediaPlaye ...

  3. Android媒体播放框架MediaSessionCompat介绍实践

    前言 最近维护项目的时候遇到了MediaSessionCompat框架的音乐播放器,简单搜索记录一下这套实现播放器的结构吧. MediaSession框架简介 我们先来看看如何设计一款音乐播放App的 ...

  4. MediaSession框架介绍

    很多同学,在学习安卓的时候,可能会完成一个音乐播放器的项目,因为音乐播放器项目会贯穿安卓的四大组件.在项目中,大家一定会在服务中使用MediaPlayer去播放音乐,但是界面如何控制服务进行音乐的更换 ...

  5. 2018年android常用的框架介绍

    转载地址:http://blog.csdn.net/RuingMan/article/details/73546718 http://www.cnblogs.com/jincheng-yangchao ...

  6. 2017年Android百大第三方框架排行榜

    转载自金城:http://www.cnblogs.com/jincheng-yangchaofan 1 榜单介绍 排行榜包括四大类: 单一框架:仅提供路由.网络层.UI层.通信层或其他单一功能的框架 ...

  7. 关于Android adb实现框架和应用

    关于Android adb实现框架和应用 链接: https://pan.baidu.com/s/1tMSw6OnbgQz5GH2E8i6JKw 提取码: 7a5u 另外我的相关培训视频请看: 欢迎观 ...

  8. Android图片缓存框架Glide

    Android图片缓存框架Glide Glide是Google提供的一个组件.它具有获取.解码和展示视频剧照.图片.动画等功能.它提供了灵活的API,帮助开发者将Glide应用在几乎任何网络协议栈中. ...

  9. 15类Android通用流行框架

    15类Android通用流行框架 Android流行框架 缓存 DiskLruCache Java实现基于LRU的磁盘缓存 图片加载 Android Universal Image Loader 一个 ...

  10. Android接口和框架学习

    Android接口和框架学习 缩写: HAL:HardwareAbstraction Layer,硬件抽象层 CTS:CompatibilityTest Suite,兼容性测试套件 Android让你 ...

最新文章

  1. java ubuntu 14.04,Ubuntu 14.04安装java的方法
  2. MyBatis无限输出日志
  3. [剑指offer]面试题22:栈的压入、弹出序列
  4. Thread类和Runnable接口
  5. windows无法检索有关这台计算机上的磁盘信息_磁盘镜像软件OO DiskImage Pro 15.5介绍及安装教程...
  6. 嘉和生物-B确定发行价每股24.00港元 公开发售获认购1247.52倍
  7. sqrt()平方根计算函数的实现1——二分法
  8. Mysql数据库 自动增长 重新从0开始
  9. TFS无法连接:TF31002
  10. QQ 腾讯QQ(简称“QQ”)是腾讯公司开发的一款基于Internet的即时通信(IM)软件...
  11. Linux 卸载JDK以及安装步骤
  12. Tcl 语言——Synopsys Tcl篇
  13. android 简书饿了么,分析饿了么详情页布局
  14. Stata:快速转换工作路径
  15. 威金蠕虫(网吧杀手)肆虐互联网 九千用户十余企业遭攻击
  16. php无版权图库api,12个无版权限制的大图特供网站_交互设计教程
  17. 删除的备忘录怎么恢复
  18. 天大计算机辅助设计与制造考题,2017年CAD工程师认证考题答案及解析
  19. Echarts饼图实现颜色渐变
  20. 关于小米路由器的局域网内相互ping设备IP的解决方法

热门文章

  1. Apache doris Datax DorisWriter扩展使用方法
  2. linux skype4.3安装指令,Ubuntu下安装skype的脚本
  3. 毕业生论文必备!!让英文摘要不是难事
  4. oracle视图、函数、循环、case when
  5. CSS手写向下小三角(极简代码)
  6. 脑子傻怎么学php,小孩子学习不好脑子不开窍怎么办?4个方法让“笨”孩子聪明起来...
  7. 网站文章内容发现重复率过高的解决办法
  8. ArcGIS学习笔记-1.功能-1.1裁剪
  9. html简单图片轮播居中,html简单图片轮播的实现
  10. 终于知道电脑版微信为啥只能扫码登录了