Подтвердить что ты не робот

KeyEvent.ACTION_UP активирован TWICE для ACTION_MEDIA_BUTTON

У меня есть этот широковещательный приемник для 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>

Затем в моей библиотечной деятельности (за этот совет) в OnCreate():

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

Надеюсь, это даст более полную картину, которая поможет решить эту тайну.

4b9b3361

Ответ 1

Я заметил, что вы используете этот приемник в библиотеке (часть "mylib" в вашем манифесте).

Если это действительно так, и у вас есть этот реестр, зарегистрированный двумя приложениями, использующими один и тот же регистрационный код, вы увидите эти события дважды.

Если три приложения регистрируют этот приемник, вы получите эти события в три раза...

Убедитесь, что каждое приложение использует другой (уникальный) <receiver android:name.

Ответ 2

Я столкнулся с этой проблемой и провел некоторое время, ударяя головой о стену, прежде чем понял, что каждое нажатие кнопки генерирует два события: KeyEvent.ACTION_DOWN и KeyEvent.ACTION_UP. Поэтому для использования медиа-кнопки необходимы два теста:

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

и

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

Итак, если кто-то еще окажется здесь в результате одной и той же ошибки, возможно, этот ответ поможет.

Ответ 3

Для обеспечения того, чтобы в первый раз вы всегда могли использовать флаг, чтобы сказать, что это первое действие.

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