B4A Class Manage External Storage - access internal external storage >= SDK 30

Google seems intent on dumbing down Android to the point of uselessnes to me. I think of my devices as little computers and I want a proper file system on them, not the limited tortuous things that Google offers and that I don't understand, ContentChooser, FileProvider, ... o_O I'm getting old and can't cope with complications like that! :(

So here is a class that lets apps on SDK 30 and higher devices treat the file store as a real file store and not some dumbed down abstracted thing. 😁

It uses a new permission that Google will not allow for most Play Store apps.
Manage all files on a storage device | Android Developers
As I will never have apps in the Play Store this worries me not one jot :p

The class uses code stolen from Erel's ExternalStorage class to provide a similar API - thank you Erel 🤩
ExternalStorage - Access SD cards and USB sticks | B4X Programming Forum


  • ManageExternalStorage_1.00.zip
    13.4 KB · Views: 274
Last edited:


Well-Known Member
Licensed User
Small change to read the package name
Thank you @agraham
Thank you @Erel

Public Sub GetPermission
    If HasPermission Then
    End If
    Dim in As Intent
    ' Be sure to reference your app package name in "pakageg:xxx"                                             ^^^^^^^^^^^^^^^^^
    in.Initialize("android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION", "package:" & Application.PackageName)
End Sub


Licensed User
Using your great example. I'm still not able to do simple file operations
I checked app setting and I do have permission: Allow management of all file
running Android 11
Just to test, All I did was add a button and textbox to this example.

Private Sub Button2_Click
edittext1.text = "/Android/data/lb.myapp.lbochs/files"   NOTE:  this is NOT my app folder!

    File.WriteString(File.DirRootExternal & EditText1.Text,"scott.txt","scott was here")
        MsgboxAsync("didn't work: " & File.DirRootExternal & EditText1.Text & "/scott.txt","")
    End Try
End Sub

file.copy(...) wont work either

What am I doing wrong?



Licensed User


Licensed User
Thanks for your reply. I read your link. Basically that says we cant access /Android/data anymore. but I really want to. Haa
apps like x-plore can do it, so why cant we? I've even tried adding

and enabled it in app settings
didn't work


Licensed User
Thanks for your useful source. This source works fine, but I still have trouble copying a file to the Android / data folder, and Android 11 does not allow access to this folder. What can I do about this problem?
Please help


Licensed User
Hello Agraham

I put your example in my app and I can share everything too. Now how can I access my database in a folder? When initializing it comes this error. Sorry for the bad English it is a deepl.com translation.

android.database.sqlite.SQLiteCantOpenDatabaseException: Cannot open database '/storage/emulated/0/Test/dbRE.db3': File /storage/emulated/0/Test/dbRE.db3 is not readable
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:365)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:226)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:737)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:284)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:251)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:1392)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:1337)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:946)
at anywheresoftware.b4a.sql.SQL.Initialize(SQL.java:44)
at ch.ziwalig.replikateinrichten.msqlitedb._dbinitialisieren(msqlitedb.java:35)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.shell.DebugResumableSub$RemoteResumableSub.resume(DebugResumableSub.java:22)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8587)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 2062 SQLITE_CANTOPEN_EACCES[2062]): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:337)
... 28 more


Well-Known Member
Licensed User
attn: @zwalig
android 11, sdk30

for what it's worth,
1) i put an sqlite3 db in dir.assets
2) i copied it to dir.rootexternal
3) i opened it and made a simple query
cap1.png image attached.

4) i created a "Test" folder in dirrootexternal
5) i copied the db from assets to the Test folder
6) i opened it and made a simple query
cap2.png image attached.

cap3 shows the db in dirrootexternal
cap4 shows the db in dirrootexternal/Test

not sure how you implemented the example.


  • cap.png
    24.7 KB · Views: 37
  • cap2.png
    21.9 KB · Views: 40
  • cap3.png
    26.9 KB · Views: 34
  • cap4.PNG
    30.2 KB · Views: 33
Last edited: