如何获取当前正在播放音乐的音乐软件的包名

 我来答
huanglenzhi
推荐于2016-02-29 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117525 获赞数:517224
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
  耳机控制需要使用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 ,

  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();

  我们即可得到我们所需要的包名。
上海风华峻极智能科技
2022-05-05 广告
上海风华峻极智能科技有限公司【远程会议视频系统】一体化解决方案,如同面对面开会一般,让远程会议更简单,多种会议场景布局,舞台设备厂家,高保真语音的传输,极速快捷远程会议体验,只为高效沟通,支持万人及多房间同时在线.... 点击进入详情页
本回答由上海风华峻极智能科技提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式