Можно ли использовать content: // в качестве источника для элемента <audio>в WebView? - PullRequest
13 голосов
/ 20 декабря 2011

Я создал 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?

Ответы [ 4 ]

4 голосов
/ 02 июня 2013

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

Ошибка, которую вы получаете, связана с методом HTML5Audio setDataSource, который, если вы посмотрите на исходный код , вызывает MediaPlayer setDataSource с аудио-ссылкой. И если вы посмотрите на документацию для класса 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 голосов
/ 28 мая 2013

Вот некоторые вещи, которые я нашел полезными:

Просто чтобы уточнить, пути к файлам

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

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

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

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

Получение активов с использованием AssetManager:

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

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

Звук в Webview

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

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

HTML-аудио в веб-обозревателе Android

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

С уважением,

1 голос
/ 02 июня 2013

Опция № 1: Файл манифеста.

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

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

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

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

Опция № 3: Разрешения на чтение

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

0 голосов
/ 17 сентября 2013

Мне удалось заставить это работать после долгих потрясений.По какой-то причине вызов вашего провайдера контента из 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...