Android基于MediaBroswerService的App实现概述

mSession.setPlaybackState(mStateBuilder.build());

// 5. 关联 SessionToken
setSessionToken(mSession.getSessionToken());
}
}

根据包名做权限判断之后,返回根路径

@Override

public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {

// 根据包名对每个访问端做一些访问权限判断等

}

用来根据mediaID来返回第三放App所需要获得媒体数据

@Override

public void onLoadChildren(final String parentMediaId,

final Result<List> result) {

// 根据parentMediaId返回播放列表相关信息

}

客户端连接

private void initMediaBrowser() {

//1.待连接的服务

ComponentName componentName = new ComponentName(“com.example.android.uamp”,“com.example.android.uamp.MusicService”);

//2.创建MediaBrowser

mMediaBrowser = new MediaBrowserCompat(this, componentName, mConnectionCallbacks, null);

//3.建立连接

mMediaBrowser.connect();

}

设置相应的callback,连接Callback,数据变化Callback

连接状态同步

数据变化Callback设置

private final MediaBrowserCompat.ConnectionCallback mConnectionCallbacks =
new MediaBrowserCompat.ConnectionCallback() {

@Override
public void onConnected() {
//连接成功回调
}

@Override
public void onConnectionSuspended() {
//连接中断回调
}

@Override
public void onConnectionFailed() {
//连接失败回调
}
};

MediaControllerCompat.Callback controllerCallback =

new MediaControllerCompat.Callback() {
public void onSessionDestroyed() {
//Session销毁
}

@Override
public void onRepeatModeChanged(int repeatMode) {
//循环模式发生变化
}

@Override
public void onShuffleModeChanged(int shuffleMode) {
//随机模式发生变化
}

@Override
public void onMetadataChanged(MediaMetadataCompat metadata) {
//数据变化
}

@Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
//播放状态变化
}
};

客户端与服务端数据交互

MediaBrowser通过调用subscribe,会回调到MediaService的onLoadChildren,在这里做一个判断然后构造相应的列表将列表数据返回。返回数据之后。

  • 根据MediaID获取数据

客户端通过调用subscribe方法,传递MediaID,在SubscriptionCallback的方法中进行处理。

mMediaBrowser.subscribe(“ID”, new MediaBrowserCompat.SubscriptionCallback() {
@Override
public void onChildrenLoaded(@NonNull String parentId, @NonNull List<MediaBrowserCompat.MediaItem> children) {
//children 为来自Service的列表数据
}
});

服务端和客户端之间传递的数据为MediaItem列表。MediaItem中具备的字段:MediaId,Title,SubTitle,Description,Icon,IconUri,MediaUri等字段。通过其可以帮助我们携带一些数据来进行歌曲的展示和播放。

@Override
public void onLoadChildren(@NonNull final String parentMediaId,
@NonNull final Result<List> result) {
List items = new ArrayList<>();
//根据MediaID做数据填充
switch (parent
MediaId) {
case:
default: break;
}
result.sendResult(items);
}

  • 发送自定义数据获取内容

客户端通过调用sendCustomAction,根据与服务端的协商,制定相应的action类型,进行数据的传递交互。

mMediaBrowser.sendCustomAction(action, extras, new MediaBrowserCompat.CustomActionCallback() {
@Override
public void onProgressUpdate(String action, Bundle extras, Bundle data) {
super.onProgressUpdate(action, extras, data);
}

@Override
public void onResult(String action, Bundle extras, Bundle resultData) {
super.onResult(action, extras, resultData);
}

@Override
public void onError(String action, Bundle extras, Bundle data) {
super.onError(action, extras, data);
}
});

服务端实现onCustomAction,根据action类型返回相应的数据

@Override
public void onCustomAction(@NonNull String action, Bundle extras, @NonNull Result result) {
//分支判断
if (GET_LIST.equals(action)) {
Bundle bundle = new Bundle();
ArrayList list = new ArrayList<>();
//填充数据
bundle.putStringArrayList(LIST_NAMES, list);
result.sendResult(bundle);
}
}

播放控制

  • 客户端

客户端通过getMediaController getTransportControls()来进行播放,暂停,上一首,下一首的控制。

//获取播放状态
int pbState = MediaControllerCompat.getMediaController(MainActivity.this).getPlaybackState().getState();
//根据播放状态进行播放控制
if (pbState == PlaybackStateCompat.STATE_PLAYING) {
MediaControllerCompat.getMediaController(MainActivity.this).getTransportControls().pause();
} else {
MediaControllerCompat.getMediaController(MainActivity.this).getTransportControls().play();
}

  • 服务端

在服务端为MediaSession设置SessionCallback,来实现相应的播放功能。

mSession.setCallback(mSessionCallback);

image.png

客户端通过MediaController可以进行播放,暂停,根据MediaID播放下一个音乐,音乐播放快进等。所有的操作会回调到服务端的MediaSessionCallback的play,seekTo等方法,需要我们自己实现,在其中控制播放队列,然后根据列表播放的情况来动态的变更队列。

播放状态同步

