Android 的外部 SDCard 文件路径
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23123461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
External SDCard file path for Android
提问by Bowie
Is it true that the file path to external SDCard on Android devices are always "/storage/extSdCard"? If not, how many variations are there?
Android 设备上外部 SDCard 的文件路径是否总是“/storage/extSdCard”?如果没有,有多少种变化?
I need it for my App to test the availability of externalSDCard.
我的应用程序需要它来测试外部SDCard的可用性。
I am using Titanium, it has a method Titanium.Filesystem.isExternalStoragePresent( )but it always return true even external SDCard is not mounted.
我正在使用 Titanium,它有一个方法Titanium.Filesystem.isExternalStoragePresent()但它总是返回 true 即使没有安装外部 SDCard。
I think it detect SDCard at local storage thus return true. But what I really want is detect whether physical SDCard is mounted or not.
我认为它在本地存储中检测到 SDCard,因此返回 true。但我真正想要的是检测是否安装了物理 SDCard。
Can I do this by detecting the existence of file "/storage/extSdCard"alone?
我可以通过单独检测文件“/storage/extSdCard”的存在来做到这一点吗?
Thanks.
谢谢。
回答by Digoun
Is it true that the file path to external SDCard on Android devices are always "/storage/extSdCard"? If not, how many variations are there?
Android 设备上外部 SDCard 的文件路径是否总是“/storage/extSdCard”?如果没有,有多少种变化?
Sadly the path to the external storage is not always the same according to manufacturer. Using Environment.getExternalStorageDirectory()
will return you the normal path for SD card which is mnt/sdcard/
. But for Samsung devices for example, the SD card path is either under mnt/extSdCard/
or under mnt/external_sd/
.
遗憾的是,根据制造商的不同,外部存储的路径并不总是相同的。使用Environment.getExternalStorageDirectory()
将返回 SD 卡的正常路径,即mnt/sdcard/
. 但例如,对于三星设备,SD 卡路径要么mnt/extSdCard/
在mnt/external_sd/
.
So one way to proceed would be to check the existence of external directory according to the path used by each manufacturer. With something like this:
因此,一种方法是根据每个制造商使用的路径检查外部目录是否存在。像这样:
mExternalDirectory = Environment.getExternalStorageDirectory()
.getAbsolutePath();
if (android.os.Build.DEVICE.contains("samsung")
|| android.os.Build.MANUFACTURER.contains("samsung")) {
File f = new File(Environment.getExternalStorageDirectory()
.getParent() + "/extSdCard" + "/myDirectory");
if (f.exists() && f.isDirectory()) {
mExternalDirectory = Environment.getExternalStorageDirectory()
.getParent() + "/extSdCard";
} else {
f = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/external_sd" + "/myDirectory");
if (f.exists() && f.isDirectory()) {
mExternalDirectory = Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/external_sd";
}
}
}
But what I really want is detect whether physical SDCard is mounted or not.
但我真正想要的是检测是否安装了物理 SDCard。
I didn't try the code yet, but the approach of Dmitriy Lozenko in this answeris much more interesting. His method returns the path of all mounted SD cards on sytem regardless of the manufacturer.
我还没有尝试代码,但 Dmitriy Lozenko 在这个答案中的方法更有趣。无论制造商如何,他的方法都会返回系统上所有已安装 SD 卡的路径。
回答by Alex Evtushik
I hope it will be useful for you :)
我希望它对你有用:)
import android.os.Environment;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class MemoryStorage {
private MemoryStorage() {}
public static final String SD_CARD = "sdCard";
public static final String EXTERNAL_SD_CARD = "externalSdCard";
/**
* @return True if the external storage is available. False otherwise.
*/
public static boolean isAvailable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
public static String getSdCardPath() {
return Environment.getExternalStorageDirectory().getPath() + "/";
}
/**
* @return True if the external storage is writable. False otherwise.
*/
public static boolean isWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/**
* @return A map of all storage locations available
*/
public static Map<String, File> getAllStorageLocations() {
Map<String, File> map = new HashMap<String, File>(10);
List<String> mMounts = new ArrayList<String>(10);
List<String> mVold = new ArrayList<String>(10);
mMounts.add("/mnt/sdcard");
mVold.add("/mnt/sdcard");
try {
File mountFile = new File("/proc/mounts");
if (mountFile.exists()) {
Scanner scanner = new Scanner(mountFile);
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("/dev/block/vold/")) {
String[] lineElements = line.split(" ");
String element = lineElements[1];
// don't add the default mount path
// it's already in the list.
if (!element.equals("/mnt/sdcard"))
mMounts.add(element);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
File voldFile = new File("/system/etc/vold.fstab");
if (voldFile.exists()) {
Scanner scanner = new Scanner(voldFile);
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.equals("/mnt/sdcard"))
mVold.add(element);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < mMounts.size(); i++) {
String mount = mMounts.get(i);
if (!mVold.contains(mount))
mMounts.remove(i--);
}
mVold.clear();
List<String> mountHash = new ArrayList<String>(10);
for (String mount : mMounts) {
File root = new File(mount);
if (root.exists() && root.isDirectory() && root.canWrite()) {
File[] list = root.listFiles();
String hash = "[";
if (list != null) {
for (File f : list) {
hash += f.getName().hashCode() + ":" + f.length() + ", ";
}
}
hash += "]";
if (!mountHash.contains(hash)) {
String key = SD_CARD + "_" + map.size();
if (map.size() == 0) {
key = SD_CARD;
} else if (map.size() == 1) {
key = EXTERNAL_SD_CARD;
}
mountHash.add(hash);
map.put(key, root);
}
}
}
mMounts.clear();
if (map.isEmpty()) {
map.put(SD_CARD, Environment.getExternalStorageDirectory());
}
return map;
}
}
回答by Honey Agarwal
This is how I finally got sdcard path using :
这就是我最终使用以下方法获得 sdcard 路径的方式:
public String getExternalStoragePath() {
String internalPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String[] paths = internalPath.split("/");
String parentPath = "/";
for (String s : paths) {
if (s.trim().length() > 0) {
parentPath = parentPath.concat(s);
break;
}
}
File parent = new File(parentPath);
if (parent.exists()) {
File[] files = parent.listFiles();
for (File file : files) {
String filePath = file.getAbsolutePath();
Log.d(TAG, filePath);
if (filePath.equals(internalPath)) {
continue;
} else if (filePath.toLowerCase().contains("sdcard")) {
return filePath;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
if (Environment.isExternalStorageRemovable(file)) {
return filePath;
}
} catch (RuntimeException e) {
Log.e(TAG, "RuntimeException: " + e);
}
}
}
}
return null;
}
回答by Paresh Kalinani
I just figured out something. At least for my Android Emulator, I had the SD Card Path like ' /storage/????-???? 'where every ?is a capital letter or a digit.
我只是想通了一些东西。至少对于我的 Android 模拟器来说,我的 SD 卡路径像' /storage/????-???? '每一处?是大写字母或数字。
So, if /storage/directory has a directory which is readable and that is not the internal storage directory, it must be the SD Card.
所以,如果/storage/目录中有一个可读的目录不是内部存储目录,那么它一定是SD卡。
My code worked on my android emulator!
我的代码适用于我的 android 模拟器!
String removableStoragePath;
File fileList[] = new File("/storage/").listFiles();
for (File file : fileList)
{ if(!file.getAbsolutePath().equalsIgnoreCase(Environment.getExternalStorageDirectory().getAbsolutePath()) && file.isDirectory() && file.canRead())
removableStoragePath = file.getAbsolutePath(); }
//If there is an SD Card, removableStoragePath will have it's path. If there isn't it will be an empty string.
If there is an SD Card, removableStoragePathwill have it's path. If there isn't it will be an empty string.
如果有 SD 卡,则可移动存储路径将有它的路径。如果没有,它将是一个空字符串。
回答by Mahadev Mane
I have got solution on this after 4 days, Please note following points while giving path to File class in Android(Java):
我在 4 天后得到了解决方案,请注意以下几点,同时在 Android(Java) 中提供 File 类的路径:
- Use path for internal storage String
path="/storage/sdcard0/myfile.txt";
- use path for external storage
path="/storage/sdcard1/myfile.txt";
- mention permissions in Manifest file.
- 使用内部存储字符串的路径
path="/storage/sdcard0/myfile.txt";
- 使用外部存储路径
path="/storage/sdcard1/myfile.txt";
- 在清单文件中提及权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- First check file length for confirmation.
- Check paths in ES File Explorer regarding sdcard0 & sdcard1 is this same or else...
- 首先检查文件长度进行确认。
- 检查 ES 文件资源管理器中关于 sdcard0 和 sdcard1 的路径是否相同,否则...
e.g.:
例如:
File file = new File(path);
long = file.length();//in Bytes