iOS Question Check Microphone permission

Alex_197

Active Member
Licensed User
Hi all.
I have a question. My app needs to use a microphone to record a voice message to play it later. On the first start after installation it asks for a permission to use a microphone and if the use allows it it works fine.

But what if the user on the first start allowed it and later for some reason will revoke this permission?

I did a test and answered Don't Allow on the first start. When I click on Record button timer starts and it looks like my app records what user says into the microphone. Of course it doesn't record anything but it looks like it does.

How can I check if the microphone is still allowed?

I attached a small project with microphone

Thank you,
 

Attachments

Semen Matusovskiy

Well-Known Member
Licensed User
B4X:
    Dim no As NativeObject
    Select Case no.Initialize ("AVAudioSession").GetField ("sharedInstance").GetField ("recordPermission").AsNumber
        Case 1735552628 ' AVAudioSessionRecordPermissionGranted
            Log ("Granted")
        Case 1684369017 ' AVAudioSessionRecordPermissionDenied
            Log ("Denied")
        Case 1970168948 ' AVAudioSessionRecordPermissionUndetermined
            Log ("Undetermined")    
    End Select
 

Alex_197

Active Member
Licensed User
B4X:
    Dim no As NativeObject
    Select Case no.Initialize ("AVAudioSession").GetField ("sharedInstance").GetField ("recordPermission").AsNumber
        Case 1735552628 ' AVAudioSessionRecordPermissionGranted
            Log ("Granted")
        Case 1684369017 ' AVAudioSessionRecordPermissionDenied
            Log ("Denied")
        Case 1970168948 ' AVAudioSessionRecordPermissionUndetermined
            Log ("Undetermined")   
    End Select
Thanks
 

Alex_197

Active Member
Licensed User
B4X:
    Dim no As NativeObject
    Select Case no.Initialize ("AVAudioSession").GetField ("sharedInstance").GetField ("recordPermission").AsNumber
        Case 1735552628 ' AVAudioSessionRecordPermissionGranted
            Log ("Granted")
        Case 1684369017 ' AVAudioSessionRecordPermissionDenied
            Log ("Denied")
        Case 1970168948 ' AVAudioSessionRecordPermissionUndetermined
            Log ("Undetermined")   
    End Select
It works, thanks, now I have another question - on the first start user sees a message that he needs to allow a microphone - what if clicks Don't Allow? Is it possible to check what he clicked - Allow or Don't Allow?

Here is my code
B4X:
Sub btnStartRecording_Click
    
    If CheckPermission=False Then
        Dim HUD As HUD
        HUD.ToastMessageShow("Please allow microphone",True)
        Return
    End If
    
    If File.Exists(File.DirDocuments,"Test2.wav")=True Then
        File.Delete(File.DirDocuments,"Test2.wav")
    End If
    
    StartRecording
End Sub

private Sub CheckPermission As Boolean
    
    Try
        
        Dim no As NativeObject
        Select Case no.Initialize ("AVAudioSession").GetField ("sharedInstance").GetField ("recordPermission").AsNumber
            Case 1735552628 ' AVAudioSessionRecordPermissionGranted
                Log ("Granted")
                Return True
            Case 1684369017 ' AVAudioSessionRecordPermissionDenied
                Log ("Denied")
                Return False
            Case 1970168948 ' AVAudioSessionRecordPermissionUndetermined
                Log ("Undetermined")
                Return True
            Case Else
                Return False
        End Select
    Catch
        Log(LastException)
        Return False
    End Try
    
End Sub


Sub StartRecording
    Try
        
        recordingStart = DateTime.Now
        Timer2.Enabled=True
        Timer2_Tick
        
        recorder.Record ' This line asks for a permission
        Log("StartRecording")
    
    Catch
        Log("StartRecording " & LastException)
    End Try
    
End Sub
Line 49 asks for a permission - so I want to know what the user clicked on permission message pop-up.
 

Semen Matusovskiy

