Андроид бесплатно, размер внутренней/внешней памяти


Я хочу получить размер свободной памяти на внутренней/внешней памяти устройства программно. Я использую этот кусок кода :

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 72

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-картой, это также может быть крепление внутренней памяти. Смотрите:

найти внешнее расположение 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

о внешней менори, есть еще один способ:
File external = Environment.getExternalStorageDirectory(); free:external.getFreeSpace(); total:external.getTotalSpace();