Compruebe si la tarjeta SD está presente, boolean siempre es cierto

En mi pantalla de inicio, quiero verificar si el teléfono tiene una tarjeta SD. La statement booleana está debajo de:

Boolean isSDPresent = android.os.Environment.getExternalStorageState() .equals(android.os.Environment.MEDIA_MOUNTED ); 

Entonces, si tengo la tarjeta SD en la ranura de mi teléfono, este booleano volverá verdadero, hasta ahora todo bien. Cuando voy a “Desmontar tarjeta SD” desde el menú de configuración, y quito la tarjeta SD, luego elimino la aplicación y la lanzo de nuevo, la booleana también será verdadera.

Y si lanzo Astro File Manager después de desmontar y eliminar la tarjeta SD, aún puedo acceder a la ruta /mnt/sdcard , ¿por qué?

¿Cómo puedo lograr esto?

¡Gracias por adelantado!

EDITAR

Probando con el siguiente código:

 File path = Environment.getExternalStorageDirectory(); String pathS = path.getPath(); 

Cuando la SDCard está en la ranura, la pathS contiene mnt/sdcard , pero cuando elimino la pathS la pathS sigue siendo /mnt/sdcard

Descubrí que los teléfonos, como los teléfonos Galaxy de Samsung, tienen un punto /mnt/sdcard en la memoria interna y no en la tarjeta SD externa como se esperaba.

Puede saber si la ruta devuelta por Environment.getExternalStorageDirectory () es en realidad la tarjeta SD externa con una llamada a Environment.isExternalStorageRemovable ()

Solo quería agregar de los documentos para getExternalStorageDirectory () esta nota importante:

Nota: no se confunda con la palabra “externo” aquí. Este directorio se puede considerar mejor como almacenamiento multimedia / compartido. Es un sistema de archivos que puede contener una cantidad relativamente grande de datos y que se comparte en todas las aplicaciones (no impone permisos). Tradicionalmente, esta es una tarjeta SD, pero también se puede implementar como almacenamiento integrado en un dispositivo que es distinto del almacenamiento interno protegido y se puede montar como un sistema de archivos en una computadora.

No debería ser:

 boolean isPresent = Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED ); 

Como dice la documentación para Environment.getExternalStorageState() :

Obtiene el estado actual del dispositivo de almacenamiento “externo” principal .

Y para el entorno.MEDIA_MOUNTED -constant :

getExternalStorageState() devuelve MEDIA_MOUNTED si el medio está presente y montado en su punto de assembly con acceso de lectura / escritura .

Y esto funcionará desde el Nivel de API 1+

Modifiqué que si existe una tarjeta SD, establece el camino allí si no lo establece en el directorio interno

  Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); if(isSDPresent) { path = theAct.getExternalCacheDir().getAbsolutePath() + "/GrammarFolder"; } else { path = theAct.getFilesDir() + "/GrammarFolder"; } 

Si quiere mostrar si la tarjeta SD está insertada o no, simplemente copie y pegue este código funcionando 100% para todos los dispositivos, el código está aquí:

 File file = new File("/mnt/extSdCard"); try { File list[] = file.listFiles(); Toast.makeText(getApplicationContext(), "Yes sdcard is mounted, file count "+list.length, Toast.LENGTH_LONG).show(); } catch(NullPointerException o) { Toast.makeText(getApplicationContext(), "Sorry no sdcard is mounted:", Toast.LENGTH_LONG).show(); } 

Tenemos dos estados de memoria. Una es la tarjeta de memoria interna y otra es la tarjeta sd externa. Depende del dispositivo fabrica cómo han fabricado la ruta de la tarjeta de memoria. Por lo tanto, si está comprobando la disponibilidad de la tarjeta sd, puede que sea verdadera en ambos casos debido a la memoria interna. Entonces ve por este método:

 File[] listOfInternalAndExternalStorage=context.getExternalFilesDirs(null); if(listOfInternalAndExternalStorage.length>=2){ // it contains sd card } 

El código anterior verificará si listOfInternalAndExternalStorage es más de uno y luego tiene almacenamiento externo; de lo contrario, no contiene la tarjeta sd.

// Prueba esto si prefieres guardar un archivo externo …

 public String preferextstorage(Context con){ int version = Build.VERSION.SDK_INT; String result=con.getFilesDir().getPath(); if (version>=19) { File[] listOfInternalAndExternalStorage = con.getExternalFilesDirs(null); if (listOfInternalAndExternalStorage.length >= 2) { // it contains sd card if (listOfInternalAndExternalStorage[1]==null){ result=listOfInternalAndExternalStorage[0].getPath(); }else { result=listOfInternalAndExternalStorage[1].getPath(); } return result; } } return result; } 

Este fragmento de código puede ser útil para detectar y tratar con la excepción de los dispositivos Samsung:

 public static String getExternalStorage() { String str = Environment.getExternalStorageDirectory().getAbsolutePath(); if ( isSamsungDevice() ) { if ( isSamsungExternalSDMounted() ) { str += "/external_sd"; } } return str; } private static boolean isSamsungDevice() { return new File( Environment.getExternalStorageDirectory().getAbsolutePath() + "/external_sd" ).exists(); } private static boolean isSamsungExternalSDMounted() { return exec( "mount" ).indexOf( "external_sd" ) >= 0; } public static String exec( String paramString ) { try { String str = ""; InputStream localInputStream = Runtime.getRuntime().exec( paramString ).getInputStream(); byte[] arrayOfByte = new byte[1024]; StringBuilder localStringBuilder = new StringBuilder(); while ( true ) { int i = localInputStream.read( arrayOfByte, 0, arrayOfByte.length ); if ( i == -1 ) { str = localStringBuilder.toString(); break; } localStringBuilder.append( new String( arrayOfByte, 0, i ) ); } return str; } catch ( IOException e ) { e.printStackTrace(); return null; } }