Андроид бесплатно, размер внутренней/внешней памяти
Я хочу получить размер свободной памяти на внутренней/внешней памяти устройства программно. Я использую этот кусок кода :
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
прямо сейчас. Как я могу исправить этот код, чтобы я мог получить свободный размер ?
10 ответов:
Ниже приведен код для ваших целей :
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(); }
получить размер ОЗУ
ActivityManager actManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); MemoryInfo memInfo = new ActivityManager.MemoryInfo(); actManager.getMemoryInfo(memInfo); long totalMemory = memInfo.totalMem;
вот как я это сделал:
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);
начиная с API 9 вы можете сделать:
long freeBytesInternal = new File(ctx.getFilesDir().getAbsoluteFile().toString()).getFreeSpace(); long freeBytesExternal = new File(getExternalFilesDir(null).toString()).getFreeSpace();
чтобы получить все доступные папки хранения (включая 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);
обратите внимание, что я думаю, что внутреннее хранилище может быть таким же, как и первое внешнее хранилище, так как первое является эмулируемым.
@Android-Droid-вы ошибаетесь
Environment.getExternalStorageDirectory()
указывает на внешнюю память, которая не должна быть SD-картой, это также может быть крепление внутренней памяти. Смотрите:
очень легко узнать доступное хранилище, если вы получаете внутренний, а также внешний путь хранения. Также внешний путь хранения телефона действительно очень легко узнать с помощью
окружающая среда.getExternalStorageDirectory().getPath();
поэтому я просто концентрируюсь на том, как узнать пути внешнего съемного носителя, такого как съемная sdcard, 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's 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's external storage path, but when i test it in Moto X Play (6.0) with removable sdcard, //this method does not include phone's 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's external storage path. out.remove(phoneExternalPath); return out; }
попробуйте этот простой фрагмент
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]; }
быстрое добавление к теме внешней памяти
не путайте имя метода
externalMemoryAvailable()
в ответе Динеша Праджапати.
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
дает вам текущее состояние памяти, если носитель присутствует и установлен в своей точке монтирования с доступом для чтения/записи. Вы получитеtrue
даже на устройствах без SD-карт, таких как Nexus 5. Но все же это "обязательный" метод перед любыми операциями с хранилищем.чтобы проверить, есть ли SD-карта на вашем устройстве вы можете использовать метод
ContextCompat.getExternalFilesDirs()
он не показывает переходные устройства, такие как USB-накопители.
также имейте в виду, что
ContextCompat.getExternalFilesDirs()
на Android 4.3 и ниже всегда возврат только 1 записи (SD-карта, если она доступна, в противном случае внутренняя). Вы можете прочитать больше об этом здесь.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-карты, так что если вы нужны все они-откорректируйте код выше.
@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