2

デバイスの内部および外部スペースの量を取得したいのですが、StackOverflow に関するいくつかの投稿を行った後、これは簡単であることがわかりました。これを使用して内部スペースの量を取得できます:

StatFs sfsInternal = new StatFs(Environment.getRootDirectory().getAbsolutePath());
return Long.valueOf(sfsInternal.getBlockCount()) * Long.valueOf(sfsInternal.getBlockSize());

...そして、これを使用して外部スペースの量を取得できます:

StatFs sfsExternal = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
return Long.valueOf(sfsExternal.getBlockCount()) * Long.valueOf(sfsExternal.getBlockSize());

「内部」ストレージについて読んだとき、それはデバイスの取り外し不可能なオンボード ストレージであり、「外部」はリムーバブル フラッシュ カード ストレージであると想定しましたが、これは完全には当てはまりません。

Samsung デバイス (Galaxy Note 2) では、内部ストレージの大部分が外部として表示されることがわかりました。これは、同じことを議論する答えです。https://stackoverflow.com/a/12087556/304151

Samsung の Galaxy デバイスのエッジ ケースを考慮しながら、内部ストレージ (オンボードおよび非リムーバブル) の量と外部ストレージ (フラッシュおよびリムーバブル) の量を取得するにはどうすればよいですか。このシナリオの完全な実用的なソリューションを提供する StackOverflow に関する回答はまだ見つかりません。私のコードは API レベル 17 用です。

ありがとう。

4

4 に答える 4

0

このブログ投稿でこれを行うコードを見つけました。

package com.sapien.music.importer.util;

import java.io.File;

@SuppressLint("NewApi")
public class StorageOptions {
public static String[] labels;
public static String[] paths;
public static int count = 0;

private static Context sContext;
private static ArrayList<String> sVold = new ArrayList<String>();

public static void determineStorageOptions(Context context) {
    sContext = context.getApplicationContext();

    readVoldFile();

    testAndCleanList();

    setProperties();
}

private static void readVoldFile() {
    /*
     * Scan the /system/etc/vold.fstab file and look for lines like this:
     * dev_mount sdcard /mnt/sdcard 1
     * /devices/platform/s3c-sdhci.0/mmc_host/mmc0
     * 
     * When one is found, split it into its elements and then pull out the
     * path to the that mount point and add it to the arraylist
     * 
     * some devices are missing the vold file entirely so we add a path here
     * to make sure the list always includes the path to the first sdcard,
     * whether real or emulated.
     */

    sVold.add("/mnt/sdcard");

    try {
        Scanner scanner = new Scanner(new File("/system/etc/vold.fstab"));
        while (scanner.hasNext()) {
            String line = scanner.nextLine();
            if (line.startsWith("dev_mount")) {
                String[] lineElements = line.split(" ");
                String element = lineElements[2];

                if (element.contains(":"))
                    element = element.substring(0, element.indexOf(":"));

                if (element.contains("usb"))
                    continue;

                // don't add the default vold path
                // it's already in the list.
                if (!sVold.contains(element))
                    sVold.add(element);
            }
        }
    } catch (Exception e) {
        // swallow - don't care
        e.printStackTrace();
    }
}

private static void testAndCleanList() {
    /*
     * Now that we have a cleaned list of mount paths, test each one to make
     * sure it's a valid and available path. If it is not, remove it from
     * the list.
     */

    for (int i = 0; i < sVold.size(); i++) {
        String voldPath = sVold.get(i);
        File path = new File(voldPath);
        if (!path.exists() || !path.isDirectory() || !path.canWrite())
            sVold.remove(i--);
    }
}

private static void setProperties() {
    /*
     * At this point all the paths in the list should be valid. Build the
     * public properties.
     */

    ArrayList<String> labelList = new ArrayList<String>();

    int j = 0;
    if (sVold.size() > 0) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD)
            labelList.add("Auto");
        else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            if (Environment.isExternalStorageRemovable()) {
                labelList.add(sContext
                        .getString(R.string.text_external_storage) + " 1");
                j = 1;
            } else
                labelList.add(sContext
                        .getString(R.string.text_internal_storage));
        } else {
            if (!Environment.isExternalStorageRemovable()
                    || Environment.isExternalStorageEmulated())
                labelList.add(sContext
                        .getString(R.string.text_internal_storage));
            else {
                labelList.add(sContext
                        .getString(R.string.text_external_storage) + " 1");
                j = 1;
            }
        }

        if (sVold.size() > 1) {
            for (int i = 1; i < sVold.size(); i++) {
                labelList.add(sContext
                        .getString(R.string.text_external_storage)
                        + " " + (i + j));
            }
        }
    }

    labels = new String[labelList.size()];
    labelList.toArray(labels);

    paths = new String[sVold.size()];
    sVold.toArray(paths);

    count = Math.min(labels.length, paths.length);

    /*
     * don't need these anymore, clear the lists to reduce memory use and to
     * prepare them for the next time they're needed.
     */
    sVold.clear();
}
于 2013-07-11T10:31:30.307 に答える
0

「内部ストレージ」は、非公開のデータ用です。アプリケーション自体に関連しているため、内部と呼ばれます。アプリケーションのデータをサンドボックス化し、非公開にするためのものです。

Environment.getRootDirectory() は、電話機のシステム フォルダを取得します。これは内部ストレージではなく、外部ストレージです。

外部ストレージは、アプリケーションの外部で公開されている共有データ用です。

マウントの命名規則は電話機によって大きく異なるため、SD カードと通常のオンボード ディレクトリを区別するのが難しい場合があります。ただし、通常、sd カードはディレクトリ /sdcard/ にマウントされます。

于 2013-07-01T11:14:10.227 に答える