Я пытаюсь выяснить доступное дисковое пространство на телефоне Android, на котором работает мое приложение. Есть ли способ сделать это программно?
Спасибо,
Я пытаюсь выяснить доступное дисковое пространство на телефоне Android, на котором работает мое приложение. Есть ли способ сделать это программно?
Спасибо,
Попробуйте StatFs.getAvailableBlocks. Вам нужно будет преобразовать количество блоков в КБ с помощью getBlockSize.
Пример: получение читаемого человеком размера, такого как 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 "???";
}
Есть несколько тонкостей относительно путей, к которым не обращается ни один из текущих ответов. Вы должны использовать правильный путь, исходя из того, какую статистику вы интересуете. Основываясь на глубоком погружении в DeviceStorageMonitorService.java, который генерирует предупреждения о низком диске в области уведомлений и липкие трансляции для ACTION_DEVICE_STORAGE_LOW, вот некоторые из путей которые вы можете использовать:
Чтобы проверить свободное пространство на внутреннем диске, используйте каталог данных, полученный через Environment.getDataDirectory(). Это даст вам свободное место на разделе данных. В разделе данных хранится все внутреннее хранилище для всех приложений на устройстве.
Чтобы проверить свободное пространство на внешнем (SDCARD) диске, используйте внешний каталог хранилища, полученный через Environment.getExternalStorageDirectory(). Это даст вам свободное пространство на SDCARD.
Чтобы проверить доступную память на системном разделе, который содержит файлы ОС, используйте Environment.getRootDirectory(). Поскольку ваше приложение не имеет доступа к системному разделу, этот stat, вероятно, не очень полезен. DeviceStorageMonitorService использует в информационных целях и вводит его в журнал.
Чтобы проверить временные файлы/кэш-память, используйте Environment.getDownloadCacheDirectory(). DeviceStorageMonitorService пытается очистить некоторые временные файлы, когда память становится низкой.
Пример кода для получения внутренней (/data), внешней (/sdcard) и OS (/системной) свободной памяти:
// Get internal (data partition) free space
// This will match what 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();
}
На основе ответа @XXX я создал фрагмент кода gist, который обертывает StatFs для легкого и простого использования. Вы можете найти здесь как GitHub gist.
Введите целочисленные значения задолго до выполнения умножения. Умножение между двумя большими целыми числами может переполниться и дать отрицательный результат.
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;
}
С помощью небольшого google вы могли бы найти StatFs
-class, который:
[...] a Wrapper для Unix statfs().
Приведены примеры
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;
}
}
Так как blockize и 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
/**
* 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";
}
Расположение памяти:
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);
}
}