Не удается создать папку на внешнем хранилище на Android

Мой телефон разработки – Nexus 5 , работающий Android 4.4.2 управлением Android 4.4.2 .

В моем приложении я пытаюсь создать папку на внешнем хранилище, которая будет хранить отладочную информацию для моего приложения. В основном он будет содержать все команды, выполняемые приложением, поэтому, когда пользователь сталкивается с проблемой, у меня есть возможность отправить мне информацию из папки отладки для анализа.

Я начал, пытаясь записать файл в папку, но обнаружил, что возникла ошибка при создании папки. Сначала я использовал mkdir() , затем перешел на mkdirs() который также не работал.

У меня есть <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> в моем манифесте.

Вот код для создания папки:

  File folder = new File(Environment.getExternalStorageDirectory() + "/DebugData"); String path = folder.getPath(); if(!folder.mkdirs() || !folder.exists()){ Log.e(LOG_TAG, path + " failed"); } else { Log.d(LOG_TAG, path + " succeeded"); } 

Вот что я также пробовал:

  //Check SD card state String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) || !Environment.MEDIA_MOUNTED.equals(state)) { Log.e(LOG_TAG, "Error: external storage is read only or unavailable"); } else { Log.d(LOG_TAG, "External storage is not read only or unavailable"); } 

Это возвращает, что внешнее хранилище не доступно для чтения или недоступно.

Я также пробовал разные пути, такие как File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Folder1");

Это стало действительно запутанным.

Я пробовал разработку на разных телефонах. Во-первых, я захватил Galaxy S4 GT-i9505 управлением Android 4.2.2 и он сработал. Мне удалось создать папки и написать им. Это показало мне, что код работает. Также путь, возвращаемый при запуске кода на S4 и Nexus 5, был таким же.

Тогда я подумал, что это может быть версия для Android. Поэтому я захватил Nexus 4 с Android 4.4.2 и код работал над ним. Создал папки и разрешил мне писать им.

Ни один из телефонов не укоренен и не является стандартным. Нет никаких специальных приложений или чего-либо, что я могу думать о настройках на Nexus 5, которые могли бы вызвать проблемы с разрешениями. Соединение установлено на Media Device (MTP).

РЕДАКТИРОВАТЬ:

Я должен добавить, что я пробовал следовать, что также не помогло:

  • Запись файла в корневой каталог внешнего хранилища
  • Создание файла во внешнем корневом каталоге хранилища и запись на него
  • Создание папки в указанном пути и запись в нее файла
  • Создание файла в указанном пути и записи на него

Я смущен тем, что вызывает это, есть ли что-нибудь еще, что я могу проверить или изменить, чтобы исправить проблему?

EDIT 2:

Оказывается, проблема возникла из-за, я думаю, индексации.

В основном все другие устройства, на которых я тестировался, позволили мне снова подключить USB-соединение и просмотреть созданные файлы и папки.

По какой-то причине мой Nexus 5 не индексирует папки / файлы, даже если они существуют.

Я загрузил другое стороннее приложение-проводник файла и заметил, что все папки и файлы были там.

Поэтому для просмотра этих папок и файлов с помощью USB-отладки я должен перезагрузить телефон, чтобы повторно проиндексировать их, что кажется довольно раздражающим, но это лучше, чем вообще не работает.

Благодарю.

Что касается проблемы с индексацией Nexus, это сработало для меня:

 MediaScannerConnection.scanFile(this, new String[] { file.toString() }, null, new MediaScannerConnection.OnScanCompletedListener() { public void onScanCompleted(String path, Uri uri) { Log.i("ExternalStorage", "Scanned " + path + ":"); Log.i("ExternalStorage", "-> uri=" + uri); } }); 

Вы должны называть это сразу после создания и сохранения файла. Используя сканер, я смог видеть только что созданные файлы и каталоги, просто перегружая устройство.

Согласно документам :

MediaScannerConnection предоставляет возможность приложениям передавать вновь созданный или загруженный мультимедийный файл в службу медиаплеера. Служба медиаплеера будет считывать метаданные из файла и добавлять файл к поставщику медиаконтента.

Надеюсь, это поможет кому-то другому.

Оказывается, проблема возникла из-за, я думаю, индексации.

