118 votes

Android obtient la taille libre de la mémoire interne/externe

Je veux obtenir la taille de la mémoire libre sur le stockage interne/externe de mon appareil de manière programmatique. J'utilise ce morceau de code :

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);

et le résultat que j'obtiens est :

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

Le problème est que je veux récupérer la mémoire libre de la SdCard qui est 1,96GB en ce moment. Comment puis-je corriger ce code pour obtenir la taille gratuite ?

1 votes

Depuis le niveau 18 de l'API, la méthode a été renommée pour se terminer par Long. Il faudrait probablement ajouter une vérification du niveau d'API précédent.

0 votes

Toutes les solutions que j'ai essayées ne fonctionnent pas, quand je fais le formatage en tant que stockage interne ... pouvez-vous m'aider, comment faire pour réaliser cela ?

0 votes

Fermé en tant que duplicate - un post plus récent a des réponses jusqu'à Android R

198voto

Dinesh Prajapati Points 4485

Vous trouverez ci-dessous le code à utiliser :

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();
    }

Obtenir la taille de la RAM

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

0 votes

Et comment obtenir la taille de la mémoire RAM ? combien de mémoire totale et combien de mémoire utilisée ?

2 votes

getBlockSize() et getBlockCount sont dépréciés.

3 votes

@DineshPrajapati Merci pour la réponse, j'ai une question, si j'utilise Environment.getRootDirectory() au lieu de Environment.getDataDirectory pour calculer le stockage interne, j'obtiens une certaine sortie ..cela fait référence à la mémoire interne autre mémoire

42voto

Android-Droid Points 4086

C'est la façon dont je l'ai fait :

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);

4 votes

Mais c'est déraciné :(

0 votes

@ArMo372 , Est-ce que vous avez trouvé le code de remplacement pour ça ?

4 votes

Remplacez simplement getBlockSize et getAvailableBlocks avec getBlockSizeLong et getAvailableBlocksLong .

33voto

android developer Points 20939

Pour obtenir tous les dossiers de stockage disponibles (y compris les cartes SD), vous devez d'abord obtenir les fichiers de stockage :

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

Ensuite, vous pouvez obtenir la taille disponible de chacun d'eux.

Il y a trois façons de procéder :

API 8 et moins :

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

API 9 et plus :

long availableSizeInBytes=file.getFreeSpace();

API 18 et plus (non nécessaire si la précédente est correcte) :

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

Pour obtenir une belle chaîne formatée de ce que vous avez maintenant, vous pouvez utiliser :

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

ou vous pouvez utiliser ceci dans le cas où vous souhaitez voir le nombre exact d'octets mais de façon agréable :

NumberFormat.getInstance().format(availableSizeInBytes);

Notez que je pense que le stockage interne pourrait être le même que le premier stockage externe, puisque le premier est le stockage émulé.


EDIT : En utilisant StorageVolume sur Android Q et plus, je pense qu'il est possible d'obtenir l'espace libre de chacun, en utilisant quelque chose comme :

fun getStorageVolumesAccessState(context: Context) {
    val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val storageVolumes = storageManager.storageVolumes
    val storageStatsManager = context.getSystemService(Context.STORAGE_STATS_SERVICE) as StorageStatsManager
    for (storageVolume in storageVolumes) {
        var freeSpace: Long = 0L
        var totalSpace: Long = 0L
        val path = getPath(context, storageVolume)
        if (storageVolume.isPrimary) {
            totalSpace = storageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT)
            freeSpace = storageStatsManager.getFreeBytes(StorageManager.UUID_DEFAULT)
        } else if (path != null) {
            val file = File(path)
            freeSpace = file.freeSpace
            totalSpace = file.totalSpace
        }
        val usedSpace = totalSpace - freeSpace
        val freeSpaceStr = Formatter.formatFileSize(context, freeSpace)
        val totalSpaceStr = Formatter.formatFileSize(context, totalSpace)
        val usedSpaceStr = Formatter.formatFileSize(context, usedSpace)
        Log.d("AppLog", "${storageVolume.getDescription(context)} - path:$path total:$totalSpaceStr used:$usedSpaceStr free:$freeSpaceStr")
    }
}

fun getPath(context: Context, storageVolume: StorageVolume): String? {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
        storageVolume.directory?.absolutePath?.let { return it }
    try {
        return storageVolume.javaClass.getMethod("getPath").invoke(storageVolume) as String
    } catch (e: Exception) {
    }
    try {
        return (storageVolume.javaClass.getMethod("getPathFile").invoke(storageVolume) as File).absolutePath
    } catch (e: Exception) {
    }
    val extDirs = context.getExternalFilesDirs(null)
    for (extDir in extDirs) {
        val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
        val fileStorageVolume: StorageVolume = storageManager.getStorageVolume(extDir)
                ?: continue
        if (fileStorageVolume == storageVolume) {
            var file = extDir
            while (true) {
                val parent = file.parentFile ?: return file.absolutePath
                val parentStorageVolume = storageManager.getStorageVolume(parent)
                        ?: return file.absolutePath
                if (parentStorageVolume != storageVolume)
                    return file.absolutePath
                file = parent
            }
        }
    }
    try {
        val parcel = Parcel.obtain()
        storageVolume.writeToParcel(parcel, 0)
        parcel.setDataPosition(0)
        parcel.readString()
        return parcel.readString()
    } catch (e: Exception) {
    }
    return null
}

J'espère que cela pourra vous aider.

1 votes

Comment obtenir l'espace libre sur une carte SD amovible (ou une clé USB OTG) sur les appareils avec API 23 ? new StatFs(file.getPath()).getAvailableBytes() or file.getUsableSpace() donne 972546048 bytes indépendamment de la taille réelle du stockage sur Nexus 5 (Marshmallow 6.0.1).

0 votes

@isabsent Le Nexus 5 n'a pas de slot pour carte SD. Comment l'avez-vous vérifié ?

0 votes

Je l'ai vérifié avec une clé USB OTG.

32voto

Tzoiker Points 123

Depuis l'API 9, vous pouvez le faire :

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

4 votes

File.getUsableSpace() est probablement meilleur car vous ne vous exécutez probablement pas en tant que Root.

0 votes

El File.getUsableSpace() semble être une méthode plus facile à utiliser plutôt que d'utiliser StatFs . Pourquoi j'utiliserais StatFs @MarkCarter ?

2 votes

@DiscoS2 Vous utiliseriez StatFs si votre minSdkVersion est inférieure à 9.

9voto

Sharp80 Points 146

@Android-Droid - vous avez tort Environment.getExternalStorageDirectory() pointe vers le stockage externe qui ne doit pas nécessairement être une carte SD, il peut également s'agir de la mémoire interne. Voir :

Trouver l'emplacement d'une carte SD externe

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