Android Question RuntimePermissions: how to use, what to expect

dcoun

Member
Licensed User
Longtime User
Having in the manifest file targetsdkversion=26, I am going to use RuntimePermissions that B4A has....
I have an activity and I want to have the "PERMISSION_READ_EXTERNAL_STORAGE" or any other dangerous permission just after activity loading, before user starts interaction with the activity.

I put the following code in activity_resume:
B4X:
Sub Activity_Resume      
      rr.CheckAndRequest(rr.PERMISSION_READ_EXTERNAL_STORAGE)
      Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
      Log("perm: "&Result)
End Sub
and I have also:
B4X:
Sub Process_Globals
    Dim rr As RuntimePermissions
End Sub

When I compile it as Debug, it runs, it shows the dialog requesting the permission.
When I complie it as Release, it runs, and enters in an endeless loop without shown the dialog requesting the permission.
When I put the above code in Activity_create there is not an endless loop in release mode but the result is false without showing the dialog requesting permission to the user. It just return false. In debug mode, it works ok.
My main problem is that the dialog requesting the permision is not shown in the release mode. I have to add that, the application in Settings has not a past answer kept denying the permission.

An other problem, is the following case:
Having an activity that starts and based on the Intent probably we need to request a dangerous permission. In such a case, the need starts inside the Activity_resume.
I was thinking to divide the "algorithm" inside the activity _resume in two parts:
a) code running inside the Activity_resume
b) From activity_resume, if needed, call with callsubdelayed a second sub to request the permission, after activity_resume is finished and activity is shown. Based on the result of the checkandrequest continue the algorithm through this sub.
What is your opinion?

I am stuck with the above with no results
Any ideas?

Previous questions on the subject:
https://www.b4x.com/android/forum/threads/runtimepermissions-request-for-permission-not-shown.95042/
https://www.b4x.com/android/forum/threads/endless-loop-in-check-permission.95015/
 
Last edited:

Mahares

Expert
Licensed User
Longtime User
I am stuck with the above with no results
Any ideas?
You have been trying to solve the run time permissions for a couple of days. Some very capable members have offered you solutions, but you insist it is a B4A bug. I think your best bet is to Export your entire project as: File, Export as zip from the IDE instead of posting scattered code snippets that are not easy to follow. You need to find a way to create a small project to upload.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Here is the entire code for your second project. tested and it works:
B4X:
Sub Process_Globals
    Public rr As RuntimePermissions
    Public all As Int
End Sub
Sub Activity_Create(FirstTime As Boolean)   
    rr.CheckAndRequest(rr.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        Log("No Permission")
        Return
    Else
        Log("Permission granted")
        CallSubDelayed(Me,"soupa")
    End If
End Sub

Sub Activity_Resume
End Sub

Sub soupa
    all=all+1
    LogColor(all, Colors.Blue)
    File.WriteString(File.DirRootExternal, "myfile.txt", "dcoun")
End Sub
 
Upvote 0

dcoun

Member
Licensed User
Longtime User
Thank you for your time.
The above is the first case: checkandrequest inside the activity_create. I did a copy-paste in a new project and it works. The second case is the checkandrequest inside activity_resume.
Can you please tell me if the above dokimi.zip runs in release mode showing the dialog requesting the permission? In my IDE and devices, it does not. And it is more or less the same code.
Thank you in advance
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Can you please tell me if the above dokimi.zip runs in release mode showing the dialog requesting the permission

Here it is full project code tested in debug and release. It works:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    rr.CheckAndRequest(rr.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        Log("No Permission")
        Return
    Else
        Log("Permission granted")
        File.WriteString(File.DirRootExternal, "myfile.txt", "dcoun")
    End If
End Sub
 
Upvote 0

dcoun

Member
Licensed User
Longtime User
Thank you again for your time. I download again from above the dokimi.zip
I change all the activity_create sub and run it in release mode.
Your code works:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    rr.CheckAndRequest(rr.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        Log("No Permission")
        Return
    Else
        Log("Permission granted")
        File.WriteString(File.DirRootExternal, "myfile.txt", "dcoun")
    End If
End Sub
My code does not work:
B4X:
Sub Activity_Create(FirstTime As Boolean)  
   rr.CheckAndRequest(rr.PERMISSION_WRITE_EXTERNAL_STORAGE)
   Wait For Activity_PermissionResult (Permission As String, Result As Boolean)  
   Log("perm: "&Result)
End Sub
Can somebody explain me why, please?
 
Upvote 0

dcoun

Member
Licensed User
Longtime User
I found the problem. B4A does not raise the dialog to request the permission, if you just make comment the File.writestring
the problem is that when B4A believes the permission is not needed, it does not present the dialog, and it returns false.
Please correct me, if I am wrong
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You are wrong. Too bad you haven't carefully watched the runtime video tutorial and instead made 20 posts.

Click on the list permissions:
SS-2018-07-15_09.31.45.png


You can immediately see that there is no dangerous permission listed. So it will never show any dialog.

You did try to add the "read external storage" permission to the manifest editor. If you were to add it correctly then it would appear as a dangerous permission:

SS-2018-07-15_09.34.31.png


B4X:
AddPermission(android.permission.READ_EXTERNAL_STORAGE)
 
Upvote 0

dcoun

Member
Licensed User
Longtime User
Dear Erel,
I apologize for my mistakes and my posts.
The initial problem was not the exact type of the permission. You have right, you have again right and again right but I did it in the process of having a project that replicates the problem and can be published.
To be also honest also, I lived all this because I tested a sub compiled as release and I noticed that an other unfinished sub did not show the permission as it did in debug mode.
I can confirm that debug and release mode act differently for requesting permissions. In everything else you have right.
 
Upvote 0

dcoun

Member
Licensed User
Longtime User
You have again right. no diffrence between debug and release.
I did not test the WRITE permission
I apologize again for the trouble
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
There is indeed one difference in debug mode and it helped to add to this confusion. The debugger does add the WRITE_EXTERNAL_STORAGE permission. So your code worked in debug mode as WRITE_EXTERNAL_STORAGE covers the READ_EXTERNAL_STORAGE permission.

I'm pretty sure that this permission is no longer needed for the debugger and it will be removed.
 
Upvote 0

dcoun

Member
Licensed User
Longtime User
Dear Erel, I am more confused now....
I entered the above addpermission you suggested in the manifest
I remove any Runtimepermission.checkandrequest
Now in debug mode I get in lineageOS 15.1 (Oneplus bacon) as android 8.1:
Error occurred on line: 181 (Starter)
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/28148 from pid=22938, uid=10053 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:2005)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:698)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1410)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1247)
at android.content.ContentResolver.openInputStream(ContentResolver.java:967)
at anywheresoftware.b4a.objects.streams.File.OpenInput(File.java:211)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:735)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:357)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:260)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA$2.run(BA.java:365)
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:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

In a Lenovo android 6, the image I want to read is shown. Can you explain it, please?...
And it is not my problem only for a non-dangerous permission: https://stackoverflow.com/questions/32431723/read-external-storage-permission-for-android
 
Last edited:
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
May I suggest something?
Is it possible to have the Runtimepermissions.checkandrequest to return true (instead of false) when B4A or android believes that the requested permission is not needed to shown to the user to accept it?

It doesn't - it returns True if the permission is not needed or is already granted. It's pretty straightforward:

1) You request the permission;
2) If permission is not required or has already been granted, it returns True;
3) If permission is required & hasn't already been granted, the dialog is shown;
3a) If the user grants permission, it returns True;
3b) If the user doesn't grant permission, it returns False.​

- Colin.
 
Upvote 0
Top