如下是我自己研究过程的总结,想知道结果的直接看最后即可。
==============================过程总结==========================================
在上篇博客中我写到,在远程控制音乐软件的实现中,我在4.4系统里遇到了问题。需要获取到当前播放的音乐软件的包名才能解决。就在进行了一定时间的查找,意外的发现android貌似没有提供这样的api。这一下我一下丢失了方向。甚至想到直接获取系统中所有的包名,直接搜索常用音乐软件来草草完成。
最后由于时间比较充裕,就多研究了一段时间,突然想到,这既然是系统的为了耳机来完成远程控制的动作,那么系统应该会注意到这个问题才对。果然,我使用耳机上的按钮来操作,则没有任何问题。所以我开始研究android的系统源码究竟是如何做到这一点的。耳机控制需要使用Intent的,在intent.java(以下代码均来源于android4.4源码)中可以找到如下字段:
public static final String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON";
这就是android自己用于耳机控制播放器的intent action字段了,我们可以利用它来找到相关代码,很容易我们找到了这个类MediaFocusControl类,其中包含方法dispatchMediaKeyEvent():
private void dispatchMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
.................
Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
....................
mRCStack.peek().mMediaIntent.send(mContext,
needWakeLock ? WAKELOCK_RELEASE_ON_FINISHED : 0 /*code*/,
keyIntent, this, mEventHandler);
....................
}
这里讲intent发送了出去,具体去了哪里我们不用操心,我们只要知道谁用了这个intent。这里的mRCStack是一个Stack类,其中包含着我们需要的RemoteControlStackEntry类对象。我们继续查看,这个对象是在哪被放入Stack中的,最后找到pushMediaButtonReceiver_syncAfRcs()方法,其中关键部分如下:
private boolean pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent,
ComponentName target, IBinder token) {
...........
if (!wasInsideStack) {
rcse = new RemoteControlStackEntry(this, mediaIntent, target, token);
}
mRCStack.push(rcse); //rcse被push进mRCStack
..........
}
由此,可以知道这个rcse就是我们需要的对象,而他是被直接new出来的,则这个构造函数的参数就变的很重要了。查看构造函数如下:
public RemoteControlStackEntry(MediaFocusControl controller, PendingIntent mediaIntent,
ComponentName eventReceiver, IBinder token)
可以发现,里面包含了一个重要的ComponentName对象,这个对象在android中就带表着一个应用程序,看来这就是我们要找的音乐播放软件了。那么他是如何被系统拿出来的呢?我们继续找。在刚刚的构造方法创建对象过程中,这个参数是使用target变量直接放入的。而这个target是pushMediaButtonReceiver_syncAfRcs方法的一个参数,那么继续根据这个线索向上找。发现这个参量是经过registerMediaButtonIntent()传入,但是仍然是方法的一个参数,那么继续找,发现找到了源头:
protected void restoreMediaButtonReceiver() {
................
String receiverName = Settings.System.getStringForUser(mContentResolver,
Settings.System.MEDIA_BUTTON_RECEIVER, UserHandle.USER_CURRENT);
ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName);
................
registerMediaButtonIntent(pi, eventReceiver, null);
}
由此我们发现了ComponentName对象的创建过程,它使用了一个receiverName对象,这个是个String,他就是我们的目标了。这是用了system的一个方法来创建,进入发现他竟然是个hide的方法,无法作为api使用。后来分析了方法名才释然,这个适用于多用户的,android4.3以后准备加入用户系统,可惜还不完善所以不给我们用,这肯定是有一般方法的,很快找到了getString方法,其实他就是调用了getStringForUser而已,只是屏蔽了id的参数。但是还有一个小问题,其实Settings.System.MEDIA_BUTTON_RECEIVER字段也是个hide字段,是不可以当做api来用的,我想这就系统根本就是不想提供获取正在播放音乐的软件的方法,不过既然是个字段就没问题了,我们查看一下源码就能看到MEDIA_BUTTON_RECEIVER字段其实就代表着"media_button_receiver"而已。到这里我们已经可以实现功能了。方法如下,其实就简单的三句即可:
================================功能实现===========================================
String receiverName = Settings.System.getString(this.getContentResolver(),
"media_button_receiver");
ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName);
String musicPlayerPkgName = eventReceiver.getPackageName();
我们即可得到我们所需要的包名。
相关推荐
# 乐谱JS代码大全:包含播放音乐、调整音量、显示时间等 JavaScript是一种非常强大的编程语言,可以实现许多功能。在这份文档中,我们将介绍一些基于JavaScript的乐谱代码,包括播放音乐、调整音量、显示时间等功能...
10、支持指定曲目插播,即可以暂停当前播放的音乐,播放插播的曲目,播放完后返 回原来曲目断点处播放 11、支持中英文路径插播,除了指定曲目插播,同时也支持指定路径插播,只需要发 送插播的路径即可以轻松实现 12...
可 以查看当前播放音乐的相关属性,如:歌曲名,歌手,发布时间,所属专辑等等 。 2.需求分析 1、时间跟踪条:根据歌曲播放的进度,控制条自动进行追踪,用户可以随时了解 歌曲的播放进度 2、音量控制键:可以点击...
可以查看当前播放音乐的相关属性,如:歌曲名,歌手,发布时间,所属专辑等 等。 2.需求分析 1、时间跟踪条:根据歌曲播放的进度,控制条自动进展追踪,用户可以随时理解 歌曲的播放进度 2、音量控制键:可以点击...
- 当前播放的歌曲名动态显示 - 双击播放指定歌曲 文件树结构: E:. │ musicplayer.py │ musicplayer.spec │ myui.py │ playermanager.py │ ├─exe │ musicplayer.exe │ ├─mp3 ├─Qt Designer │ ...
1.本设计基于STC89C51/52(与AT89S51/52、AT89C51/52通用,可任选)单片机的电路为基础; 2.外部加上放音设备,喇叭用LM...7.有流水灯的音乐盒为扩展功能,16个led灯,当播放音乐时有个按键可以控制流水灯的画面切换~~
用户可以通过双击播放列表中的歌曲来选择并播放音乐。此外,该播放器还提供了实时的播放时间和总时间显示,使用户能够清楚地了解当前的播放进度。界面布局简洁明了,所有的控制按钮和信息展示都经过精心设计,以提供...
当前需要外部软件才能将 ReplayGain 信息写入文件标签以利用此功能。 音乐文件夹的内容以方便的结构化风格/艺术家/专辑/歌曲视图显示。 默认情况下,显示“我的音乐”文件夹或 Windows 音乐库文件夹的内容。您可以将...
nodecg-nowplaying 此捆绑包显示当前正在播放的歌曲,以及可选的消息。 要进行设置,请遵循添加捆绑软件的常规过程,但是您还需要设置首选方法: -如果您在本地运行NodeCG,请告诉您的音乐播放器/脚本将当前歌曲转储...
暂停:停止当前播放的歌曲,而显示播放的图标; ④下一首:播放歌曲列表的下一首; ⑤歌曲列表:只要播放歌曲即可将歌曲添加至列表,添加成功则更新了歌曲列表; 删除歌曲:选中歌曲列表中的歌曲后,点击旁边的删除...
3. 播放音乐:小星星,播放结束后自动停止,如果婴儿再次啼 哭步进电机进行摇床和播放音乐 手动模式下:(睡眠模式) 1. 按第一个按键进行切换 2. 电机进行旋转,禁止开启音乐(防止吵醒婴儿)模拟摇床 3.第...
快速访问当前播放歌曲允许总量控制在一个方便的途径。由于易用性,这个程序很适合初学者,但其功能无数将满足即使是最苛刻的用户和高级用户。 n7player Music Player Premium 中文版n7player Music Player Premium ...
编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,...
一共10几包,每个包几十兆。 Visual.C++编程技巧精选500例源代码 内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、...
一共10几包,每个包几十兆。 Visual.C++编程技巧精选500例源代码 内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、...
压缩包内有两个源码包,一个是注册机源程序,另一个是解密机的源程序,一套完整的参考实例。 VC+MapX源码含GPS跟踪演示 VC3D 利用VC编程在界面上实现3D文字 在MFC应用程序中浏览PDF、Word文档文件 vcdialog 自...
压缩包内有两个源码包,一个是注册机源程序,另一个是解密机的源程序,一套完整的参考实例。 VC+MapX源码含GPS跟踪演示 VC3D 利用VC编程在界面上实现3D文字 在MFC应用程序中浏览PDF、Word文档文件 vcdialog 自...
压缩包内有两个源码包,一个是注册机源程序,另一个是解密机的源程序,一套完整的参考实例。 VC+MapX源码含GPS跟踪演示 VC3D 利用VC编程在界面上实现3D文字 在MFC应用程序中浏览PDF、Word文档文件 vcdialog 自...
软件支持所有的音频插件,可以将各种音乐同时播放做成音乐串烧,可以任意混合MP3文件,运用多声卡,独立调节每个文件的音调和音速。这块软件还包含了一个10波段的图形化的平衡器,绝对是专业人士必备的DJ工具软件,...