MusicDroid - Audio Player Part I


SDK Version: 
M3

Introduction

As you can imagine a popular way to load music onto a cell phone will be via removable storage, such as an SD card. In part 1 of our media player tutorial we will build a simple media player that will allow the user to select a song from the SD card and play it.

Click here if you would like to download the source for this tutorial.

Note: there is a known issue with the Emulator where the mixer will cut in and out on some systems resulting in very choppy audio, hopefully this will be addressed in the next SDK release.

Layouts

This project only consists of one Activity, a ListActivity. So, for a ListActivity we need a ListView for the actual list, and another view that will be used for each item in the list. You can get fancy, but for this example we will just use a TextView to display the name of each file.

First, here is our ListView (songlist.xml):

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.         android:orientation="vertical"
  4.         android:layout_width="fill_parent"
  5.         android:layout_height="fill_parent">
  6.  
  7.     <ListView id="@id/android:list"
  8.               android:layout_width="fill_parent"
  9.               android:layout_height="fill_parent"
  10.               android:layout_weight="1"
  11.               android:drawSelectorOnTop="false"/>
  12.  
  13.     <TextView id="@id/android:empty"
  14.               android:layout_width="fill_parent"
  15.               android:layout_height="fill_parent"
  16.               android:text="No songs found on SD Card."/>
  17. </LinearLayout>

Very standard ListView. The TextView entry will display when there are no items in the ListView because it's using the built-in id of "@id/android:empty".

And for each file here is the TextView to be used (song_item.xml):

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <TextView id="@+id/text1" xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="wrap_content"
  4.     android:layout_height="wrap_content"/>

Again, very basic, shouldn't be anything you haven't seen before.

You may be thinking, why does the screenshot above show a black ListView, when nothing in these layouts mentions color? Well, that is determined by the "theme" in the AndroidManifest.xml. In the "application" element you can define the theme by adding "android:theme="@android:style/Theme.Dark"".

The ListActivity

