- Как я могу получить внешний путь SD-карты для Android 4.0+?
- ОТВЕТЫ
- Ответ 1
- Ответ 2
- Ответ 3
- Ответ 4
- Ответ 5
- Ответ 6
- Ответ 7
- Ответ 8
- Ответ 9
- Ответ 10
- Ответ 11
- Ответ 12
- Ответ 13
- Ответ 14
- Ответ 15
- Ответ 16
- Ответ 17
- Ответ 18
- Ответ 19
- Ответ 20
- Ответ 21
- Ответ 22
- Ответ 23
- Ответ 24
- Ответ 25
- Ответ 26
- Получение пути к карте памяти SD Card на Android
- Терминология
- Результаты поиска
- Описание кода
- Пример использования
- Заключение
Как я могу получить внешний путь SD-карты для Android 4.0+?
Samsung Galaxy S3 имеет слот для карт памяти Extrenal SD, который установлен на /mnt/extSdCard .
Мой вопрос: как получить этот путь чем-то вроде Environment.getExternalStorageDirectory() ? Это вернет mnt/sdcard , и я не могу найти API для внешней SD-карты. (Или съемное USB-накопитель на некоторых планшетах)
ОТВЕТЫ
Ответ 1
У меня есть вариация на решение, которое я нашел здесь
Оригинальный метод был протестирован и работал с
- Huawei X3 (запас)
- Galaxy S2 (запас)
- Galaxy S3 (запас)
Я не уверен, какая версия для Android была включена, когда они были протестированы.
Я тестировал измененную версию с помощью
- Moto Xoom 4.1.2 (запас)
- Galaxy Nexus (cyanogenmod 10) с использованием кабеля otg
- HTC Incredible (cyanogenmod 7.2) возвращает как внутренние, так и внешние. Это устройство является чем-то странным в том, что его внутренняя часть в основном не используется, поскольку getExternalStorage() возвращает путь к SD-карте.
и некоторые отдельные устройства хранения, которые используют sdcard в качестве основного хранилища
- HTC G1 (cyanogenmod 6.1)
- HTC G1 (запас)
- HTC Vision/G2 (запас)
За исключением Incredible все эти устройства только вернули свое съемное хранилище. Вероятно, есть некоторые дополнительные проверки, которые я должен делать, но это, по крайней мере, немного лучше любого решения, которое я нашел до сих пор.
Ответ 2
Я нашел более надежный способ получить пути ко всем SD-CARD в системе. Это работает на всех версиях Android и возвращает пути ко всем хранилищам (включая эмулирование).
Работает правильно на всех моих устройствах.
P.S.: На основе исходного кода класса среды.
Ответ 3
Я предполагаю использовать внешнюю SD-карту, которую вы должны использовать:
Работает для меня. Вы должны сначала проверить, что находится в каталоге mnt, и работать там.
Вы должны использовать некоторый тип метода выбора, чтобы выбрать, какую SDCard использовать:
Ответ 4
Чтобы получить все внешние хранилища
Ответ 5
Я использовал решение Дмитрия Лозенко, пока не проверил на Asus Zenfone2, Marshmallow 6.0.1, и решение не работает. Решение не получилось при получении EMULATED_STORAGE_TARGET, в частности, для пути microSD, например: /storage/F99C-10F4/. Я отредактировал код, чтобы получить эмулированные корневые пути непосредственно из эмулируемых путей приложения с помощью context.getExternalFilesDirs(null); и добавить более известные физические пути для конкретной модели телефона.
Чтобы сделать нашу жизнь проще, я создал библиотеку здесь. Вы можете использовать его через систему построения градиентов, maven, sbt и leiningen.
Если вам нравится старомодный способ, вы также можете скопировать вставить файл прямо здесь, но вы не узнаете, есть ли обновление в будущем, не проверив его вручную.
Если у вас есть какие-либо вопросы или предложения, пожалуйста, сообщите мне
Ответ 6
Хорошие новости! В KitKat теперь есть общедоступный API для взаимодействия с этими дополнительными совместно используемыми устройствами хранения.
Новые методы Context.getExternalFilesDirs() и Context.getExternalCacheDirs() могут возвращать несколько путей, включая как первичные, так и вторичные устройства. Затем вы можете перебрать их и проверить Environment.getStorageState() и File.getFreeSpace() , чтобы определить наилучшее место для хранения ваших файлов. Эти методы также доступны на ContextCompat в библиотеке support-v4.
Также обратите внимание, что если вы заинтересованы в использовании каталогов, возвращаемых Context , вам больше не нужны разрешения READ_ или WRITE_EXTERNAL_STORAGE . В будущем вы всегда будете иметь доступ на чтение/запись к этим каталогам без каких-либо дополнительных разрешений.
Приложения также могут продолжить работу над более старыми устройствами, выполнив их запрос на разрешение следующим образом:
Ответ 7
Я сделал следующее, чтобы получить доступ ко всем внешним SD-картам.
вы получаете путь к основному внешнему SD Затем с помощью:
вы получаете родительский каталог первичного внешнего хранилища, а также родительский элемент внешнего внешнего sd. Теперь вы можете перечислить все хранилище и выбрать тот, который вы хотите.
Надеюсь, что это полезно.
Ответ 8
Вот как я получаю список путей SD-карты (исключая основное внешнее хранилище):
Ответ 9
Спасибо за подсказки, предоставленные вами, ребята, особенно @SmartLemon, я получил решение. В случае, если кому-то это понадобится, я поставил свое окончательное решение здесь (чтобы найти первую указанную внешнюю SD-карту):
Если на карте нет внешней SD-карты, она возвращает память на борту. Я буду использовать его, если sdcard не существует, возможно, вам придется его изменить.
Ответ 10
обратитесь к моему коду, надейтесь на помощь:
Ответ 11
На самом деле в некоторых устройствах внешнее имя по умолчанию sdcard отображается как extSdCard , а для другого — sdcard1 .
Этот фрагмент кода помогает узнать этот точный путь и помогает найти путь к внешнему устройству.
Ответ 12
Да. Различные производители используют другое имя SDcard, как в Samsung Tab 3, его extsd, а другие устройства samsung используют sdcard, так как этот другой производитель использует разные имена.
У меня было такое же требование, как и вы. поэтому я создал образец примера для вас из моего проекта, перейдя по ссылке Android Directory chooser, в которой используется библиотека androi-dirchooser. В этом примере обнаруживается SD-карта и список всех подпапок, а также определяется, имеет ли устройство более одну SD-карту.
Часть кода выглядит так. Для полного примера перейдите по ссылке Android Directory chooser
Ответ 13
Это решение (собранное из других ответов на этот вопрос) обрабатывает факт (как упоминалось в @ono), что System.getenv(«SECONDARY_STORAGE») бесполезен с Marshmallow.
Протестировано и работает над:
- Samsung Galaxy Tab 2 (Android 4.1.1 — Stock)
- Samsung Galaxy Note 8.0 (Android 4.2.2 — Stock)
- Samsung Galaxy S4 (Android 4.4 — Stock)
- Samsung Galaxy S4 (Android 5.1.1 — Cyanogenmod)
Samsung Galaxy Tab A (Android 6.0.1 — Stock)
Ответ 14
На некоторых устройствах (например, samsung galaxy sII) внутренняя карта памяти mabe находится в vfat. В этом случае используйте последний код, мы получим карту внутренней карты пути (/mnt/sdcad), но не внешнюю карту. Код, приведенный ниже, решает эту проблему.
Ответ 15
Ответ 16
что не верно. /mnt/sdcard/external _sd может существовать, даже если SD-карта не установлена. ваше приложение выйдет из строя, когда вы попытаетесь записать в /mnt/sdcard/external _sd, когда он не установлен.
вам нужно сначала проверить, установлена ли SD-карта, используя:
Ответ 17
Я уверен, что этот код наверняка решит ваши проблемы. Это отлично работает для меня. \
Ответ 18
Для доступа к файлам на SD-карте, на моем HTC One X (Android), я использую этот путь:
Обратите внимание на триплекс «/»!
Ответ 19
Ответ 20
Вы можете использовать что-то вроде Context.getExternalCacheDirs() или Context.getExternalFilesDirs() или Context.getObbDirs(). Они предоставляют конкретные каталоги приложений во всех внешних устройствах хранения, где приложение может хранить свои файлы.
Так что-то вроде этого: Context.getExternalCacheDirs() [i].getParentFile(). getParentFile(). getParentFile(). getParent() может получить корневой путь внешних устройств хранения.
Я знаю, что эти команды предназначены для другой цели, но другие ответы мне не помогли.
Ответ 21
System.getenv(«SECONDARY_STORAGE») возвращает значение null для Marshmallow. Это еще один способ найти все внешние источники. Вы можете проверить, является ли он съемным, который определяет, будет ли внутренний/внешний
Ответ 22
Это даст путь к внешнему вторичному хранилищу sd.
Ответ 23
Я пробовал решения, предоставленные Дмитрием Лозенко и Gnathonic на моей вкладке Samsung Galaxy Tab S2 (модель: T819Y), но никто не помог мне найдите путь к внешнему каталогу SD-карты. Выполнение команды mount содержало необходимый путь к каталогу внешней SD-карты (т.е./Storage/A5F9-15F4), но он не соответствовал регулярному выражению, поэтому он не возвращался. Я не получаю механизм именования каталогов, за которым следует Samsung. Почему они отклоняются от стандартов (т.е. Extsdcard) и придумывают что-то действительно подозрительное, как в моем случае (т.е./Storage/A5F9-15F4). Есть что-то, чего я не вижу? В любом случае, следующие изменения в регулярном выражении решения Gnathonic помогли мне получить действительный каталог sdcard:
Я не уверен, что это действительное решение, и если он даст результаты для других планшетов Samsung, но на данный момент он исправил мою проблему. Ниже приведен еще один способ получения сменного SD-карты в Android (v6.0). Я тестировал метод с android marshmallow, и он работает. Подход, используемый в нем, очень простой и, безусловно, будет работать и для других версий, но тестирование является обязательным. Некоторое понимание этого будет полезно:
Просьба поделиться, если у вас есть другой подход к решению этой проблемы. Благодаря
Ответ 24
Ответ 25
В Galaxy S3 Android 4.3 путь, который я использую, ./storage/extSdCard/Card/, и он выполняет эту работу. Надеюсь, это поможет,
Ответ 26
Следующие шаги работали для меня. Вам просто нужно написать следующие строки:
В первой строке указывается имя sd-каталога, и вам просто нужно использовать его в методе replace для второй строки. Вторая строка будет содержать путь для внутреннего и съемного sd (/storage/in my case). Мне просто нужен этот путь для моего приложения, но вы можете пойти дальше, если вам это нужно.
Источник
Получение пути к карте памяти SD Card на Android
Разрабатывая приложение для проведения соревнований, я столкнулся с проблемой хранения базы данных. Проблема состояла в том, как мне определить внешнюю карту памяти. В целом поиск в сети точного ответа не дал. Поэтому, объединив все найденные результаты, я собрал свой класс. Если кому интересно, смотрим под катом.
Итак, начнем с теории.
Терминология
Гугл нам говорит, что есть следующие понятия:
- Внутренняя (internal) память — это часть встроенной в телефон карты памяти. При ее использовании по умолчанию папка приложения защищена от доступа других приложений (Using the Internal Storage).
- Внешняя (external) память — это общее «внешнее хранилище», т.е. это может быть как часть встроенной памяти, так и удаляемое устройство. Обычно это часть встроенной памяти, как удаляемое устройство я видел в последний раз на андройде 2.2, где встроенная память была около 2Гб, и подключаемая память становилась внешней (Using the External Storage).
- Удаляемая (removable) память — все хранилища, которые могут быть удалены из устройства без «хирургических» вмешательств.
До версии KitKat 4.4 API не предоставляло функционала для получения путей к внешней памяти. Начиная с этой версии (API 19) появилась функция public abstract File[] getExternalFilesDirs (String type), которая возвращает массив строк с путями к внутренней и внешней памяти. Но как же быть с нашей SD Card, которая вставлена в слот? Путь к ней мы опять не можем получить.
Результаты поиска
Чтобы ответить на поставленный вопрос я обратился к всезнающему гуглу. Но и он мне не дал четкого ответа. Было рассмотрено множество вариантов определения от использования стандартных функций, которые ведут к внешней памяти, но ничего общего с удаляемыми устройствами хранения данных они не имеют, до обработки правил монтирования устройств (Android же на ядре Linux работает). В последних случаях были использованы «зашитые» пути к папке с примонтироваными устройствами (в различных версиях эта директория разная). Не стоит забывать, что от версии к версии правила монтирования меняются.
В конечном итоге я решил объединить все полученные знания и написал свой класс, который может нам вернуть пути к внешним и удаляемым устройствам.
Описание кода
Был создан класс MountDevice, который содержит в себе путь к устройству, тип устройства и некий хэш.
Типов устройств выделено два (внутреннюю память я не стал трогать, так как к ней доступ можно получить через API системы).
И был создан класс StorageHelper, который и осуществляет поиск доступных карт памяти.
В классе StorageHelper реализовано два способа поиска — через системное окружение (Environment) и с использованием утилиты Linux mount, а точнее результата ее выполнения.
Способ первый — Environment
При работе с окружением я использую стандартную функцию getExternalStorageDirectory() для получения информации о внешней памяти. Чтобы получить информацию о удаляемой памяти, я использую переменную окружения «SECONDARY_STORAGE«.
Внешняя память всегда одна и обычно всегда есть, поэтому проверяем ее на читаемость, вычисляем хэш и запоминаем. Удаляемой памяти может быть много, поэтому необходимо полученную строку разбить по разделителю и проверять каждое значение.
Вариант решения взят со stackoverflow. Ответ где-то там внизу.
Способ второй — mount
Так как у меня долго не получалось заставить систему мне сказать путь к удаляемой памяти, я решил искать в сторону примонтированных устройств. В системе есть файлы конфигурации, в которых описаны правила монтирования внешних устройств. Все бы хорошо, но на Android версии 4.* к этому файлу простым смертным доступа нет, поэтому рассматривать этот способ не буду.
Вернемся к утилите mount. При запуске без параметров команда возвращает список смонтированных файловых систем. Удаляемые устройства имеют обычно формат файловой системы FAT, то будем выделять строки, в которых есть характеристика «fat«. Внешняя память будет характеризоваться параметром «fuse«.
Примечание: при использовании такого способа не всегда корректно (скорее всего я что-то не учел) определяются типы смотнтированных устройств. Разницу замечал на разных версиях Android. Поэтому этот способ можно использовать как дополнительный.
Вариант решения взят со stackoverflow. Ответов там несколько примерно одинаковых.
Про дублирование
Многие замечали в директории монтирования устройств такую картину:
И что самое интересно, все это одна и та же внешняя карта памяти. Такое дробление начинается с версии Jelly Bean и сделано это для поддержки многопользовательского режима работы системы. Более подробно тут. И вот, чтобы не получать одну и туже карту памяти как различные устройства, необходим способ определения идентичности. Если бы был доступ к конфигурации монтирования, то и вопросов не было. Но доступа нет. Поэтому я тут подсмотрел решение с расчетом хэша для каждого устройства:
- создаем StringBuilder
- записываем в него общий размер устройства и размер используемого пространства устройства
- обходим содержимое корня устройства
- записываем имя каталога
- записываем имя файла и размер
- вычисляем hash
Пример использования
Заключение
Подробные рассуждения по этому вопросу понимания памяти в Android, некоторые советы можно прочитать тут.
Исходный код всего класса расположен еще нигде не расположен. На днях постараюсь разместить на gitHub.
Источник