Подтвердить что ты не робот

Как проверить доступное пространство на устройстве Android? на SD-карте?

Как проверить, сколько MB или GB осталось на устройстве Android? Я использую JAVA и Android SDK 2.0.1.

Есть ли какая-либо системная служба, которая может выставить что-то вроде этого?

4b9b3361

Ответ 1

Попробуйте этот код

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
System.out.println("Megs :"+megAvailable);

Оттуда

UPD: getBlockCount() - возвращает размер SD-карты; getAvailableBlocks() - возвращает количество блоков, которые все еще доступны для обычных программ (спасибо Джо)

Ответ 2

Ярославский ответ даст размер SD-карты, а не доступное пространство. StatFs getAvailableBlocks() вернет количество блоков, которые все еще доступны для обычных программ. Вот функция, которую я использую:

public static float megabytesAvailable(File f) {
    StatFs stat = new StatFs(f.getPath());
    long bytesAvailable = (long)stat.getBlockSize() * (long)stat.getAvailableBlocks();
    return bytesAvailable / (1024.f * 1024.f);
}

В приведенном выше коде имеется ссылка на некоторые устаревшие функции по состоянию на 13 августа 2014 года. Ниже я воспроизвожу обновленную версию:

public static float megabytesAvailable(File f) {
    StatFs stat = new StatFs(f.getPath());
    long bytesAvailable = 0;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
        bytesAvailable = (long) stat.getBlockSizeLong() * (long) stat.getAvailableBlocksLong();
    else
        bytesAvailable = (long) stat.getBlockSize() * (long) stat.getAvailableBlocks();
    return bytesAvailable / (1024.f * 1024.f);
}

Ответ 3

Я разработал некоторые готовые к использованию функции, чтобы получить доступное пространство в разных единицах. Вы можете использовать эти методы, просто скопировав любой из них в свой проект.

/**
 * @return Number of bytes available on External storage
 */
public static long getAvailableSpaceInBytes() {
    long availableSpace = -1L;
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();

    return availableSpace;
}


/**
 * @return Number of kilo bytes available on External storage
 */
public static long getAvailableSpaceInKB(){
    final long SIZE_KB = 1024L;
    long availableSpace = -1L;
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
    return availableSpace/SIZE_KB;
}
/**
 * @return Number of Mega bytes available on External storage
 */
public static long getAvailableSpaceInMB(){
    final long SIZE_KB = 1024L;
    final long SIZE_MB = SIZE_KB * SIZE_KB;
    long availableSpace = -1L;
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
    return availableSpace/SIZE_MB;
}

/**
 * @return Number of gega bytes available on External storage
 */
public static long getAvailableSpaceInGB(){
    final long SIZE_KB = 1024L;
    final long SIZE_GB = SIZE_KB * SIZE_KB * SIZE_KB;
    long availableSpace = -1L;
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
    return availableSpace/SIZE_GB;
}

Ответ 4

Новые методы были введены с API версии 18.

Я использовал что-то подобное для оценки размера большого кеш-диска (для кеша загрузчика Picasso OkHttp). Метод помощника был таким:

private static final String BIG_CACHE_PATH = "my-cache-dir";
private static final float  MAX_AVAILABLE_SPACE_USE_FRACTION = 0.9f;
private static final float  MAX_TOTAL_SPACE_USE_FRACTION     = 0.25f;

static File createDefaultCacheDirExample(Context context) {
    File cache = new File(context.getApplicationContext().getCacheDir(), BIG_CACHE_PATH);
    if (!cache.exists()) {
        cache.mkdirs();
    }
    return cache;
}

/**
 * Calculates minimum of available or total fraction of disk space
 * 
 * @param dir
 * @return space in bytes
 */
@SuppressLint("NewApi")
static long calculateAvailableCacheSize(File dir) {
    long size = 0;
    try {
        StatFs statFs = new StatFs(dir.getAbsolutePath());
        int sdkInt = Build.VERSION.SDK_INT;
        long totalBytes;
        long availableBytes;
        if (sdkInt < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            int blockSize = statFs.getBlockSize();
            availableBytes = ((long) statFs.getAvailableBlocks()) * blockSize;
            totalBytes = ((long) statFs.getBlockCount()) * blockSize;
        } else {
            availableBytes = statFs.getAvailableBytes();
            totalBytes = statFs.getTotalBytes();
        }
        // Target at least 90% of available or 25% of total space
        size = (long) Math.min(availableBytes * MAX_AVAILABLE_SPACE_USE_FRACTION, totalBytes * MAX_TOTAL_SPACE_USE_FRACTION);
    } catch (IllegalArgumentException ignored) {
        // ignored
    }
    return size;
}

