Android Question Capture voice input when Mic button is pressed

Colin Evans

Active Member
Licensed User
Longtime User
Hi, is there anyway to check when the microphone button is pressed, I can capture voice input if I have a button on the screen and when pressed I press the button on the mic to capture the voice input but I want to bypass the need for a button on screen and just press the button on the mic. I hope that makes sense.

I notice if I press the mic button, it displays 'nothing to resume' so I would assume it's possible to capture the event
 
Last edited:

Colin Evans

Active Member
Licensed User
Longtime User
An external 3.5mm jack Mic and ear pieces that you normally get with phones, I can do it with a button on the layout which works but I'd rather control the voice input via the button on the mic
 
Upvote 0

LucasHeer

Active Member
Licensed User
Longtime User
Hey sir!

I believe that I have it working, this is using MediaSessions. It is roughly based on this post:

This picks up play, pause, play/pause, next, previous.

You will need to create a service called MediaButtonService:
MediaButtonService:
#Region  Service Attributes
    #StartAtBoot: False
#End Region

Sub Process_Globals
    Private session As JavaObject
    Private mp As MediaPlayer
End Sub

Sub Service_Create
    Log("MediaButtonService: Service_Create")

    mp.Initialize2("mp")
    Log("MediaButtonService: media player initialized")

    Dim context As JavaObject
    context.InitializeContext

    session.InitializeNewInstance("android.media.session.MediaSession", Array(context, "AnyDealerMedia"))
    session.RunMethod("setFlags", Array(3))

    Dim PlaybackState As JavaObject
    PlaybackState.InitializeStatic("android.media.session.PlaybackState")

    Dim psBuilder As JavaObject
    psBuilder.InitializeNewInstance("android.media.session.PlaybackState$Builder", Null)

    Dim actions As Long = _
        PlaybackState.GetField("ACTION_PLAY_PAUSE") + _
        PlaybackState.GetField("ACTION_PLAY") + _
        PlaybackState.GetField("ACTION_PAUSE") + _
        PlaybackState.GetField("ACTION_SKIP_TO_NEXT") + _
        PlaybackState.GetField("ACTION_SKIP_TO_PREVIOUS")

    psBuilder.RunMethod("setActions", Array(actions))

    Dim st As Int = PlaybackState.GetField("STATE_PLAYING")
    Dim pos As Long = 0
    Dim spd As Float = 1
    psBuilder.RunMethod("setState", Array(st, pos, spd))

    session.RunMethod("setPlaybackState", Array(psBuilder.RunMethod("build", Null)))

    Dim cb As JavaObject
    cb.InitializeNewInstance(Application.PackageName & ".mediabuttonservice$MyCallback", Null)
    session.RunMethod("setCallback", Array(cb))

    session.RunMethod("setActive", Array(True))
    Log("MediaButtonService: session active")
End Sub

Sub Service_Start (StartingIntent As Intent)
    Log("MediaButtonService: Service_Start")
End Sub

Sub Service_Destroy
    Log("MediaButtonService: Service_Destroy")
    Try
        If mp.IsInitialized Then mp.Stop
    Catch
    End Try
    Try
        If session.IsInitialized Then
            session.RunMethod("setActive", Array(False))
            session.RunMethod("release", Null)
        End If
    Catch
    End Try
End Sub

Sub Media_OnButton(KeyCode As Int)
    Log("HEADSET KEY DOWN: " & KeyCode)
    B4XPages.MainPage.AddClickItem("HEADSET KEY DOWN: " & KeyCode)
End Sub

#If Java
import android.media.session.MediaSession;
import android.content.Intent;
import android.view.KeyEvent;

public static class MyCallback extends MediaSession.Callback {
  @Override
  public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
    BA.Log("onMediaButtonEvent fired");
    if (mediaButtonIntent == null) return false;

    KeyEvent ke = (KeyEvent) mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
    if (ke == null) return false;

    if (ke.getAction() == KeyEvent.ACTION_DOWN) {
      processBA.raiseEventFromUI(null, "media_onbutton", ke.getKeyCode());
    }
    return true;
  }
}
#End If

You will want to initialize it in your Main activity:
Main Activity:
Sub Activity_Create(FirstTime As Boolean)
    Dim pm As B4XPagesManager
    pm.Initialize(Activity)
   
    If(FirstTime) Then
        StartService(MediaButtonService)
    End If
End Sub

This worked with my Bluetooth headphones, I believe it should work the same way with AUX headphones:


Let me know how it goes,

Thank you!!
 
Upvote 0

Colin Evans

Active Member
Licensed User
Longtime User
not sure how i implement, I'm using b4A not B4X, would it work in default B4A application, and if it would could you please post an example so I can work out how to integrate into my program, many thanks for replying and offering your expertise
 
Upvote 0

LucasHeer

Active Member
Licensed User
Longtime User
not sure how i implement, I'm using b4A not B4X, would it work in default B4A application, and if it would could you please post an example so I can work out how to integrate into my program, many thanks for replying and offering your expertise
Yes sir, absolutely! This is actually B4A code, you will want to create a B4A "Service Module". You can use the Starter service, but you would have to modify the callback. If you need any further help, you can also message me on here and I will setup a video call for you 👍

Let me know if you have any questions!
 

Attachments

  • MediaSessionsTest.zip
    16.1 KB · Views: 0
Upvote 0
Top