Java Question Root Folder of any Device

Johan Schoeman

Expert
Licensed User
Longtime User
Is there a java method to find the root folder of any device (no mirco SD card)?

I need to for eg read from a folder called "books" that should be in the root folder of any android device.

Seems to me as if /storage/sdcard0/books should be inside the B4A project (and thus will get deleted when the B4A project is uninstalled - I don't want that.

On my Lollipop device it seems to be /storage/sdcard1/books (working). But this does not work on my KitKat device.

How does one solve this puzzle?
 

Johan Schoeman

Expert
Licensed User
Longtime User
File.DirRootExternal will return the path of the secondary storage. It is available on almost all devices (or all if you discard old devices).

The internal storage root is not accessible.
I have this in my code:

B4X:
    Log("File.DirRootExternal = " & File.DirRootExternal)
   
    Dim mylist As List = File.ListFiles("/storage/sdcard1/books/general/")
    Log("mylist = " & mylist)

The first Log statement logs "File.DirRootExternal = /storage/sdcard0"

But I cannot read the files from there. I have to use "File.ListFiles("/storage/sdcard1" to access the files in folders /books/blabla/blabla.

Why does B4A report /storage/sdcard0 and I have to use /storage/sdcard1 to access the files?

A bit lost here....
 

Johan Schoeman

Expert
Licensed User
Longtime User
This is the output Erel:
B4X:
(ArrayList) [Nokia, Images, qf, Documents, Sounds, Videos, Backup, cities, LOST.DIR, private, resource, sys, system, data, Others, card_content.xml, Music, Installs, Attachments, BlackBerry, tmp, databases, .dropbox.device, .android_secure, DCIM, Android, Message+, WhatsApp, .thumbnails, Download]
.

It is a listing of the external/removeable micro SD card.
 

Johan Schoeman

Expert
Licensed User
Longtime User
What is the output of Log(File.ListFiles(File.DirRootExternal)) ?
This code in the Java project does however report the root folder correctly for my S4 Mini (KitKat - /storage/sdcard0) and for my VF-795 (Lollipop - /storage/sdcard1)
B4X:
    public void libraryButtonClick() {
    BA.Log("Got here!!!");
            String sSDpath = null;
            File   fileCur = null;
            for( String sPathCur : Arrays.asList( "MicroSD","external_SD","sdcard1", "sdcard0","ext_card", "external_sd", "ext_sd", "external", "extSdCard",  "externalSdCard")) // external sdcard
             {

               fileCur = new File( "/mnt/", sPathCur);
               if( fileCur.isDirectory() && fileCur.canWrite())
                 {
                   sSDpath = fileCur.getAbsolutePath();
                   BA.Log("path1 = " + sSDpath);
                   break;
                 }
               if( sSDpath == null)  {
               fileCur = new File( "/storage/", sPathCur);
               if( fileCur.isDirectory() && fileCur.canWrite())
                 {
                   sSDpath = fileCur.getAbsolutePath();
                   BA.Log("path2 = " + sSDpath);
                   break;
                 }
               }
               if( sSDpath == null)  {
               fileCur = new File( "/storage/emulated", sPathCur);
               if( fileCur.isDirectory() && fileCur.canWrite())
                 {
                   sSDpath = fileCur.getAbsolutePath();
                   BA.Log("path3 = " + sSDpath);
                   break;
                 }
               }
             }

        BA.Log("sSDpath = " + sSDpath);
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
There is no such thing as root folder.

There are two standard folders:
File.DirInternal - Only accessible by your app.
File.DirRootExternal - Secondary storage path. Accessible by all apps.

On most devices File.DirRootExternal will not point to the sd card.

RuntimePermissions.GetAllSafeDirsExternal returns all the accessible folders (on Android 4.4+).

It is a listing of the external/removeable micro SD card.
This is strange. What happens if you remove the sd card?
 

Johan Schoeman

Expert
Licensed User
Longtime User
This is strange. What happens if you remove the sd card?


I then get this Erel (which is the correct listing as it includes the books folder):
B4X:
(ArrayList) [obb, Android, Music, Podcasts, Ringtones, Alarms, Notifications, Pictures, Movies, Download, DCIM, Message+, .mplus, books, WhatsApp, video, mVideo, .fotadownload]

But then I have to change
Dim mylist As List = File.ListFiles("/storage/sdcard1/books/general/")
to
Dim mylist As List = File.ListFiles("/storage/sdcard0/books/general/")

...in order to get to the /books folder. So it seems that when the micro SD card is present then /storage/sdcard1/books/ applies to the device's secondary storage (not the micro SD card) but when the micro SD card is removed then /storage/sdcard0/books/ applies.

I don't have the books folder on the micro SD card.
 
Last edited:

Johan Schoeman

Expert
Licensed User
Longtime User
Don't rely on any hard code path. It will be different on different devices.

B4A File.DirRootExternal = Environment.getExternalStorageDirectory(). On most devices it doesn't point to an sd card.
So how does one handle it in this case when an SD card is present? Is the way that this device handles File.DirRootExternal something out of the ordinary as it reports the SD card when the sd card is present but it reports the device's secondary storage when the sd card is removed?
 
Top