私はググググしてきましたが、どのメーカー/モデルがsdcard /外部ストレージのどのパスを使用しているかを見つけるのは非常に難しいです。
Environment.getExternalStorageDirectory()
getExternalStorageDirectory()
が一部のデバイスで外部sdカードを指す場合があることを知っています。
これが、外部パスの一般的なパスを見つけたものです(どのメーカーがどのパスを使用しているかはわかりません)。
/emmc
/mnt/sdcard/external_sd
/mnt/external_sd
/sdcard/sd
/mnt/sdcard/bpemmctest
/mnt/sdcard/_ExternalSD
/mnt/sdcard-ext
/mnt/Removable/MicroSD
/Removable/MicroSD
/mnt/external1
/mnt/extSdCard
/mnt/extsd
/mnt/usb_storage <-- usb flash mount
/mnt/extSdCard <-- usb flash mount
/mnt/UsbDriveA <-- usb flash mount
/mnt/UsbDriveB <-- usb flash mount
これらは私がグーグルで見つけたものです。
内部+外部ストレージ+ USBフラッシュドライブ全体をスキャンして、特定のファイルを探す必要があります。パスがない場合は、上記のリストに追加してください。各メーカーが使用しているパスを知っている人がいたら、ぜひ教えてください。
朗報です! KitKatには、これらのセカンダリ共有ストレージデバイスとやり取りするためのパブリックAPIがあります。
新しいContext.getExternalFilesDirs()
およびContext.getExternalCacheDirs()
メソッドは、プライマリデバイスとセカンダリデバイスの両方を含む複数のパスを返すことができます。次に、それらを反復処理し、Environment.getStorageState()
およびFile.getFreeSpace()
をチェックして、ファイルを保存するのに最適な場所を決定できます。これらのメソッドは、support-v4ライブラリのContextCompat
でも使用できます。
また、Context
によって返されるディレクトリの使用のみに関心がある場合は、READ_
またはWRITE_EXTERNAL_STORAGE
権限が不要になることにも注意してください。今後は、これらのディレクトリへの読み取り/書き込みアクセス権が常に付与され、追加の権限は必要ありません。
アプリは、次のように許可リクエストを終了することで、古いデバイスでも引き続き動作できます。
<uses-permission
Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"
Android:maxSdkVersion="18" />
私はまた、どこかからのあなたのようなリストから始めて(申し訳ありませんが、元のソースを見つけることができませんでした)、ユーザーのフィードバックから収集されたいくつかのパスを追加し続けています。上記のリストに重複があります。
/storage/sdcard1 //!< Motorola Xoom
/storage/extsdcard //!< Samsung SGS3
/storage/sdcard0/external_sdcard // user request
/mnt/extsdcard
/mnt/sdcard/external_sd //!< Samsung galaxy family
/mnt/external_sd
/mnt/media_rw/sdcard1 //!< 4.4.2 on CyanogenMod S3
/removable/microsd //!< Asus transformer prime
/mnt/emmc
/storage/external_SD //!< LG
/storage/ext_sd //!< HTC One Max
/storage/removable/sdcard1 //!< Sony Xperia Z1
/data/sdext
/data/sdext2
/data/sdext3
/data/sdext4
/sdcard1 //Sony Xperia Z
/sdcard2 //HTC One M8s
/storage/microsd //ASUS ZenFone 2
あなたが達成したいこと(特定のファイルのすべての可能なパスをスキャンすること)については、この方法で(既知のパスのリストを使用して)それを行うことはかなり不可能だと思います。同じデバイスの一部のパスは、Androidアップグレードの間に変更されました。
提供されたパスoceanuzに基づいて、外部ストレージパスを検索し(大文字と小文字は無視)、それを文字列として返すメソッドを作成しました。
注:私はメソッド内で StreamSupport ライブラリーを使用したため、それが機能するためには、jarファイルをダウンロードして、プロジェクトのlibsフォルダーに追加する必要があります。
public static String getExternalSdPath(Context context) {
List<String> listOfFoldersToSearch = Arrays.asList("/storage/", "/mnt/", "/removable/", "/data/");
List<String> listOf2DepthFolders = Arrays.asList("sdcard0", "media_rw", "removable");
List<String> listOfExtFolders = Arrays.asList("sdcard1", "extsdcard", "external_sd", "microsd", "emmc", "ext_sd", "sdext",
"sdext1", "sdext2", "sdext3", "sdext4");
final String[] thePath = {""};
Optional<File> optional = StreamSupport.stream(listOfFoldersToSearch)
.filter(s -> {
File folder = new File(s);
return folder.exists() && folder.isDirectory();
}) //I got the ones that exist and are directories
.flatMap(s -> {
try {
List<File> files = Arrays.asList(new File(s).listFiles());
return StreamSupport.stream(files);
} catch (NullPointerException e) {
return StreamSupport.stream(Collections.emptyList());
}
}) //I got all sub-dirs of the main folders
.flatMap(file1 -> {
if (listOf2DepthFolders.contains(file1.getName().toLowerCase())) {
try {
List<File> files = Arrays.asList(file1.listFiles());
return StreamSupport.stream(files);
} catch (NullPointerException e) {
return StreamSupport.stream(Collections.singletonList(file1));
}
} else
return StreamSupport.stream(Collections.singletonList(file1));
}) //Here I got all the 2 depth and 3 depth folders
.filter(o -> listOfExtFolders.contains(o.getName().toLowerCase()))
.findFirst();
optional.ifPresent(file -> thePath[0] = file.getAbsolutePath());
Log.i("Path", thePath[0]);
return thePath[0];
}
このメソッドは、SDカードのパスが見つからない場合、空の文字列を返します。
Sony Xperia XAで外部SDカードへのパスを見つけようとしました。次に、ESファイルエクスプローラーをインストールしたところ、その特性ウィンドウに、内部または外部のフォルダーへのパスが明確に表示されました。外部SDへのパスは/ storage/C4EE-F3A3として見つかりました。出力ファイルをPython3から外部SDに保存しようとしましたが、内部SDのQpythonフォルダー以外に保存する権限がありませんでした。