Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use content:// as a source for an <audio> element in a WebView

I created a ContentProvider. It exports files within my assets/ directory. I'm using content:// urls to access the exported content in a WebView.

The following HTML works as expected:

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

I'm trying to use the content provider for mp3 audio files:

<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>

I'm getting the following error message.

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

I tried the Android SDK 8 and 10 without success. I'm not seeing any access to my ContentProvider in the log. It looks like accessing content from audio-tags is not possible within a WebView. It seems strange, since the following code works as expected:

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

How can I play audio files from a ContentProvider within a WebView?

like image 746
dividuum Avatar asked Dec 20 '11 16:12

dividuum


1 Answers

The short answer is no, you can't use content:// as a source for an audio element.

The error you are getting comes from the HTML5Audio setDataSource method, which if you look at the source code, calls MediaPlayer setDataSource with the audio url. And if you look at the documentation for the MediaPlayer class, it only supports file paths and http/rtsp urls.

I think your best bet is to save your audio content to a file path and use a file: url to access it.

However, if I remember correctly, you will also need to make the file world readable in order for the MediaPlayer code to access it. This requires using the private android.os.FileUtils class with code like this:

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 is the equivalent of rwxrwxr-x which may be more permissive than necessary, so you may want to try experimenting with less permissive values. Also note that you'll likely need to set the permissions on the directory containing the file, and that directory's parent, etc. - not just the file itself.

like image 123
James Holderness Avatar answered Oct 12 '22 12:10

James Holderness