В чем причина (java.io.IOException: No such file or directory)?

185
23 марта 2018, 12:29

Пытаюсь записать аудио-поток в файл на устройство. Права на чтение/запись файлов в манифесте присутствуют.

<permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

При нажатии по соответствующей кнопке в активити, к которой привязан слушатель, в котором должен сработать метод, я получаю исключение следующего рода:

   03-21 23:11:53.066 13790-13790/com.pro W/System.err: java.io.IOException: No such file or directory
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at java.io.UnixFileSystem.createFileExclusively0(Native Method)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at java.io.File.createNewFile(File.java:948)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at com.pro.utils.AudioRecorder.createFile(AudioRecorder.java:226)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at com.pro.utils.AudioRecorder.<init>(AudioRecorder.java:188)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at com.pro.ui.activity.StationActivity$5.onClick(StationActivity.java:287)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at android.view.View.performClick(View.java:6199)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at android.view.View$PerformClick.run(View.java:23647)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at android.os.Looper.loop(Looper.java:154)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6682)
    03-21 23:11:53.067 13790-13790/com.pro W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
    03-21 23:11:53.068 13790-13790/com.pro W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
    03-21 23:11:53.068 13790-13790/com.pro W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
    03-21 23:11:53.068 13790-13790/com.pro W/System.err: java.io.FileNotFoundException: /storage/emulated/0/MyFirstApp/DFMDeep_20180321111153.mp3 (No such file or directory)
    03-21 23:11:53.068 13790-13790/com.pro W/System.err:     at java.io.FileOutputStream.open(Native Method)
    03-21 23:11:53.068 13790-13790/com.pro W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
    03-21 23:11:53.068 13790-13790/com.pro W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at com.tequila.online.radio.pro.utils.AudioRecorder.<init>(AudioRecorder.java:191)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at com.tequila.online.radio.pro.ui.activity.StationActivity$5.onClick(StationActivity.java:287)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at android.view.View.performClick(View.java:6199)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at android.view.View$PerformClick.run(View.java:23647)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at android.os.Looper.loop(Looper.java:154)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6682)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
    03-21 23:11:53.069 13790-13790/com.pro W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
    03-21 23:11:53.070 13790-13790/com.pro I/System.out: [http://uplink.181.fm:8026/;] : true

подаю url-адрес потока в метод в активити (StationActivity):

button_rec.setOnClickListener(new View.OnClickListener() {
    public void onClick(View view) {
        if (Streamer.getInstance().isPlaying()) {
            StationActivity.isRecording = true;
            AudioRecorder audioRecorder = new AudioRecorder(Streamer.getInstance().getStation().getStreams().toString(), StationActivity.context);
            button_rec.setImageResource(R.drawable.admin);
            System.out.println(Streamer.getInstance().getStation().getStreams().toString() + " : " + isRecording);
        } else if (StationActivity.isRecording && Streamer.getInstance().isPlaying()) {
            StationActivity.isRecording = false;
            button_rec.setImageResource(R.drawable.aboutus_menu);
            System.out.println(Streamer.getInstance().getStation().getStreams().toString() + " : " + isRecording);
        }
    }
});

собственно сам класс, на который всё подаётся:

  public class AudioRecorder {
private Context context;
MediaRecorder mMediaRecorder = null;
@SuppressLint("StaticFieldLeak")
private class AudioStreamRecordTask extends AsyncTask<Object, Void, FileOutputStream> {
    private FileOutputStream fileOutputStream;
    private AudioStreamRecordTask() {
    }
    protected FileOutputStream doInBackground(Object... params) {
        URL url;
        MalformedURLException e;
        FileNotFoundException e2;
        IOException e3;
        this.fileOutputStream = (FileOutputStream) params[0];
        try {
            URL url2 = new URL(Streamer.getInstance().getStation().getStreams().toString());
            try {
                BufferedInputStream bufferedInputStream = new BufferedInputStream(url2.openStream());
                byte[] buffer = new byte[1024];
                while (true) {
                    int i;
                    int bytesRead = bufferedInputStream.read(buffer);
                    if (bytesRead > 0) {
                        i = 1;
                    } else {
                        i = 0;
                    }
                    if ((i & ExoPlayer.STATE_READY) == 0) {
                        break;
                    }
                    this.fileOutputStream.write(buffer, 0, bytesRead);
                }
                this.fileOutputStream.flush();
                this.fileOutputStream.close();
                url = url2;
            } catch (MalformedURLException e4) {
                e = e4;
                url = url2;
            } catch (FileNotFoundException e5) {
                e2 = e5;
                url = url2;
            } catch (IOException e6) {
                e3 = e6;
                url = url2;
            }
        } catch (MalformedURLException e7) {
            e = e7;
            e.printStackTrace();
            return this.fileOutputStream;
        }
        return this.fileOutputStream;
    }
    protected void onPostExecute(Bitmap result) {
    }
}
public static class Transliterator {
    private Map<Character, String> charMap = null;
    public Transliterator() {
        init();
    }
    private void init() {
        this.charMap = new HashMap();
        this.charMap.put(Character.valueOf('\u0410'), "A");
        ...
        this.charMap.put(Character.valueOf(' '), "_");
    }
    public String transliterate(String string) {
        StringBuilder transliteratedString = new StringBuilder();
        for (int i = 0; i < string.length(); i++) {
            Character ch = Character.valueOf(string.charAt(i));
            String charFromMap = this.charMap.get(ch);
            if (charFromMap == null) {
                transliteratedString.append(ch);
            } else {
                transliteratedString.append(charFromMap);
            }
        }
        return transliteratedString.toString().toLowerCase();
    }
}
public AudioRecorder(String stream_url, Context context) {
    FileNotFoundException e;
    FileOutputStream fileOutputStream;
    IOException e2;
    this.context = context;
    File stream_file = createFile();
    if (stream_file != null) {
        try {
            FileOutputStream fileOutputStream2 = new FileOutputStream(stream_file);
            new AudioStreamRecordTask().execute(fileOutputStream2, stream_url);
        } catch (FileNotFoundException e5) {
            e = e5;
            e.printStackTrace();
        }
    }
}
private File createFile() {
    File newSoundFile;
    Date dNow = new Date();
    SimpleDateFormat ft = new SimpleDateFormat("yyyyMMddhhmmss", Locale.getDefault());
    //Парсим название станции
    String filename = Streamer.getInstance().getStation().getName();
    filename = (filename + "_" + ft.format(dNow) + ".mp3").replaceAll("\\s", "");
    File path;
    String path2 = Environment.getExternalStorageDirectory() + "/" + "MyFirstApp/";
    if (isSDPresent()) {
        path = new File(path2);
        if (!path.exists()) {
            path.mkdirs();
        }
        newSoundFile = new File(path, filename);
    } else {
        path = new File(path2);
        if (!path.exists()) {
            path.mkdirs();
        }
        newSoundFile = new File(path, filename);
    }
    if (newSoundFile.exists()) {
        newSoundFile.delete();
    }
    try {
        newSoundFile.createNewFile();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return newSoundFile;
}
private String generateFileName(String name) {
    return "";
}
private static boolean isSDPresent() {
    return Environment.getExternalStorageState().equals("mounted");
}
public static String getFileDuration(String filePath, Context context) {
    long duration = 0;
    MediaPlayer mp = new MediaPlayer();
    try {
        mp.reset();
        if (isSDPresent()) {
            mp.setDataSource(filePath);
        } else {
            mp.setDataSource(new FileInputStream(filePath).getFD());
        }
        mp.prepare();
        duration = (long) mp.getDuration();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e2) {
        e2.printStackTrace();
    } catch (IllegalStateException e3) {
        e3.printStackTrace();
    }
    String out = "";
    String seconds = String.valueOf((duration % 60000) / 1000);
    String minutes = String.valueOf(duration / 60000);
    if (seconds.length() == 1) {
        seconds = "0" + seconds;
    }
    if (minutes.length() == 1) {
        minutes = "0" + minutes;
    }
    return String.valueOf(minutes) + ":" + seconds;
}}
Answer 1

У вас файл /storage/emulated/0/MyFirstApp/DFMDeep_20180321111153.mp3 не существует.
Возможно, произошла ошибка при создании файла, которую вы благополучно заглушили этим кодом:

try {
    newSoundFile.createNewFile();
} catch (IOException e) {
    e.printStackTrace();
}

ИМХО, так лучше не делать, а чтобы проверить что за ошибка была, псмотрите вывод консоли, или пробрасывайте IOException выше.

Answer 2

проблема была в разрешениях. Нужно не просто запрашивать в манифесте, но и самому запросить разрешение перед созданием файла/папки. Установил запрос на кнопку, которая соб-нно и начинает запускать метод (запись потока).

  //динамическое получение прав на WRITE_EXTERNAL_STORAGE
                    if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                            == PackageManager.PERMISSION_GRANTED) {
                        android.util.Log.d(TAG, "Permission is granted");
  //что то делаем
} else {
         android.util.Log.d(TAG, "Permission is revoked");
         //запрашиваем разрешение
         ActivityCompat.requestPermissions(StationActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
READ ALSO
Отправка на Email, данные из базы данных

Отправка на Email, данные из базы данных

Ситуация такова, пытаюсь отправить сообщение на email, данные берутся из бд (firebase)Сообщение отлично отправляется

193
Как динамически добавлять фрагмент в layout

Как динамически добавлять фрагмент в layout

Как добавить фрагмент в разметку по нажатию кнопки? Существующий конструктор FragmentTransaction требует id: FragmentTransactionadd(int containerViewId, Fragment fragment, String...

113
Генерация вложенных Id-классов в Hibernate Tools

Генерация вложенных Id-классов в Hibernate Tools

Есть база, в которой много таблиц не имеют Primary KeyИспользую автогенератор Entity из Hibernate Tools, который для таких таблиц генерирует отдельный Id-класс

149