Android Question Car media buttons

apti

Member
I am trying to catch the media button presses in a car in b4x. Nothing is working or helping. Does anybody have a simple solution or detailed information on how to do this? I am new to b4x but not a new programmer. AI has not helped at all. I just want to catch the basic buttons like play, pause, next, and back.
maybe code examples that work would help, along with if I need to do anything to the manifest.
 

Cableguy

Expert
Licensed User
Longtime User
You need to give out more info, like the android version, even maybe the Car Make & model... I have a Renault Austral with Android 10 R-Link, but haven't yet tried to tap into it, but I know it can do side loading.
 
Upvote 0

apti

Member
model of car should not matter because it is just the bluetooth connection and from what I found it is no relevant. Android version would be version 13 and up. although I would prefer to support version 11 and up. I have seen other media apps that worked fine from car to car this way. Thing is mine will be totally google free. No analytics or anything that communicates with google.
I hope that is enough information, happy to give more if needed.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
So it's a OEM head unit?
You can start by creating a small app that catches keystrokes, and logs it to scren, for example... the base Android version is set in the manifest (min SDK), and as long as you find a bl.5 lib, it should be ok, even for bl6 devices...
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
Longtime User
I am trying to catch the media button presses in a car in b4x. Nothing is working or helping. Does anybody have a simple solution or detailed information on how to do this? I am new to b4x but not a new programmer. AI has not helped at all. I just want to catch the basic buttons like play, pause, next, and back.
maybe code examples that work would help, along with if I need to do anything to the manifest.

I already gave you an answer HERE.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
I already gave you an answer HERE.
Now I get it!!!
To me the OP was trying to tap into the system itself, by creating an app to run in the said system...
Now, if I now understand this correctly, what he wants to build is a MOBILE app (i.e. for a smartphone as opposed to the unit itself) so that he can control the audio system from said phone... details matter, INFO matters!
 
Upvote 0

apti

Member
Now I get it!!!
To me the OP was trying to tap into the system itself, by creating an app to run in the said system...
Now, if I now understand this correctly, what he wants to build is a MOBILE app (i.e. for a smartphone as opposed to the unit itself) so that he can control the audio system from said phone... details matter, INFO matters!
correct, I guess I was not clear. I would have been if I was aware I could use this to program the head unit. Made the assumption it was all from a mobile device.
 
Upvote 0

Scantech

Well-Known Member
Licensed User
Longtime User
I asked AI. This is what I get.

In B4X (B4A, B4i, B4J), you can listen to Bluetooth events and media control (AVRCP) button presses, but the method depends on whether you want to:

✅ Stream & Control Media (Play/Pause/Next/Prev)
✅ Connect to a custom Bluetooth device (like OBD or custom module)

Here’s how each is done:

🎶 1️⃣ Detect Car Media Button Presses (AVRCP)

When your phone is paired with the car for media playback, the car sends Media Button events (Play/Pause/Next/Prev) to the phone.
On Android (B4A), you can capture these using a BroadcastReceiver that listens for Intent actions.

Example (B4A)

B4X:
' In Globals
Private br As BroadcastReceiver

Sub Activity_Create(FirstTime As Boolean)
    br.Initialize("br")
    br.addAction("android.intent.action.MEDIA_BUTTON")
    br.SetPriority(1000) 'High priority
    br.RegisterReceiver("")
End Sub

Sub br_OnReceive (Action As String, Extras As Object)
    Dim jo As JavaObject = Extras
    Dim keyEvent As JavaObject = jo.RunMethod("getParcelable", Array("android.intent.extra.KEY_EVENT"))
    Dim actionCode As Int = keyEvent.RunMethod("getAction", Null)
    Dim keyCode As Int = keyEvent.RunMethod("getKeyCode", Null)
    Log($"Media Button: ${keyCode}, Action=${actionCode}"$)

    Select keyCode
        Case 85 'Play/Pause
            Log("Play/Pause Pressed")
        Case 87 'Next
            Log("Next Pressed")
        Case 88 'Previous
            Log("Previous Pressed")
    End Select
End Sub

'B4A does not have this. Use in if user closed = true in Activity_Pause event
Sub Activity_Destroy
    br.UnregisterReceiver
End Sub

🔹 How it works

The car sends AVRCP key events → Android generates a MEDIA_BUTTON broadcast → B4A receives it.

Key codes: 85=Play/Pause, 87=Next, 88=Prev, etc

Broadcast library

You can only capture button presses. Can't send media commands.

Update: BroadcastReceiver library alone will NOT capture media keys on Android 12+ unless your app is the current media handler.
 
Last edited:
Upvote 0

apti

Member
I asked AI. This is what I get.

In B4X (B4A, B4i, B4J), you can listen to Bluetooth events and media control (AVRCP) button presses, but the method depends on whether you want to:

✅ Stream & Control Media (Play/Pause/Next/Prev)
✅ Connect to a custom Bluetooth device (like OBD or custom module)

Here’s how each is done:

🎶 1️⃣ Detect Car Media Button Presses (AVRCP)

When your phone is paired with the car for media playback, the car sends Media Button events (Play/Pause/Next/Prev) to the phone.
On Android (B4A), you can capture these using a BroadcastReceiver that listens for Intent actions.

Example (B4A)

