Как получить внутренний и внешний SDK-путь в android
Большинство новых устройств Android имеют внутреннюю SD-карту и внешнюю SD-карту. Я хочу создать приложение для проводника файлов, но я не могу узнать, как получить путь к использованию в моем приложении, потому что
File file = Environment.getExternalStorageDirectory();
просто возвращается в большинстве устройств /mnt/sdcard
но есть другой путь для другой внешней SD-карты, например /storage1 or /storage2
, Любая помощь была оценена.
Ответы
Ответ 1
Как получить внутренний и внешний SDK-путь в android
Способы хранения во внутреннем хранилище:
File getDir (String name, int mode)
File getFilesDir ()
Вышеуказанные методы присутствуют в классе Context
Способы сохранения во внутренней памяти телефона:
File getExternalStorageDirectory ()
File getExternalFilesDir (String type)
File getExternalStoragePublicDirectory (String type)
В начале все использовали Environment.getExternalStorageDirectory()
, который указывал на внутреннюю память root. В результате корневой каталог был заполнен случайным контентом.
В дальнейшем эти два метода были добавлены:
В классе Context
они добавили getExternalFilesDir()
, указав на каталог, предназначенный для приложения, в внутренней памяти телефона. Этот каталог и его содержимое будут удалены, когда приложение будет удалено.
Environment.getExternalStoragePublicDirectory()
для централизованных мест для хранения известных типов файлов, таких как фотографии и фильмы. Этот каталог и его содержимое будут удалены NOT, когда приложение будет удалено.
Способы хранения в съемном хранилище, то есть карта micro SD
До уровня API 19 не было официального способа хранения на SD-карте. Но многие могли сделать это, используя неофициальные API.
Официально один метод был введен в классе Context
на уровне API уровня 19 (версия Android 4.4 - Kitkat).
File[] getExternalFilesDirs (String type)
Он возвращает абсолютные пути к каталогам конкретных приложений на всех общие/внешние устройства хранения, в которых приложение может размещать постоянными файлами, которыми он владеет. Эти файлы являются внутренними для приложения, и обычно не видны пользователю как носитель.
Это означает, что он вернет пути к карте Micro SD и внутренней памяти. Как правило, второй возвращенный путь будет местом хранения микро SD-карты.
Внутренняя и внешняя память терминология в соответствии с Google/официальными документами Android отличается от тем, что мы думаем.
Ответ 2
Да. Различные производители используют другое имя SDcard, как в Samsung Tab 3, его extsd, а другие устройства samsung используют sdcard, так как этот другой производитель использует разные имена.
У меня было такое же требование, как и вы. поэтому я создал образец примера для вас из моего проекта, перейдя по ссылке Android Directory chooser, в которой используется библиотека androi-dirchooser. В этом примере обнаруживается SD-карта и список всех подпапок, а также определяется, имеет ли устройство более одну SD-карту.
Часть кода выглядит так. Для полного примера перейдите по ссылке Android Directory chooser
/**
* Returns the path to internal storage ex:- /storage/emulated/0
*
* @return
*/
private String getInternalDirectoryPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
/**
* Returns the SDcard storage path for samsung ex:- /storage/extSdCard
*
* @return
*/
private String getSDcardDirectoryPath() {
return System.getenv("SECONDARY_STORAGE");
}
mSdcardLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String sdCardPath;
/***
* Null check because user may click on already selected buton before selecting the folder
* And mSelectedDir may contain some wrong path like when user confirm dialog and swith back again
*/
if (mSelectedDir != null && !mSelectedDir.getAbsolutePath().contains(System.getenv("SECONDARY_STORAGE"))) {
mCurrentInternalPath = mSelectedDir.getAbsolutePath();
} else {
mCurrentInternalPath = getInternalDirectoryPath();
}
if (mCurrentSDcardPath != null) {
sdCardPath = mCurrentSDcardPath;
} else {
sdCardPath = getSDcardDirectoryPath();
}
//When there is only one SDcard
if (sdCardPath != null) {
if (!sdCardPath.contains(":")) {
updateButtonColor(STORAGE_EXTERNAL);
File dir = new File(sdCardPath);
changeDirectory(dir);
} else if (sdCardPath.contains(":")) {
//Multiple Sdcards show root folder and remove the Internal storage from that.
updateButtonColor(STORAGE_EXTERNAL);
File dir = new File("/storage");
changeDirectory(dir);
}
} else {
//In some unknown scenario at least we can list the root folder
updateButtonColor(STORAGE_EXTERNAL);
File dir = new File("/storage");
changeDirectory(dir);
}
}
});
Ответ 3
Поскольку нет прямого метода для получения путей, решение может быть Сканируйте файл /system/etc/vold.fstab и найдите такие строки: dev_mount sdcard/mnt/sdcard 1 /devices/platform/s 3c-sdhci.0/mmc_host/mmc0
Когда кто-то найден, разделите его на свои элементы, а затем вытащите путь к этой точке монтирования и добавить ее в arraylist
подчеркнутые текстовые устройства пропускают файл vold целиком, поэтому мы добавляем сюда путь чтобы список всегда включал путь к первой SD-карте, будь то настоящие или эмулируемые.
sVold.add("/mnt/sdcard");
try {
Scanner scanner = new Scanner(new File("/system/etc/vold.fstab"));
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.contains("usb"))
continue;
// don't add the default vold path
// it already in the list.
if (!sVold.contains(element))
sVold.add(element);
}
}
} catch (Exception e) {
// swallow - don't care
e.printStackTrace();
}
}
Теперь, когда у нас есть очищенный список путей монтирования, проверьте каждый из них, чтобы сделать
убедитесь, что это действительный и доступный путь. Если это не так, удалите его из
список.
private static void testAndCleanList()
{
for (int i = 0; i < sVold.size(); i++) {
String voldPath = sVold.get(i);
File path = new File(voldPath);
if (!path.exists() || !path.isDirectory() || !path.canWrite())
sVold.remove(i--);
}
}
Ответ 4
Я не уверен, насколько общий ответ на это, но я тестировал его на Motorola XT830C с Android 4.4 и на Nexus 7 android 6.0.1. и на Samsung SM-T530NU Android 5.0.2.
Я использовал System.getenv("SECONDARY_STORAGE")
и Environment.getExternalStorageDirectory().getAbsolutePath()
.
Nexus, у которого нет второй SD-карты, System.getenv
возвращает null и Envirnoment.getExterna...
дает /storage/emulated/ 0.
Устройство Motorola, у которого есть внешняя SD-карта, дает /storage/sdcard 1 для System.getenv("SECONDARY_STORAGE")
и Envirnoment.getExterna...
дает/хранит/эмулирует/0.
Samsumg возвращает /storage/extSdCard для внешней SD.
В моем случае я создаю подкаталог на внешнем месте и использую
appDirectory = (System.getenv("SECONDARY_STORAGE") == null)
? Environment.getExternalStorageDirectory().getAbsolutePath()
: System.getenv("SECONDARY_STORAGE");
чтобы найти sdcard. Создание подкаталога в этом каталоге работает.
Конечно, мне нужно было установить разрешение в файле манифеста для доступа к внешней памяти.
У меня также есть цветной планшет Nook 8 ". Когда я получаю возможность протестировать их, я отправлю сообщение, если у меня возникнут проблемы с этим подходом.
Ответ 5
но есть другой путь для другого внешнего sdcard, например /storage 1 или/storage2
В Android SDK ничего нет - по крайней мере, через Android 4.1 - это дает вам доступ к этим путям. Во всяком случае, они могут быть недоступными для чтения или записи. Поведение таких мест хранения и то, для чего они используются, зависит от производителей устройств.
Ответ 6
Попробуйте этот код, это поможет
Map<String, File> externalLocations = ExternalStorage.getAllStorageLocations();
File sdCard = externalLocations.get(ExternalStorage.SD_CARD);
File externalSdCard = externalLocations.get(ExternalStorage.EXTERNAL_SD_CARD);
Ответ 7
File main=new File(String.valueOf(Environment.getExternalStorageDirectory().getAbsolutePath()));
File[]t=main.getParentFile().listFiles();
for(File dir:t)
{
Log.e("Main",dir.getAbsolutePath());
}
Вывод:
E/Main: /storage/sdcard1
E/Main: /storage/sdcard0
У меня есть одна SD-карта и встроенная память.
Ответ 8
Нет никакого открытого api для получения внутреннего/внешнего SDK-пути.
Но есть платформа api под названием StorageManager в пакете android.os.storage. см. http://goo.gl/QJj1eu.
Есть некоторые функции, такие как хранилище списков, монтирование/размонтирование хранилища, получение состояния монтирования, получение пути к хранилищу и т.д.
Но он скрыт api, и он должен быть устаревшим или сломанным в следующей версии Android.
И некоторым методам требуется специальное разрешение, и большинство из них не документированы.
Ответ 9
мы не можем получить путь, но мы можем создавать файлы на внешних носителях на карте micro sd, например, или читать.
"/mnt/your_external_storage/your_file"
File file = context.getDatabasePath("/mnt/your_external_storage/your_file");
как это может сделать u, но вам нужно положить жестко закодированный.
или проверьте мою ссылку.
База данных SQLite на внешней Micro SD-карте