20

実際には Android 2.x と Android 4.1 の両方で動作する ACTION_MEDIA_BUTTON 用のブロードキャスト レシーバーがありますが、何らかの奇妙な理由で、Android 2.x (のみ)では、それぞれを2 回取得します(一時停止ボタンを1 回クリックすると、もちろん):

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 でのみ発生します。

理由はありますか

(同じイベント時間ログ技術を使用して 2 番目の発生を除外することはできますが、最初に何が起こっているのかを理解し (私の側でプログラミングミスの可能性がありますか?)、それに対するより良い解決策があるかどうかを確認することを好みます)


以下の質問に答える: (「受信者をどのように正確に登録するか」)

最初にアプリのマニフェストで:

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

これにより、この謎を解決するのに役立つより完全な全体像が得られることを願っています。

4

3 に答える 3

8

このレシーバーをライブラリ (マニフェストの "mylib" 部分) で使用していることに気付きました。

これが実際に当てはまり、同じ登録コードを共有する2 つのアプリケーションによってそのレシーバーが登録されている場合、それらのイベントが2 回表示されます。

3 つのアプリケーションがそのレシーバーを登録すると、それらのイベントを 3 倍に受け取ることになります...

各アプリケーションが異なる (一意の) を使用していることを確認してください<receiver android:name

于 2013-04-05T03:25:52.567 に答える
6

私はこの問題に出くわし、ボタンを押すたびに KeyEvent.ACTION_DOWN と KeyEvent.ACTION_UP の 2 つのイベントが生成されることに気付く前に、頭を壁にぶつけました。したがって、メディア ボタンを使用するには 2 つのテストが必要です。

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

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

したがって、同じ間違いの結果としてここにいる誰かがいる場合は、おそらくこの返信が役立ちます.

于 2013-06-11T23:43:05.183 に答える
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:
        }
    }     
}
于 2013-04-03T13:09:24.317 に答える