B4X:
' In Globals
Private br As BroadcastReceiver

Sub Activity_Create(FirstTime As Boolean)
    br.Initialize("br")
    br.addAction("android.intent.action.MEDIA_BUTTON")
    br.SetPriority(1000) 'High priority
    br.RegisterReceiver("")
End Sub

Sub br_OnReceive (Action As String, Extras As Object)
    Dim jo As JavaObject = Extras
    Dim keyEvent As JavaObject = jo.RunMethod("getParcelable", Array("android.intent.extra.KEY_EVENT"))
    Dim actionCode As Int = keyEvent.RunMethod("getAction", Null)
    Dim keyCode As Int = keyEvent.RunMethod("getKeyCode", Null)
    Log($"Media Button: ${keyCode}, Action=${actionCode}"$)

    Select keyCode
        Case 85 'Play/Pause
            Log("Play/Pause Pressed")
        Case 87 'Next
            Log("Next Pressed")
        Case 88 'Previous
            Log("Previous Pressed")
    End Select
End Sub

'B4A does not have this. Use in if user closed = true in Activity_Pause event
Sub Activity_Destroy
    br.UnregisterReceiver
End Sub

🔹 How it works

The car sends AVRCP key events → Android generates a MEDIA_BUTTON broadcast → B4A receives it.

Key codes: 85=Play/Pause, 87=Next, 88=Prev, etc

Broadcast library
what AI did you use? so far every ai I have tried gives me bad code and hallucinations. This one is passing the IDE checks. I will try it out on a car when I fix a maven error now appearing after update.
 
Upvote 0

Scantech

Well-Known Member
Licensed User
Longtime User
what AI did you use? so far every ai I have tried gives me bad code and hallucinations. This one is passing the IDE checks. I will try it out on a car when I fix a maven error now appearing after update.
Chatgpt. Unfortunately, I found out later broadcast library won't work with Android 12+.
 
Last edited:
Upvote 0

Scantech

Well-Known Member
Licensed User
Longtime User
I asked what other solution. Using this in line Java code. Not sure the outcome. Im no Java expert

In service module
B4X:
#Region  Service Attributes
    #StartAtBoot: False
#End Region

Sub Process_Globals
    'Change event name if you like
    Public EventName As String = "MediaButton"
End Sub

Sub Service_Create
    StartForegroundService
    InitMediaSession
End Sub

Sub Service_Start (StartingIntent As Intent)
    Service.StopAutomaticForeground   'we manage notification manually
End Sub

Sub Service_Destroy
    StopMediaSession
End Sub

'---------------- Inline Java ----------------
#If Java
import android.app.*;
import android.content.*;
import android.view.KeyEvent;
import androidx.core.app.NotificationCompat;
import androidx.media.session.MediaSessionCompat;
import androidx.media.session.MediaSessionCompat.Callback;

public static MediaSessionCompat mediaSession;

public static void StartForegroundService() {
    BA ba = processBA;
    Context ctx = ba.context;

    String CHANNEL_ID = "MediaSessionChannel";
    NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= 26) {
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "MediaSession",
                NotificationManager.IMPORTANCE_LOW);
        nm.createNotificationChannel(channel);
    }
    Notification notification = new NotificationCompat.Builder(ctx, CHANNEL_ID)
            .setContentTitle("Media Session Active")
            .setContentText("Listening for media buttons")
            .setSmallIcon(android.R.drawable.ic_media_play)
            .build();

    Service service = (Service)ctx;
    service.startForeground(1, notification);
}

public static void InitMediaSession() {
    final BA ba = processBA;
    Context ctx = ba.context;
    mediaSession = new MediaSessionCompat(ctx, "B4AMediaSession");
    mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
                          MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
    mediaSession.setCallback(new Callback() {
        @Override
        public boolean onMediaButtonEvent(Intent intent) {
            KeyEvent keyEvent = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
            if (keyEvent != null && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
                int code = keyEvent.getKeyCode();
                String action = "";
                switch (code) {
                    case KeyEvent.KEYCODE_MEDIA_PLAY:      action = "play"; break;
                    case KeyEvent.KEYCODE_MEDIA_PAUSE:     action = "pause"; break;
                    case KeyEvent.KEYCODE_MEDIA_NEXT:      action = "next"; break;
                    case KeyEvent.KEYCODE_MEDIA_PREVIOUS:  action = "previous"; break;
                    case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:action = "toggle"; break;
                }
                if (!action.equals("")) {
                    ba.raiseEventFromUI(null, "mediabutton_event", new Object[]{action});
                }
            }
            return super.onMediaButtonEvent(intent);
        }
    });
    mediaSession.setActive(true);
}

public static void StopMediaSession() {
    if (mediaSession != null) {
        mediaSession.release();
        mediaSession = null;
    }
}
#End If
'---------------- End Inline Java ----------------

Add in main activity
B4X:
Sub MediaButton_Event(Action As String)
    Log("Media Button pressed: " & Action)
    'Values: play, pause, next, previous, toggle
End Sub

B4X:
StartService(MediaService)

Also adding Bluetooth permission in manifest and dynamically with runtime permission.

Or check this out Mediasession. The erel example looks promising. Read the whole thread. There are examples download as well. I would start here first and don't waist your time with my other post above.
 
Last edited:
Upvote 0
Top