Android Question Odd Behaviour with Permissions at Runtime **SOLVED**

stu14t

Active Member
Licensed User
Longtime User
I'm in no way a professional coder and some may look at it and say i've not followed rules of conventions in my design but up until two days ago it worked fine. What I did with one of my apps is move from the intent based camera over to using the Camera2 library, which I feel is more stable. However, since then I'm getting reports from users that there are problems and these problems are centred around permissions not being asked for / or granted. I've created a subroutine that gets called at the start (first-time only) called CheckPermissions :
B4X:
Sub CheckPermissions
    
    
    For Each permission As String In Array(rp.PERMISSION_ACCESS_FINE_LOCATION, rp.PERMISSION_WRITE_EXTERNAL_STORAGE, rp.PERMISSION_READ_EXTERNAL_STORAGE, rp.PERMISSION_CAMERA, rp.PERMISSION_READ_PHONE_STATE)
        rp.CheckAndRequest(permission)
        Wait For Activity_PermissionResult (permission As String, Result As Boolean)
        If Result = False Then
            Msgbox2Async("You have chosen NOT to allow some Permissions and the App cannot work without them. Please allow in Settings>Apps>*********>App Permissions","********","OK","","",LoadBitmap(File.DirAssets,"question.png"),False)
            Wait for msgbox_result (Result1 As Int)
            If Result1 =DialogResponse.POSITIVE Then
                Activity.Finish
                Return
            End If
            
            
        End If
    Next
End Sub

It seems as though this gets either jumped over or ignored as only some of the permissions are asked for (location and Camera) and the WRITE_EXTERNAL_STORAGE and READ_PHONE_STATE are not checked or asked for. I testing this with adding lines to log what permissions were checked and then granted, nothing showed in the logs as if the app never called that routine.

I'll include my manifest file too:

B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="29"/>
<supports-screens android:smallScreens="false"
android:normalScreens="false"
android:largeScreens="true"
android:xlargeScreens="true"
android:requiresSmallestWidthDp="600"
android:hardwareAccelerated="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
SetApplicationAttribute(android:requestLegacyExternalStorage, true)
SetActivityAttribute(main, android:windowSoftInputMode, adjustResize|stateHidden)
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)
CreateResourceFromFile(Macro, FirebaseAnalytics.Firebase)
CreateResourceFromFile(Macro, FirebaseAnalytics.Crashlytics)
'End of default text.
AddManifestText(<uses-feature android:name="android.hardware.location.gps"/>)
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)
AddPermission(android.permission.READ_EXTERNAL_STORAGE)
AddPermission(android.permission.CAMERA)
AddPermission(android.permission.READ_PHONE_STATE)
AddPermission(android.permission.INTERNET)
AddApplicationText(
  <provider
  android:name="android.support.v4.content.FileProvider"
  android:authorities="$PACKAGE$.provider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
  android:name="android.support.FILE_PROVIDER_PATHS"
  android:resource="@xml/provider_paths"/>
  </provider>
)
CreateResource(xml, provider_paths,
   <files-path name="name" path="shared" />
)

I'm completely baffled as all the code above worked fine until I removed the intent camera and replaced it with Camera2, which does work fine when all the permissions are granted.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've created a subroutine that gets called at the start (first-time only) called CheckPermissions :
This is a mistake. You should always check for a permission right before you need it.
Once a permission is granted, the user will not be asked to approve it again.

I've seen cases where requesting multiple permissions can fail if it is done inside Activity_Resume. It happens because Activity_Resume is raised when the permission dialog is dismissed.

As I wrote, the best solution is to always check for permission right before you need it. It will solve such issues (and is also safer and more logical).
 
Upvote 0

stu14t

Active Member
Licensed User
Longtime User
Erel,

Many thanks for the reply. So, remove the subrotine and create something like this below (this is for the camera) where the need for permission is first called and replicate the same for the other permissions?

B4X:
rp.CheckAndRequest(rp.PERMISSION_CAMERA)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission!", True)
        Return
    End If
 
Upvote 0

stu14t

Active Member
Licensed User
Longtime User
Thanks again Erel.

I've done as you suggested for each and all is working as it should now.
 
Upvote 0
Top