Подтвердить что ты не робот

Можно ли использовать контент://как источник для элемента <audio> в WebView

Я создал ContentProvider. Он экспортирует файлы в моем каталоге assets/. Я использую content://urls для доступа к экспортированному контенту в WebView.

Следующий HTML работает как ожидалось:

<img src="content://<provider-name>/test.jpg">

Я пытаюсь использовать контент-провайдер для mp3-аудио файлов:

<div id='player'></div>
<script>
  url = "content://<provider-name>/test.mp3";
  var audio = document.createElement('audio');
  audio.src = url;
  audio.controls = "controls";
  document.getElementById("player").appendChild(audio);
</script>

Я получаю следующее сообщение об ошибке.

E/MediaPlayer(24120): Unable to to create media player
E/HTML5Audio(24120): couldn't load the resource: content://.../test.mp3 exc: java.io.IOException: setDataSource failed.: status=0x80000000

Я пробовал Android SDK 8 и 10 без успеха. Я не вижу доступа к моему ContentProvider в журнале. Похоже, что доступ к содержимому из аудио-тегов невозможен в WebView. Кажется странным, поскольку следующий код работает так, как ожидалось:

MediaPlayer player = MediaPlayer.create(this, 
    Uri.parse("content://<provider-name>/test.mp3")
);
player.start();

Как воспроизводить аудиофайлы из ContentProvider в WebView?

4b9b3361

Ответ 1

Короткий ответ - нет, вы не можете использовать content:// в качестве источника для аудио-элемента.

Ошибка, которую вы получаете, исходит из метода HTML5Audio setDataSource, который, если вы посмотрите на исходный код, вызывает MediaPlayer setDataSource с помощью звуковой url. И если вы посмотрите документацию для класса MediaPlayer, он поддерживает только пути к файлам и URL-адреса http/rtsp.

Я считаю, что лучше всего сохранить аудиоконтент в пути к файлу и использовать URL-адрес file: для доступа к нему.

Однако, если я правильно помню, вам также потребуется сделать мир файлов доступным для того, чтобы код MediaPlayer имел к нему доступ. Для этого требуется использовать частный android.os.FileUtils класс с таким кодом:

void makeFileReadable(String filename) {
  try {
    Class fileUtils = Class.forName("android.os.FileUtils");
    Method setPermissions = fileUtils.getMethod("setPermissions", String.class,
     int.class, int.class, int.class);
    setPermissions.invoke(fileUtils, filename, 0775, -1, -1);
  }
  catch (Exception ex) {
  }
}

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

Ответ 2

Вот что я нашел полезным:

Только для пояснения, пути к файлу

Есть ли путь, похожий на файл:///android_asset/, который указывает на каталог приложений?

content:// - для уже экспортированного носителя на sdcard/

file:///android_asset - для элементов в папке assets/

Получение активов:

Вытягивание активов с помощью AssetManager:

Как получить URI из файла активов?

Внесите звук из WebView из активов программно с помощью MediaPlayer:

Звук в веб-обозревателе

Android WebView воспроизводит аудио с помощью javascript

Использование HTML5:

Html Audio в Android Webview

Вот несколько методов, которые вы не пробовали. В последнее время я работал с alot WebViews и JavaScript, так что, возможно, один из этих других методов сделает трюк.

Привет,

Ответ 3

Вариант №1: Файл манифеста.

Убедитесь, что у вас есть правильное разрешение в файле манифеста:

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

Вариант № 2: Плохой или поврежденный аудиофайл.

Проверьте, можете ли вы воспроизвести файл с помощью Android Media Player.

Вариант № 3: Разрешения на чтение

Возможно, файл на самом деле не читается игроком. В этом случае использование FileDescriptor должно работать. Я где-то читал (извините, не могу вспомнить, где), о каких-то проблемах с тем же исключением сообщалось с помощью setDataSource(FileDescriptor fd). Попытайтесь использовать setDataSource(FileDescriptor fd, long offset, long length), поскольку это, кажется, решает проблему.

Ответ 4

Мне удалось получить эту работу после большого ужаса. По какой-то причине вызов вашего провайдера контента из webView (который использует MediaPlayer) для mp3 файла не вызывает openAssetFile, а вызывает openFile. (не уверен, что провайдер обрабатывает эту маршрутизацию). Эта проблема, по-видимому, была исправлена ​​в 4.2 +

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

@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode){
    //your asset reading code that works for other file types goes here.
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode){
    try {
        AssetFileDescriptor afd = openAssetFile(uri, mode);
        return afd.getParcelFileDescriptor();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}