Samsung Galaxy S3 имеет внешний слот для SD-карты, к которому крепится /mnt/extSdCard
.
Как я могу получить этот путь чем-то вроде Environment.getExternalStorageDirectory()
?
Это вернется mnt/sdcard
, и я не могу найти API для внешней SD-карты. (Или съемный USB-накопитель на некоторых планшетах.)
android
android-sdcard
Ромул Уракаги Цай
источник
источник
Ответы:
У меня есть вариант решения, которое я нашел здесь
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; }
Оригинальный метод был протестирован и работал с
Я не уверен, на какой версии Android они были на момент тестирования.
Я тестировал свою модифицированную версию с
и некоторые отдельные устройства хранения, которые используют SD-карту в качестве основного хранилища
За исключением Incredible, все эти устройства вернули только свои съемные накопители. Вероятно, мне следует провести дополнительные проверки, но это, по крайней мере, немного лучше, чем любое решение, которое я нашел до сих пор.
источник
Я нашел более надежный способ получить пути ко всем SD-картам в системе. Это работает на всех версиях 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()]); }
источник
Pattern
для/
System.getenv("SECONDARY_STORAGE")
возвращается/storage/sdcard1
. Это местоположение не существует, но фактическое местоположение есть/storage/42CE-FD0A
, где 42CE-FD0A - серийный номер тома отформатированного раздела.Я думаю, чтобы использовать внешнюю SD-карту, вам нужно использовать это:
new File("/mnt/external_sd/")
ИЛИ
new File("/mnt/extSdCard/")
в твоем случае...
вместо
Environment.getExternalStorageDirectory()
Работает для меня. Вы должны сначала проверить, что находится в каталоге mnt, и работать оттуда ..
Вы должны использовать какой-либо метод выбора, чтобы выбрать, какую SD-карту использовать:
File storageDir = new File("/mnt/"); if(storageDir.isDirectory()){ String[] dirList = storageDir.list(); //TODO some type of selecton method? }
источник
Чтобы получить все внешние хранилища (будь то 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"); } } } }
В качестве альтернативы вы можете использовать System.getenv ("EXTERNAL_STORAGE") для получения первичного каталога внешнего хранилища (например, "/ storage / sdcard0" ) и System.getenv ("SECONDARY_STORAGE") для получения списка всех вторичных каталогов (например, " / хранилище / extSdCard: / хранилище / UsbDriveA: / хранилище / UsbDriveB " ). Помните, что и в этом случае вы можете отфильтровать список дополнительных каталогов, чтобы исключить USB-накопители.
В любом случае, обратите внимание, что использование жестко заданных путей всегда является плохим подходом (особенно когда каждый производитель может изменить его по своему усмотрению).
источник
Я использовал решение Дмитрия Лозенко , пока не проверил Asus Zenfone2 , Marshmallow 6.0.1, и решение не работает. Решение не удалось при получении EMULATED_STORAGE_TARGET , особенно для пути microSD, то есть: / storage / F99C-10F4 / . Я отредактировал код, чтобы получить эмулируемые корневые пути непосредственно из эмулированных путей приложения,
context.getExternalFilesDirs(null);
и добавил больше известных физических путей для конкретных моделей телефонов .Для того, чтобы сделать нашу жизнь проще, я сделал библиотеку здесь . Вы можете использовать его через систему сборки gradle, maven, sbt и leiningen.
Если вам нравится старомодный способ, вы также можете скопировать и вставить файл прямо отсюда , но вы не узнаете, будет ли обновление в будущем, не проверив его вручную.
Если у вас есть вопросы или предложения, дайте мне знать
источник
context.getExternalFilesDirs(null)
вернетсяnull
к одному из файлов, и в следующем цикле будет исключение. Предлагаю добавитьif (file == null) continue;
в качестве первой строчки цикла.Хорошие новости! В 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" />
источник
Я сделал следующее, чтобы получить доступ ко всем внешним SD-картам.
С участием:
File primaryExtSd=Environment.getExternalStorageDirectory();
вы получаете путь к первичной внешней SD Затем с помощью:
File parentDir=new File(primaryExtSd.getParent());
вы получаете родительский каталог первичного внешнего хранилища, а также он является родительским для всех внешних 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||!parentFile.canRead()) return file.getAbsolutePath(); file=parentFile; } }
источник
externalCacheDirs[0].getParentFile().getParentFile().getParentFile().getParentFile().getAbsolutePath()
Это рецепт катастрофы. Если вы делаете это, вы можете просто жестко закодировать нужный путь, поскольку если вы получите каталог кеша с чем-либо, кроме 4 родителей, вы получите NullPointerException или неправильный путь.Спасибо за подсказки, предоставленные вами, особенно @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; }
Если внешней SD-карты нет, то возвращается встроенное хранилище. Я воспользуюсь им, если SD-карты не существует, возможно, вам придется ее поменять.
источник
обратитесь к моему коду, надеюсь, он вам пригодится:
Runtime runtime = Runtime.getRuntime(); Process proc = runtime.exec("mount"); InputStream is = proc.getInputStream(); InputStreamReader isr = new InputStreamReader(is); String line; String mount = new String(); BufferedReader br = new BufferedReader(isr); while ((line = br.readLine()) != null) { if (line.contains("secure")) continue; if (line.contains("asec")) continue; if (line.contains("fat")) {//TF card String columns[] = line.split(" "); if (columns != null && columns.length > 1) { mount = mount.concat("*" + columns[1] + "\n"); } } else if (line.contains("fuse")) {//internal storage String columns[] = line.split(" "); if (columns != null && columns.length > 1) { mount = mount.concat(columns[1] + "\n"); } } } txtView.setText(mount);
источник
На самом деле на некоторых устройствах имя внешней SD-карты по умолчанию отображается как
extSdCard
и для другихsdcard1
.Этот фрагмент кода помогает узнать этот точный путь и помогает получить путь к внешнему устройству.
String sdpath,sd1path,usbdiskpath,sd0path; if(new File("/storage/extSdCard/").exists()) { sdpath="/storage/extSdCard/"; Log.i("Sd Cardext Path",sdpath); } if(new File("/storage/sdcard1/").exists()) { sd1path="/storage/sdcard1/"; Log.i("Sd Card1 Path",sd1path); } if(new File("/storage/usbcard1/").exists()) { usbdiskpath="/storage/usbcard1/"; Log.i("USB Path",usbdiskpath); } if(new File("/storage/sdcard0/").exists()) { sd0path="/storage/sdcard0/"; Log.i("Sd Card0 Path",sd0path); }
источник
Да. Разные производители используют разные имена SD-карт, например, в Samsung Tab 3 его extsd, а другие устройства Samsung используют SD-карту, как этот другой производитель использует разные имена.
У меня было такое же требование, как и у вас. поэтому я создал для вас пример из моего проекта, перейдите по этой ссылке Пример выбора каталога Android, который использует библиотеку 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); } } });
источник
Это решение (собранное из других ответов на этот вопрос) обрабатывает факт (как упоминается @ono), который
System.getenv("SECONDARY_STORAGE")
бесполезен для Marshmallow.Проверено и работает:
Samsung Galaxy Tab A (Android 6.0.1 - стоковый)
/** * Returns all available external SD-Card roots in the system. * * @return paths to all available external SD-Card roots in the system. */ public static String[] getStorageDirectories() { String [] storageDirectories; String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { List<String> results = new ArrayList<String>(); File[] externalDirs = applicationContext.getExternalFilesDirs(null); for (File file : externalDirs) { String path = file.getPath().split("/Android")[0]; if((Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Environment.isExternalStorageRemovable(file)) || rawSecondaryStoragesStr != null && rawSecondaryStoragesStr.contains(path)){ results.add(path); } } storageDirectories = results.toArray(new String[0]); }else{ final Set<String> rv = new HashSet<String>(); if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) { final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator); Collections.addAll(rv, rawSecondaryStorages); } storageDirectories = rv.toArray(new String[rv.size()]); } return storageDirectories; }
источник
rawSecondaryStoragesStr.contains(path)
может разрешить добавление внутренней памяти; мы можем лучше удалить это условие .. Я столкнулся с этой проблемой, так как мое устройство возвращает каталог внутренней памяти сSystem.getenv("SECONDARY_STORAGE")
, но возвращает путь к внешней карте памяти с помощьюSystem.getenv(EXTERNAL_STORAGE)
KitKat; похоже, что разные поставщики реализовали это по-разному, без какого-либо проклятого стандарта ..На некоторых устройствах (например samsung galaxy sII) внутренняя карта памяти mabe должна быть в vfat. В этом случае используйте последний код, мы получаем путь к внутренней карте памяти (/ mnt / sdcad), но без внешней карты. Код ниже решает эту проблему.
static String getExternalStorage(){ String exts = Environment.getExternalStorageDirectory().getPath(); try { FileReader fr = new FileReader(new File("/proc/mounts")); BufferedReader br = new BufferedReader(fr); String sdCard=null; String line; while((line = br.readLine())!=null){ if(line.contains("secure") || line.contains("asec")) continue; if(line.contains("fat")){ String[] pars = line.split("\\s"); if(pars.length<2) continue; if(pars[1].equals(exts)) continue; sdCard =pars[1]; break; } } fr.close(); br.close(); return sdCard; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
источник
File[] files = null; File file = new File("/storage");// /storage/emulated if (file.exists()) { files = file.listFiles(); } if (null != files) for (int j = 0; j < files.length; j++) { Log.e(TAG, "" + files[j]); Log.e(TAG, "//--//--// " + files[j].exists()); if (files[j].toString().replaceAll("_", "") .toLowerCase().contains("extsdcard")) { external_path = files[j].toString(); break; } else if (files[j].toString().replaceAll("_", "") .toLowerCase() .contains("sdcard".concat(Integer.toString(j)))) { // external_path = files[j].toString(); } Log.e(TAG, "--///--///-- " + external_path); }
источник
Я уверен, что этот код обязательно решит ваши проблемы ... У меня все работает ... \
try { File mountFile = new File("/proc/mounts"); usbFoundCount=0; sdcardFoundCount=0; if(mountFile.exists()) { Scanner usbscanner = new Scanner(mountFile); while (usbscanner.hasNext()) { String line = usbscanner.nextLine(); if (line.startsWith("/dev/fuse /storage/usbcard1")) { usbFoundCount=1; Log.i("-----USB--------","USB Connected and properly mounted---/dev/fuse /storage/usbcard1" ); } } } if(mountFile.exists()){ Scanner sdcardscanner = new Scanner(mountFile); while (sdcardscanner.hasNext()) { String line = sdcardscanner.nextLine(); if (line.startsWith("/dev/fuse /storage/sdcard1")) { sdcardFoundCount=1; Log.i("-----USB--------","USB Connected and properly mounted---/dev/fuse /storage/sdcard1" ); } } } if(usbFoundCount==1) { Toast.makeText(context,"USB Connected and properly mounted", 7000).show(); Log.i("-----USB--------","USB Connected and properly mounted" ); } else { Toast.makeText(context,"USB not found!!!!", 7000).show(); Log.i("-----USB--------","USB not found!!!!" ); } if(sdcardFoundCount==1) { Toast.makeText(context,"SDCard Connected and properly mounted", 7000).show(); Log.i("-----SDCard--------","SDCard Connected and properly mounted" ); } else { Toast.makeText(context,"SDCard not found!!!!", 7000).show(); Log.i("-----SDCard--------","SDCard not found!!!!" ); } }catch (Exception e) { e.printStackTrace(); }
источник
это не правда. / mnt / sdcard / external_sd может существовать, даже если SD-карта не подключена. ваше приложение выйдет из строя при попытке записи в / mnt / sdcard / external_sd, когда оно не смонтировано.
вам нужно сначала проверить, смонтирована ли SD-карта, используя:
boolean isSDPresent = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
источник
getExternalStorageState()
Я думаю, это бессмысленно, когда возвращает внутреннее хранилище, а не внешнюю SD-карту.String path = Environment.getExternalStorageDirectory() + File.separator + Environment.DIRECTORY_PICTURES; File dir = new File(path);
источник
Вы можете использовать что-то вроде - Context.getExternalCacheDirs () или Context.getExternalFilesDirs () или Context.getObbDirs (). Они предоставляют каталоги для конкретных приложений на всех внешних устройствах хранения, где приложение может хранить свои файлы.
Примерно так - Context.getExternalCacheDirs () [i] .getParentFile (). GetParentFile (). GetParentFile (). GetParent () может получить корневой путь к внешним устройствам хранения.
Я знаю, что эти команды предназначены для другой цели, но другие ответы мне не помогли.
Эта ссылка дала мне хорошие указатели - https://possiblemobile.com/2014/03/android-external-storage/
источник
System.getenv("SECONDARY_STORAGE")
возвращает null для Marshmallow. Это еще один способ найти все внешние каталоги. Вы можете проверить, является ли он съемным, который определяет, является ли внутренний / внешнийif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { File[] externalCacheDirs = context.getExternalCacheDirs(); for (File file : externalCacheDirs) { if (Environment.isExternalStorageRemovable(file)) { // It's a removable storage } } }
источник
Я пробовал решения, предоставленные Дмитрием Лозенко и Gnathonic на моем Samsung Galaxy Tab S2 (модель: T819Y), но ни одно не помогло мне получить путь к внешней директории SD-карты.
mount
выполнение команды содержало требуемый путь к внешней директории SD-карты (например, / Storage / A5F9-15F4), но не соответствовало регулярному выражению, поэтому не было возвращено. Я не понимаю механизма именования каталогов, за которым следует Samsung. Почему они отклоняются от стандартов (например, extsdcard) и придумывают что-то действительно подозрительное, как в моем случае (например, / Storage / A5F9-15F4) . Что мне не хватает? В любом случае, после изменений в регулярном выражении Gnathonic's решение помогло мне получить действительный каталог SDCard:final HashSet<String> out = new HashSet<String>(); String reg = "(?i).*(vold|media_rw).*(sdcard|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;
Я не уверен, что это правильное решение и даст ли оно результаты для других планшетов Samsung, но на данный момент оно устранило мою проблему. Ниже приведен еще один метод получения пути к съемной SD-карте в Android (v6.0). Я протестировал метод с зефиром Android, и он работает. Подход, используемый в нем, очень прост и, безусловно, будет работать и для других версий, но тестирование обязательно. Некоторое понимание этого будет полезно:
public static String getSDCardDirPathForAndroidMarshmallow() { File rootDir = null; try { // Getting external storage directory file File innerDir = Environment.getExternalStorageDirectory(); // Temporarily saving retrieved external storage directory as root // directory rootDir = innerDir; // Splitting path for external storage directory to get its root // directory String externalStorageDirPath = innerDir.getAbsolutePath(); if (externalStorageDirPath != null && externalStorageDirPath.length() > 1 && externalStorageDirPath.startsWith("/")) { externalStorageDirPath = externalStorageDirPath.substring(1, externalStorageDirPath.length()); } if (externalStorageDirPath != null && externalStorageDirPath.endsWith("/")) { externalStorageDirPath = externalStorageDirPath.substring(0, externalStorageDirPath.length() - 1); } String[] pathElements = externalStorageDirPath.split("/"); for (int i = 0; i < pathElements.length - 1; i++) { rootDir = rootDir.getParentFile(); } File[] files = rootDir.listFiles(); for (File file : files) { if (file.exists() && file.compareTo(innerDir) != 0) { // Try-catch is implemented to prevent from any IO exception try { if (Environment.isExternalStorageRemovable(file)) { return file.getAbsolutePath(); } } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception ex) { ex.printStackTrace(); } return null; }
Пожалуйста, поделитесь, если у вас есть другой подход к решению этой проблемы. Благодарность
источник
String secStore = System.getenv("SECONDARY_STORAGE"); File externalsdpath = new File(secStore);
Это получит путь к внешнему вторичному хранилищу SD.
источник
//manifest file outside the application tag //please give permission write this //<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> File file = new File("/mnt"); String[] fileNameList = file.list(); //file names list inside the mnr folder String all_names = ""; //for the log information String foundedFullNameOfExtCard = ""; // full name of ext card will come here boolean isExtCardFounded = false; for (String name : fileNameList) { if (!isExtCardFounded) { isExtCardFounded = name.contains("ext"); foundedFullNameOfExtCard = name; } all_names += name + "\n"; // for log } Log.d("dialog", all_names + foundedFullNameOfExtCard);
источник
Для доступа к файлам на моей SD-карте в HTC One X (Android) я использую этот путь:
file:///storage/sdcard0/folder/filename.jpg
Обратите внимание на тройной знак "/"!
источник
В Galaxy S3 Android 4.3 я использую путь ./storage/extSdCard/Card/, и он выполняет свою работу. Надеюсь, это поможет,
источник
Следующие шаги сработали для меня. Вам просто нужно написать эти строки:
String sdf = new String(Environment.getExternalStorageDirectory().getName()); String sddir = new String(Environment.getExternalStorageDirectory().getPath().replace(sdf,""));
В первой строке будет указано имя каталога sd, и вам просто нужно использовать его в методе замены для второй строки. Вторая строка будет содержать путь к внутреннему и съемному sd (в моем случае / storage /) . Мне просто нужен этот путь для моего приложения, но вы можете пойти дальше, если вам это нужно.
источник