2011-01-04 11 views
37

¿Es posible obtener la cantidad de memoria libre en un dispositivo Android (no en la tarjeta SD) a través del SDK de Android?Obtenga espacio libre en la memoria interna

Si es así, ¿cómo?

+2

Posible duplicado de [Android obtener tamaño libre de la memoria interna/externa] (https://stackoverflow.com/questions/8133417/android-get-free-size-of-internal-external-memory) –

Respuesta

63

this publicación podría encajar bien en su pregunta.

también marque this thread. hay tanta información aquí en SO.

googled un poco y aquí está la solución (que se encuentra en android git)

File path = Environment.getDataDirectory(); 
StatFs stat = new StatFs(path.getPath()); 
long blockSize = stat.getBlockSize(); 
long availableBlocks = stat.getAvailableBlocks(); 
return Formatter.formatFileSize(this, availableBlocks * blockSize); 
+1

Creo que la abrazadera en realidad preguntando por el almacenamiento real, no por el uso de memoria (lo deduzco de la mención de la tarjeta SD). – kcoppock

+0

gracias, sí, estoy hablando de memoria de almacenamiento. – clamp

+1

Buena respuesta. Por lo que puedo ver, esto no produce ninguna advertencia estricta, lo que hace que el hilo principal sea seguro. Casi esperaba una advertencia de modo estricto, ya que está relacionado con el sistema de archivos. – Mattias

9

Parece que la clase StatFs podría ser lo que necesita para su uso. No estoy seguro de qué ruta se consideraría la raíz del dispositivo, pero creo que el resultado sería el mismo independientemente del directorio, siempre que sea parte del almacenamiento interno. Algo como esto puede funcionar:

StatFs stats = new StatFs("/data"); 
int availableBlocks = stats.getAvailableBlocks(); 
int blockSizeInBytes = stats.getBlockSize(); 
int freeSpaceInBytes = availableBlocks * blockSizeInBytes; 

Si nada más, la clase statfs debería darle un buen comienzo en dónde buscar.

+1

¡Genial! Traté de obtenerlo para "/", que no funcionó. El uso de "/ data" funciona para la memoria interna. –

2

En dispositivos donde el tamaño de la memoria interna es muy grande, no funciona porque el valor int es demasiado pequeño. Por ejemplo en Motorola xum no funciona. Usted tiene que usar algo como esto:

int freeSpaceInKilobytes = availableBlocks * (blockSizeInBytes/1024);

+0

O use el tipo largo, no int. –

24
/************************************************************************************************* 
Returns size in bytes. 

If you need calculate external memory, change this: 
    StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 
to this: 
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());   
**************************************************************************************************/ 
    public long TotalMemory() 
    { 
     StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 
     long Total = ((long) statFs.getBlockCount() * (long) statFs.getBlockSize()); 
     return Total; 
    } 

    public long FreeMemory() 
    { 
     StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 
     long Free = (statFs.getAvailableBlocks() * (long) statFs.getBlockSize()); 
     return Free; 
    } 

    public long BusyMemory() 
    { 
     StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 
     long Total = ((long) statFs.getBlockCount() * (long) statFs.getBlockSize()); 
     long Free = (statFs.getAvailableBlocks() * (long) statFs.getBlockSize()); 
     long Busy = Total - Free; 
     return Busy; 
    } 

conversión de bytes a formato legible por humanos (como 1 MB, 1 GB)

public static String floatForm (double d) 
    { 
     return new DecimalFormat("#.##").format(d); 
    } 


    public static String bytesToHuman (long size) 
    { 
     long Kb = 1 * 1024; 
     long Mb = Kb * 1024; 
     long Gb = Mb * 1024; 
     long Tb = Gb * 1024; 
     long Pb = Tb * 1024; 
     long Eb = Pb * 1024; 

     if (size < Kb)     return floatForm(  size ) + " byte"; 
     if (size >= Kb && size < Mb) return floatForm((double)size/Kb) + " Kb"; 
     if (size >= Mb && size < Gb) return floatForm((double)size/Mb) + " Mb"; 
     if (size >= Gb && size < Tb) return floatForm((double)size/Gb) + " Gb"; 
     if (size >= Tb && size < Pb) return floatForm((double)size/Tb) + " Tb"; 
     if (size >= Pb && size < Eb) return floatForm((double)size/Pb) + " Pb"; 
     if (size >= Eb)     return floatForm((double)size/Eb) + " Eb"; 

     return "???"; 
    } 
+4

Debes convertir blockCount y blockSize en mucho antes de hacer los cálculos. De lo contrario, estos métodos podrían devolver un valor negativo, ya que el conteo total de bloques multiplicado por el tamaño del bloque excederá el valor máximo para un int. Sí, utilicé el código y obtuve los negativos. – christophercotton

+0

@christophercotton ¡Gracias! Hecho. – XXX

+7

Realmente necesitará hacer (largo) statFs.getBlockCount() * (long) statFs.getBlockSize() para asegurarse de que se obtengan correctamente. – christophercotton

2
/** 
* @return Number of bytes available on internal storage 
*/ 
public static long getInternalAvailableSpace() { 
    long availableSpace = -1L; 
    try {StatFs stat = new StatFs(Environment.getDataDirectory() 
      .getPath()); 
     stat.restat(Environment.getDataDirectory().getPath()); 
     availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return availableSpace; 
} 
5

Hay algunos métodos que fueron desaprobados por Google desde 2013 y que podrían cambiar estos métodos (API): 18+ solamente

  • getAvailableBlocks() a getAvailableBlocksLong()
  • getBlockCount() a getBlockCountLong()
  • getBlockSize() a getBlockSizeLong()
  • getFreeBlocks() a getFreeBlocksLong()
Cuestiones relacionadas