android 多媒体播放 MediaSession 框架
概念性简述
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 框架相关推荐
- Android 媒体播放框架MediaSession分析与实践
版权声明:本文为博主原创文章,未经博主允许不得转载 源码:AnliaLee/BauzMusic 大家要是看到有错误的地方或者有啥好的建议,欢迎留言评论 前言 最近一直在忙着学习和研究音乐播放器,发现介 ...
- Android多媒体播放器源码解析(stagefright框架)
一.android多媒体播放的调用步骤: a) android中定义一个MediaPlayer类 b) 在MediaPlayer中使用JNI技术调用的是android_media_MediaPlaye ...
- Android媒体播放框架MediaSessionCompat介绍实践
前言 最近维护项目的时候遇到了MediaSessionCompat框架的音乐播放器,简单搜索记录一下这套实现播放器的结构吧. MediaSession框架简介 我们先来看看如何设计一款音乐播放App的 ...
- MediaSession框架介绍
很多同学,在学习安卓的时候,可能会完成一个音乐播放器的项目,因为音乐播放器项目会贯穿安卓的四大组件.在项目中,大家一定会在服务中使用MediaPlayer去播放音乐,但是界面如何控制服务进行音乐的更换 ...
- 2018年android常用的框架介绍
转载地址:http://blog.csdn.net/RuingMan/article/details/73546718 http://www.cnblogs.com/jincheng-yangchao ...
- 2017年Android百大第三方框架排行榜
转载自金城:http://www.cnblogs.com/jincheng-yangchaofan 1 榜单介绍 排行榜包括四大类: 单一框架:仅提供路由.网络层.UI层.通信层或其他单一功能的框架 ...
- 关于Android adb实现框架和应用
关于Android adb实现框架和应用 链接: https://pan.baidu.com/s/1tMSw6OnbgQz5GH2E8i6JKw 提取码: 7a5u 另外我的相关培训视频请看: 欢迎观 ...
- Android图片缓存框架Glide
Android图片缓存框架Glide Glide是Google提供的一个组件.它具有获取.解码和展示视频剧照.图片.动画等功能.它提供了灵活的API,帮助开发者将Glide应用在几乎任何网络协议栈中. ...
- 15类Android通用流行框架
15类Android通用流行框架 Android流行框架 缓存 DiskLruCache Java实现基于LRU的磁盘缓存 图片加载 Android Universal Image Loader 一个 ...
- Android接口和框架学习
Android接口和框架学习 缩写: HAL:HardwareAbstraction Layer,硬件抽象层 CTS:CompatibilityTest Suite,兼容性测试套件 Android让你 ...
最新文章
- java ubuntu 14.04,Ubuntu 14.04安装java的方法
- MyBatis无限输出日志
- [剑指offer]面试题22:栈的压入、弹出序列
- Thread类和Runnable接口
- windows无法检索有关这台计算机上的磁盘信息_磁盘镜像软件OO DiskImage Pro 15.5介绍及安装教程...
- 嘉和生物-B确定发行价每股24.00港元 公开发售获认购1247.52倍
- sqrt()平方根计算函数的实现1——二分法
- Mysql数据库 自动增长 重新从0开始
- TFS无法连接:TF31002
- QQ 腾讯QQ(简称“QQ”)是腾讯公司开发的一款基于Internet的即时通信(IM)软件...
- Linux 卸载JDK以及安装步骤
- Tcl 语言——Synopsys Tcl篇
- android 简书饿了么,分析饿了么详情页布局
- Stata:快速转换工作路径
- 威金蠕虫(网吧杀手)肆虐互联网 九千用户十余企业遭攻击
- php无版权图库api,12个无版权限制的大图特供网站_交互设计教程
- 删除的备忘录怎么恢复
- 天大计算机辅助设计与制造考题,2017年CAD工程师认证考题答案及解析
- Echarts饼图实现颜色渐变
- 关于小米路由器的局域网内相互ping设备IP的解决方法
热门文章
- Apache doris Datax DorisWriter扩展使用方法
- linux skype4.3安装指令,Ubuntu下安装skype的脚本
- 毕业生论文必备!!让英文摘要不是难事
- oracle视图、函数、循环、case when
- CSS手写向下小三角(极简代码)
- 脑子傻怎么学php,小孩子学习不好脑子不开窍怎么办?4个方法让“笨”孩子聪明起来...
- 网站文章内容发现重复率过高的解决办法
- ArcGIS学习笔记-1.功能-1.1裁剪
- html简单图片轮播居中,html简单图片轮播的实现
- 终于知道电脑版微信为啥只能扫码登录了