Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/197.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 谷歌播放音乐是否占据了所有动作、媒体和按钮的意图?_Android_Android Intent - Fatal编程技术网

Android 谷歌播放音乐是否占据了所有动作、媒体和按钮的意图?

Android 谷歌播放音乐是否占据了所有动作、媒体和按钮的意图?,android,android-intent,Android,Android Intent,当发送带有动作\媒体\按钮意图的sendOrderedBroadcast(我模仿用户在蓝牙耳机上单击播放按钮)时,Google play Music会打开并播放播放的最后一张专辑,而不是前台音乐播放应用程序 如果我把它改为sendBroadcast,Google Play Music和当前的音乐播放应用程序(在我的例子中是Pandora)都会执行播放按钮 这只发生在Android 4.0及以上版本中。播放音乐是否占据了这一意图(一个bug)?您是否怀疑Pandora没有按照以下建议注册为当前媒体

当发送带有动作\媒体\按钮意图的sendOrderedBroadcast(我模仿用户在蓝牙耳机上单击播放按钮)时,Google play Music会打开并播放播放的最后一张专辑,而不是前台音乐播放应用程序

如果我把它改为sendBroadcast,Google Play Music和当前的音乐播放应用程序(在我的例子中是Pandora)都会执行播放按钮

这只发生在Android 4.0及以上版本中。播放音乐是否占据了这一意图(一个bug)?您是否怀疑Pandora没有按照以下建议注册为当前媒体按钮处理程序:

是否有一种方法可以将此意图仅指向当前的音乐播放应用程序

这是我的密码:

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

}

您必须使用一个API作为这些意图的首选接收者,但这当然可以由系统密钥的发送者来处理。看看,然后。但在这种情况下,这取决于潘多拉和谷歌音乐,所以这可能不取决于你。当然,您也可以将广播发送到特定的包(通过在intent中指定组件名称),但随后您可以决定哪个应用程序可以接收广播。我在AudioManager中快速搜索了一个隐藏的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是隐藏的,因此您必须解决这个问题。这可能是我能帮助你的最好办法了。另一种方法是注入事件。实现这一目标的一种方法是成为一种输入法,但这不太可能是前进的方向。有几种方法可以将事件注入到您自己的活动中,但我不知道有哪种方法可以注入到系统中。也许您可以看看仪器测试是如何进行的。

下面的内容应该可以做到这一点。 顺便问一下,你在哪里找到锁屏的源代码

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

我没有试过配饰,因为我没有。但愿我能。有没有办法找到当前音乐播放应用程序的组件名称?我不知道是否有可能做出明智的猜测,因为发送有序广播取决于应用程序的优先级。我假设最终其他应用程序(如Pandora)将更新到新的API…你总是可以看到哪些应用程序正在运行,但作为一个用户,我更喜欢设置(可能用一些“AI”备份)提供建议和/或默认值。也可以选择查看日志,但我不建议这样做,因为它非常不可靠。对于没有附件的测试,您可以查看我自己没有测试过这些。因此我可以尝试使用真正的附件。它可以使用三星蓝牙耳机正常工作。当前的foregrPandora应用程序响应耳机上的播放暂停和下一步按钮。耳机是否具有某种特殊的访问权限?我如何构建我的意图,使其看起来像来自耳机一样?使用你指给我的媒体按钮应用程序显示与我的应用程序相同的行为。Google play只是打开并使用意图,而不是Pandora或其他应用程序好的,潘多拉在音频服务(私有api)和PhoneWindowManager(隐藏)中注册了自己调用音频服务以调用注册期间创建的挂起意图。所有这些都是隐藏的。但是,如果您能够以某种方式注入事件,那么看看会发生什么情况会很有趣。将事件注入到活动可能没有任何好处,这就是我到目前为止发现的activity.dispatchKeyEvent()。我会继续找。有一个答案与此相关,但它没有反映。它只是使用AudioManager。