Playing an MP3 file from an Android app
I've mostly been enormously happy with my upgrade from my old Archos 5 to the Samsung Galaxy Player 5.0. The Galaxy does everything I always wanted the Archos to do, all those things the Archos should have done but couldn't because of its buggy and unsupported Android 1.6.
That is, I've been happy with everything except one thing: my birdsong app no longer worked.
I have a little HTML app based on my "tweet" python script which lets you choose from a list of birdsong MP3 files. (The actual MP3 files are ripped from the excellent 4-CD Stokes Field Guide to Western Bird Songs set.) The HTML app matches bird names as you type in characters. (If you're curious, an earlier test version is at tweet.html.)
On the Archos, I ran that under my WebClient Android app (I had to modify the HTML to add a keyboard, since in Android 1.6 the soft keyboard doesn't work in WebView text fields). I chose a bird, and WebView passed off the MP3 file to the Archos' built-in audio player. Worked great.
On the Samsung Galaxy, no such luck. Apparently Samsung's built-in
media player can only play files it has indexed itself. If you try
to use it to play an arbitrary file, say, "Song_Sparrow.mp3", it
will say: unknown file type. No matter that the file ends in .mp3 ...
and no matter that I've called
intent.setDataAndType(Uri.parse(url), "audio/mpeg");
...
and no matter that the file is sitting on the SD cad and has in fact
been indexed already by the media player. You didn't navigate to it
via the media player's UI, so it refuses to play it.
I haven't been able to come up with an answer to how to make Samsung's media player more flexible, and I was just starting a search for alternate Android MP3 player apps, when I ran across Play mp3 in SD Card, using Android's MediaPlayer and Error creating MediaPlayer with Uri or file in assets which gave me the solution. Instead of using an intent and letting WebView call up a music application, you can use an Android MediaPlayer to play your file directly.
Here's what the code looks like, inside setWebViewClient() which is itself inside onCreate():
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.endsWith(".mp3")) { MediaPlayer mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource(getApplicationContext(), Uri.parse(url)); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IllegalArgumentException e) { showMessage("Illegal argument exception on " + url); } catch (IllegalStateException e) { showMessage("Illegal State exception on " + url); } catch (IOException e) { showMessage("I/O exception on " + url); } } }
showMessage() is my little wrapper that pops up an error message dialog. Of course, you can handle other types, not just files ending in .mp3.
And now I can take the Galaxy out on a birdwalk and use it to help me identify bird songs.
[ 14:28 May 06, 2012 More programming | permalink to this entry | ]