如何从我的汽车方向盘下方的控件中捕捉事件

How to catch up events from controls below steering wheel in my car

有一辆控制在方向盘下方的汽车。按钮是:next/previous track, volume up/down, ok, source。我想赶上 Next/Previous 曲目按钮。

我已经在 activity 中尝试了 onKeyDown,但没有成功。我也试过 BroadcastReceiverMediaButtonReceiver 没有效果。似乎该应用程序没有看到任何事件。设备调试的可能性很小,实际上是没有的。

  1. 有没有办法捕捉到这样的事件?
  2. 如何在 android 中找到一些连接到 phone 的硬件。可能是每个连接设备的枚举器 class?

更新 1:

我试过:

1.

<receiver
   android:name="android.support.v4.media.session.MediaButtonReceiver">
   <intent-filter>
     <action android:name="android.intent.action.MEDIA_BUTTON" />
     <action android:name="android.media.browse.MediaBrowserService" />
   </intent-filter>
</receiver>

<service
  android:name=".OrionPlaybackService"
  android:enabled="true"
  android:exported="true"
  tools:ignore="ExportedService">
  <intent-filter>
    <action android:name="android.intent.action.MEDIA_BUTTON" />
    <action android:name="android.media.browse.MediaBrowserService" />
  </intent-filter>
</service>

public class OrionPlaybackService extends MediaBrowserServiceCompat {
  private MediaSessionCompat mediaSessionCompat;
  ...
  private final MediaSessionCompat.Callback callback = new 
    MediaSessionCompat.Callback() {
    ...
    @Override
    public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
      Toast.makeText(getBaseContext(), "onMediaButtonEvent", Toast.LENGTH_SHORT).show();
      Log.d(static_variables.TAG, "onMediaButtonEvent");
      static_functions.addLocalLogRecord(getApplicationContext(), "onMediaButtonEvent");
      return super.onMediaButtonEvent(mediaButtonEvent);
      }
    ...
}
  @Override
  public void onCreate() {
    Toast.makeText(getBaseContext(), "Service created", Toast.LENGTH_SHORT).show();
    Log.d(static_variables.TAG, "Service created");
    static_functions.addLocalLogRecord(getApplicationContext(), "Service created");
    if (mediaSessionCompat==null) {
      mediaSessionCompat = new MediaSessionCompat(getApplicationContext(), "OrionPlaybackService");
 mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
 mediaSessionCompat.setCallback(callback);
 mediaSessionCompat.setActive(true);
  }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(getBaseContext(), "Command received", Toast.LENGTH_SHORT).show();
    Log.d(static_variables.TAG, "Command received");
    static_functions.addLocalLogRecord(getApplicationContext(), "Command received");
    MediaButtonReceiver.handleIntent(mediaSessionCompat, intent);
    return super.onStartCommand(intent, flags, startId);
  }
}
  1. 使用

    以编程方式创建接收器
    createReceiver.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
      IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
      //intentFilter.setPriority(Integer.MAX_VALUE);
      intentFilter.setPriority(999);
      context.registerReceiver(new SteeringWheelReceiver(), intentFilter);
      }
    });
    

有两个优先级 999 和 7FFF FFFF。

  1. 创建接收器

    createReceiver2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            ComponentName mReceiverComponent = new ComponentName(context, SteeringWheelReceiver.class);
            audioManager.registerMediaButtonEventReceiver(mReceiverComponent);
            Toast.makeText(context, "Receiver 2 registered", Toast.LENGTH_SHORT).show();
        }
    });
    
  2. 创建接收器

    createReceiver3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            ComponentName mReceiverComponent = new ComponentName(context, OrionPlaybackService.class);
            audioManager.registerMediaButtonEventReceiver(mReceiverComponent);
            Toast.makeText(context, "Receiver 3 registered", Toast.LENGTH_SHORT).show();
        }
    });
    

我的 class SteeringWheel 是

public class SteeringWheelReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    Toast.makeText(context, "onMediaButtonEvent", Toast.LENGTH_SHORT).show();
    Log.d(static_variables.TAG, "onMediaButtonEvent");
    static_functions.addLocalLogRecord(context, "onMediaButtonEvent");
  }
}
  1. 测试按钮是

    sendBroadcast.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
            context.sendBroadcast(intent);
        }
    });
    
    emulateMedia.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY);
            audioManager.dispatchMediaKeyEvent(keyEvent);
            keyEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY);
            audioManager.dispatchMediaKeyEvent(keyEvent);
        }
    });
    
  2. 所以当我什么都不做,或者当我点击 Test buttons 中的任何一个变体(无论如何)创建接收器时,我看到吐司、日志消息和其他。当我尝试在方向盘上按 Next track 时,我没有任何消息。就像什么都没发生一样。

  3. 这不是媒体按钮?但是什么? USB 分子向我显示两个设备 1. 调制解调器 2. 闪存卡。输入设备向我显示 3 个设备、触摸屏或其他?不管怎样,rk29-keypad - 我想那是我的设备。
  4. VLC 播放器使用媒体按钮没有问题。 VLC 有一个开源的。但是 copy/paste(见上面的方法)什么也没给我。

我开始相信奇迹了...

已解决。

重要的三件事(虽然不知道为什么第一件事)

  1. 所有接收者的注册都应该在服务中完成。未使用 activity 中的按钮。都在服役。还有 2 和 3.

  2. 忘记了

mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);

其他应用程序(内置)获得焦点。

  1. Android 4.4.2 有 RemoteControlClient 而不是 MediaSessionCompat。可能取决于当前的测试设备(非标准)。