Android Question How to write to External Storage folder Download folder

johnaaronrose

Active Member
Licensed User
Longtime User
This concerns writing to my phone's External Storage Download folder using B4XPages . I've seen old threads at https://www.b4x.com/android/forum/t...ns-android-6-0-permissions.67689/page-3#posts and https://www.b4x.com/android/forum/t...folder-with-getsafedirdefaultexternal.110020/ So I'm starting a new thread as requested in those threads.
I want to copy a file from Internal Storage (where a .jpg file was downloaded successfully from a https URL in the app where the coding below originates from) to the Download folder in External Storage: the purpose of this is so that I can view the file in my the phone's Photos or similar Android app.
B4X:
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private WebServer As String = "https://rose.myddns.me"
    Private ISFolder As String = xui.DefaultFolder
    Private FileName As String = "Summer.jpg"
    Private ASFolder As String File.DirRootExternal & "/Download"

Sub Download
    Dim HTTP1 As HttpJob
    Dim ServerPath As String = WebServer & "/" & FileName
    HTTP1.Initialize("", Me)
    HTTP1.Download(ServerPath)
    Wait For (HTTP1) JobDone(HTTP1 As HttpJob)
    If HTTP1.Success Then
        Log("File was downloaded successfully")
        Dim out As OutputStream = File.OpenOutput(ISFolder, FileName, False)
        File.Copy2(HTTP1.GetInputStream, out)
        out.Close '<------ very important
        Log("File was copied successfully to Internal Storage")
    Else
        Log(HTTP1.GetString)
        Log("Error downloading file")
    End If
    HTTP1.Release
    Sleep(0)
    File.Copy(ISFolder, FileName, ASFolder, FileName)

The https download works Ok as the log shows both "File was downloaded successfully" and "File was copied successfully to Internal Storage".
However, there is a runtime error of "java.io.FileNotFoundException: /storage/emulated/0/download/Summer.jp (Permission Denied)" on the File.Copy line. What should I change in the above code?
BTW The previously referred to threads recommend using RuntimePermissions with GetSafeDirDefaultExternal: I've tried code of RuntimePermissions, after including the RuntimePermissions library, but that gives a Compiler error on RuntimePermissions. Why? Also, one of those threads states that the user will be asked to give a permission at runtime and I don't want that to happen. So should I not use RuntimePermissions with GetSafeDirDefaultExternal?
 

agraham

Expert
Licensed User
Longtime User
If you are targeting SDK 30 and Android 11 then you cannot use File.DirRootExternal as Google has restriced app access to external storage.

 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
If you are targeting SDK 30 and Android 11 then you cannot use File.DirRootExternal as Google has restriced app access to external storage.

If I've understood correctly, targeting for SDK 30 &Android 11, an app cannot write to the secondary (external) storage on a phone.
Or can it be done, and if so how?
But can it access a real (i.e. physical) sdcard? If so, what would be the changes to my earlier code? Alternatively, please give a short coding example.
I want to be able to see the file's entry in Google's Files app and view the file using my phone's Google's Photos app. That was the reason for my wanting to copy the app to the phone's Download folder in External Storage.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Or can it be done, and if so how?
I already posted the ways that are available
 
Upvote 1

johnaaronrose

Active Member
Licensed User
Longtime User
I forgot to repeat (from post#1) that I don't want the user to have to reply to any question at runtime.
If I've understood correctly: targeting for SDK 30 &Android 11, an app cannot write to the secondary (external) storage on a phone, except by using the RP method..
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
You can only work with what is allowed if your app is to go in the store. If it is for your own use then either target SDK 28 and request PERMISSION_WRITE_EXTERNAL_STORAGE or target SDK 30 and request MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
 
Upvote 1

johnaaronrose

Active Member
Licensed User
Longtime User
You can only work with what is allowed if your app is to go in the store. If it is for your own use then either target SDK 28 and request PERMISSION_WRITE_EXTERNAL_STORAGE or target SDK 30 and request MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
Interestingly, I didn't need either of the above options when debugging to my Android 9 SDK 28 phone. I used RuntimePermissions to specify a folder for the downloaded file to be copied to. On running my app, I was not asked for any permissions or other questions. When the app finished the download & file copy successfully, I was able to navigate to that file with Google's Files app and view it.
B4X:
Dim rp As RuntimePermissions
ASFolder = rp.GetSafeDirDefaultExternal("")
 
Upvote 0

virpalacios

Active Member
Licensed User
Longtime User
Please for SDK 30 and Android 11, use App Own Files (DirInternal). I got some troubles with Android 11, without using SDK 30. I think in near future Android will require all apps have to work with their own storage area.

Best Regards from Panama

Virgilio
 
Upvote 0
Top