KeyEvent.ACTION_UP为ACTION_MEDIA_BUTTON触发了TWICE

时间:2013-03-01 23:45:43

标签: android broadcastreceiver android-audiomanager

我有ACTION_MEDIA_BUTTON的广播接收器,它实际上适用于Android 2.x和Android 4.1,但由于一些奇怪的原因,在 Android 2.x(仅限),我得到每个偶数两次(当然,暂停按钮单击):

public class RemoteControlReceiver extends BroadcastReceiver {
  private static long prevEventTime = 0;

  @Override
  public void onReceive(Context ctx, Intent intent) {
    if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
      KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
      long curEventTime = event.getEventTime();
      if (event != null && (event.getAction() == KeyEvent.ACTION_UP) /*&& (curEventTime != prevEventTime)*/) {
        int keycode = event.getKeyCode();
        switch (keycode)
        {
          case KeyEvent.KEYCODE_MEDIA_NEXT:
            Log.i(TAG, "KEYCODE_MEDIA_NEXT"); 
            break;
          case KeyEvent.KEYCODE_HEADSETHOOK:
            Log.i(TAG, "KEYCODE_HEADSETHOOK" + " " +  curEventTime + " <> " + prevEventTime + " (" + event.getAction() + ")");
            prevEventTime = curEventTime;
            break;
          case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
            Log.i(TAG, "KEYCODE_MEDIA_PREVIOUS"); 
            break;
          default:
        }
      }     
    }
  }

}

尝试理解这个谜团,我记录每次发生的事件时间:

03-01 18:27:05.264: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142304436 <> 0 (1)
03-01 18:27:05.434: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142304436 <> 142304436 (1)

03-01 18:27:14.054: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142313265 <> 142304436 (1)
03-01 18:27:14.074: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142313265 <> 142313265 (1)

03-01 18:27:24.254: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142323464 <> 142313265 (1)
03-01 18:27:24.264: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142323464 <> 142323464 (1)

03-01 18:27:37.574: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142336795 <> 142323464 (1)
03-01 18:27:37.614: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142336795 <> 142336795 (1)

03-01 18:27:45.214: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142344433 <> 142336795 (1)
03-01 18:27:45.284: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142344433 <> 142344433 (1)

03-01 18:27:52.474: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142351687 <> 142344433 (1)
03-01 18:27:52.504: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142351687 <> 142351687 (1)

同样,这种双重发生在Android 4.1中不会发生。它只发生在Android 2.x中。

任何想法为什么?

(虽然我可以使用相同的事件时间记录技术来过滤掉第二次出现,但我更喜欢先了解发生了什么(我可能会出现编程错误?)并查看是否有更好的解决方案)


回答以下问题:(“您如何准确注册接收方”)

首先在应用程序的清单中:

<receiver android:name="com.example.mylib.RemoteControlReceiver" android:enabled="true">
    <intent-filter android:priority="2147483647" >
        <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</receiver>

然后,在我的图书馆的活动中(每this tip),在OnCreate()中:

mRemoteControlReceiver = new ComponentName(this, RemoteControlReceiver.class);
mAudioManager.registerMediaButtonEventReceiver(mRemoteControlReceiver);

我希望这能提供一个更完整的图片来帮助解决这个谜。

3 个答案:

答案 0 :(得分:8)

我注意到你在图书馆中使用这个接收器(清单中的&#34; mylib&#34;部分)。

如果确实如此,并且您的两个应用程序注册的接收者共享相同的注册码,您会看到两次的事件。

如果三个应用程序注册了该接收者,您将收到这些事件三倍......

确保每个应用程序使用不同的(唯一的)<receiver android:name

答案 1 :(得分:6)

我遇到了这个问题并花了一些时间撞到墙上,然后才意识到按下按钮会产生两个事件:KeyEvent.ACTION_DOWN和KeyEvent.ACTION_UP。因此,使用媒体按钮需要两个测试:

if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {}

if (event.getAction() == KeyEvent.ACTION_DOWN) {}

因此,如果其他人因为同样的错误而发现自己在这里,也许这个回复会有所帮助。

答案 2 :(得分:0)

为了确保这是第一次总是你可以使用一个标志告诉它这是第一次行动。

boolean firstAction= false;
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
    firstAction= !firstAction;
    if(!firstAction)
    {
        return true;
    }

    KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
    long curEventTime = event.getEventTime();
    if (event != null && (event.getAction() == KeyEvent.ACTION_UP) /*&& (curEventTime != prevEventTime)*/) {
        int keycode = event.getKeyCode();
        switch (keycode)
        {
          case KeyEvent.KEYCODE_MEDIA_NEXT:
            Log.i(TAG, "KEYCODE_MEDIA_NEXT"); 
            break;
          case KeyEvent.KEYCODE_HEADSETHOOK:
            Log.i(TAG, "KEYCODE_HEADSETHOOK" + " " +  curEventTime + " <> " + prevEventTime + " (" + event.getAction() + ")");
            prevEventTime = curEventTime;
            break;
          case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
            Log.i(TAG, "KEYCODE_MEDIA_PREVIOUS"); 
            break;
          default:
        }
    }     
}