Android Question Should I replace File.DirRootExternal?

creeper82

Member
In my private (not publishing to Play Store and using on my private Android 10 device) phone I've made myself an app that saves its' backups in storage/emulated (File.DirRootExternal), I've implemented permission checking and everything works well. I really prefer to have it over there as it's really important for me to do different things with that file and this way it's very easy.

If that matters, I've placed SetApplicationAttribute(android:requestLegacyExternalStorage, true) in the manifest editor (which I'm still not sure what does).
My question is, will Android updates break that functionality? Is there any other non-deprecated way to write files in that storage? For example apps like Whatsapp still hold their data in Whatsapp folder.

As mentioned in Erel's "Code smells" post:
"File.DirRootExternal - It will soon become inaccessible directly. If really needed then use ContentChooser or ExternalStorage."
What is ExternalStorage? Is it a library or is it associated with runtimePermissions? I'll be happy to hear any answers, also sorry if I've done something wrong in the forum posting that question there (for example wrong thread or something)

TL;DR: Is there any other way to save in the same location as DirRootExternal refers to? And will it support new Android versions?
 
Solution
What is ExternalStorage?
It is a B4A class that allows access to a user selected folder in external storage as well as SD cards and USB sticks.

For a private app I would either do as Erel suggests and target SDK 28 or 29 using the PERMISSION_WRITE_EXTERNAL_STORAGE permission or use the MANAGE_EXTERNAL_STORAGE permission and target SDK 30.

Erel

B4X founder
Staff member
Licensed User
Longtime User
With a non-play store app, you can keep targetSdkVersion on 29 and use android:requestLegacyExternalStorage. Using this combination will allow you to continue directly accessing File.DirRootExternal.

Whatsapp isn't accessing File.DirRootExternal. Maybe RuntimePermission.GetSafeDirDefaultExternal (no good reasons to use it).

Indirect ways to access File.DirRootExternal: https://www.b4x.com/android/forum/t...list-of-other-related-methods.129897/#content
 
Upvote 1

agraham

Expert
Licensed User
Longtime User
What is ExternalStorage?
It is a B4A class that allows access to a user selected folder in external storage as well as SD cards and USB sticks.

For a private app I would either do as Erel suggests and target SDK 28 or 29 using the PERMISSION_WRITE_EXTERNAL_STORAGE permission or use the MANAGE_EXTERNAL_STORAGE permission and target SDK 30.
 
Upvote 1
Solution

creeper82

Member
With a non-play store app, you can keep targetSdkVersion on 29 and use android:requestLegacyExternalStorage. Using this combination will allow you to continue directly accessing File.DirRootExternal.
Thanks for the reply, so if I understand right, the only problem with using older SDK versions is that google play may have problem with it, right? So for private apps, the only thing that could happen in future is the old app warning on app boot-up (a lot of phones show it when the target sdk is very low)
For a private app I would either do as Erel suggests and target SDK 28 or 29 using the PERMISSION_WRITE_EXTERNAL_STORAGE permission or use the MANAGE_EXTERNAL_STORAGE permission and target SDK 30.
So if I'd for some reason need to set SDK to 30 and I'd not publish it to Play store, I'd just have to add MANAGE_EXTERNAL_STORAGE and the DirRootExternal will work the exact way as before.. Would Android 10 understand that permission? Can you combine these two for further compatibility? Thanks for the reply, too!
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
older SDK versions is that google play may have problem with it, right?
Yes. You might miss out on some later features, though I don't know of any relevant ones for SDK 30 and 31.
So if ...SDK to 30 ... not publish it to Play store, ... add MANAGE_EXTERNAL_STORAGE ... DirRootExternal will work ... as before.. Would Android 10 understand that permission? Can you combine these two for further compatibility?
You can combine the two as follows. Put SetApplicationAttribute(android:requestLegacyExternalStorage, true) in the manifest (it should be ignored on old devices) and it should work on all devices. Note the comment that File.DirRootExternalneeds to be referenced. This is needed so B4A adds the required manifest entry. Un-comment it if you don't use it elsewhere.
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
   ...
    Dim device As Phone
    Dim MES As ManageExternalStorage
