web-dev-qa-db-ja.com

androidで内部および外部のSDカードパスを取得する方法

ほとんどの新しいAndroidデバイスには内部SDカードと外部SDカードがあります。ファイルエクスプローラーアプリを作成したいのですが、アプリで使用するパスを取得する方法がわかりません。

File file = Environment.getExternalStorageDirectory();

ほとんどのデバイスで/mnt/sdcardを返しますが、/storage1 or /storage2のような他の外部SDカードへの別のパスがあります。任意の助けに感謝します。

18
Mahmoud Jorban

Androidで内部および外部のSDカードパスを取得する方法

内部ストレージに保存する方法:

_File getDir (String name, int mode)

File getFilesDir () 
_

上記のメソッドはContextクラスにあります

電話の内部メモリに保存する方法:

_File getExternalStorageDirectory ()

File getExternalFilesDir (String type)

File getExternalStoragePublicDirectory (String type)
_

最初は、誰もがEnvironment.getExternalStorageDirectory()を使用しました。これは、電話機の内部メモリのrootを指していました。その結果、ルートディレクトリはランダムなコンテンツでいっぱいになりました。

その後、次の2つのメソッドが追加されました。

Contextクラスでは、getExternalFilesDir()を追加し、電話の内部メモリ上のアプリ固有のディレクトリを指し示しました。このディレクトリとその内容は、アプリをアンインストールすると削除されます。

Environment.getExternalStoragePublicDirectory()は、写真や映画などのよく知られているファイルの種類を保存するための集中管理された場所です。このディレクトリとその内容は[〜#〜] not [〜#〜]アプリがアンインストールされると削除されます。

リムーバブルストレージに保存する方法、つまりマイクロSDカード

APIレベル19以前は、SDカードに保存する公式の方法はありませんでした。しかし、多くは非公式のAPIを使用してそれを行うことができます。

公式には、1つのメソッドがAPIレベル19(Androidバージョン4.4-KitKat)のContextクラスに導入されました。

_File[] getExternalFilesDirs (String type)
_

アプリケーションが所有する永続ファイルを配置できるすべての共有/外部ストレージデバイス上のアプリケーション固有のディレクトリへの絶対パスを返します。これらのファイルはアプリケーションの内部にあり、通常はユーザーがメディアとして見ることはできません。

つまり、Micro SDカードと内部メモリの両方へのパスを返します。通常、2番目に返されるパスは、マイクロSDカードのストレージパスになります。

内部および外部ストレージ用語 Google/officialによればAndroid docs is まったく異なる私たちの考えから。

9
AnV

はい。異なるメーカーは、Samsung Tab 3のextsdなどの異なるSDカード名を使用し、他のサムスンデバイスは、この異なるメーカーが異なる名前を使用するようにsdcardを使用します。

あなたと同じ要件がありました。だから私はあなたのプロジェクトからあなたのためのサンプル例を作成しましたこのリンクに行きます Android Directory chooser androi-dirchooserライブラリを使用する例。この例では、SDカードを検出し、すべてのサブフォルダーを一覧表示します。また、デバイスに複数のSDカードがあるかどうかも検出します。

コードの一部は次のようになります。完全な例については、リンクに移動してください Android Directory Chooser

/**
* Returns the path to internal storage ex:- /storage/emulated/0
 *
* @return
 */
private String getInternalDirectoryPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath();
 }

