Как узнать объем свободной памяти (дискового пространства), оставшейся на Android? - PullRequest
29 голосов
/ 19 августа 2011

Я пытаюсь определить доступное дисковое пространство на телефоне Android с моим приложением. Есть ли способ сделать это программно?

Спасибо

Ответы [ 10 ]

48 голосов
/ 12 января 2012

Пример: получение удобочитаемого размера, например, 1 Гб

Память строк = bytesToHuman (totalMemory ())

/*************************************************************************************************
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  = (statFs.getBlockCount() * statFs.getBlockSize());
        return total;
    }

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

    public long busyMemory()
    {
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());   
        long   total  = (statFs.getBlockCount() * statFs.getBlockSize());
        long   free   = (statFs.getAvailableBlocks() * statFs.getBlockSize());
        long   busy   = total - free;
        return busy;
    }

Преобразование байтов в читаемый человеком формат (например, 1 Мб, 1 Гб)

    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 "???";
    }
13 голосов
/ 19 августа 2011

Попробуйте StatFs.getAvailableBlocks . Вам нужно преобразовать количество блоков в КБ с помощью getBlockSize.

7 голосов
/ 19 февраля 2016

Есть некоторые тонкости, касающиеся путей, которые ни один из текущих ответов не адресует. Вы должны использовать правильный путь в зависимости от того, какую статистику вы интересуете. На основе глубокого погружения в DeviceStorageMonitorService.java, который генерирует предупреждения о недостаточном дисковом пространстве в области уведомлений и липкие широковещательные рассылки для ACTION_DEVICE_STORAGE_LOW, вот некоторые из путей что вы можете использовать:

  1. Для проверки свободного внутреннего дискового пространства используйте каталог данных, полученный с помощью Environment.getDataDirectory (). Это даст вам свободное место на разделе данных. Раздел данных содержит все внутреннее хранилище для всех приложений на устройстве.

  2. Чтобы проверить свободное внешнее (SDCARD) дисковое пространство, используйте каталог внешнего хранилища, полученный с помощью Environment.getExternalStorageDirectory (). Это даст вам свободное место на SDCARD.

  3. Чтобы проверить доступную память в системном разделе, содержащем файлы ОС, используйте Environment.getRootDirectory (). Поскольку ваше приложение не имеет доступа к системному разделу, эта статистика, вероятно, не очень полезна. DeviceStorageMonitorService использует в информационных целях и заносит его в журнал.

  4. Чтобы проверить наличие временных файлов / кэш-памяти, используйте Environment.getDownloadCacheDirectory (). DeviceStorageMonitorService пытается очистить некоторые временные файлы при нехватке памяти.

Пример кода для получения внутренней (/ data), внешней (/ sdcard) и ОС (/ system) свободной памяти:

// Get internal (data partition) free space
// This will match what's shown in System Settings > Storage for 
// Internal Space, when you subtract Total - Used
public long getFreeInternalMemory()
{
    return getFreeMemory(Environment.getDataDirectory());
}

// Get external (SDCARD) free space
public long getFreeExternalMemory()
{
    return getFreeMemory(Environment.getExternalStorageDirectory());
}

// Get Android OS (system partition) free space
public long getFreeSystemMemory()
{
    return getFreeMemory(Environment.getRootDirectory());
}

// Get free space for provided path
// Note that this will throw IllegalArgumentException for invalid paths
public long getFreeMemory(File path)
{
    StatFs stats = new StatFs(path.getAbsolutePath());
    return stats.getAvailableBlocksLong() * stats.getBlockSizeLong();
}
6 голосов
/ 16 июля 2013

Основываясь на ответе @ XXX, я создал фрагмент гист-кода, который оборачивает StatFs для легкого и простого использования.Вы можете найти его здесь как GitHub gist .

4 голосов
/ 26 апреля 2013

Введите целочисленные значения задолго до выполнения умножения. Умножение между двумя большими целыми числами может переполниться и дать отрицательный результат.

public long sd_card_free(){
    File path = Environment.getExternalStorageDirectory();
    StatFs stat = new StatFs(path.getPath());
    int availBlocks = stat.getAvailableBlocksLong();
    int blockSize = stat.getBlockSizeLong();
    long free_memory = (long)availBlocks * (long)blockSize;

    return free_memory;
}
3 голосов
/ 19 августа 2011

С небольшим количеством Google вы могли бы найти StatFs -класс , который:

[...] Оболочка для Unix statfs ().

Примеры предоставляются

2 голосов
/ 30 ноября 2018
/**
 * Returns the amount of free memory.
 * @return {@code long} - Free space.
 */