End Sub


    ' get the device SDK version
    Dim SdkVersion As Int = device.SdkVersion
 
    ' Choose which permission to request in order to access external storgage
    If SdkVersion < 30 Then
        Log("SDK = " & SdkVersion & " : Requesting WRITE_EXTERNAL_STORAGE permission")
        Dim rp As RuntimePermissions
        rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) ' Implicit read capability if granted
        Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
        Log($"PERMISSION_WRITE_EXTERNAL_STORAGE = ${Result}"$)
        'Log(File.DirRootExternal) ' reference needed somewhere so compiler knows permission needed, here in Button1_Click

    Else
        Log("SDK = " & SdkVersion & " : Requesting MANAGE_EXTERNAL_STORAGE permission")
        Log("On Entry MANAGE_EXTERNAL_STORAGE = " & MES.HasPermission)
        If Not(MES.HasPermission) Then
            MsgboxAsync("This app requires access to all files, please enable the option", "Manage All Files")
            Wait For Msgbox_Result(Res As Int)
            Log("Getting permission")
            MES.GetPermission
            Wait For MES_StorageAvailable        
        End If
    End If
End Sub

PS: Note this from the MANAGE_EXTERNAL_STORAGE thread.
For these cases, we have added the MANAGE_EXTERNAL_STORAGE permission to give access to all files on external storage, except the Android/data and Android/obb directories. To learn more about related Google Play guidelines, read the updated policy from the Policy Help Center.
 
Last edited:
Upvote 0

creeper82

Member
Thank you. Now I understand everything, imo Google went a little bit crazy with the filesystem related changes, but I suppose it's just all for privacy
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Note this from the MANAGE_EXTERNAL_STORAGE thread.
Since no permission is required before SDK 23, shouldn't your class code include something like this or is not a big deal.: It runs fine without anyway..
B4X:
If SdkVersion < 23 Then  'added by mahares
        Log("No Permission at all required for external")    'added by mahares
    else If SdkVersion >=23 And SdkVersion < 30 Then
'......
Else
By the way, how is that tractor running.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
shouldn't your class code include something like this
Probably but as I don't have any phones earlier than Android 10 it doesn't matter to me.
By the way, how is that tractor running.
Good memory or lucky forum search? ? Both our lawn tractors are safely tucked up for the winter awaiting the joys of spring to awaken them from their slumber. Let's just hope the bloody engines start after a few idle months. The first start of the spring usually isn't any trouble with a fully charged battery but a good dose of ether in the air filter will work as a last resort if necessary. ?
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Good memory or lucky forum search?
No, it is not a lucky search. I remember it from one your posts 5, 6 or more years ago, where you mentioned that you want to check out the tractor. I do not want to distract from this thread, but, the links you have to Google Developer docs regarding MANAGE_EXTERNAL_STORAGE, I did not see anywhere that Google says they will not accept apps in google Play that request it, although I did not read it too carefully.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
I did not see anywhere that Google says they will not accept apps
From here
You should request the MANAGE_EXTERNAL_STORAGE permission only when your app cannot effectively make use of the more privacy-friendly APIs, such as Storage Access Framework or the Media Store API. Additionally, the app's usage of the permission must fall within permitted uses, and must be directly tied to the core functionality of the app. If your app includes a use case that's similar to the following examples, it's likely to be allowed to request the MANAGE_EXTERNAL_STORAGE permission:

  • File managers
  • Backup and restore apps
  • Anti-virus apps
  • Document management apps
  • On-device file search
  • Disk and file encryption
  • Device-to-device data migration
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Thank you. I saw that. doesn't Document management apps include SQLite databases, which is a very integral part of an app and many users prefer to store it and manipulate it while in File.DirRootExternal.
;t
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Document management apps include SQLite databases,
No, that's far too sweeping an assertion. An app using a data base does not necessarily qualify just because the user wants to use File.DirRootExternal. Google will only permit this on a store app by specific request by the developer to use it and if Google agrees the app functionality meets their stringent requirements. Those requirements are limited to those apps that need it for their primary function and cannot perform that function using any other available APIs.
 
Upvote 0
Top