我正在开发文件管理器应用。我希望向用户显示内部存储和SD卡存储(如果存在)。对于内部存储,我使用Environment.getExternalStorageDirectory().getPath()
。我如何获得SD存储?
答案 0 :(得分:6)
不确定这个解决方案是否符合文件管理器,但经过多年努力获得正确的代码,这是我最近的一个:
/**
* Returns 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 standard way to get it.
*
* @return paths to all available SD-Cards in the system (include emulated)
*/
public static String[] getStorageDirectories(Context pContext)
{
// Final set of paths
final Set<String> rv = new HashSet<>();
//Get primary & secondary external device storage (internal storage & micro SDCARD slot...)
File[] listExternalDirs = ContextCompat.getExternalFilesDirs(pContext, null);
for(int i=0;i<listExternalDirs.length;i++){
if(listExternalDirs[i] != null) {
String path = listExternalDirs[i].getAbsolutePath();
int indexMountRoot = path.indexOf("/Android/data/");
if(indexMountRoot >= 0 && indexMountRoot <= path.length()){
//Get the root path for the external directory
rv.add(path.substring(0, indexMountRoot));
}
}
}
return rv.toArray(new String[rv.size()]);
}
答案 1 :(得分:4)
如果您只使用Android 4.0 +。这些答案可以帮助您:
how-can-i-get-external-sd-card-path-for-android-4-0
答案中的一些代码示例:
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;
}
这里的另一个答案。
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()]);
}
第三个答案是:
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");
}
}
}
}
答案 2 :(得分:3)
与上面的代码相似但没有编码“/ Android / data”
public List<File> getAllStorageLocations() {
List<File> storageLocations = new ArrayList<>();
File storageDir = Environment.getExternalStorageDirectory();
String storagePath = storageDir.getAbsolutePath();
File[] extFileDirs = getContext().getExternalFilesDirs(null);
String suffixToStrip = null;
for (File nextFile : extFileDirs) {
String nextPath = nextFile.getAbsolutePath();
if (nextPath.startsWith(storagePath)) {
suffixToStrip = nextPath.substring(storagePath.length());
break;
}
}
if (suffixToStrip != null) {
for (File nextFile : extFileDirs) {
String nextPath = nextFile.getAbsolutePath();
int stripIndex = nextPath.lastIndexOf(suffixToStrip);
if (stripIndex > -1) {
File path = new File(nextPath.substring(0, stripIndex));
storageLocations.add(path);
}
}
}
if (storageLocations.size() == 0) {
storageLocations.add(storageDir);
}
return storageLocations;
}
答案 3 :(得分:0)
试试这个,从根文件夹迭代。
File rootFolder = new File("/");
boolean isSdcardRemovable = false;
String path = null;
loop:
for(int i=0; i<rootFolder.listFiles().length; i++) {
if(rootFolder.listFiles()[i].listFiles() != null &&
!rootFolder.listFiles()[i].toString().contains("system") &&
!rootFolder.listFiles()[i].toString().contains("etc") &&
!rootFolder.listFiles()[i].toString().contains("dev") ) {
File dataDir = new File(Environment.getDataDirectory().getAbsolutePath());
long dataDirSize = dataDir.getFreeSpace()/(1000*1000);
long folderSize = rootFolder.listFiles()[i].getFreeSpace()/(1000*1000);
if(dataDirSize == folderSize || (dataDirSize > folderSize &&
folderSize > (dataDirSize-80))) {
System.err.println("INTERNAL1 "+rootFolder.listFiles()[i]);
System.err.println(dataDirSize);
System.err.println(folderSize);
}
else {
File rootSubFolder1 = new File(rootFolder.listFiles()[i].getAbsolutePath());
if(rootSubFolder1.listFiles() != null) {
for(int j=0; j<rootSubFolder1.listFiles().length; j++) {
if(rootSubFolder1.listFiles()[j].getTotalSpace() != 0 &&
rootSubFolder1.listFiles()[j].getFreeSpace() != 0 &&
rootSubFolder1.listFiles()[j].listFiles() != null) {
Log.i(TAG, "" + rootSubFolder1.listFiles()[j]);
if(rootSubFolder1.listFiles()[j].toString().contains("sdcard") ||
rootSubFolder1.listFiles()[j].toString().contains("storage") ||
rootSubFolder1.listFiles()[j].toString().contains("mnt")) {
folderSize = rootSubFolder1.listFiles()[j].getFreeSpace()/(1000*1000);
if(dataDirSize == folderSize || (dataDirSize > folderSize &&
folderSize > (dataDirSize-80))) {
System.err.println("INTERNAL2 " + rootSubFolder1.listFiles()[j]);
System.err.println(dataDirSize);
System.err.println(folderSize);
}
else {
int pos = rootSubFolder1.listFiles()[j].getAbsolutePath().lastIndexOf('/');
String str = rootSubFolder1.listFiles()[j].getAbsolutePath().substring(pos+1);
if(str.matches("(sd|ext|3039|m_external_sd).*")) {
isSdcardRemovable = true;
System.err.println("EXTERNAL "+rootSubFolder1.listFiles()[j]);
System.err.println(dataDirSize);
System.err.println(folderSize);
path = rootSubFolder1.listFiles()[j].getAbsolutePath()+"/";
break loop;
}
}
}
}
}
}
}
}
}
if(isSdcardRemovable) {
if(path != null) {
getMemoryDetails(path);
finish();
}
else {
saveResult("fail", "External memory not found.");
Log.e(TAG, "External memory not found.");
finish();
}
} else {
saveResult("fail", "External memory not available.");
Log.e(TAG, "External memory not available.");
finish();
}