We now must work on our ListActivity which we will call MusicDroid. Here is the declaration of this class and it's onCreate() function:

  1. public class MusicDroid extends ListActivity {
  2.  
  3.         private static final String MEDIA_PATH = new String("/sdcard/");
  4.         private List<String> songs = new ArrayList<String>();
  5.         private MediaPlayer mp = new MediaPlayer();
  6.         private int currentPosition = 0;
  7.  
  8.         @Override
  9.         public void onCreate(Bundle icicle) {
  10.                 super.onCreate(icicle);
  11.                 setContentView(R.layout.songlist);
  12.                 updateSongList();
  13.         }

First we set up some private member variables to be used by this Activity. The first one is MEDIA_PATH, and we set it to "/sdcard" because that is the location of the SD card. Next comes a List of Strings that will hold the filename for each song on the list. And of course we need a MediaPlayer object, which we call mp. The final one up there is currentPosition, which we will use to store the index of the song currently playing.

The onCreate() function is pretty basic, we set our view to be the songlist view that we created above and call the function updateSongList(), here is that function:

  1. public void updateSongList() {
  2.         File home = new File(MEDIA_PATH);
  3.         if (home.listFiles(new Mp3Filter()).length > 0) {
  4.                 for (File file : home.listFiles(new Mp3Filter())) {
  5.                         songs.add(file.getName());
  6.                 }
  7.  
  8.                 ArrayAdapter<String> songList = new ArrayAdapter<String>(this,
  9.                                 R.layout.song_item, songs);
  10.                 setListAdapter(songList);
  11.         }
  12. }

Here we create a File Object called "home" which points to "/sdcard". We loop through the files returned by home.ListFiles(), adding each file to our List object "songs". Once we have this list filled we create an ArrayAdapter passing in the songs list and then set it to be our ListActivity's ListAdapter on line 47. This will populate our ListView.

You may have noticed the object above called "Mp3Filter". This is an object that implements FilenameFilter. This object is used to filter out what files should be returned, this is done by implementing the accept(File, String) function. Here is the object that we can use to filter so that listFiles() only returns MP3 files:

  1. class Mp3Filter implements FilenameFilter {
  2.         public boolean accept(File dir, String name) {
  3.                 return (name.endsWith(".mp3"));
  4.         }
  5. }

Now we should be able to build a list of all the MP3 files in /sdcard. So now we just need to be able to select a song and play it. Fist things first, let's override onListItemClick() so we will be notified when a song is clicked on:

  1. @Override
  2. protected void onListItemClick(ListView l, View v, int position, long id) {
  3.         currentPosition = position;
  4.         playSong(MEDIA_PATH + songs.get(position));
  5. }

Pretty basic function here. We set currentPosition to hold the index of the position that was clicked on and then pass in the path of the song to playSong(String), so lets take a look at what's happening in playSong(String):

  1. private void playSong(String songPath) {
  2.         try {
  3.  
  4.                 mp.reset();
  5.                 mp.setDataSource(songPath);
  6.                 mp.prepare();
  7.                 mp.start();
  8.  
  9.                 // Setup listener so next song starts automatically
  10.                 mp.setOnCompletionListener(new OnCompletionListener() {
  11.  
  12.                         public void onCompletion(MediaPlayer arg0) {
  13.                                 nextSong();
  14.                         }
  15.  
  16.                 });
  17.  
  18.         } catch (IOException e) {
  19.                 Log.v(getString(R.string.app_name), e.getMessage());
  20.         }
  21. }

The MediaPlayer object makes things really easy for us here. First we call mp.reset(), which will reset the MediaPlayer to its normal state. This is required if you were playing a song and want to change the data source. The reset() function will also stop whatever is playing, so if a song is playing and then you select another it will stop that one before starting the next song.

We then pass in the path to the song to mp.setDataSource(String) and call prepare() and start(). At this point the MediaPlayer will start playing your song.

Next job is to setup an OnCompletionListener starting on line 66. The function onCompletion(MediaPlayer) will be called when the song is over. All we do there is call the function nextSong() from our Activity. Here is nextSong():

  1. private void nextSong() {
  2.         if (++currentPosition >= songs.size()) {
  3.                 // Last song, just reset currentPosition
  4.                 currentPosition = 0;
  5.         } else {
  6.                 // Play next song
  7.                 playSong(MEDIA_PATH + songs.get(currentPosition));
  8.         }
  9. }

Here we check to make sure this isn't the last song on the list, if it is we won't do anything, if not we'll play the next song using the playSong(String) function.

So that's it for the code, on the next page we'll figure out how to get this thing running...

Emulator Command Line Options

There are 2 command line options that must be set for this project to work. One to mount an SD card so that you can access it at "/sdcard" and another to enable audio.

To enable the SD card first you need to create an sd card image, to do this you need to open a command prompt in your SDK/tools folder and type the following command:

mksdcard <size>M <file>

Where <size> is the size of the SD card in MB, and this must be reasonably large as a small SD card image actually crashes the emulator. And <file> is the path to the file to create. This is the command that I used:

mksdcard 128M c:\temp\sd.img

Now your SD card image is setup, so once you have your project setup you will need to supply the 2 command line arguments. So, in Eclipse go to "Run -> Open Run Dialog". Now you may need to create a new configuration if there is not one there for your application, you can do that by double clicking on "Android Application" and supplying the Name, Project, and starting Activity on the "Android" tab. On the "Emulator" tab you need to supply 2 arguments, "-sdcard <file>" and "-useaudio".

It should look something like this:

So now that this is all setup we should be ready to run this thing right? Doh, here's what we see:

We need to add songs to the SD card for this thing to work. This is pretty easy, just open a command prompt in the SDK/tools folder once again and use the "adb push <file> <destination>" command. For example:

adb push "c:\music\02 Paranoid Android.mp3" /sdcard

And after you push a song or many songs out there you'll be able to start using this very primitive music player.

What do you have to look forward to in the next installments?

  • Creating a service for the MediaPlayer
  • Adding animated controls
  • ID3 Tag Support

So, be sure to check back!

Comments

very good tuto

it is very good tuto... able to get it right.
only small change i have done in emulator command line as i am using 2.2

-audio-in winaudio -sdcard c:\sdcard.img

So far so good..

I followed the tutorial exactly, and I have to say that I have media player working! Thanks. On to part 2!

Plastic Garden Chairs

First have SD card image is

First have SD card image is set up. When you have your project set up you'll need to supply the two command line arguments. wow cd keys

I followed the tutorial, but

I followed the tutorial, but the music does not start even I get no errors. I can see the files in the SDcard but they don't play.

Website submission

what do you use to parse the

what do you use to parse the XML file? Sax or DOM?
I am asking because I want to know what is better in this situation.
Search Engine Optimization

SAX or DOM

Suppose you need to develop a Java application that accesses and displays data in XML documents such as books.xml. These documents contain data about books, such as book name, author, description, and ISBN identification number. You could use the SAX or DOM approach to access an XML document and then display the data.
Train Boxer Puppy

Play MP3 file from resources "raw" folder

Hi!!

First of all thanks for this great tutorial.

I am new to android platform, so it helped me a lot to get started playing files from sd card. It worked perfectly for me.

But now I want to play file available under Resources "raw" folder.

So is it possible to play MP3 files having bigger size from raw folder.

I used the following syntax to play file but it didn't work for me.

>>> MediaPlayer.create(this,R.raw.filename);

Please help.. I am stuck to it.

Thanks in advance.

I prefer to have a phone, a

I prefer to have a phone, a layer and a camera separately (and what's more important, of a good quality-as a rule such universal devices lack it). audio player is a separate issue

email extractor software

Updated the code to work on android 2.1

Hi,
I updated this and got it working. I'm still a n00b, so the min sdk version is probably too high (I left it at 7, the same as another project I'm doing).
Also, I didn't know how to get it use the dark theme so left this.

It also works in Eclipse (once you fix up the path to your android sdk)

http://stuartaxon.com/files/MusicDroid1.zip

Help.

Very good tutorial.
Correctly follow the tutorial and when I run no errors appear, but the music does not start. I can see the name of the songs that I put in SDcard, but did not hear any sound. It appears the phrase "sounds found on SD Card", but I insert songs in SDcard. Can anyone help me?
Thank you.

I had some problems with the

I had some problems with the SD card and just couldn't realise how to solve them, though thanks for the post. I don't have any problems now :)
__________________
ACCA Online

