Android Question audio recording programmatically

Leni Berry

Active Member
Licensed User
Longtime User
How to add functionality for recording audio into wav file programmatically in API 23 (Android 6)?
 

Leni Berry

Active Member
Licensed User
Longtime User
dear erel,

when i run the example, it works... but when i integrate to my app as new activity. same exactly with the example. and i call the activity with startactivity and click start recording, the apps suddenly stop.... error log something like this :

** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (firebasemessaging) Create **
** Service (firebasemessaging) Start **
** Service (imagedownloader) Create **
** Service (imagedownloader) Start **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
** Service (httputils2service) Start **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (sos) Create, isFirst = true **
** Activity (sos) Resume **
sos_btnstartrecording_click (java line: 395)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
at android.media.AudioRecord.startRecording(AudioRecord.java:943)
at anywheresoftware.b4a.audio.AudioStreamer.StartRecording(AudioStreamer.java:98)
at com.idcloud.nusantara.sos._btnstartrecording_click(sos.java:395)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:78)
at android.view.View.performClick(View.java:5697)
at android.widget.TextView.performClick(TextView.java:10815)
at android.view.View$PerformClick.run(View.java:22534)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
sos_btnstartrecording_click (java line: 395)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
at android.media.AudioRecord.startRecording(AudioRecord.java:943)
at anywheresoftware.b4a.audio.AudioStreamer.StartRecording(AudioStreamer.java:98)
at com.idcloud.nusantara.sos._btnstartrecording_click(sos.java:395)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:78)
at android.view.View.performClick(View.java:5697)
at android.widget.TextView.performClick(TextView.java:10815)
at android.view.View$PerformClick.run(View.java:22534)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (firebasemessaging) Create **
** Service (firebasemessaging) Start **
** Service (imagedownloader) Create **
** Service (imagedownloader) Start **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = false **
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
: startRecording() called on an uninitialized AudioRecord

Looks like you forget to initialize

Sure you copy all code from example?
 
Upvote 0

Leni Berry

Active Member
Licensed User
Longtime User
: startRecording() called on an uninitialized AudioRecord

Looks like you forget to initialize

Sure you copy all code from example?

yes... here is the code on an activity name 'sos' :

B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Private streamer As AudioStreamer
    Private buffers As List
    Private timer1 As Timer
    Private recordingStart As Long
    Private output As OutputStream
    Private recording As Boolean
    Private mBitRate As Int = 16
    Private mSampleRate As Int = 22050
    Private mMono As Boolean = True
    Private mFileName As String = "sos.wav"
    Private mp As MediaPlayer
End Sub

Sub Globals
    Dim Label1 As Label
    Dim btnPlay As Button
    Dim btnStartRecording As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("sos")
    If FirstTime Then
        streamer.Initialize("streamer", mSampleRate, mMono, mBitRate, streamer.VOLUME_MUSIC)
        buffers.Initialize
        timer1.Initialize("timer1", 1000)
        mp.Initialize2("mp")
    End If
End Sub

