41 votes

Obtenir de l'espace libre sur la mémoire interne

Est-il possible d'obtenir la quantité de mémoire libre sur un appareil Android (pas sur la CARTE SD) via le SDK Android ?

Si oui, comment ?

2 votes

64voto

mad Points 2492

ce pourrait bien répondre à votre question.

Vérifiez également ce fil . il y a tellement d'informations ici sur le SO.

J'ai cherché un peu sur Google et voici la solution (trouvée à l'adresse suivante 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 votes

Je crois que Clamp demande en fait le stockage réel, pas l'utilisation de la mémoire (je le déduis de la mention de la carte SD).

1 votes

Belle réponse. D'après ce que je vois, il n'y a pas d'avertissement de mode strict, ce qui le rend sûr pour le thread principal. Je m'attendais à un avertissement en mode strict puisque c'est lié au système de fichiers.

0 votes

La taille qu'il renvoie est en Ko ou en Mo ?

25voto

Zaur Points 3277
/*************************************************************************************************
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;
    }

Conversion d'octets en format lisible par l'homme (comme 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 votes

Vous devez convertir le blockCount et le blockSize en un long avant de faire les calculs. Sinon, ces méthodes pourraient renvoyer une valeur négative, car le nombre total de blocs multiplié par la taille du bloc dépassera la valeur maximale d'un int. Oui, j'ai utilisé le code et j'ai obtenu les valeurs négatives.

0 votes

@christophercotton Merci ! Terminé.

7 votes

Vous devrez en fait faire (long) statFs.getBlockCount() * (long) statFs.getBlockSize() pour vous assurer qu'ils sont correctement convertis.

10voto

kcoppock Points 57219

On dirait que le StatFs pourrait être ce que vous devez utiliser. Je ne suis pas sûr du chemin qui serait considéré comme la racine de l'appareil, mais je pense que le résultat serait le même quel que soit le répertoire, tant qu'il fait partie du stockage interne. Quelque chose comme ceci pourrait fonctionner :

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

Si rien d'autre n'est fait, le cours StatFs devrait vous donner un bon point de départ pour savoir où chercher.

2 votes

Cool ! J'ai essayé de le prendre pour "/", mais ça n'a pas marché. Utiliser "/data" fonctionne pour la mémoire interne.

2voto

Ilyas Points 21

Sur les appareils où la taille de la mémoire interne est très grande, cela ne fonctionne pas car la valeur int est trop petite. Par exemple, sur le Motorola xum, cela ne fonctionne pas. Vous devez utiliser quelque chose comme ceci :

int freeSpaceInKilobytes = availableBlocks * (blockSizeInBytes / 1024);

2voto

/**
 * @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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X