Error

When i use this code and run the application in emulator i get error message "application has stopped unexpectedly". Could anybody explain why i'am getting this message.

Thanks,

Couldn't find the option

Hello,

I am using AVD 2.1 latest release.

I couldn't find "Run -> Open Run Dialog". And the last option
"-sdcard " and "-useaudio".

I could create only sd.img file. I couldn't add this file to sdcard folder.
Can you please help me?

I thought the Android

I thought the Android software would be easier to handle but I found myself in quite a bit of trouble when I tried to make some changes and my phone jammed. Thanks for the Musicdroid, it's a wonderful application and it's so easy to use. Keep posting these tutorials, they're really helpful!
_________
Lilia Gephardt | VPS hosting UK

Musicdroid show the beauty

Musicdroid show the beauty and the simplicity of Android programming. You can customize your phone's applications as you wish and these kind of tutorials make it all very easy and fun to do.Phoenix Dj

you know, I used to be rather

you know, I used to be rather sceptical concerning this modern tendency to stuff a device with everything imaginable. I prefer to have a phone, a layer and a camera separately (and what's more important, of a good quality-as a rule such universal devices lack it). audio player is a separate issue. I have it with me all the time (can't imagine my life without music I download by http://www.mp3hunting.com search engine) recently I was considering buying a droid, but the quality of a player didn't satisfy me. now I see that there are certain improvements in this sphere, so I can (and probably will) change my mind.

report

there is no clarity in the coding part... please check that coding(musicdroid part 1)... theme is not found in the resources...

problem with BinderNative file

cant not find BinderNative file in Android OS

updated MusicDroid to m5

Hi Hobbs,

I did a crude fix for MusicDroid so that i can run it in android M5. I mainly fixed the method calls and xml tags so that they match the ones in M5. There are some null text appearing on the screen and i didn't look into them, but I can play mp3 files with it. would you like my crude update so that others can use it?

Kevin

musicdoid with mp5

can u please send me the crude crude updates.thank you

MusicDroid m5

Could you send the apk file to me ?
thanks

Hey Kevin, Thanks for in the

Hey Kevin,

Thanks for in the info. If you want to contact me via the "Contact" link on the top I'll email you so we can get your fixes up for this tutorial! I've been very busy with the ADC still, but would love to get some of these updated for M5.

Thanks,
Zach

M5 update

Hi Kevin,

I guess that most users are very interested in the m5 update!

You may post the main changes, i guess there are not a lot beside the layout (id).

Best regards!

Very useful

thx a lot, u explained all very precise.

Thank you for the code. I am

Thank you for the code.
I am very new to Android.
I am working for the similar type of work for images.
Can anybody plz explain the simulation of SD card on Android phone?
I am having problem with this. Its not working properly at my end.
It is giving Application Error:

An error occurered in **.**.** (Name of the activity)
Unabel to start activity
ComponentInfo{aaplication name};
null pointer Exception

thanks in advance

Musicdroid-player 1

This tutorial is gr8 as it explains the steps very nicely...very helpful for beginners like me:)

A simple Tutorial done good

This is a good tutorial. The best I have had so far.

Anyone with Java experience and a keen eye for the new platform can follow and understand this. I am Grateful to the author.

Now I understand how Android works. We need more of such

songlist.xml

First of all, thanks for this Tutorial!

Just a comment on the layout file. With the new SDK (m5-rc14) i think that id= should be replaced with android:id= but i haven't tested yet if it still works correctly with id=

Greetz
Zoder

Yep, unfortunately the

Yep, unfortunately the MusicDroid tutorials are still for M3...maybe I'll have time to update them all after April 14 :)

for Audio Player Part1

it is very helpful for me to lean android.media.. thanksss.

Open a file in sd card through application

Hi I am writing a file browser for sd card. And i want to open the files ( any kind of files like text file, word file...) whenever user click on it. Can anyone suggest me how can I do this..

Thanks