public long getFreeInternalMemory() {
    return getFreeMemory(Environment.getDataDirectory());
}

/**
 * Returns the free amount in SDCARD.
 * @return {@code long} - Free space.
 */
public long getFreeExternalMemory() {
    return getFreeMemory(Environment.getExternalStorageDirectory());
}

/**
 * Returns the free amount in OS.
 * @return {@code long} - Free space.
 */
public long getFreeSystemMemory() {
    return getFreeMemory(Environment.getRootDirectory());
}

/**
 * Returns the free amount in mounted path
 * @param path {@link File} - Mounted path.
 * @return {@code long} - Free space.
 */
public long getFreeMemory(File path) {
    if ((null != path) && (path.exists()) && (path.isDirectory())) {
        StatFs stats = new StatFs(path.getAbsolutePath());
        return stats.getAvailableBlocksLong() * stats.getBlockSizeLong();
    }
    return -1;
}

/**
 * Convert bytes to human format.
 * @param totalBytes {@code long} - Total of bytes.
 * @return {@link String} - Converted size.
 */
public String bytesToHuman(long totalBytes) {
    String[] simbols = new String[] {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
    long scale = 1L;
    for (String simbol : simbols) {
        if (totalBytes < (scale * 1024L)) {
            return String.format("%s %s", new DecimalFormat("#.##").format((double)totalBytes / scale), simbol);
        }
        scale *= 1024L;
    }
    return "-1 B";
}
2 голосов
/ 21 сентября 2017

с размерами блоков и getAvailableBlocks

устарели

этот код можно использовать

примечание, основанное выше ответ пользователя 802467

public long sd_card_free(){
    File path = Environment.getExternalStorageDirectory();
    StatFs stat = new StatFs(path.getPath());
    long availBlocks = stat.getAvailableBlocksLong();
    long blockSize = stat.getBlockSizeLong();
    long free_memory = availBlocks * blockSize;

    return free_memory;
}

мы можем использовать getAvailableBlocksLong и getBlockSizeLong

2 голосов
/ 23 октября 2016
    File pathOS = Environment.getRootDirectory();//Os Storage
    StatFs statOS = new StatFs(pathOS.getPath());

    File pathInternal = Environment.getDataDirectory();// Internal Storage
  StatFs statInternal = new StatFs(pathInternal.getPath());

    File pathSdcard = Environment.getExternalStorageDirectory();//External(SD CARD) Storage
    StatFs statSdcard = new StatFs(pathSdcard.getPath());

    if((android.os.Build.VERSION.SDK_INT < 18)) {
        // Get Android OS (system partition) free space API 18 & Below
        int totalBlocksOS = statOS.getBlockCount();
        int blockSizeOS = statOS.getBlockSize();
        int availBlocksOS = statOS.getAvailableBlocks();
        long total_OS_memory = (long) totalBlocksOS * (long) blockSizeOS;
        long free_OS_memory = (long) availBlocksOS * (long) blockSizeOS;
        long Used_OS_memory = total_OS_memory - free_OS_memory;
        TotalOsMemory       =   total_OS_memory ;
        FreeOsMemory        =   free_OS_memory;
        UsedOsMemory        =   Used_OS_memory;

        // Get internal (data partition) free space API 18 & Below
        int totalBlocksInternal = statInternal.getBlockCount();
        int blockSizeInternal = statOS.getBlockSize();
        int availBlocksInternal = statInternal.getAvailableBlocks();
        long total_Internal_memory = (long) totalBlocksInternal * (long) blockSizeInternal;
        long free_Internal_memory = (long) availBlocksInternal * (long) blockSizeInternal;
        long Used_Intenal_memory = total_Internal_memory - free_Internal_memory;
        TotalInternalMemory =   total_Internal_memory;
        FreeInternalMemory  =   free_Internal_memory ;
        UsedInternalMemory  =   Used_Intenal_memory ;

        // Get external (SDCARD) free space for API 18 & Below
        int totalBlocksSdcard = statSdcard.getBlockCount();
        int blockSizeSdcard = statOS.getBlockSize();
        int availBlocksSdcard = statSdcard.getAvailableBlocks();
        long total_Sdcard_memory = (long) totalBlocksSdcard * (long) blockSizeSdcard;
        long free_Sdcard_memory = (long) availBlocksSdcard * (long) blockSizeSdcard;
        long Used_Sdcard_memory = total_Sdcard_memory - free_Sdcard_memory;
        TotalSdcardMemory   =   total_Sdcard_memory;
        FreeSdcardMemory    =   free_Sdcard_memory;
        UsedSdcardMemory    =   Used_Sdcard_memory;
    }
    else {
        // Get Android OS (system partition) free space for API 18 & Above
        long   total_OS_memory          = (statOS.       getBlockCountLong()      * statOS.getBlockSizeLong());
        long   free_OS_memory           = (statOS.       getAvailableBlocksLong() * statOS.getBlockSizeLong());
        long Used_OS_memory = total_OS_memory - free_OS_memory;
        TotalOsMemory       =   total_OS_memory ;
        FreeOsMemory        =   free_OS_memory;
        UsedOsMemory        =   Used_OS_memory;

        // Get internal (data partition) free space for API 18 & Above
        long   total_Internal_memory    = (statInternal. getBlockCountLong()      * statInternal.getBlockSizeLong());
        long   free_Internal_memory     = (statInternal. getAvailableBlocksLong() * statInternal.getBlockSizeLong());
        long Used_Intenal_memory = total_Internal_memory - free_Internal_memory;
        TotalInternalMemory =   total_Internal_memory;
        FreeInternalMemory  =   free_Internal_memory ;
        UsedInternalMemory  =   Used_Intenal_memory ;

        // Get external (SDCARD) free space for API 18 & Above
        long   total_Sdcard_memory      = (statSdcard.   getBlockCountLong()      * statSdcard.getBlockSizeLong());
        long   free_Sdcard_memory       = (statSdcard.   getAvailableBlocksLong() * statSdcard.getBlockSizeLong());
        long Used_Sdcard_memory = tota*emphasized text*l_Sdcard_memory - free_Sdcard_memory;
        TotalSdcardMemory   =   total_Sdcard_memory;
        FreeSdcardMemory    =   free_Sdcard_memory;
        UsedSdcardMemory    =   Used_Sdcard_memory;
    }
}
0 голосов
/ 06 ноября 2017

