Android получит бесплатный размер внутренней/внешней памяти
Я хочу программно получить размер свободной памяти на внутренней/внешней памяти моего устройства. Я использую этот фрагмент кода:
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);
и результат, который я получаю, следующий:
11-15 10:27:18.844: E/(25822): Available MB : 7572
11-15 10:27:18.844: E/(25822): Format : 869MB
Проблема в том, что я хочу получить бесплатную память SdCard, которая находится сейчас 1,96GB
. Как я могу исправить этот код, чтобы получить свободный размер?
Ответы
Ответ 1
Так я это сделал:
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);
Ответ 2
Ниже приведен код для вашей цели:
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();
}
Получить размер RAM
ActivityManager actManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
MemoryInfo memInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
long totalMemory = memInfo.totalMem;
Ответ 3
Так как API 9 вы можете сделать:
long freeBytesInternal = new File(ctx.getFilesDir().getAbsoluteFile().toString()).getFreeSpace();
long freeBytesExternal = new File(getExternalFilesDir(null).toString()).getFreeSpace();
Ответ 4
Чтобы получить все доступные папки для хранения (включая SD-карты), вы сначала получаете файлы для хранения:
File internalStorageFile=getFilesDir();
File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);
Затем вы можете получить доступный размер каждого из них.
Есть 3 способа сделать это:
API 8 и ниже:
StatFs stat=new StatFs(file.getPath());
long availableSizeInBytes=stat.getBlockSize()*stat.getAvailableBlocks();
API 9 и выше:
long availableSizeInBytes=file.getFreeSpace();
API 18 и выше (не требуется, если предыдущий в порядке):
long availableSizeInBytes=new StatFs(file.getPath()).getAvailableBytes();
Чтобы получить отформатированную строку того, что вы получили сейчас, вы можете использовать:
String formattedResult=android.text.format.Formatter.formatShortFileSize(this,availableSizeInBytes);
или вы можете использовать это, если хотите увидеть точное количество байтов, но приятно:
NumberFormat.getInstance().format(availableSizeInBytes);
Обратите внимание, что я думаю, что внутреннее хранилище может быть таким же, как первое внешнее хранилище, так как первое - эмулируемое.
РЕДАКТИРОВАТЬ: Используя StorageVolume на Android Q и выше, я думаю, что можно получить свободное место каждого, используя что-то вроде:
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
AsyncTask.execute {
for (storageVolume in storageVolumes) {
val uuid: UUID = storageVolume.uuid?.let { UUID.fromString(it) } ?: StorageManager.UUID_DEFAULT
val allocatableBytes = storageManager.getAllocatableBytes(uuid)
Log.d("AppLog", "allocatableBytes:${android.text.format.Formatter.formatShortFileSize(this,allocatableBytes)}")
}
}
Я не уверен, что это правильно, и я не могу найти способ получить общий размер каждого, поэтому я написал об этом здесь и спросил об этом здесь.
Ответ 5
@Android-Droid - вы ошибаетесь Environment.getExternalStorageDirectory()
указывает на внешнее хранилище, которое не обязательно должно быть SD-картой, оно также может быть встроено в внутреннюю память. См:
Найти местоположение внешней SD-карты
Ответ 6
Очень легко найти доступное хранилище, если вы получите внутренний и внешний путь хранения. Кроме того, внешний вид внешнего хранилища телефона очень легко узнать, используя
Environment.getExternalStorageDirectory() GetPath();.
Итак, я просто сосредоточен на том, как узнать пути внешнего съемного хранилища, такие как съемная SD-карта, USB OTP (не протестировано USB OTG, поскольку у меня нет USB OTG).
Ниже приведен список всех возможных внешних путей хранения.
/**
* This method returns the list of removable storage and sdcard paths.
* I have no USB OTG so can not test it. Is anybody can test it, please let me know
* if working or not. Assume 0th index will be removable sdcard path if size is
* greater than 0.
* @return the list of removable storage paths.
*/
public static HashSet<String> getExternalPaths()
{
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try
{
final Process process = new ProcessBuilder().command("mount").redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1)
{
s = s + new String(buffer);
}
is.close();
}
catch (final Exception e)
{
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines)
{
if (!line.toLowerCase(Locale.US).contains("asec"))
{
if (line.matches(reg))
{
String[] parts = line.split(" ");
for (String part : parts)
{
if (part.startsWith("/"))
{
if (!part.toLowerCase(Locale.US).contains("vold"))
{
out.add(part.replace("/media_rw","").replace("mnt", "storage"));
}
}
}
}
}
}
//Phone external storage path (Not removal SDCard path)
String phoneExternalPath = Environment.getExternalStorageDirectory().getPath();
//Remove it if already exist to filter all the paths of external removable storage devices
//like removable sdcard, USB OTG etc..
//When I tested it in ICE Tab(4.4.2), Swipe Tab(4.0.1) with removable sdcard, this method includes
//phone external storage path, but when i test it in Moto X Play (6.0) with removable sdcard,
//this method does not include phone external storage path. So I am going to remvoe the phone's
//external storage path to make behavior consistent in all the phone. Ans we already know and it easy
// to find out the phone external storage path.
out.remove(phoneExternalPath);
return out;
}
Ответ 7
Попробуйте этот простой сниппет
public static String readableFileSize() {
long availableSpace = -1L;
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
availableSpace = (long) stat.getBlockSizeLong() * (long) stat.getAvailableBlocksLong();
else
availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
if(availableSpace <= 0) return "0";
final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
int digitGroups = (int) (Math.log10(availableSpace)/Math.log10(1024));
return new DecimalFormat("#,##0.#").format(availableSpace/Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}
Ответ 8
Быстрое добавление к теме внешней памяти
Не путайте имя метода externalMemoryAvailable()
в ответе Динеш Праджапати.
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
дает текущее состояние памяти, если носитель присутствует и монтируется в точке монтирования с доступом для чтения/записи.
Вы получите true
даже на устройствах без SD-карт, таких как Nexus 5. Но все же он должен быть "обязательным" перед любыми операциями с хранилищем.
Чтобы проверить, есть ли на вашем устройстве SD-карта, вы можете использовать метод ContextCompat.getExternalFilesDirs()
Он не показывает переходные устройства, например, флэш-накопители USB.
Также имейте в виду, что ContextCompat.getExternalFilesDirs()
на Android 4.3 и ниже будет всегда возвращать только 1 запись (SD-карта, если она доступна, иначе Internal). Вы можете прочитать об этом здесь.
public static boolean isSdCardOnDevice(Context context) {
File[] storages = ContextCompat.getExternalFilesDirs(context, null);
if (storages.length > 1 && storages[0] != null && storages[1] != null)
return true;
else
return false;
}
в моем случае этого было достаточно, но не забывайте, что некоторые из Android-устройств могут иметь 2 SD-карты, поэтому, если вам нужны все они - настройте код выше.
Ответ 9
@RequiresApi(api = Build.VERSION_CODES.O)
private void showStorageVolumes() {
StorageStatsManager storageStatsManager = (StorageStatsManager) getSystemService(Context.STORAGE_STATS_SERVICE);
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
if (storageManager == null || storageStatsManager == null) {
return;
}
List<StorageVolume> storageVolumes = storageManager.getStorageVolumes();
for (StorageVolume storageVolume : storageVolumes) {
final String uuidStr = storageVolume.getUuid();
final UUID uuid = uuidStr == null ? StorageManager.UUID_DEFAULT : UUID.fromString(uuidStr);
try {
Log.d("AppLog", "storage:" + uuid + " : " + storageVolume.getDescription(this) + " : " + storageVolume.getState());
Log.d("AppLog", "getFreeBytes:" + Formatter.formatShortFileSize(this, storageStatsManager.getFreeBytes(uuid)));
Log.d("AppLog", "getTotalBytes:" + Formatter.formatShortFileSize(this, storageStatsManager.getTotalBytes(uuid)));
} catch (Exception e) {
// IGNORED
}
}
}
Класс StorageStatsManager представил Android O и выше, который может предоставить вам бесплатный и общий байт во внешнем/внутреннем хранилище. Подробно с исходным кодом вы можете прочитать в моей следующей статье. Вы можете использовать отражение ниже, чем Android O
https://medium.com/cashify-engineering/how-to-get-storage-stats-in-android-o-api-26-4b92eca6805b
Ответ 10
О внешнем менталитете есть другой способ:
File external = Environment.getExternalStorageDirectory();
free:external.getFreeSpace();
total:external.getTotalSpace();
Ответ 11
Это способ, которым я это сделал..
внутренняя общая память
double totalSize = new File(getApplicationContext().getFilesDir().getAbsoluteFile().toString()).getTotalSpace();
double totMb = totalSize / (1024 * 1024);
Внутренний свободный размер
double availableSize = new File(getApplicationContext().getFilesDir().getAbsoluteFile().toString()).getFreeSpace();
double freeMb = availableSize/ (1024 * 1024);
Внешняя свободная и полная память
long freeBytesExternal = new File(getExternalFilesDir(null).toString()).getFreeSpace();
int free = (int) (freeBytesExternal/ (1024 * 1024));
long totalSize = new File(getExternalFilesDir(null).toString()).getTotalSpace();
int total= (int) (totalSize/ (1024 * 1024));
String availableMb = free+"Mb out of "+total+"MB";