Sub StartWaveFile(Dir As String, FileName As String, SampleRate As Int, Mono As Boolean _
        , BitsPerSample As Int) As OutputStream
    File.Delete(Dir, FileName)
    Dim raf As RandomAccessFile
    raf.Initialize2(Dir, FileName, False, True)
    raf.WriteBytes("RIFF".GetBytes("ASCII"), 0, 4, raf.CurrentPosition)
    raf.CurrentPosition = 8 'skip 4 bytes for the size
    raf.WriteBytes("WAVE".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteBytes("fmt ".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteInt(16, raf.CurrentPosition)
    raf.WriteShort(1, raf.CurrentPosition)
    Dim numberOfChannels As Int
    If Mono Then numberOfChannels = 1 Else numberOfChannels = 2
    raf.WriteShort(numberOfChannels, raf.CurrentPosition)
    raf.WriteInt(SampleRate, raf.CurrentPosition)
    raf.WriteInt(SampleRate * numberOfChannels * BitsPerSample / 8, raf.CurrentPosition)
    raf.WriteShort(numberOfChannels * BitsPerSample / 8, raf.CurrentPosition)
    raf.WriteShort(BitsPerSample, raf.CurrentPosition)
    raf.WriteBytes("data".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteInt(0, raf.CurrentPosition)
    raf.Close
    Return File.OpenOutput(Dir, FileName, True)
End Sub

Sub CloseWaveFile(Dir As String, FileName As String)
    Dim raf As RandomAccessFile
    raf.Initialize2(Dir, FileName, False, True)
    raf.WriteInt(raf.Size - 8, 4)
    raf.WriteInt(raf.Size - 44, 40)
    raf.Close
End Sub

Sub streamer_RecordBuffer (Buffer() As Byte)
    If recording Then output.WriteBytes(Buffer, 0, Buffer.Length)
    'the above check is required as the last message will arrive after we call StopRecording.
End Sub

Sub btnStartRecording_Click
    buffers.Clear
    output = StartWaveFile(File.DirInternalCache, mFileName, mSampleRate, mMono, mBitRate)
    recording = True
    streamer.StartRecording
    recordingStart = DateTime.Now
    timer1.Enabled = True
    Timer1_Tick
    btnPlay.Enabled = False
End Sub

Sub Timer1_Tick
    Label1.Text = "Recording: " & _
        Round((DateTime.Now - recordingStart) / DateTime.TicksPerSecond) & " seconds"
End Sub

Sub btnStopRecording_Click
    streamer.StopRecording
    recording = False
    output.Close
    CloseWaveFile(File.DirInternalCache, mFileName)
    timer1.Enabled = False
    btnPlay.Enabled = True
    Label1.Text = ""
End Sub

Sub btnPlay_Click
    mp.Load(File.DirInternalCache, mFileName)
    mp.Play
End Sub
Sub mp_Complete
    Log("PlaybackComplete")
    btnStartRecording.Enabled = True
End Sub


Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

PS: i 'm sorry double post because my slow internet connection, i just delete another post and edit code tag...
 
Last edited:
Upvote 0

Leni Berry

Active Member
Licensed User
Longtime User
Use code Tags when Posting code!
Edit your post to make the code read able. Or better. Export the project as zip

You dont need to do this for me as i put you on my ignorelist

i 'm so sorry about double post, it happen because my slow internet connection, i just delete another post and edit code tag...
 
Upvote 0

Leni Berry

Active Member
Licensed User
Longtime User
Note that the layout file is missing from the zip.

The RECORD_AUDIO permission is a "dangerous" permission. If you set the targetSdkVersion to 23 then you must request this permission at runtime:
Runtime Permissions (Android 6.0+ Permissions)

My mistake when trying simplified the project, i just edit the sample project... added runtime permission "RECORD_AUDIO permission", but still error...
 

Attachments

  • Login registrasi - Sound Recorder Failed.zip
    258.5 KB · Views: 206
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
added runtime permission "RECORD_AUDIO permission", but still error...
but you start recording without waiting for the permission-request-result

B4X:
Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = Starter.rp.PERMISSION_RECORD_AUDIO Then
        If Result Then
            ' NOW you are allowed to record audio...
            ' Wait to this and set a process global variable to be allowed....
            ' Start record ONLY after this code here runs...
        End If
    End If
End Sub
 
Last edited:
Upvote 0

Leni Berry

Active Member
Licensed User
Longtime User
dear erel,

any update? the problem occur if i integrate between firebase capabality and audio recording in my project. firebase working well (FB and Google login, push messaging, analytics) , but audio recording stop working...

is it possible to integrate them in single project?
 
Upvote 0

Leni Berry

Active Member
Licensed User
Longtime User
The issue has nothing to do with Firebase. If you set the targetSdkVersion to 23 then you need to handle runtime permissions. See the tutorial.
tq erel,
i'll check for another permission need handle with runtime permission...
 
Upvote 0

Leni Berry

Active Member
Licensed User
Longtime User
but you start recording without waiting for the permission-request-result

B4X:
Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = Starter.rp.PERMISSION_RECORD_AUDIO Then
        If Result Then
            ' NOW you are allowed to record audio...
            ' Wait to this and set a process global variable to be allowed....
            ' Start record ONLY after this code here runs...
        End If
    End If
End Sub

ohh.. ya.. my mistake... i'll try...
 
Upvote 0
Top