对于播放状态的同步,比如当前播放到哪一个歌曲,当前是暂停还是播放中。客户端通过Controller回调就可以得到相应的变化,但是,变化状态,服务端如何发送呢?

setMetadata(android.media.MediaMetadata));
setPlaybackState(android.media.session.PlaybackState));

设置当前的歌曲信息,设置当前的播放状态。设置之后,客户端将会得到更新。

获取手机内的媒体服务

private void discoverBrowseableMediaApps(Context context) {
PackageManager packageManager = context.getPackageManager();
Intent intent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
List services = packageManager.queryIntentServices(intent, 0);
for (ResolveInfo resolveInfo : services) {
if (resolveInfo.serviceInfo != null && resolveInfo.serviceInfo.applicationInfo != null) {

ApplicationInfo applicationInfo = resolveInfo.serviceInfo.applicationInfo;
String label = (String) packageManager.getApplicationLabel(applicationInfo);
Drawable icon = packageManager.getApplicationIcon(applicationInfo);
String className = resolveInfo.serviceInfo.name;
String packageName = resolveInfo.serviceInfo.packageName;

MusicService service = new MusicService();
service.icon = icon;
service.lable = label;
service.className = className;
service.packageName = packageName;
musicServiceList.add(service);
}
}

}

结语

通过本篇文章,对MediaBroswerService做了一个简单的介绍,但对于播放器的具体实现,特别是在服务端还是比较复杂的,需要维护歌曲队列,进行播放,同时负责状态的更新。

最后,小编这里放上自己整理的Android学习思维脑图及架构资料。

image

资料领取

点赞+加群免费获取 Android IOC架构设计

加群领取获取往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-uyDfPFGj-1718987439150)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取
id工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助**。

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-uyDfPFGj-1718987439150)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/732375.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论文解读:Pandora: 朝着结合自然语言动作与视频状态的通用世界模型发展

论文《Pandora: 朝着结合自然语言动作与视频状态的通用世界模型发展》探索了构建一个高度集成的AI系统&#xff0c;旨在理解自然语言指令并在视频所代表的视觉环境中执行相应操作&#xff0c;从而推进对复杂动态场景的建模与预测能力。以下是该论文的关键点和贡献的详细解读&am…

无法打开微软商店

今天给大家讲一下我在使用win11系统时遇到的一些问题&#xff0c;希望对出现类似情况的人有所帮助。 首先就是微软商店打不开的问题。相信许多windows系统的用户都会碰到此问题。我在打开时会出 现一直转圈的界面&#xff0c;在网上找了一些方法&#xff0c;但都没什么用处。…

小阿轩yx-MySQL数据库初体验

小阿轩yx-MySQL数据库初体验 数据库简介 21 世纪迈入了“信息爆炸时代”&#xff0c;大量的数据、信息在不断产生&#xff0c;伴随而来的就是如何安全、有效地存储、检索和管理它们。 对数据的有效存储、高效访问、方便共享和安全控制已经成为信息时代亟待解决的问题。 使用…

【STM32-MAP文件分析】

STM32-MAP文件分析 ■ MDK编译生成文件简介■ .o■ .axf■ .hex■ .crf■ .d■ .dep■ .lnp■ .lst■ .map■ .build_log.htm■ .htm 文件■ .map 文件 ■ map文件分析■ map 文件的 MDK 设置■ 1. 要生成 map 文件 在 Listing 选项卡里面■ 2. Keil5 中打开.map 文件 ■ map 文…

来自 Kubecon Paris 的快讯

一年一度的 KubeconEU 审查时间到了——它未经过滤&#xff0c;偶尔不受 CNCF 的欢迎——但剧透警告&#xff0c;巴黎取得了巨大的成功。我们总是爱这里的人&#xff0c;我们并不总是爱场地或演出管理&#xff0c;但巴黎是一场胜利&#xff0c;更重要的是&#xff0c;Kubernete…

无线麦克风一拖二哪个牌子好,揭秘目前音质最好的麦克风

在自媒体的世界里&#xff0c;无线领夹麦克风已经成了一种标准配置&#xff0c;它受到广大视频创作者的青睐。无论是刚刚踏入短视频领域的新手&#xff0c;还是已经拥有丰富经验的资深博主&#xff0c;都深知一款好的领夹麦克风对于提升视频音频质量的重要性。它不仅能帮助创作…

从数据资源到数据资产之数据要素及其市场运作【AMT企源】

题记 本文旨在探讨企业数据资产化的过程中&#xff0c;数据要素及其资产化市场的构成&#xff0c;形成可交易的数据产品的过程&#xff0c;以及如何在大数据交易市场中发挥价值。最后通过一个典型案例的分析&#xff0c;浅谈数据要素的社会化配置与数据资产的入表&#xff0c;…

深度学习Day-21:ResNet与DenseNet结合

&#x1f368; 本文为&#xff1a;[&#x1f517;365天深度学习训练营] 中的学习记录博客 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] 要求&#xff1a; 探索ResNet与DenseNet结合的可能性根据模型特性构建新的模型框架验证改进后模型的效果 一、 基础配…

