1

Have a car with controls below steering wheel. Buttons are: next/previous track, volume up/down, ok, source. I want catch up Next/Previous track button.

I've tried onKeyDown in my activity with no luck. Also i've tried BroadcastReceiver and MediaButtonReceiver with no effect. Seems that application didn't see any events. Debug possibilities on device is very small, they are absent in fact.

  1. Is there way to catch such event?
  2. How in android find some hardware connected to phone. May be some enumerator class for every connected device?

Update 1:

I'd tried:

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. Create Receiver programatically, using

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

with two priorities 999 and 7FFF FFFF.

  1. Create receiver with

    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. Create receiver with

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

My class SteeringWheel were

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. Test buttons Were

    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. So when I do nothing, or create receiver with one of variants(no matter) when I click any of Test buttons i see toast, log message and other. When I try press Next track on steering wheel I have no message. Like nothing happens and.

  3. It's not Media buttons? But what? USB numerator shows me two devices 1. Modem 2. Flash card. Input devices show me 3 devices, touch screen, something else? no matter, and rk29-keypad - i suppose that's my device.
  4. VLC player working with media buttons with no problems. VLC have an open source. But copy/paste(see methods above) gives me nothing.

I'm starting believe in miracles...

DuhVir
  • 447
  • 1
  • 4
  • 15
  • In what way android device is connected your steering wheel buttons? – Ufkoku Sep 12 '19 at 14:13
  • Actually I don't know. That's one more problem. I can't disassembly my car ) I think it's an USB. – DuhVir Sep 12 '19 at 14:15
  • As I understood you already tried this one https://developer.android.com/guide/topics/media-apps/mediabuttons#mediabuttons-and-active-mediasessions – Ufkoku Sep 12 '19 at 14:20
  • Yes. Exactly this one article. Both ways. My Android is 4.4.2 – DuhVir Sep 12 '19 at 14:22
  • If it is USB you can try to list connected devices https://developer.android.com/guide/topics/connectivity/usb/host#enumerate-devices you can try to connect to it, and in experimental way found command for your buttons – Ufkoku Sep 12 '19 at 14:25
  • If there is an opportunity to read logs, maybe some are wrote in logcat, when button is pressed. You need something to start with) – Ufkoku Sep 12 '19 at 14:32
  • I'll try to enumerate USB devices for now. There is no logcat, only toast, but this bad idea ) Device even didn't show error if there is exception in application, it's just close it. Very small debug possibilities. And more, my car in other part of city, because of that only one test by day ) – DuhVir Sep 13 '19 at 06:43
  • Dis it work? Is it USB? – Ufkoku Sep 15 '19 at 10:49
  • Checked it only yesterday ) No, it didn't ( Enumeration gives me two devices. First is my USB modem, second is USB flash. Have no idea what connection can it be... if it's CAN or something like this, than it should act as keyboard and `onKeyDown` must work. I pretty new in android(less than 2 years), and may be you know any other connection possibilities? – DuhVir Sep 16 '19 at 06:52
  • You can check this one https://stackoverflow.com/a/11510564/3858030 – Ufkoku Sep 16 '19 at 07:34
  • This is variant of article from above. A little different registration process, but same input. Through `broadcastreceiver` which didn't work. I will try tonight, but I think I know result ) – DuhVir Sep 16 '19 at 11:19
  • Didn't work. I'd disassembly one application which works on device with no problem. In manifest i saw only standard receiver `` and... that's all, my knowledge of smali not so good ) Will try tomorrow check all again – DuhVir Sep 16 '19 at 17:28

1 Answers1

0

Solved.

Vital were three things(though don't know why first are)

  1. All registeration of receivers should be done in Service. Not using button in activity. All in service. Also 2 and 3.

  2. I forgot about

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

And other apps(built-in) takes focus.

  1. Android 4.4.2 have RemoteControlClient instead of MediaSessionCompat. Possibly depends on current testing device(Non standard).
DuhVir
  • 447
  • 1
  • 4
  • 15