Well-Known Member
Licensed User
To manipulate a permission you need two functions.
First should return a current status (we already discussed this). Another function should ask a permission. It can looks so:
B4X:
#If OBJC
@import AVFoundation;
- (void) askRecordPermission { [[AVAudioSession sharedInstance] requestRecordPermission: ^(BOOL granted) {}]; }
#End If
To run it
B4X:
  Dim nativeObjectMe As NativeObject = Me     
 nativeObjectMe.RunMethod ("askRecordPermission", Null)
A logic can be different.
For a example, when the app starts, it checks a current status. If Undetermined (the app was started a first time), use askRecordPermission.
If a new status after askRecordPermission is Denied, ask user the second time. If Denied again, do not ask anymore and do not use B4i 'Record' statements.
 

Alex_197

Active Member
Licensed User
To manipulate a permission you need two functions.
First should return a current status (we already discussed this). Another function should ask a permission. It can looks so:
B4X:
#If OBJC
@import AVFoundation;
- (void) askRecordPermission { [[AVAudioSession sharedInstance] requestRecordPermission: ^(BOOL granted) {}]; }
#End If
To run it
B4X:
  Dim nativeObjectMe As NativeObject = Me    
nativeObjectMe.RunMethod ("askRecordPermission", Null)
A logic can be different.
For a example, when the app starts, it checks a current status. If Undetermined (the app was started a first time), use askRecordPermission.
If a new status after askRecordPermission is Denied, ask user the second time. If Denied again, do not ask anymore and do not use B4i 'Record' statements.
Thank you.

And the last question - what if I want to check for the permission not on start but by on button click? Is it possible to wait for a user replay? Let say it's Undetermined and we need to ask for a permission. But it will not stop the code for execution. Is it possible to use Wait_For for it?
 

Semen Matusovskiy

Well-Known Member
Licensed User
About Wait For I have no idea, but you can do following
1) Add a variable in Process_Globals, for example, Private Busy As Boolean
2) Replace
B4X:
- (void) askRecordPermission { [[AVAudioSession sharedInstance] requestRecordPermission: ^(BOOL granted) {}]; }
with
B4X:
- (void) askRecordPermission { [[AVAudioSession sharedInstance] requestRecordPermission: ^(BOOL granted) { __busy = NO; }]; }
In this case IOS will set Busy to False when user will reply.
3) Call askRecordPermission by following way
B4X:
    Dim nativeObjectMe As NativeObject = Me
    Busy = True
    nativeObjectMe.RunMethod ("askRecordPermission", Null)
    Do While Busy
        Sleep (10)
    Loop
 

Mike1970

Well-Known Member
Licensed User
About Wait For I have no idea, but you can do following
1) Add a variable in Process_Globals, for example, Private Busy As Boolean
2) Replace
B4X:
- (void) askRecordPermission { [[AVAudioSession sharedInstance] requestRecordPermission: ^(BOOL granted) {}]; }
with
B4X:
- (void) askRecordPermission { [[AVAudioSession sharedInstance] requestRecordPermission: ^(BOOL granted) { __busy = NO; }]; }
In this case IOS will set Busy to False when user will reply.
3) Call askRecordPermission by following way
B4X:
    Dim nativeObjectMe As NativeObject = Me
    Busy = True
    nativeObjectMe.RunMethod ("askRecordPermission", Null)
    Do While Busy
        Sleep (10)
    Loop
Hi @Semen Matusovskiy , i tried out this method, and i found out that works ONLY if the user did not answer to that permission before.
I mean:
The first time appears, i answer "Deny", then i try to show it again to answer and nothing happens :(((
 
Last edited:

Semen Matusovskiy

Well-Known Member
Licensed User
Nothing terrible. If a permission is denied, simply inform user about it. Theoretically it's better to ask every time, when you want to record. Users are enough strange guys. They are able to turn off a permission after an app is started (using Settings).
 

Mike1970

Well-Known Member
Licensed User
Nothing terrible. If a permission is denied, simply inform user about it. Theoretically it's better to ask every time, when you want to record. Users are enough strange guys. They are able to turn off a permission after an app is started (using Settings).
Yes in fact is what I did :p
Thanks Semen for the tips and your contribution :D
 
Top