Пытаюсь записать аудио-поток в файл на устройство. Права на чтение/запись файлов в манифесте присутствуют.
<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;
}}
У вас файл /storage/emulated/0/MyFirstApp/DFMDeep_20180321111153.mp3 не существует.
Возможно, произошла ошибка при создании файла, которую вы благополучно заглушили этим кодом:
try {
newSoundFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
ИМХО, так лучше не делать, а чтобы проверить что за ошибка была, псмотрите вывод консоли, или пробрасывайте IOException выше.
проблема была в разрешениях. Нужно не просто запрашивать в манифесте, но и самому запросить разрешение перед созданием файла/папки. Установил запрос на кнопку, которая соб-нно и начинает запускать метод (запись потока).
//динамическое получение прав на 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);
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Ситуация такова, пытаюсь отправить сообщение на email, данные берутся из бд (firebase)Сообщение отлично отправляется
Как добавить фрагмент в разметку по нажатию кнопки? Существующий конструктор FragmentTransaction требует id: FragmentTransactionadd(int containerViewId, Fragment fragment, String...
Есть база, в которой много таблиц не имеют Primary KeyИспользую автогенератор Entity из Hibernate Tools, который для таких таблиц генерирует отдельный Id-класс
У меня есть следующий файл app-contextxml: