Rom*_*'ai 91 android android-sdcard
三星Galaxy S3有一个extrenal SD卡插槽,安装到/mnt/extSdCard
.
我的问题是:如何通过类似的方式获得这条路径Environment.getExternalStorageDirectory()
?这将返回mnt/sdcard
,我找不到外部SD卡的API.(或某些平板电脑上的可移动USB存储器)
谢谢!
Gna*_*nic 56
我对这里找到的解决方案有所不同
public static HashSet<String> getExternalMounts() {
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);
}
}
}
}
return out;
}
Run Code Online (Sandbox Code Playgroud)
原始方法经过测试和使用
我不确定它们在测试时会使用哪个Android版本.
我已经测试了我的修改版本
以及一些使用SD卡作为主存储的单个存储设备
除了令人难以置信的所有这些设备只返回其可移动存储.我可能会做一些额外的检查,但这至少比我迄今为止找到的任何解决方案都要好一些.
小智 53
我找到了更可靠的方法来获取系统中所有SD-CARD的路径.这适用于所有Android版本并返回所有存储的路径(包括模拟).
在我的所有设备上正常工作.
PS:基于Environment类的源代码.
private static final Pattern DIR_SEPORATOR = Pattern.compile("/");
/**
* Raturns all available SD-Cards in the system (include emulated)
*
* Warning: Hack! Based on Android source code of version 4.3 (API 18)
* Because there is no standart way to get it.
* TODO: Test on future Android versions 4.4+
*
* @return paths to all available SD-Cards in the system (include emulated)
*/
public static String[] getStorageDirectories()
{
// Final set of paths
final Set<String> rv = new HashSet<String>();
// Primary physical SD-CARD (not emulated)
final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
// All Secondary SD-CARDs (all exclude primary) separated by ":"
final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
// Primary emulated SD-CARD
final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
if(TextUtils.isEmpty(rawEmulatedStorageTarget))
{
// Device has physical external storage; use plain paths.
if(TextUtils.isEmpty(rawExternalStorage))
{
// EXTERNAL_STORAGE undefined; falling back to default.
rv.add("/storage/sdcard0");
}
else
{
rv.add(rawExternalStorage);
}
}
else
{
// Device has emulated storage; external storage paths should have
// userId burned into them.
final String rawUserId;
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
{
rawUserId = "";
}
else
{
final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
final String[] folders = DIR_SEPORATOR.split(path);
final String lastFolder = folders[folders.length - 1];
boolean isDigit = false;
try
{
Integer.valueOf(lastFolder);
isDigit = true;
}
catch(NumberFormatException ignored)
{
}
rawUserId = isDigit ? lastFolder : "";
}
// /storage/emulated/0[1,2,...]
if(TextUtils.isEmpty(rawUserId))
{
rv.add(rawEmulatedStorageTarget);
}
else
{
rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
}
}
// Add all secondary storages
if(!TextUtils.isEmpty(rawSecondaryStoragesStr))
{
// All Secondary SD-CARDs splited into array
final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
Collections.addAll(rv, rawSecondaryStorages);
}
return rv.toArray(new String[rv.size()]);
}
Run Code Online (Sandbox Code Playgroud)
Fab*_*ook 32
我想使用你需要使用的外部SD卡:
new File("/mnt/external_sd/")
Run Code Online (Sandbox Code Playgroud)
要么
new File("/mnt/extSdCard/")
Run Code Online (Sandbox Code Playgroud)
在你的情况下......
取代 Environment.getExternalStorageDirectory()
适合我.您应该首先检查目录mnt中的内容,然后从那里开始工作.
您应该使用某种类型的选择方法来选择使用哪个SD卡:
File storageDir = new File("/mnt/");
if(storageDir.isDirectory()){
String[] dirList = storageDir.list();
//TODO some type of selecton method?
}
Run Code Online (Sandbox Code Playgroud)
Pao*_*lli 15
要检索所有外部存储(无论是SD卡还是内部不可移动存储),您可以使用以下代码:
final String state = Environment.getExternalStorageState();
if ( Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) ) { // we can read the External Storage...
//Retrieve the primary External Storage:
final File primaryExternalStorage = Environment.getExternalStorageDirectory();
//Retrieve the External Storages root directory:
final String externalStorageRootDir;
if ( (externalStorageRootDir = primaryExternalStorage.getParent()) == null ) { // no parent...
Log.d(TAG, "External Storage: " + primaryExternalStorage + "\n");
}
else {
final File externalStorageRoot = new File( externalStorageRootDir );
final File[] files = externalStorageRoot.listFiles();
for ( final File file : files ) {
if ( file.isDirectory() && file.canRead() && (file.listFiles().length > 0) ) { // it is a real directory (not a USB drive)...
Log.d(TAG, "External Storage: " + file.getAbsolutePath() + "\n");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用System.getenv("EXTERNAL_STORAGE")来检索主外部存储目录(例如"/ storage/sdcard0")和System.getenv("SECONDARY_STORAGE")以查找所有辅助目录的列表(例如"/storage/extSdCard:/ storage/UsbDriveA:/ storage/UsbDriveB").请记住,同样在这种情况下,您可能希望过滤辅助目录列表以排除USB驱动器.
在任何情况下,请注意使用硬编码路径始终是一种不好的方法(特别是当每个制造商可能会高兴地改变它时).
Hen*_*aWD 14
我正在使用Dmitriy Lozenko的解决方案,直到我检查了Asus Zenfone2,Marshmallow 6.0.1并且该解决方案无效.获取EMULATED_STORAGE_TARGET时,解决方案失败,特别是对于microSD路径,即:/ storage/F99C-10F4 /.我编辑了代码以直接从模拟的应用程序路径获取模拟的根路径,context.getExternalFilesDirs(null);
并添加更多已知的特定于电话模型的物理路径.
为了让我们的生活更轻松,我在这里建了一个图书馆.您可以通过gradle,maven,sbt和leiningen构建系统使用它.
如果你喜欢老式的方式,你也可以直接从这里复制粘贴文件,但是如果没有手动检查,你将不知道将来是否有更新.
如果您有任何问题或建议,请告诉我
Jef*_*key 13
好消息!在KitKat中,现在有一个用于与这些辅助共享存储设备交互的公共API.
新的Context.getExternalFilesDirs()
和Context.getExternalCacheDirs()
方法可以返回多个路径,包括主设备和辅助设备.然后,您可以迭代它们并检查Environment.getStorageState()
并File.getFreeSpace()
确定存储文件的最佳位置.这些方法也可以ContextCompat
在support-v4库中找到.
另请注意,如果您只对使用返回的目录感兴趣,则Context
不再需要READ_
或WRITE_EXTERNAL_STORAGE
权限.展望未来,您将始终拥有对这些目录的读/写访问权限,而无需其他权限.
应用还可以通过终止其权限请求继续处理旧设备,如下所示:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
Run Code Online (Sandbox Code Playgroud)
我做了以下操作来访问所有外部SD卡.
附:
File primaryExtSd=Environment.getExternalStorageDirectory();
Run Code Online (Sandbox Code Playgroud)
你得到主要外部SD的路径然后:
File parentDir=new File(primaryExtSd.getParent());
Run Code Online (Sandbox Code Playgroud)
您获得主外部存储的父目录,它也是所有外部sd的父目录.现在,您可以列出所有存储并选择所需的存储.
希望它有用.
以下是我获取SD卡路径列表(不包括主外部存储)的方法:
/**
* returns a list of all available sd cards paths, or null if not found.
*
* @param includePrimaryExternalStorage set to true if you wish to also include the path of the primary external storage
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static List<String> getSdCardPaths(final Context context,final boolean includePrimaryExternalStorage)
{
final File[] externalCacheDirs=ContextCompat.getExternalCacheDirs(context);
if(externalCacheDirs==null||externalCacheDirs.length==0)
return null;
if(externalCacheDirs.length==1)
{
if(externalCacheDirs[0]==null)
return null;
final String storageState=EnvironmentCompat.getStorageState(externalCacheDirs[0]);
if(!Environment.MEDIA_MOUNTED.equals(storageState))
return null;
if(!includePrimaryExternalStorage&&VERSION.SDK_INT>=VERSION_CODES.HONEYCOMB&&Environment.isExternalStorageEmulated())
return null;
}
final List<String> result=new ArrayList<>();
if(includePrimaryExternalStorage||externalCacheDirs.length==1)
result.add(getRootOfInnerSdCardFolder(externalCacheDirs[0]));
for(int i=1;i<externalCacheDirs.length;++i)
{
final File file=externalCacheDirs[i];
if(file==null)
continue;
final String storageState=EnvironmentCompat.getStorageState(file);
if(Environment.MEDIA_MOUNTED.equals(storageState))
result.add(getRootOfInnerSdCardFolder(externalCacheDirs[i]));
}
if(result.isEmpty())
return null;
return result;
}
/** Given any file/folder inside an sd card, this will return the path of the sd card */
private static String getRootOfInnerSdCardFolder(File file)
{
if(file==null)
return null;
final long totalSpace=file.getTotalSpace();
while(true)
{
final File parentFile=file.getParentFile();
if(parentFile==null||parentFile.getTotalSpace()!=totalSpace)
return file.getAbsolutePath();
file=parentFile;
}
}
Run Code Online (Sandbox Code Playgroud)
感谢你们提供的线索,特别是@SmartLemon,我得到了解决方案.如果其他人需要它,我把我的最终解决方案放在这里(找到第一个列出的外部SD卡):
public File getExternalSDCardDirectory()
{
File innerDir = Environment.getExternalStorageDirectory();
File rootDir = innerDir.getParentFile();
File firstExtSdCard = innerDir ;
File[] files = rootDir.listFiles();
for (File file : files) {
if (file.compareTo(innerDir) != 0) {
firstExtSdCard = file;
break;
}
}
//Log.i("2", firstExtSdCard.getAbsolutePath().toString());
return firstExtSdCard;
}
Run Code Online (Sandbox Code Playgroud)
如果没有外部SD卡,则返回板载存储.如果sdcard不存在我会使用它,你可能需要更改它.
归档时间: |
|
查看次数: |
166065 次 |
最近记录: |