Android Question CheckAndRequest PERMISSION SDK > 32

andyp

Member
Licensed User
Hi

I think I have a problem requesting permissions with SDK > 32. I have read this
https://www.b4x.com/android/forum/t...sion-with-targetsdkversion-33.148233/#content
but don't understand the changes required. My app works with SDK 32 and below. But crashes with SDK > 32 (33 and 34, Android 13 and 14).

Main includes:
B4X:
    rp1.CheckAndRequest(rp1.PERMISSION_ACCESS_FINE_LOCATION)
    rp1.CheckAndRequest(rp1.PERMISSION_WRITE_EXTERNAL_STORAGE)
and
B4X:
Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = rp1.PERMISSION_ACCESS_FINE_LOCATION Then
        If Result = True Then
            'do something
        Else
'            ToastMessageShow("Sorry, need GPS position - terminating program", True)
            Msgbox("Sorry, need device permissions - terminating program", "Warning!")
            Activity.finish
        End If
    End If
    If Permission = rp1.PERMISSION_WRITE_EXTERNAL_STORAGE Then
        If Result = True Then
            'do someting
        Else
    '        ToastMessageShow("Sorry, need device storage - terminating program", True)
            Msgbox("Sorry, need device permissions - terminating program", "Warning!")
            Activity.finish
        End If
    End If
End Sub

And I have a fileprovider class with this in the manifest:
B4X:
<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>
)

And the fileprovider class is:

B4X:
'v1.00
Sub Class_Globals
    Public SharedFolder As String
    Public UseFileProvider As Boolean
    Private rp As RuntimePermissions
End Sub

Public Sub Initialize
    Dim p As Phone
    If p.SdkVersion >= 24 Or File.ExternalWritable = False Then
        UseFileProvider = True
'        SharedFolder = rp.GetSafeDirDefaultExternal("shared")        
        SharedFolder = File.Combine(File.DirInternal, "shared")
        File.MakeDir("", SharedFolder)
    Else
        UseFileProvider = False
        SharedFolder = rp.GetSafeDirDefaultExternal("shared")
    End If
    Log($"Using FileProvider? ${UseFileProvider}"$)
End Sub

'Returns the file uri.
Public Sub GetFileUri (FileName As String) As Object    
    If UseFileProvider = False Then
        Dim uri As JavaObject
        Return uri.InitializeStatic("android.net.Uri").RunMethod("parse", Array("file://" & File.Combine(SharedFolder, FileName)))
    Else
        Dim f As JavaObject
        f.InitializeNewInstance("java.io.File", Array(SharedFolder, FileName))
        Dim fp As JavaObject
        Dim context As JavaObject
        context.InitializeContext
        fp.InitializeStatic("android.support.v4.content.FileProvider")        
        Log(FileName)        
        Return fp.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
    End If
End Sub

'Replaces the intent Data field with the file uri.
'Resets the type field. Make sure to call Intent.SetType after calling this method
Public Sub SetFileUriAsIntentData (Intent As Intent, FileName As String)
    Dim jo As JavaObject = Intent
    jo.RunMethod("setData", Array(GetFileUri(FileName)))
    Intent.Flags = Bit.Or(Intent.Flags, 1) 'FLAG_GRANT_READ_URI_PERMISSION
End Sub
 

drgottjr

Expert
Licensed User
Longtime User
this is the culprit: PERMISSION_WRITE_EXTERNAL_STORAGE. basically, you can't use it anymore. unfortunately, your description of what you're doing is very vague. also, saying your app crashes without posting the log output is useless. it is possible you simply made a programming error having nothing to do with permissions...

imagine external storage as a basin with a faucet (or tap) that allows you to control the flow of water into the basin. then, image a mr. google with a wrench who starts to shut down the flow of water. every so often, he returns and tightens the valve a little more. eventually, he tells you that if you want water, you have to ask him for it.
this is - more or less - what has happened since, what, maybe android 8 or 9. with every passing new sdk and new os version, access to external storage has been restricted.

if you want to describe specifically what your use case is, there should be some examples available here. a lot depends on your target device(s) and exactly what you are trying to achieve.
 
Upvote 1

andyp

Member
Licensed User
@drgottjr Thank you - Yep that was the issue. I need to do a bit more testing, but I am only using internal storage so all I needed to do was comment out that one permission line :rolleyes: Not really sure why I thought I needed external storage permission when I wrote the app.......
 
Upvote 0
Top