Расположение памяти:

File[] roots = context.getExternalFilesDirs(null);
String path = roots[0].getAbsolutePath(); // PhoneMemory
String path = roots[1].getAbsolutePath(); // SCCard (if available)
String path = roots[2].getAbsolutePath(); // USB (if available)

использование

long totalMemory = StatUtils.totalMemory(path);
long freeMemory = StatUtils.freeMemory(path);

final String totalSpace = StatUtils.humanize(totalMemory, true);
final String usableSpace = StatUtils.humanize(freeMemory, true);

Вы можете использовать это

public final class StatUtils {

    public static long totalMemory(String path) {
        StatFs statFs = new StatFs(path);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            //noinspection deprecation
            return (statFs.getBlockCount() * statFs.getBlockSize());
        } else {
            return (statFs.getBlockCountLong() * statFs.getBlockSizeLong());
        }
    }

    public static long freeMemory(String path) {
        StatFs statFs = new StatFs(path);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            //noinspection deprecation
            return (statFs.getAvailableBlocks() * statFs.getBlockSize());
        } else {
            return (statFs.getAvailableBlocksLong() * statFs.getBlockSizeLong());
        }
    }

    public static long usedMemory(String path) {
        long total = totalMemory(path);
        long free = freeMemory(path);
        return total - free;
    }

    public static String humanize(long bytes, boolean si) {
        int unit = si ? 1000 : 1024;
        if (bytes < unit) return bytes + " B";
        int exp = (int) (Math.log(bytes) / Math.log(unit));
        String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
        return String.format(Locale.ENGLISH, "%.1f %sB", bytes / Math.pow(unit, exp), pre);
    }
}
...