Android obtiene tamaño libre de memoria interna / externa

Quiero obtener el tamaño de memoria libre en el almacenamiento interno / externo de mi dispositivo mediante progtwigción. Estoy usando este fragmento de código:

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount(); long megAvailable = bytesAvailable / 1048576; Log.e("","Available MB : "+megAvailable); File path = Environment.getDataDirectory(); StatFs stat2 = new StatFs(path.getPath()); long blockSize = stat2.getBlockSize(); long availableBlocks = stat2.getAvailableBlocks(); String format = Formatter.formatFileSize(this, availableBlocks * blockSize); Log.e("","Format : "+format); 

y el resultado que obtengo es:

 11-15 10:27:18.844: E/(25822): Available MB : 7572 11-15 10:27:18.844: E/(25822): Format : 869MB 

El problema es que quiero obtener la memoria gratuita de SdCard que es de 1,96GB este momento. ¿Cómo puedo arreglar este código para poder obtener el tamaño gratis?

A continuación está el código para su propósito:

 public static boolean externalMemoryAvailable() { return android.os.Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); } public static String getAvailableInternalMemorySize() { File path = Environment.getDataDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSizeLong(); long availableBlocks = stat.getAvailableBlocksLong(); return formatSize(availableBlocks * blockSize); } public static String getTotalInternalMemorySize() { File path = Environment.getDataDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSizeLong(); long totalBlocks = stat.getBlockCountLong(); return formatSize(totalBlocks * blockSize); } public static String getAvailableExternalMemorySize() { if (externalMemoryAvailable()) { File path = Environment.getExternalStorageDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSizeLong(); long availableBlocks = stat.getAvailableBlocksLong(); return formatSize(availableBlocks * blockSize); } else { return ERROR; } } public static String getTotalExternalMemorySize() { if (externalMemoryAvailable()) { File path = Environment.getExternalStorageDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSizeLong(); long totalBlocks = stat.getBlockCountLong(); return formatSize(totalBlocks * blockSize); } else { return ERROR; } } public static String formatSize(long size) { String suffix = null; if (size >= 1024) { suffix = "KB"; size /= 1024; if (size >= 1024) { suffix = "MB"; size /= 1024; } } StringBuilder resultBuffer = new StringBuilder(Long.toString(size)); int commaOffset = resultBuffer.length() - 3; while (commaOffset > 0) { resultBuffer.insert(commaOffset, ','); commaOffset -= 3; } if (suffix != null) resultBuffer.append(suffix); return resultBuffer.toString(); } 

Obtener tamaño RAM

 ActivityManager actManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); MemoryInfo memInfo = new ActivityManager.MemoryInfo(); actManager.getMemoryInfo(memInfo); long totalMemory = memInfo.totalMem; 

Esta es la forma en que lo hice:

 StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); long bytesAvailable; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { bytesAvailable = stat.getBlockSizeLong() * stat.getAvailableBlocksLong(); } else { bytesAvailable = (long)stat.getBlockSize() * (long)stat.getAvailableBlocks(); } long megAvailable = bytesAvailable / (1024 * 1024); Log.e("","Available MB : "+megAvailable); 

Desde API 9 puedes hacer:

 long freeBytesInternal = new File(ctx.getFilesDir().getAbsoluteFile().toString()).getFreeSpace(); long freeBytesExternal = new File(getExternalFilesDir(null).toString()).getFreeSpace(); 

Para obtener todas las carpetas de almacenamiento disponibles (incluidas las tarjetas SD), primero obtienes los archivos de almacenamiento:

 File internalStorageFile=getFilesDir(); File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null); 

Entonces puede obtener el tamaño disponible de cada uno de ellos.

Hay 3 formas de hacerlo:

API 8 y abajo:

 StatFs stat=new StatFs(file.getPath()); long availableSizeInBytes=stat.getBlockSize()*stat.getAvailableBlocks(); 

API 9 y superior:

 long availableSizeInBytes=file.getFreeSpace(); 

API 18 y superior (no es necesario si el anterior está bien):

 long availableSizeInBytes=new StatFs(file.getPath()).getAvailableBytes(); 

Para obtener una buena secuencia formateada de lo que tienes ahora, puedes usar:

 String formattedResult=android.text.format.Formatter.formatShortFileSize(this,availableSizeInBytes); 

o puede usar esto en caso de que desee ver el número exacto de bytes pero muy bien:

 NumberFormat.getInstance().format(availableSizeInBytes); 

Tenga en cuenta que creo que el almacenamiento interno podría ser el mismo que el primer almacenamiento externo, ya que el primero es el emulado.