/**
 * Returns the SDcard storage path for samsung ex:- /storage/extSdCard
 *
 * @return
 */
    private String getSDcardDirectoryPath() {
    return System.getenv("SECONDARY_STORAGE");
}


 mSdcardLayout.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        String sdCardPath;
        /***
         * Null check because user may click on already selected buton before selecting the folder
         * And mSelectedDir may contain some wrong path like when user confirm dialog and swith back again
         */

        if (mSelectedDir != null && !mSelectedDir.getAbsolutePath().contains(System.getenv("SECONDARY_STORAGE"))) {
            mCurrentInternalPath = mSelectedDir.getAbsolutePath();
        } else {
            mCurrentInternalPath = getInternalDirectoryPath();
        }
        if (mCurrentSDcardPath != null) {
            sdCardPath = mCurrentSDcardPath;
        } else {
            sdCardPath = getSDcardDirectoryPath();
        }
        //When there is only one SDcard
        if (sdCardPath != null) {
            if (!sdCardPath.contains(":")) {
                updateButtonColor(STORAGE_EXTERNAL);
                File dir = new File(sdCardPath);
                changeDirectory(dir);
            } else if (sdCardPath.contains(":")) {
                //Multiple Sdcards show root folder and remove the Internal storage from that.
                updateButtonColor(STORAGE_EXTERNAL);
                File dir = new File("/storage");
                changeDirectory(dir);
            }
        } else {
            //In some unknown scenario at least we can list the root folder
            updateButtonColor(STORAGE_EXTERNAL);
            File dir = new File("/storage");
            changeDirectory(dir);
        }


    }
});
2
Shivaraj Patil

パスを取得するための直接的な手段がないため、ソリューションは/system/etc/vold.fstabファイルをスキャンし、次のような行を探すことができます。dev_mount sdcard/mnt/sdcard 1 /devices/platform/s3c-sdhci.0/ mmc_Host/mmc0

見つかったら、その要素に分割し、そのマウントポイントへのパスを引き出して、arraylistに追加します

強調テキスト一部のデバイスではvoldファイルが完全に欠落しているため、ここにパスを追加して、リストに実際のまたはエミュレートされた最初のsdcardへのパスが常に含まれるようにします。

    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() 
{
    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--);
    }
}
1
Emel Elias

これがどれほど一般的な答えかわかりませんが、Motorola XT830CでAndroid 4.4とNexus 7 Android 6.0.1。とSamsung SM-T530NU Android 5.0.2。System.getenv("SECONDARY_STORAGE")およびEnvironment.getExternalStorageDirectory().getAbsolutePath()を使用しました。
2番目のSDカードがないNexus(_System.getenv_はnullを返し、_Envirnoment.getExterna..._は/ storage/emulated/0を返します。
外部SDカードを持つMotorolaデバイスは、System.getenv("SECONDARY_STORAGE")および_Envirnoment.getExterna..._に対して/ storage/sdcard1を提供し、/ storage/emulated/0を提供します。
samsumgは、外部SDの/ storage/extSdCardを返します。
私の場合、外部の場所にサブディレクトリを作成し、使用しています

_ appDirectory = (System.getenv("SECONDARY_STORAGE") == null)
       ? Environment.getExternalStorageDirectory().getAbsolutePath()
       : System.getenv("SECONDARY_STORAGE");
_

sDカードを見つけるために。このディレクトリにサブディレクトリを作成しています。
もちろん、外部メモリにアクセスするには、マニフェストファイルにアクセス許可を設定する必要がありました。
Nook 8インチカラータブレットも持っています。テストする機会があれば、このアプローチで問題があれば投稿します。

1
steven smith

このコードを試してみてください

Map<String, File> externalLocations = ExternalStorage.getAllStorageLocations();
File sdCard = externalLocations.get(ExternalStorage.SD_CARD);
File externalSdCard = externalLocations.get(ExternalStorage.EXTERNAL_SD_CARD);
0
Rahul

ただし、/ storage1や/ storage2など、他の外部SDカード用の別のパスがあります

Android SDK-少なくともAndroid 4.1-を介してこれらのパスにアクセスできるようになります。とにかく、そのような保存場所の動作と使用目的は、デバイスのメーカー次第です。

0
CommonsWare
File main=new File(String.valueOf(Environment.getExternalStorageDirectory().getAbsolutePath()));
File[]t=main.getParentFile().listFiles();

for(File dir:t)
{
    Log.e("Main",dir.getAbsolutePath());
}

出力:

E/Main: /storage/sdcard1
E/Main: /storage/sdcard0

1枚のSDカードと内蔵メモリがあります。

0
kumar