Ответ 5

На основе этого ответа, Добавлена ​​поддержка версии для Android < 18

public static float megabytesAvailable(File file) {
    StatFs stat = new StatFs(file.getPath());
    long bytesAvailable;
    if(Build.VERSION.SDK_INT >= 18){
        bytesAvailable = getAvailableBytes(stat);
    }
    else{
        //noinspection deprecation
        bytesAvailable = stat.getBlockSize() * stat.getAvailableBlocks();
    }

    return bytesAvailable / (1024.f * 1024.f);
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private static long getAvailableBytes(StatFs stat) {
    return stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
}

Ответ 6

также, если вы хотите проверить доступное пространство во внутренней памяти, используйте:

File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());

...

Ответ 7

Google имеет информацию об этом на странице начала работы - см. Query Free Space. Говорят, что вы можете проверить доступное пространство на getFreeSpace(), но они заявляют, что это неточно, и вы должны ожидать немного меньше свободного места, чем это. Они говорят:

Если возвращаемое число на несколько МБ больше, чем размер данных, которые вы хотите сохранить, или если файловая система заполнена на 90%, тогда, вероятно, она безопасна для продолжения. В противном случае вы, вероятно, не должны записывать на хранение.

Также они дают советы, что часто полезно не проверять свободное пространство вообще и просто try catch для ошибки:

Вам не требуется проверять объем доступного пространства перед сохранением файла. Вместо этого вы можете попытаться записать файл сразу, а затем поймать IOException, если это произойдет. Возможно, вам понадобится сделать это, если вы не знаете, сколько места вам нужно. Например, если вы изменили кодировку файла, прежде чем сохранить его, преобразов PNG-изображение в JPEG, вы не будете знать размер файла заранее.

Я бы рекомендовал, чтобы только для очень больших размеров файлов вы должны заранее проверить доступное хранилище, чтобы не потерять время загрузки или создания файла, который, если явно слишком большой, чтобы удерживать. В любом случае вы всегда должны использовать try catch, поэтому я считаю, что единственный аргумент для проверки доступного свободного места заранее, если это либо ненужное использование ресурсов, а время слишком много.

Ответ 8

Надеюсь, этот код поможет другим. Протестировано. Спасибо, чтобы уточнить его.

/**
 * Get the free disk available space in boolean to download requested file 
 * 
 * @return boolean value according to size availability
 */

protected static boolean isMemorySizeAvailableAndroid(long download_bytes, boolean isExternalMemory) {
    boolean isMemoryAvailable = false;
    long freeSpace = 0;

    // if isExternalMemory get true to calculate external SD card available size
    if(isExternalMemory){
        try {
            StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
            freeSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
            if(freeSpace > download_bytes){
                isMemoryAvailable = true;
            }else{
                isMemoryAvailable = false;
            }
        } catch (Exception e) {e.printStackTrace(); isMemoryAvailable = false;}
    }else{
        // find phone available size
        try {
            StatFs stat = new StatFs(Environment.getDataDirectory().getPath());
            freeSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
            if(freeSpace > download_bytes){
                isMemoryAvailable = true;
            }else{
                isMemoryAvailable = false;
            }
        } catch (Exception e) {e.printStackTrace(); isMemoryAvailable = false;}
    }

    return isMemoryAvailable;
}

Ответ 9

public String TotalExtMemory()
{
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());   
    int Total = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;

    String strI = Integer.toString(Total);
    return strI;
}

public String FreeExtMemory()
{
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
    int Free  = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
    String strI = Integer.toString(Free);
    return strI;
}

public String BusyExtMemory()
{
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());   
    int Total = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;
    int Free  = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
    int Busy  = Total - Free;
    String strI = Integer.toString(Busy);
    return strI;
}