如何从我的汽车方向盘下方的控件中捕捉事件
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
,但没有成功。我也试过 BroadcastReceiver
和 MediaButtonReceiver
没有效果。似乎该应用程序没有看到任何事件。设备调试的可能性很小,实际上是没有的。
- 有没有办法捕捉到这样的事件?
- 如何在 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);
}
}
使用
以编程方式创建接收器
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。
创建接收器
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();
}
});
创建接收器
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");
}
}
测试按钮是
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);
}
});
所以当我什么都不做,或者当我点击 Test buttons
中的任何一个变体(无论如何)创建接收器时,我看到吐司、日志消息和其他。当我尝试在方向盘上按 Next track
时,我没有任何消息。就像什么都没发生一样。
- 这不是媒体按钮?但是什么? USB 分子向我显示两个设备 1. 调制解调器 2. 闪存卡。输入设备向我显示 3 个设备、触摸屏或其他?不管怎样,
rk29-keypad
- 我想那是我的设备。
- VLC 播放器使用媒体按钮没有问题。 VLC 有一个开源的。但是 copy/paste(见上面的方法)什么也没给我。
我开始相信奇迹了...
已解决。
重要的三件事(虽然不知道为什么第一件事)
所有接收者的注册都应该在服务中完成。未使用 activity 中的按钮。都在服役。还有 2 和 3.
忘记了
mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
其他应用程序(内置)获得焦点。
- Android 4.4.2 有
RemoteControlClient
而不是 MediaSessionCompat
。可能取决于当前的测试设备(非标准)。
有一辆控制在方向盘下方的汽车。按钮是:next/previous track, volume up/down, ok, source。我想赶上 Next/Previous 曲目按钮。
我已经在 activity 中尝试了 onKeyDown
,但没有成功。我也试过 BroadcastReceiver
和 MediaButtonReceiver
没有效果。似乎该应用程序没有看到任何事件。设备调试的可能性很小,实际上是没有的。
- 有没有办法捕捉到这样的事件?
- 如何在 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);
}
}
使用
以编程方式创建接收器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。
创建接收器
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(); } });
创建接收器
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");
}
}
测试按钮是
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); } });
所以当我什么都不做,或者当我点击
Test buttons
中的任何一个变体(无论如何)创建接收器时,我看到吐司、日志消息和其他。当我尝试在方向盘上按Next track
时,我没有任何消息。就像什么都没发生一样。- 这不是媒体按钮?但是什么? USB 分子向我显示两个设备 1. 调制解调器 2. 闪存卡。输入设备向我显示 3 个设备、触摸屏或其他?不管怎样,
rk29-keypad
- 我想那是我的设备。 - VLC 播放器使用媒体按钮没有问题。 VLC 有一个开源的。但是 copy/paste(见上面的方法)什么也没给我。
我开始相信奇迹了...
已解决。
重要的三件事(虽然不知道为什么第一件事)
所有接收者的注册都应该在服务中完成。未使用 activity 中的按钮。都在服役。还有 2 和 3.
忘记了
mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
其他应用程序(内置)获得焦点。
- Android 4.4.2 有
RemoteControlClient
而不是MediaSessionCompat
。可能取决于当前的测试设备(非标准)。