【教程】PVE下uhd630核显直通HDMI输出 以NUC9为例村雨Murasame

大家好&#xff0c;村雨本雨又来发教程了 最近在搞小主机&#xff0c;之前hp400g3仅仅200多元成功核显直通HDMI&#xff0c;作为简单NAS、解码机、伺服机、中控都非常棒&#xff0c;待机仅9w 村雨Murasame&#xff1a;【教程】7代核显直通HDMI成功输出画面 PVE下7代intel核显…

Android studio安卓期末大作业,智学英语App

目录 1 系统主要功能 2 登陆 3 主菜单界面 4 单词查询 5 美文阅读 6 客服聊天 7 关于我们 1 系统主要功能 应用启动 打开应用&#xff0c;将看到一个欢迎界面&#xff0c;这通常是一个简短的动画或静态图像&#xff0c;用于引导进入主界面。 登录功能 &#xff08;1…

R语言数据分析案例32-针对芬兰污染指数的分析与考察

一、 研究背景及意义 近年来&#xff0c;随着我国科技和经济高速发展&#xff0c;人们生活质量也随之显著提高。但是&#xff0c; 环境污染问题也日趋严重&#xff0c;给人们的生活质量和社会生产的各个方面都造成了许多不 利的影响。空气污染作为环境污染主要方面&#xff0c…

keepalive+nginx高可用架构

keepalivenginx架构 一.配置真实服务器web1和web2 1.关闭防火墙&#xff0c;并在真实服务器下载http服务 [rootlocalhost ~]# systemctl stop firewalld.service [rootlocalhost ~]# setenforce 0 [rootlocalhost ~]# yum install httpd -y 2.分别在web1和web2上制作网页…

慎投!新增7本期刊被“On Hold“,14本影响因子下降!

本周投稿推荐 SSCI • 中科院2区&#xff0c;6.0-7.0&#xff08;录用友好&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; CNKI • 7天录用-检索&#xff08;急录友好&#xff09; SCI&EI • 4区生物医学类&#xff0c;0.5-1.0&#xff08;录用…

如何使用Excel与Outlook实现邮件群发:详细教程

引言 在工作中&#xff0c;我们经常需要发送大量邮件。手动发送既费时又容易出错。本教程将教你如何使用Excel和Outlook&#xff0c;通过简单的VBA代码实现邮件的自动群发&#xff0c;提高工作效率。 准备工作 在开始之前&#xff0c;你需要确保以下工具已经安装在电脑上&am…

骨传导耳机值不值得入手?五款运动好物骨传导耳机推荐!

开放式耳机在如今社会中已经迅速成为大家购买耳机的新趋势&#xff0c;开放式蓝牙耳机作为骨传导耳机&#xff0c;深受喜欢听歌和热爱运动的人群欢迎。当大家谈到佩戴的稳固性时&#xff0c;后挂式骨传导耳机都会收到一致好评。对于热爱运动的人士而言&#xff0c;高品质的骨传…

WordPress插件:子比zibll主题插件 炙焰美化全开源插件V3.2

在网络世界中&#xff0c;开源内容管理系统&#xff08;CMS&#xff09;已经成为了网站构建的关键工具之一。WordPress&#xff0c;作为最受欢迎的开源CMS之一&#xff0c;其广泛的应用及其灵活性使得它成为了创建和管理各种类型网站的理想选择。而Zibll主题插件&#xff0c;作…

vue3中h函数的使用

h函数是用于创建一个 vnodes &#xff0c;它既可以用于创建原生元素&#xff0c;也可以创建组件&#xff0c;其渲染后的效果等同于使用模版语言来进行创建。 h函数的传参如下&#xff1a; // 完整参数签名 function h(type: string | Component,props?: object | null,child…

【GD32F303红枫派使用手册】第二十二节 IIC-IIC OLED显示实验

22.1 实验内容 通过本实验主要学习以下内容&#xff1a; OLED驱动原理 IIC驱动OLED显示操作 22.2 实验原理 OLED模块的驱动芯片为SSD1306&#xff0c;其显存大小总共为 128*64bit 大小&#xff0c;SSD1306 将这些显存分为了 8 页&#xff0c;其对应关系如下所示&#xff1…

如何将办公文档压缩成rar格式文件?

压缩包格式是我们生活工作中常用到的文件格式&#xff0c;那么如何得到一个rar格式的压缩文件&#xff1f;或者说如何将文件压缩成rar格式而不是zip格式呢&#xff1f;今天我们来了解一下如何压缩为rar格式文件。 首先&#xff0c;下载并安装WinRAR&#xff0c;然后用鼠标选择需…

FlinkCDC介绍及使用

CDC简介 什么是CDC&#xff1f; cdc是Change Data Capture(变更数据获取)的简称。核心思想是&#xff0c;监测并捕获数据库的 变动(包括数据或数据表的插入&#xff0c;更新以及删除等)&#xff0c;将这些变更按发生的顺序完整记录下来&#xff0c;写入到消息中间件以供其它服…