В основном все другие устройства, на которых я тестировался, позволили мне снова подключить USB-соединение и просмотреть созданные файлы и папки.

По какой-то причине мой Nexus 5 не индексирует папки / файлы, даже если они существуют.

Я загрузил другое стороннее приложение-проводник файла и заметил, что все папки и файлы были там.

Поэтому для просмотра этих папок и файлов с помощью USB-отладки я должен перезагрузить телефон, чтобы повторно проиндексировать их, что кажется довольно раздражающим, но это лучше, чем вообще не работает.

Была та же проблема. Оказалось, что я тестировал на Android 6 и не проверял разрешение WRITE_EXTERNAL_STORAGE.

Во-первых, новый File() просто создает объект для подключения к файлу.
Вы хотите использовать этот файл, файл существует или createNewFile() .
Если вы хотите использовать этот файл для создания каталога, проверьте, что файл существует, isDirectory() после этого mkDir() .
Во-вторых, проверьте Environment.getExternalStorageDirectory – переменный путь.
Вы можете использовать DDMS или ADB для работы.
Кроме того, я думаю, вы добавляете разрешение на чтение внешнего хранилища на предмет какой-либо ошибки.

Если вы используете Android-устройство с api> = 23, вам нужно запросить разрешение пользователя перед вызовом функции mkdir (). Мой предыдущий ответ с примером кода можно найти https://stackoverflow.com/a/38694026/5089713

Для android sdk версии 23 и выше вы должны проверить, предоставил ли пользователь разрешение на внешнее хранилище.

 private void createFolder() { if (isStoragePermissionGranted()) { File folder = new File(Environment.getExternalStorageDirectory()+ File.separator + "DebugData"); if(!folder.exists()){ folder.mkdir(); } } public boolean isStoragePermissionGranted() { if (Build.VERSION.SDK_INT >= 23) { if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { return true; } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); return false; } } else { //permission is automatically granted on sdk<23 upon installation return true; } } 

Этот код работал для меня, и я надеюсь, что он сработает для вас.

Обычно я делаю это:

 /** * Return a dedicated directory named "MyApp" at the top of external storage */ public static file getDataDir() { File sdcard = Environment.getExternalStorageDirectory(); if( sdcard == null || !sdcard.isDirectory() ) { // TODO: warning popup Log.w(TAG, "Storage card not found " + sdcard); return null; } File dataDir = new File(sdcard, "MyApp"); if( !confirmDir(dataDir) ) { // TODO: warning popup Log.e(TAG, "Unable to create " + dataDir); return null; } return dataDir; } private static boolean confirmDir(File dir) { if (dir.isDirectory()) return true; // already exists if (dir.exists()) return false; // already exists, but is not a directory return dir.mkdirs(); // create it } 

Кроме того, добавьте это разрешение в свой манифест:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

Если вам требуется частное хранилище (обычно под / data /) для вашего приложения (а не на SD-карте), getDir() , getFilesDir() , fileList() , openFileInput() , openFileOutput() и т. Д.

Существуют также вспомогательные функции для получения частных каталогов в SD-карте для API 8 и выше: getExternalFilesDir() , getExternalCacheDir() и т. Д.

Intereting Posts
Предпочтения разной высоты в пределах PreferenceActivity Android EditText и кнопка на одной строке Тип android.support.v4.app.Fragment не может быть разрешен. Он косвенно ссылается на требуемые файлы .class, Facebook Android External App Install (на SD-карте), перезагрузите аварийные сигналы будильника при повторном монтировании через приемник Запрос CallLog.Calls по дате SpeechRecognizer с Google Search версии 3.6.14.1337016 не может распознавать другие голосовые языки, кроме стандартных Как вы принудительно изменяете ориентацию в тесте на Android Instrumentation? Android: создайте TextView, который мигает при нажатии Событие прослушивания Android onTouch Размер предварительного просмотра для сканера штрих-кода от зрения api Персонализация первой буквы на клавиатуре Android для редактирования Каковы платы за разработку на iOS, Android и WP? PhoneGap: есть ли способ, чтобы клавиатура не изменяла размер представления? Использование arraylist для конечного автомата Android Phonegap приложение – перенос активности на передний план