我一直在嘗試訪問內部和外部的SD卡在Android。我已經嘗試了很多StackOverFlow中可用的代碼,但在大多數或所有Android版本上都不起作用。然後,我找到了兩個解決方案。一個在Kitkat &上面工作,另一個在比Kitkat更低的地方工作。我試圖合併他們兩個,它的工作原理!如何在android中訪問外部存儲(可移動SD卡)?
如果有人比這更好的解決方案,請分享。
我一直在嘗試訪問內部和外部的SD卡在Android。我已經嘗試了很多StackOverFlow中可用的代碼,但在大多數或所有Android版本上都不起作用。然後,我找到了兩個解決方案。一個在Kitkat &上面工作,另一個在比Kitkat更低的地方工作。我試圖合併他們兩個,它的工作原理!如何在android中訪問外部存儲(可移動SD卡)?
如果有人比這更好的解決方案,請分享。
這兩個答案是我合併得到它的工作。
這裏的解決方案,
加入這行代碼在AndroidManifest.xml
從Android獲得權限讀取外部存儲器。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
現在,將此類添加到您的項目中。
public class StoragePath {
File[] getExternalFilesDirs;
/**
* Constructor for KitKat & above
* @param getExternalFilesDirs
*/
public StoragePath(File[] getExternalFilesDirs) {
this.getExternalFilesDirs = getExternalFilesDirs;
}
/**
* Constructor for lower than Kitkat
*
*/
public StoragePath() {
}
public String[] getDeviceStorages() {
List<String> results = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //Method 1 for KitKat & above
File[] externalDirs = getExternalFilesDirs;
for (File file : externalDirs) {
String path = file.getPath().split("/Android")[0];
boolean addPath = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
addPath = Environment.isExternalStorageRemovable(file);
} else {
addPath = Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(file));
}
if (addPath) {
results.add(path);
}
}
}
if (results.isEmpty()) { //Method 2 for all versions
final List<String> out = new ArrayList<>();
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);
}
}
}
}
results.addAll(out);
}
//Below few lines is to remove paths which may not be external memory card, like OTG (feel free to comment them out)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (int i = 0; i < results.size(); i++) {
if (!results.get(i).toLowerCase().matches(".*[0-9a-f]{4}[-][0-9a-f]{4}")) {
Log.d("Tag", results.get(i) + " might not be extSDcard");
results.remove(i--);
}
}
} else {
for (int i = 0; i < results.size(); i++) {
if (!results.get(i).toLowerCase().contains("ext") && !results.get(i).toLowerCase().contains("sdcard")) {
Log.d("Tag", results.get(i) + " might not be extSDcard");
results.remove(i--);
}
}
}
//Get path to the Internal Storage aka ExternalStorageDirectory
final String internalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
results.add(0, internalStoragePath);
String[] storageDirectories = new String[results.size()];
for (int i = 0; i < results.size(); ++i) storageDirectories[i] = results.get(i);
return storageDirectories;
}
}
我們使用這個類,
StoragePath storagePath;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
storagePath = new StoragePath(getExternalFilesDirs(null));
}else {
storagePath = new StoragePath();
}
String[] storages;
storages = storagePath.getDeviceStorages();
String數組storages
現在包含了存儲器的路徑。
如果你真的必須downvote然後至少評論爲什麼如此: )你面對什麼問題?答案中出了什麼問題?也許那時我可以改善缺乏的東西 –
分享此信息以幫助其他想要獲得外部SD卡路徑的人 –
您的問題應該包含合併代碼。你的問題是「什麼是替代方式」。此外,您需要清單權限 –
@ cricket_007我忘記了在答案中添加清單權限。我把合併後的代碼放在答案中,因爲它的工作原理,因爲StackOverFlow有一個選項來回答你自己的問題,我認爲這是最好的。 –