Android Question [Solution found] Does SD Card exist?

Roger Daley

Well-Known Member
Licensed User
Longtime User
Hi All
This or something similar has been asked many times but things have been changing quickly.
The Q&A that I could find, all ended up in internal memory or secondary memory.

What is the best current method to determine if a physical SD Card is fitted to the device?
IE:
B4X:
If File.Exists(File.SDCard, "")Then

The Q&A that I could find all ended up in internal memory or secondary memory.

Regards Roger
 
Last edited:

Pendrush

Well-Known Member
Licensed User
Longtime User
Code below is not tested as I don't have device with SD Card
B4X:
Sub Process_Globals
End Sub

Sub Globals  
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
    Private Jo As JavaObject
    Jo.InitializeContext 
    Dim SdCardExist As Boolean = Jo.RunMethod("sdExist", Null)
    Log ("SD card exist: " & SdCardExist) 
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

#If JAVA
import android.os.Environment;
public boolean sdExist() {
    Boolean isSDPresent = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
    Boolean isStorageRemovable = Environment.isExternalStorageRemovable();
    if(isStorageRemovable && isSDPresent) {
        return true;
    }
    else {
        return false;
    }
}
#End If
 
Upvote 0

Roger Daley

Well-Known Member
Licensed User
Longtime User
Code below is not tested as I don't have device with SD Card
B4X:
Sub Process_Globals
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
    Private Jo As JavaObject
    Jo.InitializeContext
    Dim SdCardExist As Boolean = Jo.RunMethod("sdExist", Null)
    Log ("SD card exist: " & SdCardExist)
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub
[/QUOTE]


[QUOTE="Pendrush, post: 849160, member: 31308"]


#If JAVA
import android.os.Environment;
public boolean sdExist() {
    Boolean isSDPresent = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
    Boolean isStorageRemovable = Environment.isExternalStorageRemovable();
    if(isStorageRemovable && isSDPresent) {
        return true;
    }
    else {
        return false;
    }
}
#End If

Thanks for the reply but I get the following error when I try to run the code.
The MethodName sdExist appears unknown. I don't know where these MethodNames come from so I couldn't check. [Search didn't help]


Regards Roger

EDIT: Reading up on methods, may find something.

Logger connected to: samsung SM-A705YN
--------- beginning of main
--------- beginning of system
** Activity (main) Create, isFirst = true **
main_activity_create (java line: 1252)
java.lang.RuntimeException: Method: sdExist not found in: horsetrailer.B4A.AntennaBearingTool.main
at anywheresoftware.b4j.object.JavaObject$MethodCache.getMethod(JavaObject.java:363)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:120)
at horsetrailer.B4A.AntennaBearingTool.main._activity_create(main.java:1252)
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Try so:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
    
    If SDExists Then
        Log("SD exists")
    Else
        Log("SD does not exist")
    End If
End Sub

Private Sub SDExists As Boolean
    Dim jo As JavaObject
    jo.InitializeStatic("android.os.Environment")
    Dim ExternalStorageState As String = jo.RunMethod("getExternalStorageState", Null)
    Dim ExternalStorageRemovable As Boolean = jo.RunMethod("isExternalStorageRemovable", Null)
    
    Return ExternalStorageState = "mounted" And ExternalStorageRemovable
End Sub
 
Upvote 0

Roger Daley

Well-Known Member
Licensed User
Longtime User
Try so:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
   
    If SDExists Then
        Log("SD exists")
    Else
        Log("SD does not exist")
    End If
End Sub

Private Sub SDExists As Boolean
    Dim jo As JavaObject
    jo.InitializeStatic("android.os.Environment")
    Dim ExternalStorageState As String = jo.RunMethod("getExternalStorageState", Null)
    Dim ExternalStorageRemovable As Boolean = jo.RunMethod("isExternalStorageRemovable", Null)
   
    Return ExternalStorageState = "mounted" And ExternalStorageRemovable
End Sub

Thanks LucaMs,

