Я разрабатываю виджет, который воспроизводит случайный звук. Моя проблема заключается в том, чтобы использовать сервис, который я использую для обработки MediaPlayer
, и воспроизводить звуки для загрузки звуковых файлов, которые я сохранил в папке с активами моего приложения.
Вместо SoundPool
, как в моем приложении, я выбрал MediaPlayer
, так как он имеет onCompletionListener
, который позволяет мне остановить службу после того, как звук был полностью воспроизведен. Таким образом, я надеюсь минимизировать использование ресурсов виджета.Загрузить файлы с данными в фоновом режиме
Точнее, в моем коде (checkout the [now outdated] commit on GitHub) Я пытаюсь загрузить случайный звук с помощью метода MediaPlayer
create()
using an Uri
to file:///android_asset/pathToFile
.
Это, однако, генерирует исключение IOException во время выполнения.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_PLAY_FART.equals(action)) {
Log.v(LOG_TAG, "Intent received");
String pathToFile = String.format(
Locale.US,
"fart%02d.ogg",
Utility.getIntBetween(1, 15)
);
MediaPlayer tempMediaPlayer = MediaPlayer.create(
this,
Uri.parse("file:///android_asset/"+pathToFile)
);
tempMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
stopSelf();
}
});
Log.v(LOG_TAG, "Start playing");
tempMediaPlayer.start();
}
}
return START_NOT_STICKY;
}
Есть простой способ (я. Е., Кроме Content Provider) для нагрузки эти файлы активов из внутриService
?
[редактировать, предоставляя больше информации]
По-видимому, можно получить доступ к файлам активов, но MediaPlayer
не может загрузить их должным образом.
Я изменил код для этого:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_PLAY_FART.equals(action)) {
Log.v(LOG_TAG, "Intent received");
String pathToFile = String.format(
Locale.US,
"fart%02d.ogg",
Utility.getIntBetween(1, 15)
);
try {
AssetFileDescriptor assetFD = this.getAssets().openFd(pathToFile);
MediaPlayer tempMediaPlayer = new MediaPlayer();
tempMediaPlayer.setDataSource(assetFD.getFileDescriptor());
tempMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
stopSelf();
}
});
Log.v(LOG_TAG, "Start playing");
tempMediaPlayer.start();
} catch (IOException e) {
Log.e(LOG_TAG, "File "+pathToFile+" could not be loaded.", e);
}
}
}
Выход я получаю:
08-29 15:29:54.868 10191-10191/com.y0hy0h.furzknopf V/VolatileFartService﹕ Intent received
08-29 15:29:54.868 10191-10191/com.y0hy0h.furzknopf V/MediaPlayer﹕ constructor
08-29 15:29:54.868 10191-10191/com.y0hy0h.furzknopf V/MediaPlayer﹕ setListener
08-29 15:29:54.868 10191-10191/com.y0hy0h.furzknopf V/MediaPlayer﹕ setDataSource(51, 0, 576460752303423487)
08-29 15:29:54.898 10191-10191/com.y0hy0h.furzknopf E/MediaPlayer﹕ Unable to to create media player
08-29 15:29:54.908 10191-10191/com.y0hy0h.furzknopf E/VolatileFartService﹕ File fart07.ogg could not be loaded.
java.io.IOException: setDataSourceFD failed.: status=0x80000000
at android.media.MediaPlayer.setDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1032)
at com.y0hy0h.furzknopf.widget.VolatileFartService.onStartCommand(VolatileFartService.java:39)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2524)
at android.app.ActivityThread.access$1900(ActivityThread.java:138)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1302)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4929)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565)
at dalvik.system.NativeStart.main(Native Method)
Обратите внимание, что линии 39 является
tempMediaPlayer.setDataSource(assetFD.getFileDescriptor());
Alternitavely, есть путь к p ass FileDescriptor или другой объект для загрузки службы?
Возможно, существует еще один способ для обработки воспроизведения, возможно, нескольких звуков одновременно, чем для добавления этой функции в Service
?
Вы можете загрузить файл из папки Assets в службе, но, прежде чем предлагать ответ, Пожалуйста, включите ваши коды, чтобы люди могли легко помочь, а не предполагая, что вы можете или не можете понадобиться , – Want2bExpert
Я добавил фрагмент кода. Для большей части кода я включил ссылки на мой репозиторий GitHub. Это плохой способ предоставить код, должен ли я включать больше кода прямо в Stackoverflow? – J0hj0h
Вы пробовали AssetManager asset = Context.get assets(); asset.open ("имя_файла") ;? – Want2bExpert