Ответ 1
Используйте StatFs
и передайте путь к файлу внешнего хранилища конструктору, и вы можете вызвать такие функции, как getAvailableBlocks()
и getBlockSize()
для объекта StatFs
.
Как вы проверяете, заполнена ли SD-карта или нет, чтобы ваше приложение могло решить, может ли он продолжать выполнять свою работу, то есть записывать на внешнее хранилище или уведомлять пользователя о том, что хранилище закончилось.
Используйте StatFs
и передайте путь к файлу внешнего хранилища конструктору, и вы можете вызвать такие функции, как getAvailableBlocks()
и getBlockSize()
для объекта StatFs
.
Подход в этот ответ разбит на устройства с большим внешним хранилищем. Например, на моем Nexus 7 он в настоящее время возвращает ~ 2 ГБ, когда на самом деле осталось ~ 10 ГБ пространства.
// DOES NOT WORK CORRECTLY ON DEVICES WITH LARGE STORAGE DUE TO INT OVERFLOW
File externalStorageDir = Environment.getExternalStorageDirectory();
StatFs statFs = new StatFs(externalStorageDirectory.getAbsolutePath());
int free = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1024 / 1024;
У StatFs есть методы замены, возвращающие long
, getAvailableBlocksLong()
и getBlockCountLong()
, но проблема в том, что они были добавлены только в уровне API 18.
Самый простой способ - использовать getFreeSpace()
в java.io.File, добавленный в уровень API 9, который возвращает long
:
Возвращает количество свободных байтов в разделе, содержащем это дорожка. Возвращает 0, если этот путь не существует.
Итак, чтобы получить свободное пространство на внешнем хранилище ( "SD-карта" ):
File externalStorageDir = Environment.getExternalStorageDirectory();
long free = externalStorageDir.getFreeSpace() / 1024 / 1024;
В качестве альтернативы, если вы действительно хотите использовать StatFs, но должны поддерживать уровень API < 18, это исправит целочисленное переполнение:
File externalStorageDir = Environment.getExternalStorageDirectory();
StatFs statFs = new StatFs(externalStorageDir.getAbsolutePath());
long blocks = statFs.getAvailableBlocks();
long free = (blocks * statFs.getBlockSize()) / 1024 / 1024;
/******************************************************************************************
Returns size in MegaBytes.
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()) / 1048576;
return total;
}
public long freeMemory()
{
StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
long free = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
return free;
}
public long busyMemory()
{
StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
long total = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;
long free = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
long busy = total - free;
return busy;
}
Я думаю, вы можете использовать это утверждение для решения своей проблемы. этот вопрос не проверяет наличие или отсутствие достаточной емкости SD-карты.
if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){
//to do something in here
}
/**
* @return Number of bytes available on external storage
*/
public static long getExternalStorageAvailableSpace() {
long availableSpace = -1L;
try {
StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
stat.restat(Environment.getExternalStorageDirectory().getPath());
availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
} catch (Exception e) {
e.printStackTrace();
}
return availableSpace;
}
Вот как вы получаете размеры внутреннего хранилища:
StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
long blockSize = statFs.getBlockSize();
long totalSize = statFs.getBlockCount()*blockSize;
long availableSize = statFs.getAvailableBlocks()*blockSize;
long freeSize = statFs.getFreeBlocks()*blockSize;
Вот как вы получаете внешние размеры хранилища (размер SD-карты):
StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
long blockSize = statFs.getBlockSize();
long totalSize = statFs.getBlockCount()*blockSize;
long availableSize = statFs.getAvailableBlocks()*blockSize;
long freeSize = statFs.getFreeBlocks()*blockSize;