On my Nexus, under KitKat, it works perfect.
On my LG... it only works for the first recording. The second recording dies at Record.start
Error occurred on line: 9953 (main)
java.lang.RuntimeException: start failed.
at android.media.MediaRecorder.native_start(Native Method)
at android.media.MediaRecorder.start(MediaRecorder.java:706)
at com.rootsoft.audiorecorder.AudioRecorder.start(AudioRecorder.java:227)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:519)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:235)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:174)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:161)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:157)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:66)
at android.view.View.performClick(View.java:3524)
at android.view.View$PerformClick.run(View.java:14194)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4476)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:816)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:583)
at dalvik.system.NativeStart.main(Native Method)
When I look in /sdcard/Android/data/b4a.acim/files/ it has written the filename; but it is zero-size big.
HERE IS A LINK TO THE ACTIVTY (Bigger than 512mb):
http://thewind777.angelfire.com/recorder.htm
In the Library file are the two libraries you'll need (GifDecoder and AudioRecorder)
The problem has nothing to do with the GifDecoder... because I added that afterwards.
#Region Project Attributes
#ApplicationLabel: B4A QuadAudioRecorder
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#End Region
#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region
Sub process_Globals
Dim Debug As Boolean : Debug = True
' Variables Needed For Rest of Program
Dim WBNumber As String : WBNumber = "1"
Dim Underscore As String : Underscore = Chr(95)
Dim PGRecordTimer As Timer
Dim PGDelayPlayTimer As Timer
Dim PGGifTimer As Timer
Dim Frame As Int
Dim PGRecordHL As Bitmap
Dim PGRecordUP As Bitmap
Dim PGPlayON As Bitmap
Dim PGPlayOFF As Bitmap
Dim Record As AudioRecorder
Dim PlayRecording As MediaPlayer
Dim StartedRecording As Boolean : StartedRecording = False
Dim DoAudioRecorder As Boolean : DoAudioRecorder = True
Dim HILIGHT As Boolean : HILIGHT = True
Dim NOHILIGHT As Boolean : NOHILIGHT = False
Dim RecordingToggle As Boolean : RecordingToggle = NOHILIGHT
End Sub
Sub Globals
' Variables needed for "about" layout
Dim LabelProgramName, LabelVersionNumber, LabelMyName As Label
Dim ImageViewLogo As ImageView
Dim gif As GifDecoder
' Variables needed for Audio Recorder layout
Dim ButtonRTBack, ButtonRTForward, ButtonTempt As Button
Dim EditTextRTUR, EditTextRT, EditTextRTNumber, EditTextRTT As EditText
Dim LabelRTTTally As Label
Dim ButtonPlay1, ButtonPlay2, ButtonPlay3, ButtonPlay4 As Button
Dim ButtonRec1, ButtonRec2, ButtonRec3, ButtonRec4 As Button
Dim pnlRT As Panel
Dim pnlAbout As Panel
Dim WhichRecordButton As Button
Dim PlayButtons() As Button
Dim RecButtons() As Button
End Sub
Sub Activity_Create(Firsttime As Boolean)
If Firsttime Then
Record.Initialize()
PlayRecording.Initialize
PGRecordHL = LoadBitmap(File.DirAssets, "recordhl.png")
PGRecordUP = LoadBitmap(File.DirAssets, "record.png")
PGPlayON = LoadBitmap(File.DirAssets, "playon.png")
PGPlayOFF = LoadBitmap(File.DirAssets, "playoff.png")
End If
If PGRecordTimer.IsInitialized = False Then PGRecordTimer.Initialize("PGRecordTimer",500)
If PGDelayPlayTimer.IsInitialized = False Then PGDelayPlayTimer.Initialize("DelayPlayTimer",500)
' Set-up the "Audio Recording" panel using "audiorecorder" Layout
pnlRT.Initialize("")
Activity.AddView(pnlRT,0dip,0dip,100%x,100%y)
pnlRT.LoadLayout("audiorecorder")
pnlRT.Visible=True
' Set-up the "About" panel using "about" Layout
pnlAbout.Initialize("")
Activity.AddView(pnlAbout,0dip,0dip,100%x,100%y)
pnlAbout.LoadLayout("about")
pnlAbout.Visible=False
Activity.AddMenuItem("Record/Play","RecordPlay") ' LastPanel = 7
Activity.AddMenuItem("About","about")
If PGGifTimer.IsInitialized = False Then PGGifTimer.Initialize("PGGifTimer",0)
PlayButtons = Array As Button(ButtonPlay1,ButtonPlay2,ButtonPlay3,ButtonPlay4)
RecButtons = Array As Button(ButtonRec1,ButtonRec2,ButtonRec3,ButtonRec4)
End Sub
Sub Activity_Pause
If Record.isRecording Then Record.stop
If DoAudioRecorder Then
PGRecordTimer.Enabled = False
PGDelayPlayTimer.Enabled = False
StartedRecording = False
If Record.isRecording Then Record.stop
If WhichRecordButton.IsInitialized Then WhichRecordButton.SetBackgroundImage(PGRecordUP)
End If
PGGifTimer.Enabled = False
End Sub
Sub Activity_Resume
End Sub
Sub ButtonPlay1_Click
DoSoundPlay(1)
End Sub
Sub ButtonPlay2_Click
DoSoundPlay(2)
End Sub
Sub ButtonPlay3_Click
DoSoundPlay(3)
End Sub
Sub ButtonPlay4_Click
DoSoundPlay(4)
End Sub
Sub DoSoundPlay(ANumber As Int)
Dim TheFileName As String
Dim NumberMinusOne As Int
NumberMinusOne = ANumber - 1
Dim NumberAsString As String
NumberAsString = IntToStr(ANumber)
' If a WAV file won't play, it is likely that the original source file was not 44100Hz stereo.
If Debug Then Log(" +++ Begin of ButtonPlay1_Click")
TheFileName = "sound" & Underscore & WBNumber & Underscore & NumberAsString & ".wav"
EditTextRT.Text = "PLAYING WAV FILE /sdcard/Android/data/b4a.acim/files/" & TheFileName
StopAllRecordAndPlay("")
If Debug Then Log("ButtonRec1_Click - TheFileName = " & TheFileName)
If Record.isRecording = False Then
If File.Exists(File.DirDefaultExternal, TheFileName) Then
If Debug Then Log("ButtonPlay1_Click - PERFORMING PlayRecording.Load(File.DirDefaultExternal," & QUOTE & TheFileName & QUOTE & ")")
PlayRecording.Load(File.DirDefaultExternal, TheFileName)
If Debug Then Log("ButtonPlay1_Click - SUCCEEDED PlayRecording.Load(File.DirDefaultExternal," & QUOTE & TheFileName & QUOTE & ")")
PGDelayPlayTimer.Enabled = True ' Play in 500 ms
Else
Msgbox("Record an Audio File first by clicking on the red circle","WARNING")
End If
Else
ToastMessageShow("STILL RECORDING, Stop Recording first.",False)
End If
If Debug Then Log(" --- End of ButtonPlay1_Click")
If Debug Then Log(" ")
End Sub
Sub DelayPlayTimer_tick
If Debug Then Log(" +++ Begin of DelayPlayTimer_tick")
PGDelayPlayTimer.Enabled = False
PlayRecording.Play
If Debug Then Log(" --- End of DelayPlayTimer_tick")
If Debug Then Log(" ")
End Sub
Sub ButtonRec1_Click
DoSoundRecord(1)
End Sub
Sub ButtonRec2_Click
DoSoundRecord(2)
End Sub
Sub ButtonRec3_Click
DoSoundRecord(3)
End Sub
Sub ButtonRec4_Click
DoSoundRecord(4)
End Sub
Sub DoSoundRecord(ANumber As Int)
Dim TheFileName As String
Dim NumberAsString As String
Dim NumberMinusOne As Int
NumberMinusOne = ANumber - 1
NumberAsString = IntToStr(ANumber)
WhichRecordButton = RecButtons(NumberMinusOne)
If Debug Then Log(" +++ Begin of ButtonRec1_Click")
TheFileName = "sound" & Underscore & WBNumber & Underscore & NumberAsString & ".wav"
If Debug Then Log("ButtonRec1_Click - TheFileName = " & TheFileName)
EditTextRT.Text = "RECORDING WAV FILE /sdcard/Android/data/b4a.acim/files/" & TheFileName
If PlayRecording.IsPlaying Then PlayRecording.Pause
If StartedRecording Then
' Turn-off Recording Timer
ToastMessageShow("STOPPED Recording",False)
PGRecordTimer.Enabled = False
If Debug Then Log("ButtonRec1_Click - PERFORMING Record.Stop")
If Record.isRecording Then
Record.Stop
End If
If Debug Then Log("ButtonRec1_Click - SUCCEEDED Record.Stop")
StartedRecording = False
WhichRecordButton.SetBackgroundImage(PGRecordUP)
StopAllRecordAndPlay("")
RefreshRecordPlayImages("")
Else
' Turn-on Recording Timer
PrepareRecorder(TheFileName)
If Record.isRecording = False Then
If Debug Then Log("ButtonRec1_Click - PERFORMING Record.Start")
Record.Start
If Debug Then Log("ButtonRec1_Click - SUCCEEDED Record.Start")
ToastMessageShow("STARTED Recording",False)
StartedRecording = True
Else
If Debug Then Log("ButtonRec1_Click - WHOOPS, TRYING TO START RECORDING WHEN STILL RECORDING")
End If
PGRecordTimer.Enabled = True
End If
If Debug Then Log(" --- End of ButtonRec1_Click")
If Debug Then Log(" ")
End Sub
Sub PrepareRecorder(FileName As String)
If Debug Then Log(" +++ Begin of PrepareRecorder()")
Dim NumSeconds As Int
Record.AudioSource = Record.AS_MIC
Record.OutputFormat = Record.OF_THREE_GPP
Record.AudioEncoder = Record.AE_AMR_NB ' AudioCodecAMRAdaptive Multi-Rate narrowband audio codec, also known as AMR OR AMR-NB
'Record.AudioEncoder = Record.AE_AAC ' it seems like Android doesn't natively support streaming of AAC files.
'Record.AudioEncoder = Record.AE_AMR_WB ' wouldn't load
' 2 Min = 120
' 4 Min = 240
' 5 Min = 300
' 7 Min = 420
' 10 Min = 600
NumSeconds = 300 ' 5 Minutes
Record.MaxDuration = NumSeconds * 1000 ' in ms
Record.AudioEncodingBitRate = 44100
' On the Nexus, the directory it writes to with DirDefaultExternal is:
' /sdcard/Android/data/b4a.acim/files/
If Debug Then Log("ButtonRec1_Click - PERFORMING Record.setOutputFile")
Record.setOutputFile(File.DirDefaultExternal,FileName)
If Debug Then Log("ButtonRec1_Click - SUCCEEDED Record.setOutputFile")
If Debug Then Log("ButtonRec1_Click - PERFORMING Record.prepare()")
Record.Prepare()
If Debug Then Log("ButtonRec1_Click - SUCCEEDED Record.prepare()")
If Debug Then Log(" --- End of PrepareRecorder()")
If Debug Then Log(" ")
End Sub
Sub PGRecordTimer_tick
If Debug Then Log(" +++ Begin of PGRecordTimer_tick")
Dim WhichImage As Bitmap
If DoAudioRecorder Then
If Record.isRecording Then
If RecordingToggle = NOHILIGHT Then
RecordingToggle = HILIGHT
WhichRecordButton.SetBackgroundImage(PGRecordHL)
If Debug Then Log("PGRecordTimer_tick - HILIGHT Image")
Else
RecordingToggle = NOHILIGHT
WhichRecordButton.SetBackgroundImage(PGRecordUP)
If Debug Then Log("PGRecordTimer_tick - NOHILIGHT Image")
RefreshRecordPlayImages("")
End If
End If
Else
RecordingToggle = NOHILIGHT
WhichRecordButton.SetBackgroundImage(PGRecordUP)
If Debug Then Log("PGRecordTimer_tick - DoAudioRecorder = FALSE... NOHILIGHT Image")
End If
If Debug Then Log(" --- End of PGRecordTimer_tick")
If Debug Then Log(" ")
End Sub
Sub IntToStr(TheNumber As Int) As String
' Convert Int to String
Dim ReturnString As String
ReturnString = TheNumber
Return ReturnString
End Sub
Sub ButtonRTDelete_Click
If DoAudioRecorder Then
If Debug Then Log(" +++ Begin ButtonRTDelete_Click")
AskThenDeleteFourRecordings("")
EditTextRT.Text = ""
End If
End Sub
Sub AskThenDeleteFourRecordings(BlankString As String)
Dim TheFileName As String
Dim z As Int
Dim Count As Int : Count = 0
Dim DeleteFour As Int
Dim Icon As Bitmap
Dim PositiveResponse As Int
Dim Success As Boolean
Dim RecordingWord As String
Icon = LoadBitmap(File.DirAssets, "msgboxicon.png")
For z = 1 To 4
TheFileName = "sound" & Underscore & WBNumber & Underscore & IntToStr(z) & ".wav"
If File.Exists(File.DirDefaultExternal,TheFileName) Then
Count = Count + 1
End If
Next
If Count = 1 Then
RecordingWord = "Recording"
Else
RecordingWord = "Recordings"
End If
If Count <> 0 Then
DeleteFour = Msgbox2("Do you wish to delete the " & IntToStr(Count) & " Audio " & RecordingWord & "? You can not reverse this process.","DELETING AUDIO FILES","YES","","NO",Icon)
End If
PositiveResponse = DialogResponse.POSITIVE
';
If DeleteFour = PositiveResponse Then
For z = 1 To 4
TheFileName = "sound" & Underscore & WBNumber & Underscore & IntToStr(z) & ".wav"
If File.Exists(File.DirDefaultExternal,TheFileName) Then
Success = File.Delete(File.DirDefaultExternal, TheFileName)
End If
Next
End If
RefreshRecordPlayImages("")
End Sub
Sub RefreshRecordPlayImages(BlankString As String)
Dim z As Int
Dim zm1 As Int
Dim TheFileName As String
If Debug Then Log(" +++ Begin of StopAllRecordAndPlay()")
For z = 1 To 4
zm1 = z - 1
If RecButtons(zm1).IsInitialized Then
RecButtons(zm1).SetBackgroundImage(PGRecordUP)
Else
If Debug Then Log("RefreshRecordPlayImages() - RecButtons(" & IntToStr(zm1) & ") WASN'T INITIALIZED")
End If
TheFileName = "sound" & Underscore & WBNumber & Underscore & IntToStr(z) & ".wav"
If Debug Then Log("RefreshRecordPlayImages() - TheFileName = " & TheFileName)
If File.Exists(File.DirDefaultExternal, TheFileName) Then
If Debug Then Log("RefreshRecordPlayImages() - TheFileName = " & TheFileName & " EXISTS")
' Put PGPlayON into Button
If PlayButtons(zm1).IsInitialized Then
PlayButtons(zm1).SetBackgroundImage(PGPlayON)
Else
If Debug Then Log("RefreshRecordPlayImages() - PlayButtons(" & IntToStr(zm1) & ") WASN'T INITIALIZED")
End If
Else
If Debug Then Log("RefreshRecordPlayImages() - TheFileName = " & TheFileName & " DOES NOT EXIST")
' Put PGPlayOFF into Button
If PlayButtons(zm1).IsInitialized Then
PlayButtons(zm1).SetBackgroundImage(PGPlayOFF)
Else
If Debug Then Log("RefreshRecordPlayImages() - PlayButtons(" & IntToStr(zm1) & ") WASN'T INITIALIZED")
End If
End If
Next
If Debug Then Log(" --- End of StopAllRecordAndPlay()")
If Debug Then Log(" ")
End Sub
Sub StopAllRecordAndPlay(BlankString As String)
If Debug Then Log(" +++ Begin of StopAllRecordAndPlay()")
If PGDelayPlayTimer.IsInitialized Then PGDelayPlayTimer.Enabled = False
If PGDelayPlayTimer.IsInitialized Then PGDelayPlayTimer.Enabled = False
If PlayRecording.IsPlaying Then
PlayRecording.Pause
ToastMessageShow("STOPPED Playing",False)
End If
If Record.isRecording Then
Record.stop
ToastMessageShow("STOPPED Recording",False)
End If
If Debug Then Log(" --- End of StopAllRecordAndPlay()")
If Debug Then Log(" ")
End Sub
Sub ButtonRTBack_Click
Dim TheNumber As Int
TheNumber = StrToInt(WBNumber)
TheNumber = TheNumber - 1
If TheNumber < 0 Then TheNumber = 0
WBNumber = IntToStr(TheNumber)
EditTextRTNumber.Text = WBNumber
End Sub
Sub ButtonRTForward_Click
Dim TheNumber As Int
TheNumber = StrToInt(WBNumber)
TheNumber = TheNumber + 1
If TheNumber < 0 Then TheNumber = 0
WBNumber = IntToStr(TheNumber)
EditTextRTNumber.Text = WBNumber
End Sub
Sub StrToInt(TheString As String) As Int
' Convert String to Number
Dim ReturnVal As Int
If TheString = "" OR TheString = Null Then TheString = "0"
ReturnVal = TheString
Return ReturnVal
End Sub
Sub RecordPlay_click
pnlRT.Visible=True
pnlAbout.Visible=False
End Sub
Sub About_click
StopAllRecordAndPlay("")
pnlRT.Visible=False
pnlAbout.Visible=True
gif.DisposeFrames
gif.Load(File.DirAssets, "dino.gif")
Frame = 0
PGGifTimer.Interval = gif.Delay(Frame)
ImageViewLogo.Bitmap = gif.Frame(Frame)
'ImageViewLogo.Gravity = Gravity.FILL
PGGifTimer.Enabled = True
End Sub
Sub ButtonAboutMenu_Click
Activity.OpenMenu
End Sub
Sub ButtonRTMenu_Click
' Turn off About Animation
If PGGifTimer.IsInitialized = True Then PGGifTimer.Enabled = False
Activity.OpenMenu
End Sub
Sub PGGifTimer_Tick
PGGifTimer.Enabled = False
Frame = Frame + 1
If Frame >= gif.FrameCount Then
Frame = 0
End If
PGGifTimer.Interval = gif.Delay(Frame)
ImageViewLogo.Bitmap = gif.Frame(Frame)
PGGifTimer.Enabled = True
End Sub
This is extracted from a huge program... so the problem exhibited itself with the huge program, as well.
It will seem to work fine on many phones, such as my Nexus.
Some kind of memory problem, maybe?
I have a 32 GB SD Card... but system memory is 288.25 used, 102.05 free (as reported by Memory Cleaner). 236 MB free after cleaning.
So, probably not a memory problem.
To use the recorder... click on one of the four sound recorder buttons. It will blink orange as it records it. Then click the blinking orange button to stop the recording. Click the green play button to the left of it to hear it.
You can record another set of four each time you click the forward or backward button (to infinity).
However, with my LG Optiumus Extreme L40G under Android 4.0.3, it crashes the second time you try to record. Works fine on my Nexus.
Version Number of the Library: AudioRecorder 2.1.0
====================
Two other people have commented about the same problem.
This library only seems to work the first time you use it. The second time, it crashes with a 'failed to start'.
I tried putting a 500 ms - 1000 ms delay between prepare and start... no difference.
This problem seems to be there for any Android 4.0 and before. I've tried it on 2.3 and 4.0 and both does same thing.
If we had the Reset() and Release() functions, might be able to do a work-around.
Tried re-initializing the Recorder again, then loading up the parameters, then preparing, then starting. Same thing.
Since there is only one MediaRecorder instance on the Android (possibly?)... might it be possible to call mRecorder.reset or mRecorder.release using some different library to release it?
..
Every place out on the internet that reports this error says it is related to not doing a mRecorder.release() and/or an mRecorder.reset() after the mRecorder.stop() is done (inside the class, which is inside the .jar file as a compiled binary; so WE can't control that).
So, he needs to do it the right way.
Since this was only a problem that seems to bug Android v4.0 and before, most aren't seeing the problem.
If the Library had the release() and reset() functions built-in to the library, we could do it ourselves. For the life of me, I can't think of a way to get at the instance after the .stop has already occurred. Anybody???