Bug? File.DirDefaultExternal returns the internal directory

PhilipBrown

Active Member
Licensed User
I used Erel's code supplied in http://www.b4x.com/android/forum/threads/how-to-ext-sd-card-write-on-android-4-4.42177/#post-255351

B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim paths() As Object = GetContext.RunMethod("getExternalFilesDirs", Array(Null))
   For Each p As Object In paths
     Log(p)
   Next
End Sub

Sub GetContext As JavaObject
  Return GetBA.GetField("context")
End Sub

Sub GetBA As JavaObject
  Dim jo As JavaObject
  Dim cls As String = Me
  cls = cls.SubString("class ".Length)
  jo.InitializeStatic(cls)
  Return jo.GetFieldJO("processBA")
End Sub
The first path will be the same as File.DirDefaultExternal.
But I find that it's the SECOND path which refers to the external drive. My log says:

B4X:
/storage/emulated/0/Android/data/uk.co.pennypress.FileLocations/files
/storage/external_SD/Android/data/uk.co.pennypress.FileLocations/files
Therefore I think that File.DirDefaultExternal should return the second location, not the first!!
 
Last edited:

Erel

Administrator
Staff member
Licensed User
This is not a bug. File.DirDefaultExternal and File.DirRootExternal return the path to the secondary storage. On 99% of the devices the secondary storage is not the external sd card.
File.DirDefaultExternal is a special folder in the secondary storage dedicated to your app. It will be deleted when the app is uninstalled.
Also remember that the API you are now using is only available on Android 4.4+.
 

PhilipBrown

Active Member
Licensed User
File.DirDefaultExternal and File.DirRootExternal return the path to the secondary storage
I agree they should, but they don't on my phone, which is running Android 5.0.2
They return folders on the internal drive, /storage/emulated/0, not the external which is /storage/external_SD/

This is proven because the following code copies files to the internal drive.

Here's the code

B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    Log("File.DirInternal=" & File.DirInternal)
    Log("file.DirDefaultExternal=" & File.DirDefaultExternal)
    Log("File.DirRootExternal=" & File.DirRootExternal)
    If File.ExternalReadable Then
        Log ("File.ExternalReadable")
    Else
        Log ("Not File.ExternalReadable")
    End If
    If File.ExternalWritable Then
        Log ("File.ExternalWritable")
    Else
        Log ("Not File.ExternalWritable")
    End If
  
    Dim strSystemDirectory As String
    strSystemDirectory = getSystemDirectory
    Log ("strSystemDirectory = " & strSystemDirectory)
    File.Copy(File.DirAssets,"ArmCurlWalk1.jpg", strSystemDirectory, "ArmCurlWalk1.jpg")
    If File.Exists(strSystemDirectory, "ArmCurlWalk1.jpg") Then
        Log ("Copied File " & strSystemDirectory & "/ArmCurlWalk1.jpg")
    Else
        Log ("Failed to copy File " & strSystemDirectory & "/ArmCurlWalk1.jpg")
    End If

' from http://www.b4x.com/android/forum/threads/how-to-ext-sd-card-write-on-android-4-4.42177/#post-255351
    Log("Using getExternalFilesDirs")
    Dim paths() As Object = GetContext.RunMethod("getExternalFilesDirs", Array(Null))
    For Each p As Object In paths
        Log(p)
    Next

    Activity.Finish
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub getSystemDirectory As String
    Dim systemDirectory As String
    If File.ExternalWritable And File.ExternalReadable Then
        systemDirectory = File.DirDefaultExternal
        Log ("getSystemDirectory using File.DirDefaultExternal for systemDirectory = " & systemDirectory)
    Else
        ' have to use internal folder
        systemDirectory = File.DirInternal
        Log ("getSystemDirectory using File.DirInternal for systemDirectory = " & systemDirectory)
    End If

    Return systemDirectory
End Sub


Sub GetContext As JavaObject
  Return GetBA.GetField("context")
End Sub

Sub GetBA As JavaObject
  Dim jo As JavaObject
  Dim cls As String = Me
  cls = cls.SubString("class ".Length)
  jo.InitializeStatic(cls)
  Return jo.GetFieldJO("processBA")
End Sub
Here's my log:

B4X:
File.DirInternal=/data/data/uk.co.pennypress.FileLocations/files
file.DirDefaultExternal=/storage/emulated/0/Android/data/uk.co.pennypress.FileLocations/files
File.DirRootExternal=/storage/emulated/0
File.ExternalReadable
File.ExternalWritable
getSystemDirectory using File.DirDefaultExternal for systemDirectory = /storage/emulated/0/Android/data/uk.co.pennypress.FileLocations/files
strSystemDirectory = /storage/emulated/0/Android/data/uk.co.pennypress.FileLocations/files
Copied File /storage/emulated/0/Android/data/uk.co.pennypress.FileLocations/files/ArmCurlWalk1.jpg
Using getExternalFilesDirs
/storage/emulated/0/Android/data/uk.co.pennypress.FileLocations/files
/storage/external_SD/Android/data/uk.co.pennypress.FileLocations/files
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
 

Erel

Administrator
Staff member
Licensed User
Top