Returns False, SD Card or not.

Regards Roger
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Android has shifted from being file system based to a more generic resources system. Go with the flow. The user will have better experience. It is also quite simple to do, you just need to use ContentChooser and SaveAs.

RuntimePermissions.GetAllSafeDirsExternal will return all the accessible external folders. It should return folders in sd cards as well.
 
Upvote 0

Roger Daley

Well-Known Member
Licensed User
Longtime User
Erel,

I am using ContentChooser and SaveAs to enable exporting and importing files between the App and the real world.
IE: SQL as CSV files.
[When you posted the TextEditor example I said it was great and planned to use it. It has been very useful.]

In the instructions I have directed the user to use the SD Card for such functions. If the App can accurately determine if a SD Card is NOT available it can then warn or block these functions. Currently running the TextEditor on a device without a SD Card takes the user to the Download folder for both Save and Load.
I am not sure how RuntimePermissions would fit the bill. I will play around it just to see.

The suggestions by Pendrush and LucaMs seem to be the way to go, just not quite there.

Regards Roger
 
Upvote 0

Roger Daley

Well-Known Member
Licensed User
Longtime User
Why? Why not let the user choose their Google Drive and similar other services?
Good point. I somewhere gained the impression that everything should go in and out from the SD Card. A quick check and I can't see where I Gained that idea. I'll rewrite the instructions.

Just for future reference, I assume there is no way to check for a SD Card.

Regards Roger
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Clipboard02.jpg


Perhaps the problem is that we passed Null as the Path parameter.

I can't but I would try passing:
B4X:
Array("/")

' or

Array("/*.*")
 
Upvote 0

Roger Daley

Well-Known Member
Licensed User
Longtime User
View attachment 119081

Perhaps the problem is that we passed Null as the Path parameter.

I can't but I would try passing:
B4X:
Array("/")

' or

Array("/*.*")

LucaMs,
Thanks for trying but unfortunately not a winner.
The Log for each is below.

Regards Roger

Dim ExternalStorageState As String = jo.RunMethod("getExternalStorageState", Array("/"))
Dim ExternalStorageRemovable As Boolean = jo.RunMethod("isExternalStorageRemovable", Array("/"))

Logger connected to: samsung SM-A705YN
--------- beginning of main
--------- beginning of system
** Activity (main) Create, isFirst = true **
main_sdexists (java line: 8995)
java.lang.RuntimeException: Method: getExternalStorageState not matched.
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:130)
at horsetrailer.B4A.AntennaBearingTool.main._sdexists(main.java:8995)
at horsetrailer.B4A.AntennaBearingTool.main._activity_create(main.java:1247)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
at horsetrailer.B4A.AntennaBearingTool.main.afterFirstLayout(main.java:105)
at horsetrailer.B4A.AntennaBearingTool.main.access$000(main.java:17)
at horsetrailer.B4A.AntennaBearingTool.main$WaitForLayout.run(main.java:83)
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:8506)
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:1139)
java.lang.RuntimeException: Method: getExternalStorageState not matched.





Dim ExternalStorageState As String = jo.RunMethod("getExternalStorageState", Array("/*.*"))
Dim ExternalStorageRemovable As Boolean = jo.RunMethod("isExternalStorageRemovable", Array("/*.*"))

** Activity (main) Create, isFirst = true **
main_sdexists (java line: 8995)
java.lang.RuntimeException: Method: getExternalStorageState not matched.
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:130)
at horsetrailer.B4A.AntennaBearingTool.main._sdexists(main.java:8995)
at horsetrailer.B4A.AntennaBearingTool.main._activity_create(main.java:1247)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
at horsetrailer.B4A.AntennaBearingTool.main.afterFirstLayout(main.java:105)
at horsetrailer.B4A.AntennaBearingTool.main.access$000(main.java:17)
at horsetrailer.B4A.AntennaBearingTool.main$WaitForLayout.run(main.java:83)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
 
Upvote 0
Top