Android Question Runtime Permissions Error

TimN

Member
Licensed User
Longtime User
I have upgraded to b4a v10 and now has this problem.
1596046826641.png
 

TimN

Member
Licensed User
Longtime User
I actually added that as a work aground for the devices that have already approved the permission. For the devices that have not approved at least once since the app was installed the error triggers
 
Upvote 0

TimN

Member
Licensed User
Longtime User
I am sorry. Here is the text of the code and error.

Code:
    Log("before rp.CheckAndRequest(rp.PERMISSION_CAMERA")
    rp.CheckAndRequest(rp.PERMISSION_CAMERA)
    Log("after rp.CheckAndRequest(rp.PERMISSION_CAMERA")
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission!", True)
        Return Null   
    End If
    
    Wait For (cam.OpenCamera(front)) Complete (TaskIndex As Int)


Code:
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = false **
** Activity (timeclockplus) Create, isFirst = true **
** Activity (timeclockplus) Resume **
before rp.CheckAndRequest(rp.PERMISSION_CAMERA
after rp.CheckAndRequest(rp.PERMISSION_CAMERA
java.lang.Exception: Sub activity_permissionresult was not found.
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:219)
    at anywheresoftware.b4a.BA$2.run(BA.java:387)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:7000)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
java.lang.Exception: Sub activity_permissionresult was not found.
 
Upvote 0

TimN

Member
Licensed User
Longtime User
It is located in a Class Module. Shown below.

B4X:
Sub Class_Globals
    
    Dim cam As CamEx2
    Dim MyTaskIndex As Int
    Dim pnlCamera As Panel
    Dim Dir As String
    Dim fn As String
    Dim Confirm As Boolean
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(p As Panel,D As String,f As String, c As Boolean)
    pnlCamera = p
    Dir = D
    fn = f
    Confirm  = c
End Sub

Sub TakePicture(front As Boolean) As ResumableSub
    Dim rp As RuntimePermissions
    
    pnlCamera.RemoveAllViews
    cam.Initialize(pnlCamera)
    
    Log("before rp.CheckAndRequest(rp.PERMISSION_CAMERA")
    rp.CheckAndRequest(rp.PERMISSION_CAMERA)
    Log("after rp.CheckAndRequest(rp.PERMISSION_CAMERA")
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission!", True)
        Return Null   
    End If
    
    Wait For (cam.OpenCamera(front)) Complete (TaskIndex As Int)
    If TaskIndex > 0 Then
        MyTaskIndex = TaskIndex 'hold this index. It will be required in later calls.
        cam.PreviewSize.Initialize(1920, 1080) 'sizes can be modified here
        Wait For (cam.PrepareSurface(MyTaskIndex)) Complete (Success As Boolean)
        If Success = False    Then
            ToastMessageShow("Failed to open camera", True)
            Log(LastException)
            Return Null
        End If
            
        cam.StartPreview(MyTaskIndex,False)
        Dim lbl As Label
        lbl.Initialize("lblTakePic")
        lbl.Typeface = Typeface.FONTAWESOME
        lbl.TextSize = 100
        lbl.TextColor = Colors.White
        lbl.Text = Chr(0xF030)
                
        pnlCamera.AddView(lbl,(pnlCamera.Width/2)-50dip,pnlCamera.Height-150dip,250dip,250dip)

        Wait For lblTakePic_click
        If front Then
           Wait For(cam.TakePictureNow(MyTaskIndex)) Complete (Data() As Byte)
        Else
           Wait For(cam.FocusAndTakePicture(MyTaskIndex)) Complete (Data() As Byte)
        End If
        
        cam.stop
        pnlCamera.RemoveAllViews
        
        Dim bmp As Bitmap = cam.DataToBitmap(Data)
        If front Then
            bmp = bmp.Rotate(-90)
        Else
            bmp = bmp.Rotate(90)
        End If
            

        Dim save As Boolean = True
        If Confirm Then
            pnlCamera.SetBackgroundImage(bmp).Gravity = Gravity.FILL
                    
            Dim lbl As Label
            lbl.Initialize("lblokRetry")
            lbl.Typeface = Typeface.MATERIALICONS
            lbl.TextSize = 50
            lbl.TextColor = Colors.White
            lbl.Gravity = Gravity.top
            lbl.Text = Chr(0xE876)
            pnlCamera.AddView(lbl,pnlCamera.Width - 150dip,pnlCamera.Height-75dip,50dip,50dip)

            Dim lbl As Label
            lbl.Initialize("lblokRetry")
            lbl.Typeface = Typeface.MATERIALICONS
            lbl.TextSize = 50
            lbl.TextColor = Colors.White
            lbl.Text = Chr(0xE5C9)
            pnlCamera.AddView(lbl,50dip,pnlCamera.Height-75dip,50dip,50dip)
        
            Wait For lblokRetry_click
            Dim lbl As Label = Sender
            If lbl.Text = "Retry" Then
                Wait For (CallSub(Me,"TakePicture")) complete (r As Object)
            Else
                save = True
            End If
        End If
        
        If save Then
            Dim out As OutputStream = File.OpenOutput(Dir, fn, False)
            bmp.WriteToStream(out, 100, "JPEG")           
            out.Close
        End If
                
    End If
    Return Null
End Sub
 
Upvote 0

TimN

Member
Licensed User
Longtime User
That was it. I moved to activity and all good. It was nice having in the class but no big deal.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
I think I am wrong about being able to handle PermissionResult in a class. From Erel's Permissions tutorial
The CheckAndRequest method can only be called from an Activity.
There is another method named Check that only tests whether the permission has already been approved or not. This method can be called from any module.
It might be tempting to first test whether there is a permission and only if there is no permission call CheckAndRequest. However it will just make the program flow more complicated as you will need to deal with all cases anyway.
As a general rule, you shouldn't call RuntimePermissions.Check from an Activity. It will be simpler to always call CheckAndRequest.
As I understand Check should work in a class but not CheckAndRequest so if it worked before I have no idea why!
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
CheckAndRequest can be called from the class, assuming that it was initialized from an activity, however the event is an activity event and will be raised in the activity. There was a bug in the past which caused the event to be raised in the class in some cases.

Note that with B4XPages, everything is simple, including this case. You can handle the B4XPage_PermissionResult event (with Wait For).
 
Upvote 0
Top