Android Question RuntimePermisssions Issue

RichardN

Well-Known Member
Licensed User
Longtime User
I cut & pasted some proven code from a mature project to read some common resource files from FileDirRootExternal.

Having gained the necessary RTP for PERMISSION_WRITE_EXTERNAL_STORAGE I was surprised to find that File.ListFiles(AppDir) was returning an uninitialized List. So I tried a simple write operation...
B4X:
Sub Activity_Create(FirstTime As Boolean)

    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    
    If Result = False Then
        ToastMessageShow("External Read/Write Permission Refused",True)
        Activity.Finish
    Else
        Log("All OK")            'This is output every time
    End If
    
    Activity.LoadLayout("main")
    
    AppDir = File.DirRootExternal & "/MyDir/"
    File.WriteString(AppDir,"text.txt","1234")    'Error here: write permission refused   
        
End Sub

The log error is:

java.io.FileNotFoundException: /storage/emulated/0/MyDir/text.txt: open failed: EACCES (Permission denied)

The puzzling thing is that if I modify the old project code to look at the new path specified in AppDir it works perfectly.

Any ideas?
 

agraham

Expert
Licensed User
Longtime User
If your target SDK is 29 then it won't work. Read this
 
Upvote 0

RichardN

Well-Known Member
Licensed User
Longtime User
Thanks @agraham.... How very inconvenient. I'm not a full-time user of B4A and keeping up with the latest changes is becoming quite a task.

To add to my confusion I recompiled my legacy application (using API29) to test the code and it read the subject directory just fine.
 
Upvote 0

RichardN

Well-Known Member
Licensed User
Longtime User
I thought perhaps I was going mad! I just tried it again and the legacy app does NOT perform as you suggest. The legacy manifest now has :
B4X:
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="29"/>

    'Without.... 

SetApplicationAttribute(android:requestLegacyExternalStorage, true)

And it installs & runs just fine. To be fair this app has remained installed on this device for a long time. My guess is it was originally installed with a target of sub-29 and has somehow retained access privileges from a previous API level..... just a guess on my part.

To test that..... I have deleted the app entirely from the device, reinstalled with TargetSDK=29 plus the manifest item LegacyExternalStorage. It now performs entirely as you suggested. A rather confusing predicament for the developer but demonstrates the value of making a completely clean install when debugging changes to an app.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
SetApplicationAttribute(android:requestLegacyExternalStorage, true)
That's what makes it work with targetSDK = 29. But that is a temporary expedient and will not work for targetSDK = 30.

You stated "I recompiled my legacy application (using API29)" by which I understood that it was unchanged, but it could not have originally included that manifest entry which you must have added recently. Did you read that link I posted above?
 
Upvote 0
Top