Google Play音乐占用了所有的ACTION_MEDIA_BUTTON意图吗?

当发送带有ACTION_MEDIA_BUTTON意图的sendOrderedBroadcast(我模仿用户点击蓝牙耳机上的播放button)时,Google Play音乐将打开并播放上一个播放的专辑,而不是前台音乐播放应用程序。

如果我将其更改为sendBroadcast,Google Play音乐和当前的音乐播放应用程序(在我的案例中为潘多拉盒型拼版软件)都将制作播放button。

这只发生在Android 4.0及以上 。 是玩音乐霸占这个意图(一个bug)? 你是否怀疑潘多拉盒型录音机并没有注册成为当前的媒体button处理程序: http : //android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html

有没有一种方法可以将这个意图指向目前的音乐播放应用程序?

这是我的代码:

public void broadcastMediaIntent(MediaIntent intentType){ long eventtime = SystemClock.uptimeMillis(); Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); Intent upIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); KeyEvent downEvent = null; KeyEvent upEvent = null; switch(intentType){ case NEXT: downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT, 0); upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT, 0); break; case PLAY_PAUSE: downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0); upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0); break; case PREVIOUS: downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0); upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0); break; case FAST_FORWARD: downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, 0); upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, 0); break; case REWIND: downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_REWIND, 0); upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_REWIND, 0); break; default: break; } downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent); sendOrderedBroadcast(downIntent, null); upIntent.putExtra(Intent.EXTRA_KEY_EVENT, upEvent); sendOrderedBroadcast(upIntent, null); } 

Solutions Collecting From Web of "Google Play音乐占用了所有的ACTION_MEDIA_BUTTON意图吗?"

有一个API必须用来作为这些意图的首选接收者,但是这当然可以由系统密钥的发送者来处理。 看看这个post ,和文档 。 但在这种情况下,这是潘多拉和谷歌音乐,所以这可能不是你自己。 你当然也可以把你的广播发送到一个特定的包(通过在intent中指定组件名),然后你决定哪个应用得到它。 我在AudioManager中快速search了一个隐藏的API,但是看起来并不怎么样。

你用附件试过了吗? 如果这样做的话,我会研究如何发送意图。 如果没有,我会看看安装了哪些应用程序,并进行“智能”猜测或询问用户发送意图的应用程序。 也许最后一个是在任何情况下去的最好的方法,因为它使用公共的API,并不会惹恼用户猜错:)

编辑:这可以工作,但它也可能被权限和证书守护。 在锁屏中,媒体密钥的处理方式如下:

 void handleMediaKeyEvent(KeyEvent keyEvent) { IAudioService audioService = IAudioService.Stub.asInterface( ServiceManager.checkService(Context.AUDIO_SERVICE)); if (audioService != null) { try { audioService.dispatchMediaKeyEvent(keyEvent); } catch (RemoteException e) { Log.e("KeyguardViewBase", "dispatchMediaKeyEvent threw exception " + e); } } else { Slog.w("KeyguardViewBase", "Unable to find IAudioService for media key event"); } } 

但是,API是隐藏的,所以你必须解决这个问题。 这可能是最好的,我可以帮助你。 另一种方法是注入事件。 要做到这一点的一个方法是成为一种input方法,但这不太可能是一种前进的方式。 有几种方法可以将事件注入到自己的活动中,但我不知道是否有任何注入系统。 也许你可以看看仪器testing是如何做的。

以下应该做的伎俩。 顺便说一句,你在哪里find锁屏的源代码?

  public void handleMediaKeyEvent(KeyEvent keyEvent) { /* * Attempt to execute the following with reflection. * * [Code] * IAudioService audioService = IAudioService.Stub.asInterface(b); * audioService.dispatchMediaKeyEvent(keyEvent); */ try { // Get binder from ServiceManager.checkService(String) IBinder iBinder = (IBinder) Class.forName("android.os.ServiceManager") .getDeclaredMethod("checkService",String.class) .invoke(null, Context.AUDIO_SERVICE); // get audioService from IAudioService.Stub.asInterface(IBinder) Object audioService = Class.forName("android.media.IAudioService$Stub") .getDeclaredMethod("asInterface",IBinder.class) .invoke(null,iBinder); // Dispatch keyEvent using IAudioService.dispatchMediaKeyEvent(KeyEvent) Class.forName("android.media.IAudioService") .getDeclaredMethod("dispatchMediaKeyEvent",KeyEvent.class) .invoke(audioService, keyEvent); } catch (Exception e1) { e1.printStackTrace(); } }