Intereting Posts
Как автоматически настроить размер шрифта в панели инструментов панели действий на основе ориентации? Android 6.0 Marshmallow: странная ошибка с анимацией фрагментов Android Intent Не удается разрешить конструктор Android не освобождает Bitmap из памяти Захват звука для анализа и визуализации частот в Android SQLite – вставка строки с новыми строками в базу данных из файла csv Android: что такое inputType для имени пользователя Полученный токен доступа: null. Com.google.android.gms.auth.GoogleAuthException: Неизвестно Запуск Android-телефона в качестве стабильного веб-сервера (для сценария CGI Python) Любое имя страны в текущем стандартном локали Как запустить код в фоновом режиме, даже если экран выключен? Android не может подключиться к серверу SignalR через WiFi / LAN, а через 3G Сделать вывод ящика навигации за панель состояния Google Play: в вашем приложении были найдены SDK объявлений Я получаю намерение INSTALL_REFERRER из магазина приложений amazon?

Android не может создать файл в каталоге dir getExternalStoragePublicDirectory ()

Я пытаюсь скопировать свои собственные сигналы тревоги в систему Android, следуя этим объяснениям и этому коду .

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

Это мой AndroidManifest (я поместил внешний тег приложения WRITE_EXTERNAL_STORAGE, как указано здесь ):

... <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application... 

И это мой код. Он запускается в новом потоке, начиная с onCreate моего основного действия. Метод «void onFirstTime ()» вызывается из этого нового потока, и этот метод неоднократно вызывает «void copyRawRingtone (File dstPath, int resId)»:

 void copyRawRingtone(File dstPath, int resId) { final String fileName = getResources().getResourceEntryName(resId) + ".mp3"; File dstFile = new File(dstPath, fileName); if (!dstFile.exists()) { InputStream srcStream = getResources().openRawResource(resId); FileOutputStream dstStream = null; try { dstFile.createNewFile(); // THIS THROWS THE EXCEPTION dstStream = new FileOutputStream(dstFile); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = srcStream.read(buffer)) > 0) { dstStream.write(buffer, 0, bytesRead); } // Set the file metadata final String mimeType = "audio/mpeg"; final String dstAbsPath = dstFile.getAbsolutePath(); ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.MediaColumns.DATA, dstAbsPath); contentValues.put(MediaStore.MediaColumns.TITLE, fileName); contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType); contentValues.put(MediaStore.Audio.Media.IS_ALARM, true); contentValues.put(MediaStore.Audio.Media.IS_NOTIFICATION, false); contentValues.put(MediaStore.Audio.Media.IS_RINGTONE, false); contentValues.put(MediaStore.Audio.Media.IS_MUSIC, false); // Add the metadata to the file in the database Uri contentUri = MediaStore.Audio.Media.getContentUriForPath(dstAbsPath); Uri newUri = getContentResolver().insert(contentUri, contentValues); // Tell the media scanner about the new ringtone MediaScannerConnection.scanFile( this, new String[]{newUri.toString()}, new String[]{mimeType}, null ); } catch (Exception e) { e.printStackTrace(); } finally { if (dstStream != null) { try { dstStream.close(); } catch (IOException e) { e.printStackTrace(); } } } try { srcStream.close(); } catch (IOException e) { e.printStackTrace(); } } } // First time initialization (called in a new thread from onCreate) void onFirstTime() { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File dstPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS); // This returns false but since I run it on an emulator, I don't know how to check if it actually exists: dstPath.mkdirs(); Field[] rawResources = R.raw.class.getFields(); final ProgressBar installProgress = (ProgressBar) findViewById(R.id.progressBar); final int length = rawResources.length; runOnUiThread(new Runnable() { @Override public void run() { installProgress.setMax(length); } }); for (int i = 0; i < length; ++i) { try { int resId = rawResources[i].getInt(rawResources[i]); copyRawRingtone(dstPath, resId); // Call the method above } catch (IllegalAccessException e) { e.printStackTrace(); } final int progress = i + 1; runOnUiThread(new Runnable() { @Override public void run() { installProgress.setProgress(progress); } }); } } } 

Строка: dstFile.createNewFile (); Бросает исключение:

 java.io.IOException: open failed: ENOENT (No such file or directory) 

Я не понимаю, в чем проблема. Я запускаю это на эмуляторе: Nexus_S_API_21_armeabi-v7a.

Я не вижу хранилище эмулятора под своим ПК, поэтому я считаю, что хранилище эмуляторов телефона не смонтировано на моем ПК, поэтому я не думаю, что это может быть проблемой .

В момент исключения это некоторые переменные значения:

 dstPath="/storage/sdcard/Alarms" fileName="whistle_alarm.mp3" dstFile="/storage/sdcard/Alarms/whistle_alarm.mp3" 

Поскольку это возвращает true:

 Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) 

Кажется, что медиа смонтировано и доступно для записи (не MEDIA_MOUNTED_READ_ONLY). Поэтому я не знаю, в чем проблема! Кто-нибудь знает?

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

Я добавил эти две строки (я также поставил одну строку до и один раз, чтобы увидеть ее в контексте:

 File dstPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS); final boolean exists = dstPath.exists(); // Added. exists=true final boolean canWrite = dstPath.canWrite(); // Added. canWrite=true dstPath.mkdirs(); 

Я также удалил:

 dstFile.createNewFile(); // THIS THROWS THE EXCEPTION 

И теперь это работает!

Но я тестировал много раз без этой строки createNewFile (), и это не сработало. Действительно, я добавил эту строку, чтобы посмотреть, смогу ли я с ней работать. Поэтому я снова попробовал эту линию, и она тоже работает!

Я подозреваю, что фактическим решением было перезапустить эмулятор.