@ Android-Droid: está equivocado. Environment.getExternalStorageDirectory() apunta a un almacenamiento externo que no tiene que ser una tarjeta SD, también puede ser una copia de la memoria interna. Ver:

Encuentra una ubicación de tarjeta SD externa

Es muy fácil descubrir el almacenamiento disponible si obtiene una ruta de almacenamiento interna y externa. También la ruta de almacenamiento externo del teléfono es muy fácil de descubrir usando

Environment.getExternalStorageDirectory (). GetPath ();

Así que solo me estoy concentrando en cómo encontrar las rutas de almacenamiento extraíble externo, como la tarjeta SD extraíble, USB OTP (no probado USB OTG ya que no tengo USB OTG).

El siguiente método proporcionará una lista de todas las rutas de almacenamiento extraíbles externas posibles.

  /** * This method returns the list of removable storage and sdcard paths. * I have no USB OTG so can not test it. Is anybody can test it, please let me know * if working or not. Assume 0th index will be removable sdcard path if size is * greater than 0. * @return the list of removable storage paths. */ public static HashSet getExternalPaths() { final HashSet out = new HashSet(); String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*"; String s = ""; try { final Process process = new ProcessBuilder().command("mount").redirectErrorStream(true).start(); process.waitFor(); final InputStream is = process.getInputStream(); final byte[] buffer = new byte[1024]; while (is.read(buffer) != -1) { s = s + new String(buffer); } is.close(); } catch (final Exception e) { e.printStackTrace(); } // parse output final String[] lines = s.split("\n"); for (String line : lines) { if (!line.toLowerCase(Locale.US).contains("asec")) { if (line.matches(reg)) { String[] parts = line.split(" "); for (String part : parts) { if (part.startsWith("/")) { if (!part.toLowerCase(Locale.US).contains("vold")) { out.add(part.replace("/media_rw","").replace("mnt", "storage")); } } } } } } //Phone's external storage path (Not removal SDCard path) String phoneExternalPath = Environment.getExternalStorageDirectory().getPath(); //Remove it if already exist to filter all the paths of external removable storage devices //like removable sdcard, USB OTG etc.. //When I tested it in ICE Tab(4.4.2), Swipe Tab(4.0.1) with removable sdcard, this method includes //phone's external storage path, but when i test it in Moto X Play (6.0) with removable sdcard, //this method does not include phone's external storage path. So I am going to remvoe the phone's //external storage path to make behavior consistent in all the phone. Ans we already know and it easy // to find out the phone's external storage path. out.remove(phoneExternalPath); return out; } 

Prueba este simple fragmento

  public static String readableFileSize() { long availableSpace = -1L; StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) availableSpace = (long) stat.getBlockSizeLong() * (long) stat.getAvailableBlocksLong(); else availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); if(availableSpace <= 0) return "0"; final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" }; int digitGroups = (int) (Math.log10(availableSpace)/Math.log10(1024)); return new DecimalFormat("#,##0.#").format(availableSpace/Math.pow(1024, digitGroups)) + " " + units[digitGroups]; } 

Adición rápida al tema de la memoria externa

No se confunda con el nombre del método externalMemoryAvailable() en la respuesta de Dinesh Prajapati.

Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) le proporciona el estado actual de la memoria, si el medio está presente y montado en su punto de assembly con acceso de lectura / escritura. Se hará true incluso en dispositivos sin tarjetas SD, como Nexus 5. Pero aún así es un método imprescindible antes de cualquier operación de almacenamiento.

Para verificar si hay una tarjeta SD en su dispositivo, puede usar el método ContextCompat.getExternalFilesDirs()

No muestra dispositivos transitorios, como unidades flash USB.

También tenga en cuenta que ContextCompat.getExternalFilesDirs() en Android 4.3 y ContextCompat.getExternalFilesDirs() inferiores siempre devolverá solo 1 entrada (tarjeta SD si está disponible, de lo contrario interna). Puedes leer más sobre esto aquí .

  public static boolean isSdCardOnDevice(Context context) { File[] storages = ContextCompat.getExternalFilesDirs(context, null); if (storages.length > 1 && storages[0] != null && storages[1] != null) return true; else return false; } 

en mi caso fue suficiente, pero no olvides que algunos de los dispositivos con Android pueden tener 2 tarjetas SD, así que si los necesitas a todos, ajusta el código anterior.

Sobre menory externo, hay otra manera:
File external = Environment.getExternalStorageDirectory(); free:external.getFreeSpace(); total:external.getTotalSpace();