KeyEvent.ACTION_UP fired TWICE for ACTION_MEDIA_BUTTON

旧街凉风 提交于 2019-12-12 07:44:57

问题


I have this broadcast receiver for ACTION_MEDIA_BUTTON which actually works for both Android 2.x and Android 4.1, but for some strange reason, on Android 2.x (only), I get each even twice (for a single click on the pause button, of course):

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:
        }
      }     
    }
  }

}

Attempting to understand the mystery, I log the event time for each such occurrence:

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)

Again, this double-occurrence doesn't happen in Android 4.1. It only happens in Android 2.x.

Any idea why?

(while I can use the same event time logging technique to filter-out the second occurrence, I prefer to understand first what's happening (possible programming mistake on my side?) and to see whether there is a better solution for that)


Answering the question below: ("how exactly you register your receiver")

First in the app's manifest:

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

Then, in my library's activity (per this tip), in OnCreate():

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

I hope this provides a more complete picture that can help solve this mystery.


回答1:


I noticed that you are using this receiver in a library (the "mylib" part in your manifest).

If this is indeed the case and you have that receiver registered by two applications sharing the same registration code, you will see those events twice.

If three applications register that receiver, you will receive those events tripled...

Make sure that each application uses a different (unique) <receiver android:name.




回答2:


I ran across this issue and spent a while banging my head against the wall before I realized that each press of the button generates two events: a KeyEvent.ACTION_DOWN, and a KeyEvent.ACTION_UP. So two tests are needed to use a media button:

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

and

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

So if anyone else finds themselves here as a result of the same mistake, perhaps this reply will help.




回答3:


For ensuring that it's the first time always you can use a flag to tell that it's the first action.

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:
        }
    }     
}


来源:https://stackoverflow.com/questions/15168803/keyevent-action-up-fired-twice-for-action-media-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!