Android Question Record audio with system default app

vecino

Well-Known Member
Licensed User
Longtime User
Hi, I am making a simple program with which the user records videos, photos and audios. Then he can watch them or play them back.
I save all the files in a local directory of the program.
In all cases I use the default program that the user has installed on his device.
With videos and photos, so far, I have not had any problem, however with audio files it works on some devices and not on others.
At first I did it this way (code summary):

B4X:
Sub Class_Globals
  Dim aud As AudioRecordApp

Sub Audio
    Dim cTestAudio As String = "test.ogg"
    aud.Record( ShCode.cDirShared, cTestAudio )
    Wait For aud_RecordComplete (Success As Boolean)
    If Success Then ' copy to local directory
        Wait For (File.CopyAsync(ShCode.cDirShared,cTestAudio,ShCode.cDirMedia,cTestAudio)) complete (Success As Boolean)
        If Success Then ' delete from shared
            File.Delete(ShCode.cDirShared,cTestAudio)
        End If       
    End If
End Sub

Then, as it did not work on many devices, I tried this other way:

B4X:
Sub Audio
    Dim cTestAudio As String = "test.ogg"

    Dim in As Intent
    in.Initialize("android.provider.MediaStore.RECORD_SOUND", "")

    StartActivityForResult(in)
    Wait For ion_Event (MethodName As String, Args() As Object)
            
    Dim iRes As Int = Args(0)
    If iRes=(-1) Then    ' ok
        Dim in As Intent = Args(1)
        Dim uri As String = in.GetData
        
        Wait For (File.CopyAsync("ContentDir",uri, ShCode.cDirMedia, cTestAudio)) Complete (Success As Boolean)
        If Success Then                        ' delete from system dir
            File.Delete("ContentDir",uri)
        End If
                
    End If
End Sub

Sub StartActivityForResult(i As Intent)
    Dim jo As JavaObject = Me
    jo = jo.RunMethod("getBA", Null)
    ion = jo.CreateEvent("anywheresoftware.b4a.IOnActivityResult", "ion", Null)
    jo.RunMethod("startActivityForResult", Array(ion, i))
End Sub

In this last way it also works in some yes and in others no, specifically it calls the default program but then I don't know how to access the directory where it has saved the audio because I don't know with which name it has saved it.
On other devices it works correctly.

In short, my question is how can you call any default program, which uses any audio format, and then I can access the saved file to move it to the local directory of my program.
Thank you very much.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
This code will never work:
B4X:
If Success Then                        ' delete from system dir
            File.Delete("ContentDir",uri)
        End If
ContentDir is not a real folder and the uri is not a path to a real file. You are reading the data from a content provider. The only thing that you can do is to open an input stream, as done with File.CopyAsync.

What is the output of Log(uri) with the second code snippet?
 
Upvote 0

vecino

Well-Known Member
Licensed User
Longtime User
And using the first code I posted, the log says this:

B4X:
b4xmainpage$ResumableSub_getAudioresume (java line: 1232)
java.lang.RuntimeException: Object should first be initialized (List).
    at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:67)
    at anywheresoftware.b4a.objects.collections.List.getSize(List.java:129)
    at anywheresoftware.b4a.audio.AudioRecordApp.Record(AudioRecordApp.java:97)
    at conkex.happybits.b4xmainpage$ResumableSub_getAudio.resume(b4xmainpage.java:1232)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:207)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
    at anywheresoftware.b4a.keywords.Common$14.run(Common.java:1770)
    at android.os.Handler.handleCallback(Handler.java:888)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:213)
    at android.app.ActivityThread.main(ActivityThread.java:8178)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
 
Upvote 0

vecino

Well-Known Member
Licensed User
Longtime User
Hi, so how should I delete the original audio?
With CopyAsync is it correct to use "ContentDir"?

I am using this code, and the log says this:

B4X:
Sub getAudio
  Dim cNFaudio as string = "test.ogg"

    Dim in As Intent
    in.Initialize("android.provider.MediaStore.RECORD_SOUND", "")

    StartActivityForResult(in)
    Wait For ion_Event (MethodName As String, Args() As Object)
    
    Dim iRes As Int = Args(0)
    If iRes=(-1) Then     ' ok
        Dim in As Intent = Args(1)   
        Dim uri As String = in.GetData
                
        Log(uri)
        Log(Args(1))               
        
        Wait For (File.CopyAsync("ContentDir",uri, ShCode.cDirMedia, cNFaudio)) complete (Success As Boolean)
        If Success Then
'            File.Delete("ContentDir",uri)
        End If

    End If
End Sub

B4X:
content://com.github.axet.audiorecorder/8641f5388f9cc310513f1e6cdbc554a6/2021-09-27%2012.31.31.ogg
Intent { dat=content://com.github.axet.audiorecorder/8641f5388f9cc310513f1e6cdbc554a6/2021-09-27 12.31.31.ogg typ=audio/ogg flg=0x3 }

Thank you.
 
Upvote 0

vecino

Well-Known Member
Licensed User
Longtime User
Yes, 'CopyAsync', that works well.

About the "ContentResolver", any idea, please? I found an example that works with the list of contacts, but I don't know how to access an audio saved by the default program installed on each device.
Thank you.
 
Upvote 0

vecino

Well-Known Member
Licensed User
Longtime User
Hello, after searching for information on how to use it and doing several tests, I have not achieved anything.
I am using this code, which I don't know if it is correct or not, but it doesn't work, it doesn't do anything.
Thank you.
B4X:
    StartActivityForResult(in)
    Wait For ion_Event (MethodName As String, Args() As Object)
    '
    Dim iRes As Int = Args(0)
    If iRes=(-1) Then    ' ok
        Dim in As Intent = Args(1)    
        Dim uri As String = in.GetData
      
        Log(uri)
        ' Example:
        ' content://com.github.axet.audiorecorder/9a86bd75eedd6c0de8e20caf748e0fdd/2021-09-29%2013.50.48.ogg
      
        Wait For (File.CopyAsync("ContentDir",uri, ShCode.cDirMedia, cNFaudio)) complete (Success As Boolean)
        If Success Then    
'            File.Delete("ContentDir",uri)

            Dim cr As ContentResolver
            Dim u As Uri
            u.Parse(uri)
  
            cr.Initialize("")
            cr.Delete(u,"",Array As String(""))

        End If

Thank you.
 
Last edited:
Upvote 0

vecino

Well-Known Member
Licensed User
Longtime User
After many tests, I am not able to get the original directory to delete the audio from there, and not have 2 copies of it.
I also don't understand why "ContenDir" works using copy, and yet it doesn't work with delete.
Let's see if some expert can give me a hand.
Thanks.
 
Upvote 0
Top