How to Make a Simple Media Player for Android

Let's get to work Android!
Let's get to work Android!

Android Media Player

People ask me all the time how to develop an Android program that can load up and play music. Sadly, there are not a lot of good answers on the internet. The good news is, it's really not all that bad. Today we are going to:

  1. Learn how to implement features of the android.media.MediaPlayer class.
  2. Load Drawables on the fly from the SD card using the createFromPath() function
  3. Learn what assets are and how to incorporate these into our program
  4. Learn how to load media from an SD card
  5. Write a fully functional Media Player program
  6. Become a better Java Monkey!

By the end of this tutorial, you will not only have a fully functional simple media player, but you will also have a clear understanding of how to incorporate media into your apps. Before going any further, make sure your development environment is set up correctly for Android development. If you are unsure, check my guide here.

*** I recommend you download the source code for this project here, as it contains sample tracks and all of the drawables you will need, as well as a cheesy icon I made myself ***

File   New   Android Project
File New Android Project
New Android Project (Name, Path, Target)
New Android Project (Name, Path, Target)
New Android Project (Properties)
New Android Project (Properties)
File   Import
File Import
Import Existing Projects into Workspace
Import Existing Projects into Workspace
Browse for the project you want to import and click OK, check the checkbox, and then click Finish
Browse for the project you want to import and click OK, check the checkbox, and then click Finish

Here we go!

When making a media player, a few things come to mind:

  1. There will be multiple tracks to load
  2. Moving from track to track
  3. Play, Pause, and Stop functionality
  4. Shuffle and Loop functionality
  5. The SD Card must be mounted by the phone in order to load music/pictures from it

Doesn't sound too hard right? So let's begin:

  1. Create a new project File > New > Android Project
  2. Name it MyMediaPlayer
  3. Set the MinSdk to 3 and the TargetSdk to 8
  4. Name your package
  5. Eclipse will create the onCreate Activity for you (e.g. 'MyMediaPlayerActivity.java' ) If you want to name it something else, go ahead; it won't hurt anything.

If you have downloaded the source for this project and want to simply import it:

  1. Make sure that the MyMediaPlayer project is in the "Eclipse Projects" folder
  2. File > Import > Existing Projects into Workspace
  3. Browse > MyMediaPlayer > OK
  4. Make sure the checkbox in the "Projects:" box is checked > Finish


Now let's take a look at the manifest file.

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.technegames.mymediaplayer"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MyMediaPlayerActivity" android:configChanges="orientation|keyboardHidden"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
</manifest>

Manifest

As you can see, the manifest acts like a parental guardian for your App. It is responsible for supplying the versionCode, which is important when uploading applications to the Android Market. It also determines how and when activities can be launched via intent filters. The manifest is also where you specify certain permissions such as internet access. For example, in MyMediaPlayer, we use the WAKE_LOCK permission so that we can keep the phone on while the app is running. Otherwise, the song would pause itself after 20 seconds or so. Without the permission specified in the manifest, the application would crash upon loading because it attempted to utilize a wake lock without permission.

The Android Manifest is an important XML document, so familiarize yourself with it. Eclipse will generate a manifest file for you when creating a new project, so if you created this project from scratch, the only line you would have to add would be the "uses-permission" for the WAKE_LOCK

Alright, while on the topic of XML documents, let's take a look at our main layout. After this we will get to the Java code I promise!

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/screen" android:layout_width="fill_parent" android:layout_height="fill_parent" >
	<LinearLayout android:orientation="vertical" android:layout_alignParentTop="true" 
		android:layout_alignParentLeft="true" android:layout_width="fill_parent" android:layout_height="fill_parent" 
		android:weightSum="7" >
		<LinearLayout android:layout_weight="6" android:orientation="vertical" android:layout_alignParentTop="true" 
			android:layout_alignParentLeft="true" android:layout_width="fill_parent" android:layout_height="0dip" >
			<ImageView android:id="@+id/bg" android:layout_width="fill_parent" android:layout_height="fill_parent" >
			</ImageView>
		</LinearLayout>
		<LinearLayout android:layout_weight="1" android:id="@+id/buttons" android:orientation="horizontal" android:weightSum="5" 
			android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:gravity="center" 
			android:layout_width="fill_parent" android:layout_height="0dip" android:background="#FFFFFF" >
			<Button android:id="@+id/btnPrevious" android:layout_width="0dip" android:layout_height="fill_parent" 
				android:layout_weight="1" android:background="@drawable/previous" android:layout_margin="5dp" 
				android:onClick="click" />
			<View android:layout_weight="1" android:layout_width="0dip" android:layout_height="0dip" />
			<Button android:id="@+id/btnPlay" android:layout_width="0dip" android:layout_height="fill_parent" 
				android:layout_weight="1" android:background="@drawable/play" android:layout_margin="5dp" 
				android:onClick="click" />
			<View android:layout_weight="1" android:layout_width="0dip" android:layout_height="0dip" />
			<Button android:id="@+id/btnNext" android:layout_width="0dip" android:layout_height="fill_parent" 
				android:layout_weight="1" android:background="@drawable/next" android:layout_margin="5dp" 
				android:onClick="click" />
		</LinearLayout>
	</LinearLayout>
</RelativeLayout>

main

If you are unfamilar with XML, at first glance this code might look very confusing. I assure you it is very simple, and is one of the greatest features of Android. If you are coming into Android Development from a Java Swing background, you will be happy to know that you can completely separate your layout/gui elements from your main code by setting it up in an XMLdocument.

In the MyMediaPlayer program, we use a Relative Layout with Linear Layouts nested inside. The Relative Layout allows us to specify where the Linear Layouts are placed in relation to each other. The topmost Linear Layout is used for the album art. We use the android:layout_alignParentTop="true" and android:layout_alignParentLeft="true" to specify that the album art layout is aligned to the topleft corner of the screen. We use layout_weight to dictate that the layout containing the image takes up 6/7 of the screen, with the remaining 1/7 for the buttons. Speaking of buttons, in each of the buttons there is android:onClick="click". This means that when you click on any of these buttons, they call a function called click in MyMediaPlayerActivity.java, which we will get to in a bit.

The best way to learn Android layouts is to simply play around with one that works. Adjust settings and values and notice the changes. Parent/Child relationships can get very complicated, so it is best to just take it one step at a time. There is a nice Tool online that generates an XML layout based on what you drag-and-drop onto the screen. If you think this tool may help you with Android Layouts, click here to download it!

Alright, Let's dive into some java code!

Music.java

package com.technegames.mymediaplayer;

import java.io.FileDescriptor;
import java.io.IOException;

import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;

public class Music implements OnCompletionListener{
	MediaPlayer mediaPlayer;
	boolean isPrepared = false;
	
	public Music(AssetFileDescriptor assetDescriptor){
		mediaPlayer = new MediaPlayer();
		try{
			mediaPlayer.setDataSource(assetDescriptor.getFileDescriptor(), assetDescriptor.getStartOffset(), assetDescriptor.getLength());
			mediaPlayer.prepare();
			isPrepared = true;
			mediaPlayer.setOnCompletionListener(this);
		} catch(Exception ex){
			throw new RuntimeException("Couldn't load music, uh oh!");
		}
	}
	
	public Music(FileDescriptor fileDescriptor){
		mediaPlayer = new MediaPlayer();
		try{
			mediaPlayer.setDataSource(fileDescriptor);
			mediaPlayer.prepare();
			isPrepared = true;
			mediaPlayer.setOnCompletionListener(this);
		} catch(Exception ex){
			throw new RuntimeException("Couldn't load music, uh oh!");
		}
	}
	
	public void onCompletion(MediaPlayer mediaPlayer) {
		synchronized(this){
			isPrepared = false;
		}
	}

	public void play() {
		if(mediaPlayer.isPlaying()){
			return;
		}
		try{
			synchronized(this){
				if(!isPrepared){
					mediaPlayer.prepare();
				}
				mediaPlayer.start();
			}
		} catch(IllegalStateException ex){
			ex.printStackTrace();
		} catch(IOException ex){
			ex.printStackTrace();
		}
	}

	public void stop() {
		mediaPlayer.stop();
		synchronized(this){
			isPrepared = false;
		}
	}
	
	public void switchTracks(){
		mediaPlayer.seekTo(0);
		mediaPlayer.pause();
	}
	
	public void pause() {
		mediaPlayer.pause();
	}

	public boolean isPlaying() {
		return mediaPlayer.isPlaying();
	}
	
	public boolean isLooping() {
		return mediaPlayer.isLooping();
	}
	
	public void setLooping(boolean isLooping) {
		mediaPlayer.setLooping(isLooping);
	}

	public void setVolume(float volumeLeft, float volumeRight) {
		mediaPlayer.setVolume(volumeLeft, volumeRight);
	}

	public void dispose() {
		if(mediaPlayer.isPlaying()){
			stop();
		}
		mediaPlayer.release();
	}
}

Music

Alright, if you gave the above code a good scan, you probably noticed that Music.java is responsible for instantiating our media player and controlling it. It implements the OnCompletionListener so that we can monitor when a song is finished playing. The reason we do all of this in a separate class is because we will instantiate it every time we seek to a different track, rather than trying to load all of the tracks into memory.

Whenever you feel comfortable with the Music class, let's move on to the main attraction, MyMediaPlayerActivity.java

MyMediaPlayerActivity.java Variables

package com.technegames.mymediaplayer;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MyMediaPlayerActivity extends Activity {
	WakeLock wakeLock;
	private static final String[] EXTENSIONS = { ".mp3", ".mid", ".wav", ".ogg", ".mp4" }; //Playable Extensions
	List<String> trackNames; //Playable Track Titles
	List<String> trackArtworks; //Track artwork names
	AssetManager assets; //Assets (Compiled with APK)
	File path; //directory where music is loaded from on SD Card
	File path2; //directory where album artwork is loaded from on SD Card
	Music track; //currently loaded track
	ImageView bg; //Track artwork
	Button btnPlay; //The play button will need to change from 'play' to 'pause', so we need an instance of it
	Random random; //used for shuffle
	boolean shuffle; //is shuffle mode on?
	boolean isTuning; //is user currently jammin out, if so automatically start playing the next track
	int currentTrack; //index of current track selected
	int type; //0 for loading from assets, 1 for loading from SD card

MyMediaPlayerActivity Variables

Before we discuss the onCreate activity, let's talk about our Class Level variables.

First, we have our wakeLock, which if you recall from earlier is used to keep the phone on. We also have our EXTENSIONS array, which is used to validate that the files we load into our program are actual sound files. The trackNames ArrayList is used to store all of the track names in memory for reference by the media player. The trackArtworks ArrayList matches the trackNames List except it does not contain any extensions. It is used when trying to find a picture with the same name as the track currently playing and if so load that image. The assets are used to retrieve a list of all the files in the 'assets' folder of your program. Assets are the resources that get compiled along with your program. I've included 4 tracks in the source of this program below. The program by default loads up the assets folder. By pressing the MENU button on your phone and then clicking the SOURCE option you can specify the program to load tracks from the 'music' folder on the root of your SD card. The rest of the variables are pretty self explanatory and if not I've included inline comments.

MyMediaPlayerActivity.java onCreate, onResume, onPause

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setVolumeControlStream(AudioManager.STREAM_MUSIC);
		PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
		wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MyMediaPlayer");
        setContentView(R.layout.main);
        
        initialize(0);
    }
    
    @Override
    public void onResume(){
    	super.onResume();
    	wakeLock.acquire();
    }
	
    @Override
	public void onPause(){
		super.onPause();
		wakeLock.release();
		if(track != null){
			if(track.isPlaying()){
				track.pause();
				isTuning = false;
				btnPlay.setBackgroundResource(R.drawable.play);
			}
			if(isFinishing()){
				track.dispose();
				finish();
			}
		} else{
			if(isFinishing()){
				finish();
			}
		}
	}

onCreate, onResume, onPause

These functions override their parent counterparts from Activity class. They are important because they handle the Activity Lifecycle. Lines 4-8 set up full-screen mode and a wakeLock to insure that the phone screen does not turn off (which would result in an onPause event). On Line 9 we set the content view to the layout we created above, meaning we will have an ImageView and 3 Buttons on the screen. The last thing we do in onCreate is call initialize(0). The 0 in the parentheses means that the media player will load files from the program's assets upon load. Change it to a 1 to load from the SD Card upon load. We will look at the initialize method in the next code block.

The onResume method is where we will acquire the wakeLock. We do this in onResume because we release it in the onPause method. If we were to acquire the wakeLock in the onCreate method, it would only be done so once.

The onPause method is fired when the program is interrupted. For example, the phone is receiving a phone call or the user presses the HOME button. To prepare for something like this, we override the onPause method from Activity. If track is not null and it is playing it gets paused and the pause button gets turned into a play button. We could have also chosen to override onStop, but the isFinishing method serves the same purpose. If the program is finishing, we dispose the mediaplayer object and call the Activity's finish() method.

MyMediaPlayerActivity.java initialize, addTracks, loadTrack

    private void initialize(int type){
    	bg = (ImageView) findViewById(R.id.bg);
        btnPlay = (Button) findViewById(R.id.btnPlay);
        btnPlay.setBackgroundResource(R.drawable.play);
    	trackNames = new ArrayList<String>();
    	trackArtworks = new ArrayList<String>();
    	assets = getAssets();
    	currentTrack = 0;
    	shuffle = false;
    	isTuning = false;
    	random = new Random();
    	this.type = type;
    	
    	addTracks(getTracks());
    	loadTrack();
    }
    
    //Generate a String Array that represents all of the files found
    private String[] getTracks(){
    	if(type == 0){
    		try {
    			String[] temp = getAssets().list("");
    			return temp;
    		} catch (IOException e) {
    			e.printStackTrace();
    			Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG).show();
    		}
    	} else if(type == 1){
    		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) 
        			|| Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY)){
        		path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
        		path2 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    			String[] temp = path.list();
    			return temp;
    		} else{
    			Toast.makeText(getBaseContext(), "SD Card is either mounted elsewhere or is unusable", Toast.LENGTH_LONG).show();
    		}
    	}
    	return null;
    }
    
    //Adds the playable files to the trackNames List
    private void addTracks(String[] temp){
    	if(temp != null){
			for(int i = 0; i < temp.length; i++){
				//Only accept files that have one of the extensions in the EXTENSIONS array
				if(trackChecker(temp[i])){
					trackNames.add(temp[i]);
					trackArtworks.add(temp[i].substring(0, temp[i].length()-4));
				}
			}
			Toast.makeText(getBaseContext(), "Loaded " + Integer.toString(trackNames.size()) + " Tracks", Toast.LENGTH_SHORT).show();
		}
    }
    
    //Checks to make sure that the track to be loaded has a correct extenson
    private boolean trackChecker(String trackToTest){
    	for(int j = 0; j < EXTENSIONS.length; j++){
			if(trackToTest.contains(EXTENSIONS[j])){
				return true;
			}
		}
    	return false;
    }
    
    //Loads the track by calling loadMusic
    private void loadTrack(){
    	if(track != null){
    		track.dispose();
    	}
    	if(trackNames.size() > 0){
    		track = loadMusic(type);
    		setImage("drawable/" + trackArtworks.get(currentTrack));
    	}
    }

initialize, addTracks, loadTrack

The initialize method initializes all of our variables so that we do not end up getting null pointer exceptions. The bottom of the method adds all of the tracks from either the compiled assets or from "scard/music", making sure to only add tracks with a valid extension ( e.g. ".mp3", ".mid" ) After that, the loadTrack() method is called.

The loadTrack() method will be called everytime a new track has been selected. In the loadTrack() method, we call loadMusic() and setImage(), which we will take a look at below.

MyMediaPlayerActivity.java loadMusic, setImage

	//loads a Music instance using either a built in asset or an external resource
    private Music loadMusic(int type){
    	switch(type){
    	case 0:
    		try{
    			AssetFileDescriptor assetDescriptor = assets.openFd(trackNames.get(currentTrack));
    			return new Music(assetDescriptor);
    		} catch(IOException e){
    			e.printStackTrace();
    			Toast.makeText(getBaseContext(), "Error Loading " + trackNames.get(currentTrack), Toast.LENGTH_LONG).show();
    		}
    		return null;
    	case 1:
    		try{
    			FileInputStream fis = new FileInputStream(new File(path, trackNames.get(currentTrack)));
    			FileDescriptor fileDescriptor = fis.getFD();
    			return new Music(fileDescriptor);
    		} catch(IOException e){
    			e.printStackTrace();
    			Toast.makeText(getBaseContext(), "Error Loading " + trackNames.get(currentTrack), Toast.LENGTH_LONG).show();
    		}
    		return null;
    	default:
    		return null;
    	}
    }
    
    //Sets the background image to match the track currently playing or a default image
	private void setImage(String name) {
		if(type == 0){
			int imageResource = getResources().getIdentifier(name, null, getPackageName());
		    if(imageResource != 0){
		    	Drawable image = getResources().getDrawable(imageResource);
		    	bg.setImageDrawable(image);
		    } else{
		    	int defaultImageResource = getResources().getIdentifier("drawable/defaultbg", null, getPackageName());
			    if(defaultImageResource != 0){
			    	Drawable image = getResources().getDrawable(defaultImageResource);
			    	bg.setImageDrawable(image);
			    }
		    }
		} else if(type == 1){
			if(new File(path2.getAbsolutePath(), trackArtworks.get(currentTrack) + ".jpg").exists()){
				bg.setImageDrawable(Drawable.createFromPath(path2.getAbsolutePath() + "/" + trackArtworks.get(currentTrack) + ".jpg"));
			} else{
		    	int defaultImageResource = getResources().getIdentifier("drawable/defaultbg", null, getPackageName());
			    if(defaultImageResource != 0){
			    	Drawable image = getResources().getDrawable(defaultImageResource);
			    	bg.setImageDrawable(image);
			    }
		    }
		}
	}

loadMusic, setImage

The loadMusic is probably the most important method in the entire program. You will want to learn the Music.java class and this method because they can translate to any program that needs music, not just a media player.

In our loadMusic() method, we either load up a track from our compiled assets (the ones I include with the download above) or one of your songs located in the "music" folder on your SD Card.

The setImage() method is called immediately the loadMusic() method to change the album art accordingly. In our simple example, it simply scans the "pictures" folder on your SD Card for a picture with same name as the track currently playing excluding the extension and sets it accordingly. If no image can be found, a default image is loaded up from the drawable folder of your project.

Alright, I know we have covered a lot of ground here, but we are almost done. The next two sections cover the user input.

MyMediaPlayerActivity.java Menu, Options, setShuffle

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
		super.onCreateOptionsMenu(menu);
		createMenu(menu);
		return true;
	}
    
    private void createMenu(Menu menu){
		MenuItem miLooping = menu.add(0, 0, 0, "Looping");{
			miLooping.setIcon(R.drawable.looping);
		}
		MenuItem miShuffle = menu.add(0, 1, 1, "Shuffle");{
			miShuffle.setIcon(R.drawable.shuffle);
		}
		MenuItem miStop = menu.add(0, 2, 2, "Stop");{
			miStop.setIcon(R.drawable.stop);
		}
		MenuItem miSource = menu.add(0, 3, 3, "Source");{
			miSource.setIcon(R.drawable.source);
		}
	}
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item){
		switch(item.getItemId()){
		case 0:
			//Set Looping
			synchronized(this){
				if(track.isLooping()){
					track.setLooping(false);
					Toast.makeText(getBaseContext(), "Playing Tracks Sequentially", Toast.LENGTH_SHORT).show();
				} else{
					track.setLooping(true);
					Toast.makeText(getBaseContext(), "Looping " + trackNames.get(currentTrack), Toast.LENGTH_SHORT).show();
				}
			}
			return true;
		case 1:
			//Set Shuffle
			synchronized(this){
				if(shuffle){
					setShuffle(false);
				} else{
					setShuffle(true);
				}
			}
			return true;
		case 2:
			//Stop Music
			synchronized(this){
				track.switchTracks();
				btnPlay.setBackgroundResource(R.drawable.play);
			}
			return true;
		case 3:
			//Change Source from Assets to SD Card and vice versa
			synchronized(this){
				type++;
				if(type > 1){
					type = 0;
				}
			}
			if(type == 0){
				Toast.makeText(getBaseContext(), "Loading Tracks from Assets ", Toast.LENGTH_SHORT).show();
			} else if(type == 1){
				Toast.makeText(getBaseContext(), "Loading Tracks from SD Card", Toast.LENGTH_SHORT).show();
			}
			initialize(type);
			return true;
		default:
			return false;
		}
	}
    
    //Simply sets shuffle to isShuffle and then displays a message for confirmation
    private void setShuffle(boolean isShuffle) {
    	shuffle = isShuffle;
    	if(shuffle){
    		Toast.makeText(getBaseContext(), "Shuffle On", Toast.LENGTH_SHORT).show();
    	} else{
    		Toast.makeText(getBaseContext(), "Shuffle Off", Toast.LENGTH_SHORT).show();
    	}
	}

Menu, Options, setShuffle

First off, we must override a functon called onCreateOptionsMenu(). It is called whenever the Menu Button is pressed on your phone. It is particularly useful if there are extra controls you want to provide to your users without having to clutter the screen with additional buttons. In our onCreateOptionsMenu() method, we call a createMenu() method.

The createMenu() method is responsible for setting populating the menu options. We have 4 menu options in total: "Looping", "Shuffle", "Stop", and "Source"

The onOptionsItemSelected() method provides functionality for these menu options. We use a switch on the item.getItemId() function, which returns an int that distinguishes the options from each other. The "Looping" and "Stop" Options seem pretty self explanatory, so I won't go over those.

When the "Shuffle" Option is clicked, the setShuffle() method is called, which sets shuffle to to either true of false and displays a message for confirmation.

When the "Source" Option is clicked, type is switched from 0 to 1 and vice versa and the initialize() method is called again, except this time with the new type. If the type is set to 1, the SD Card will be loaded up instead of the "assets" folder of your project.

Alright, let's move on to the on-screen controls!

MyMediaPlayerActivity.java click, setTrack, playTrack

    public void click(View view){
		int id = view.getId();
		switch(id){
		case R.id.btnPlay:
			synchronized(this){
				if(isTuning){
					isTuning = false;
					btnPlay.setBackgroundResource(R.drawable.play);
					track.pause();
				} else{
					isTuning = true;
					btnPlay.setBackgroundResource(R.drawable.pause);
					playTrack();
				}
			}
			return;
		case R.id.btnPrevious:
			setTrack(0);
			loadTrack();
			playTrack();
			return;
		case R.id.btnNext:
			setTrack(1);
			loadTrack();
			playTrack();
			return;
		default:
			return;
		}
	}
    
    private void setTrack(int direction){
    	if(direction == 0){
    		currentTrack--;
			if(currentTrack < 0){
				currentTrack = trackNames.size()-1;
			}
    	} else if(direction == 1){
    		currentTrack++;
			if(currentTrack > trackNames.size()-1){
				currentTrack = 0;
			}
    	}
    	if(shuffle){
			int temp = random.nextInt(trackNames.size());
			while(true){
				if(temp != currentTrack){
					currentTrack = temp;
					break;
				}
				temp++;
				if(temp > trackNames.size()-1){
					temp = 0;
				}
			}
		}
    }
    
    //Plays the Track
    private void playTrack(){
    	if(isTuning && track != null){
			track.play();
			Toast.makeText(getBaseContext(), "Playing " + trackNames.get(currentTrack).substring(0, trackNames.get(currentTrack).length()-4), Toast.LENGTH_SHORT).show();
		}
    }

click, setTrack, playTrack, setShuffle

If you recall from earlier when we created our main.xml layout, we talked about the android:onClick="click" in each of the buttons. The click function must be public, have a return type of void, and accept a View instance as a parameter; otherwise you will receive errors. Since all of the buttons call the same function, how do we know which button called it? We set up a switch on the view.getId() function, which returns the id of the button. The Next and Previous Buttons simply call the setTrack() method, the loadTrack() method we discussed earlier, and then the playTrack() method, which plays the newly loaded song if the user was playing the last song.

The setTrack() method moves the currentTrack index either forward or backward. If shuffle is on, then currentTrack index becomes a random number not equal to what it was before the method call.

The playTrack() method simply calls the play() method from Music.java, provided that track is not null.

Run   Run As   Android Application
Run Run As Android Application

Compiling and Running!

Did I forget anything? I think that's about it, if you have been following along and creating your project from scratch, make sure you do not have any pesky red underlines in your code. At this point, we can go ahead and run our program. You can either click Run > Run As > Android Application or right-click your project and Run As > Android Application

Well? Do the Buttons work? How about the Menu Options? Try alternating between Loop and Shuffle Mode. Click the Source button to load up your SD Card, but make sure you disconnect your phone from the PC first!

Playing the built in tracks from the "assets" folder of your project
Playing the built in tracks from the "assets" folder of your project
Playing Songs from the SD Card's "music" folder
Playing Songs from the SD Card's "music" folder

Congratulations

You now have a working custom media player for your Android Device! The program works decently, but there is more to be desired isn't there? If you wanted to publish this it most likely would not perform well on the Market, as there are much better media players available. To make this media player better, you could add a thread that constantly checks if the onCompletionListener event is satisfied and if so go to the next song. Or you could stream album art from a locally stored database instead of relying on the "pictures" folder of the SD card. Animating visualizations would be nice too wouldn't they? The possibilities are endless! As an Android Developer, these choices are entirely yours, so experiment and try new things!

*** If you had any problems with this tutorial, get the source code here and take a look at it. Play around with the code and understand how it all works together. Good Luck! ***

Insectoid Defense for Android and iOS. Coming soon to Windows Phone 8!
Insectoid Defense for Android and iOS. Coming soon to Windows Phone 8!

Questions?

You can comment this page below and I will respond as quickly as possible.

If you plan on developing games for Android, consider following my OpenGL ES tutorial series.

To give you an idea of what can be accomplished with OpenGL ES, download my free Tower Defense game.

More by this Author


Comments 156 comments

thewebprograms profile image

thewebprograms 4 years ago from India

Excellent article, I like it very much, thank you, I am going to try this now, to create a Media player under my name..thanks again


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@thewebprograms,

The fun part will be making the media player more dynamic! Also, it would be fun to incorporate a web service of some kind to fetch album art/information!

Have fun!


Leandro Llevado 4 years ago

Wow awesome work!!!!

Helps me alot by the way im creating music visualization could you teach me how?


Nuhendra 4 years ago

Grt tutorial..but i want some more functionality like rewind..fast forward and progress slidebar in mediaplayer.

Hope u can help me to achieve this thnks


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@Nuhendra,

I have given you everything you need to figure it out on your own, which is funnest part anyway!

Look at Music.java

Play with the mediaPlayer object, see what you can do with it; whenever you find something useful, turn it into an accessible function that you can call from your activity.

Give it a try!


freezbay 4 years ago

Really complete guide. You took the time to write it down. Really appreciate it!


phi 4 years ago

I use the API 7. So where path = Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_MUSIC);

path2 = Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES) I will have to change how? Thanks


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@phi,

Those Environment String constants are only applicable with API level 8 and above.

Therefore, you gotta do it the old fashioned way.

String path2 = Environment.getExternalStoragePublicDirectory("Pictures/");


phi 4 years ago

Thank you so much! But still doesn't work.

Error:The method getExternalStoragePublicDirectory()is undefined for the type Enviroment.

Can you please guide you how to add next and previous button?

Thanks!


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@phi,

Oh wow, I didn't bother to check the method you were using. Yeah you have to be using API Level 8 and above for that one.

If you're using API Level 7 or lower, use getExternalStorageDirectory(), to open a File representing the root of the external storage. You should then write your data in the following directory:

/Android/data/files/


phi 4 years ago

I did it, I admire you too!

Thanks you so much!

Please guide me how after the play finished a song can automatically play the next song.


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@phi,

In this method below:

public void onCompletion(MediaPlayer mediaPlayer) {

synchronized(this){

isPrepared = false;

}

}

You will need to send a broadcast to MyMediaPlayerActivity telling it that you have completed a file. When MyMediaPlayerActivity receives this broadcast, it can decide whether or not to play the next track, or any track you want!


phi 4 years ago

I really do not understand it. can you do that on the code?

Thanks.


sam 4 years ago

Thanks alot for the very detailed tutorial...

but the player force closes everytime I scan the sdcard and press the play button....this is the logcat report:

04-13 04:21:03.588: E/AndroidRuntime(275): FATAL EXCEPTION: main

04-13 04:21:03.588: E/AndroidRuntime(275): java.lang.IllegalStateException: Could not execute method of the activity

04-13 04:21:03.588: E/AndroidRuntime(275): at android.view.View$1.onClick(View.java:2072)

04-13 04:21:03.588: E/AndroidRuntime(275): at android.view.View.performClick(View.java:2408)

04-13 04:21:03.588: E/AndroidRuntime(275): at android.view.View$PerformClick.run(View.java:8816)

04-13 04:21:03.588: E/AndroidRuntime(275): at android.os.Handler.handleCallback(Handler.java:587)

04-13 04:21:03.588: E/AndroidRuntime(275): at android.os.Handler.dispatchMessage(Handler.java:92)

04-13 04:21:03.588: E/AndroidRuntime(275): at android.os.Looper.loop(Looper.java:123)

04-13 04:21:03.588: E/AndroidRuntime(275): at android.app.ActivityThread.main(ActivityThread.java:4627)

04-13 04:21:03.588: E/AndroidRuntime(275): at java.lang.reflect.Method.invokeNative(Native Method)

04-13 04:21:03.588: E/AndroidRuntime(275): at java.lang.reflect.Method.invoke(Method.java:521)

04-13 04:21:03.588: E/AndroidRuntime(275): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)

04-13 04:21:03.588: E/AndroidRuntime(275): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)

04-13 04:21:03.588: E/AndroidRuntime(275): at dalvik.system.NativeStart.main(Native Method)

04-13 04:21:03.588: E/AndroidRuntime(275): Caused by: java.lang.reflect.InvocationTargetException

04-13 04:21:03.588: E/AndroidRuntime(275): at com.technegames.mymediaplayer.MyMediaPlayerActivity.click(MyMediaPlayerActivity.java:309)

04-13 04:21:03.588: E/AndroidRuntime(275): at java.lang.reflect.Method.invokeNative(Native Method)

04-13 04:21:03.588: E/AndroidRuntime(275): at java.lang.reflect.Method.invoke(Method.java:521)

04-13 04:21:03.588: E/AndroidRuntime(275): at android.view.View$1.onClick(View.java:2067)

04-13 04:21:03.588: E/AndroidRuntime(275): ... 11 more

04-13 04:21:03.588: E/AndroidRuntime(275): Caused by: java.lang.IllegalStateException

04-13 04:21:03.588: E/AndroidRuntime(275): at android.media.MediaPlayer.isPlaying(Native Method)

04-13 04:21:03.588: E/AndroidRuntime(275): at com.technegames.mymediaplayer.Music.dispose(Music.java:95)

04-13 04:21:03.588: E/AndroidRuntime(275): at com.technegames.mymediaplayer.MyMediaPlayerActivity.loadTrack(MyMediaPlayerActivity.java:155)

04-13 04:21:03.588: E/AndroidRuntime(275): ... 15 more

What could be the problem?


balbirMathsApps 4 years ago

Great program exactley what need formy next project. Could you please explain how to put my own photo and music into the app so that I can send to my family. Thanks.


balbirMathsapps 4 years ago

I found your music in the assets. I have been playing around with music in raw folder. Thanks.


vivek.takneek@gmail.com 4 years ago

Your article is much good .

Please send me the code for fetch video from server and run this video on my custom media player. And noone can run these videoes excepting 50 members[they have this application].

Again Thank You Very Much *-*


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@vivek.takneek@gmail.com,

You are asking a very vague question. I need more context before I can even begin to think about helping you via code.


nomi 4 years ago

Theak hy . par thora complex laga......


shesna 4 years ago

i want to control my pc's media player by using my android phone ?.how it is possible?.


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@ shesna,

I'm sorry, but that question exceeds the scope of this article. I am prepared to answer your programming questions and help you along starting out, but that is all.


Robin 4 years ago

This was awesome...can you please help me in creating playlist...

i'll be veru thankful to you.

robinroyal15@gmail.com


Robin 4 years ago

This was awesome

can you please help me in creating playlist of audio tracks

i'll be very thankful to you

waiting for ur reply

robinroyal15@gmail.com


krishan kumar 4 years ago

This site is very informative for me. After reading this site I got much information about media player.


Rahul Upadhyay 4 years ago

Really very helpful. Can we speed up the song while playing like from 1x to 2x? If yes then how?


Haquang 4 years ago

Hello,

I tried to follow your tutorial but every time I ran the application, my phone displayed a notice that the application closed unexpectedly. Did I made mistake somewhere?

By the way, the link for your source code died. Can you upload it again? I would like to play around with your source code to understand if I made any mistake because I am a beginner!

Thanks

Haquang


abdullah 4 years ago

nice work.

I want to play music from sd card, but it gives the following error

the application mymediaplayer(process mymediaplayer )has stopped unexpectedly.pls try again. thank you


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@abdullah,

I will not be able to help you unless you showed me the logs. Force closes are typically the easiest thing to fix, but only if you know where the error occurred.


Bala 4 years ago

This is very nice tutorial...


Italo 4 years ago

Hi, I have the same problem with this code below

path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);

path2 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

I'm using API 10. Could you help me with this?

italo.malveira@gmail.com


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@Italo,

Yes, using this code, you are only attempting to reference the root of the sd card/pictures and /music folder. You still have to check whether or not that directory exists before you attempt to write files to those folders.

Now, if you were trying to use this code to gather all of the pictures and music on the sd card, you are better off using this code instead:

Replace the below "[" and "]" with a left inequality sign and a right inequality sign respectively. Hubpages does not allow the slightest hint of HTML markup in comments.

ArrayList[Uri] contents = new ArrayList[Uri]();

contents.add(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

contents.add(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);

This will give you references to all the media available, provided that an SD card scan has been ran somewhat recently (otherwise files very recently added would not be added using this code).

There are plenty of methods available for requesting a media scan if you feel that is necessary.

Hope this helps, let me know!


Asad Rehman 4 years ago

Can you expalin again what you said to Italo


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@Asad Rehman,

To get a reference to all of the pictures on a device, you could create a list of Uri elements, and add MediaStore.Images.Media.EXTERNAL_CONTENT_URI to it.

If you wanted to simply look up pictures on the sd card that were in root/pictures, you would do this:

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

Hope this helps.


manshi 4 years ago

if a song is already playing and I press next button, then it will check whether mediaplayer is playing or not. If playing, then it simply returns..how it will play the next track. (this is as per ur code0. Please reply asap.

Thanks


frozenhill 4 years ago

very nice tutorial ,

i put mp4 video in assets folder then run the app its only played the sound of video without the picture , could you please help me in doing that , im interest to get avideo player rather than music player

thanks alot


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@frozenhill,

There are plenty of nice tutorials for that on the net. I would answer your question here, but it is not only far out of the scope of this article but also a comment itself.

Let me know if you end up not being able to find anything, and thanks!


androidqq6 4 years ago

its really amazing tutorial, endless helpfull , Thanks Indeed .


frozenhill 4 years ago

i searched alot but i cant find good tutorial about video player please if you know any link tell me . Thanks


Shaily Mittal 4 years ago

It is unable to add tracks from sd card and giving force close on clicking the "play" button...


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@Shaily Mittal,

In this example, you are probably not adding tracks to the correct folder. You are more than likely encountering a NullPointerException. You should add a null check before attempting to play any music. Also, why not scan the entire SD card recursively? There are tutorials on how to do this.

Lastly, if you are on API 8 and above, you can use a ContentProvider to grab everything on the phone via a Uri type.


Mahendran 4 years ago

i got a idea

thanks....for giving the cods


Arpit Arora 4 years ago

Please Tell me that how will i show the list of the songs which are available in my sdcard.

Please tell as soon as possible.

I will be really thankfull to you.


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@Arpit Arora,

If you follow this tutorial and run the app, all you would have to do is press the menu key to switch to the sd card.


Nguyen 4 years ago

Hello Alucard.

I run your app and it is good. Thank your tut, it is helpful.

I want to run all the track auto but i don't know how to do that.

Your tut say "

public void onCompletion(MediaPlayer mediaPlayer) {

synchronized(this){

isPrepared = false;

}

} "

but i can't spent it.

I worte a function as :

public void complete(){

mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

public void onCompletion(MediaPlayer mp) {

System.out.println("The track is complete");

//setNextTrack();

}

});

}

It run well but i can't run setNextTrack();

because if i call function

public void setNextTrack(){

setTrack(1);

loadTrack();

playTrack();

}

it is NullPoiterEx, the app is close.

Can't You help me spend your thread. Thank you very much.

P.s : I 'm so sory if my English isn't good.


santhosh 4 years ago

i downloaded ur code, wen i imported to my eclipse shows an erron on my

main activity.java in R...so wat wil i do ???


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@santhosh,

Using the toolbar above, select "Project" and then "Clean..."


Kai Dupke 4 years ago

That's a nice article and perfectly fits into a project I have in my mind for long time - building a dash mounted media player for my bike. All media players till have ways too many functions.


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@Kai Dupke,

I agree, when you are on the go, media players need to be simple and have big buttons!


programmer2 4 years ago

Please can you help me any part responsible for helping the mp3 palyer read the song from the sd card and put them in a data structure to start recording them .Please help me because this issue is new and difficult for me


jagdish nagar 4 years ago

can u give me how to make a fullScreen code ...................i tried for lot i didn't get till now please help me its urgent my id is :

jagdishnagar22@gmail.com

thanks advance,,,,,,,,,,


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@jagdish nagar,

Here is one way, place this in in the application tag of your manifest.xml:

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"


stephtsf 4 years ago

This is great stuff indeed. Have you considered setting up an alternating raw audio data buffer scheme?

Say buffer #1 is ready, containing decoded audio data (32 bit) from the .mp3 decoding process. Say buffer #2 is busy, under progress, progressively receiving audio data from the source. You would only read buffer #1 and possibly elaborate some new audio data from it, using digital filtering (IIR or FIR). Such new audio data, you could send it to mass storage, or you could send it to the on-board speakers. You just made a MP3 player with an equalizer inside. That's the purpose. Or a multiband dynamic processor. Or a speaker management system (crossover). Or a hearing correction device. Do you see the applications?

When the whole content of buffer #1 gets exploited, you wait untill buffer #2 gets ready.

You then swap the buffers roles. You read buffer #2 and you allow buffer #1 to progressively fill in. And when you are done, you do the swap again. Again and again.

By the way, if you show how to hook a CM6206 USB sound card on an Android device (need ALSA ?), for giving Android devices multichannel audio capabilities, that would be absolutely wonderful, and I'll become a fan (or a customer).


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@stephtsf,

That does sound very interesting! Android already has access to multichannel sound though; up to 16 simultaneous sounds! I typically only use this for sound effects in my games though, and not music.


stephtsf 4 years ago

Yes indeed, once you want to apply your own sound effects you need to know the Linux/Android sound system in detail. Are you currently using JACK/ALSA? Let's introduce another preoccupation now: what if you want to become multiplatform, generating one source code to be compiled for Linux/ iOs. Do you have expertize?


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@stephtsf,

Yes, using native C/C++ code, you can write multiplatform code that can be used practically anywhere. For example, you could write a SoundEngine class in C++ that could be used both on Android (via the NDK) and iOS.

Often times though, this is completely unnecessary and not very beneficial.


stephtsf 4 years ago

Yes indeed. In the experimental stage, it is better to program bare metal without many abstraction layers. I'm very curious to see an example in native C code for Android relying on an alternating raw audio data buffer scheme, doing audio generation (random noise), filtering (one IIR biquad), outputting two new (specialized) audio channels over USB, with the smartphone or the tablet sound settings remaining intact, still able to do the telecoms (2G/3G/4G), still able to run an audio or video player just as usual, using the internal audio sub-assembly. Do you know Android apps sending audio data over USB? Is Android supporting USB sound cards like the CM6206?


Alucard_1990 profile image

Alucard_1990 4 years ago from Nashville, TN Author

@stephtsf,

I am not sure if Android supports USB sound cards. That would be something worth researching.


stephtsf 4 years ago

On Apr 28, 2011 Wolfgang Breyha and Takashi Iwai submitted a Linux patch adding support for the Terratec Aureon 7.1 USB which uses a C-Media CM6206 chip needing all the quirks already found in the past for getting them working under Windows.

The Wolfgang Breyha and Takashi Iwai Linux patch can be found at

http://code.google.com/p/ast-linux-patches/source/...

The Windows driver they seem to be basing on is known as the "CMedia CM-6501 Sound Series 32bit 5.12.2.4219".

Actually there is no C-Media CM-6501 chip.

The CM6206 little brother is the CM106 chip that you find in the Trust SC-5500 5.1 USB sound card. There is another Windows driver for it, known as "C-Media CM106 Like USB Audio Driver 6.12.8.2013".


Long Bunly profile image

Long Bunly 3 years ago

Anyone still here? I download your project but I miss File R.java so what can I do to solve this problem with you project, Hope you can help me

Thankz


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

R.java is generated by the Android builder. Trying doing a Project Clean followed by a "CTRL + SHIFT + O" command in the class that is missing the file.


Long Bunly profile image

Long Bunly 3 years ago

Dear @Alucard 1990

Thanks for you reply I saved me !!!

Anyways I got some error (android:onClick) in layout code in Mail.xml file

and some error on Java file (Evironment.Directory....)

I try to search google to fix it but I can't find a good solution to fix that

Hope you show me how to fix


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

Give me some more detail, and I can help.


Long Bunly profile image

Long Bunly 3 years ago

I got some error on java file

path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);

path2 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

(DIRECTORY_MUSIC cannot be resolved or is not a field)

( DIRECTORY_PICTURES cannot be resolved or is not a field )

also some error in Main.xml

(error: No resource identifier found for attribute 'onClick' in package 'android')


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly

From the Android documentation:

public static String DIRECTORY_MUSIC

Since: API Level 8

public static String DIRECTORY_PICTURES

Since: API Level 8

This means that you must be developing against at least android API Level 8 in order to access these String constants.

As for the onClick error, try referencing the documentation about it:

http://developer.android.com/reference/android/R.a...

It is only available as of API level 4. I assume you are developing against something higher than 4, but if not, then that is your problem.

Hope this helps!


Long Bunly profile image

Long Bunly 3 years ago

Thank, for your detail, I hope I can fix it, anyways I am new beginner so I just import your project and try to fix it as well as i can do. So what should i do to change API level?


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

Right click the Android project, click Properties, click Android


Long Bunly profile image

Long Bunly 3 years ago

better than before, all error are fixed except 3 errors in Main.xml file

Android:onClick

error: No resource identifier found for attribute 'onClick' in package 'android'

I try to fix it by I still can't.


Long Bunly profile image

Long Bunly 3 years ago

Thank you so much!!!!

I did it :)

so now if I want to play music from my sd card what should I do for next step ?


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

Place music on the sd card, like in the music folder or something. If you downloaded my sample project, it is set up to allow you to press the menu button to switch the source to sd card.


Long Bunly profile image

Long Bunly 3 years ago

Thank you, but I try to load music from my SD card I got a Toast message Loaded 0 tracks then app stop working and error message appear to close app


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

You'll have to show me your stack trace on this one buddy.


Long Bunly profile image

Long Bunly 3 years ago

In my sd card I created a folder name MP3 and I keep some mp3 file in there, but when I go to menu click on source, message appear

"Loaded 0 tracks"

after that app close

"unfortunately, MyMediaPlayer has stopped"


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

Make a folder called "music"


Long Bunly profile image

Long Bunly 3 years ago

Thank you so much, I did it :)

anyways could guide me for good tutorial for making basic game app ?


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

I'm actually planning on writing one sometime this week or next week.


Long Bunly profile image

Long Bunly 3 years ago

Wow!!! I can't wait to see that !! Anyways is it possible to create a global menu and add it to all activities? I have 5 activities but I want to use the same menu, but the problem is I must write the same code for each class.


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

Hahaha!! You made me laugh with that one! I figured you were new to Android, but it looks like you are new to programming in general, huh?

This is a classic case of implementing the DRY principle. Simply create a parent activity that contains the menu logic. Make all of your other activities extend this one, and they will display the menu from your parent class's menu logic.

D.R.Y = Don't Repeat Yourself


Long Bunly profile image

Long Bunly 3 years ago

I found it :) thank, but I still wonder wonder if I can create global menu with out activities, for example, my menu title is "Sound on" when I click on it, but when I click menu again it show " Sound off" I am creating a small app for my sister's request.


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

What do you mean by "Menu" here? Are you referring to "Menu" in the sense of a native Android menu? Or some UI component you are working on?


Long Bunly profile image

Long Bunly 3 years ago

I mean sense of a native android menu


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Long Bunly,

I am trying to understand what your goal is. So, are you referring to "Global Menu" as something that controls a global app behavior, such as Sound On/Off ?

In that case, simply make the menu store the setting for sound (true for on, false for off) in SharedPreferences. That way, every time you populate the menu title text, you can simply read the value from SharedPreferences to determine what the text should be.

http://developer.android.com/reference/android/con...


Long Bunly profile image

Long Bunly 3 years ago

Thank you, you saved me again and again, I have only word Thank to you. :)

next could u guide me? if I want to be game developer. what should I learn from now? for example making game "fish dairy" or "where is my water" I want some basic from you, so could you help?


Ram 3 years ago

Hi sir,

it's a great tutorial for me. thank you. I need the details of create a unique format video player. like (*.dic, *.gr). I don't use mp4, mp3, avi. i need only unique formats. ple. send the details to stillram@gmail.com.

Thank you.


Candel├╣ 3 years ago

Great tutorial! Thank you! It works for me! but I'm not satisfied with a simple copy and paste. Could you please tell me which is the best way to understand all the code! I also thought of playng around whit the code but I'm afraid of damaging it! I know java theoretically but still can not deal with java API. Please give me a good suggestion!


marco 3 years ago

Hi, I've followed your tutorial and am stuck on retrieving songs from my SD card. When I attempt to switch to SD card it says "0 songs loaded" and then crashes. I already made a folder on my SD card called "Music" where I put all my songs. However it still doesn't manage to retrieve them. Any help on this would be greatly appreciated.

Thanks in advance!


sourabh143143 3 years ago

i want to study more about creating media player for android can u help me out suggesting some books for the same!!!


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@marco,

This tutorial targets ALL Android devices. As of API level 8, you can use the content management system to collect all of the music on the device. The majority of the population uses API level 9 or above, so it is in your best interest to use the media store API:

http://www.androidsnippets.com/list-all-music-file...


Raz 3 years ago

Hi, really great tutorial and simple player,just what I was looking for :).

I have one question, how do I make the player load songs from within folders and not only song files that are inside the Music folder?

Thanks,

Raz.


Yash 3 years ago

Hey great tutorial man

I am making a similar music player app my question is how i can i automatically create a database when all the songs have been scanned.

Also is it possible to store artwork,album,artist details of a particular song in the database


marco 3 years ago

@Alucard_1990,

Thanks for the advice! I'll definitely look into that.


Max 3 years ago

Thx for the tutorial, defently shined some light on issues i was facing, but now i have been at this for days and cant get it figured out, what code needs to changed in order to make this into a streaming radio app. Let say, I run an internet radio station, and would like a simple radio app, I like the simplicity of this app, can you provide a tutorial, or let me know of what code needs to changed? thx


Kunal Verma 3 years ago

Hi, Like this article, works really well.

I want a list of tracks to be included in my app. These are .midi files. Very short sizes. I want to show them in a playlist. I read above in comments you have pointed out how to do it for media files in SD card.

But I want to include the tracks in my app. I dont want to create a list of all files in the raw folder as it would include all the sound effects.

Can I achieve this by creating a new folder inside raw and that too all these files are accessible from a play list and played through this media player


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Kunal Verma,

I include 4 midi tracks in this demonstration app.

The place to include these "packaged" audio files is the "assets" folder of your project.

Please download the source code for this project (above), and you will see what I am talking about.

Good luck!


Kunal Verma profile image

Kunal Verma 3 years ago

@ Alucard 1990

Thanks for the reply

Yeah I downloaded your project. Tested it. The files are played from the assets folder.

I created a Spinner ( like a playlist , drop down list view with checkbuttons in the list) to show the contents of the assets folder. Now in this spinner, besides the 4 .mid tracks, I see 4 other folders which are "kiosk mode, sounds, images and webkit" .

Also I put all the tracks inside a "sounds" folder ( i created it) in the assets folder

Then I see two more files other than the .mid files that are bootanim0.raw and bootanim01.raw in the list.

Also when I load the tracks from this folder, I get an error loading the tracks.

I want to play the track selected from the spinner.

I am working on it and I think I can create a music player according to my requirements modifying yours.


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Kunal Verma,

Awesome! Sounds like a really cool project.

Good luck!


Gurchela 3 years ago

Sir can anyone please give me the code how to display all videos from sd card in this player........i need it very urgently.....thanks very much in advance


Anchi 3 years ago

Sir,I am facing problem with the code below:

path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);

path2 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

I am using API 10...will u please help me out with it?I didnt gt the solution through earlier comments.


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Anchi,

I put together some sample code for you:

http://phoenixweb407.somee.com/sample_code.html


Hancini 3 years ago

Hello, thankyou for straight forward tutorial. I am using Eclipse and have problem with this part of the code...

setContentView(R.layout.activity_main);

Error say 'R cannot be resolved to a variable'

and

getMenuInflater().inflate(R.menu.activity_main, menu);

Error say 'R cannot be resolved to a variable'

What can be this problem?


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Hancini,

R refers to the R class, which is generated by the ADT from your resources located in the "res" folder.

Try doing [CTRL] + [SHIFT] + [O], to organize your imports. If that that still doesn't work, then that means your R class is not being generated correctly. In that case, try doing a Project - Clean...


Virang 3 years ago

hey Sir, I dowloaded your source code & imported it into my workspace..

MyMediaPlayer.java shows a 101 errors !!!

almost everything declared gives the error "cannot be resolved to a type" !

the very first error is in the very first line..

the error is..

"The type java.lang.String cannot be resolved. It is indirectly referenced from required .class files"

I'd be thankful if you help me through this..:)


Virang 3 years ago

Oops..

my bad..

i hadnt selected the target & hence the errors..

anyway, thanks a lot for this article..

really helpful..:)


rojy 3 years ago

Nice tutorial,Thanks

how to modify this app so that we can show lyrics for a song


Hancini 3 years ago

I tried both but to no avail, so I deleted and imported the project again and all is working now :)

This is a very handy application. I have a couple of questions.

Is there a way to display list of files? So I can see upcoming tracks & their names. Im thinking to make the artwork picture smaller, move the control bar up and place a playlist of loaded files below. Enabling me to select the music I want to hear, from the playlist.

It would be great if there is a way. I look forward to your reply. :)


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Hancini,

There are a number of ways to do that. Right now, the app is currently using the file name directly in order to playback the media, which means you have a list of file names. You can easily display these via a custom listview adapter with an icon on the left.


Hancini 3 years ago

Hello, thankyou for your reply. How could I display the list permanently? Would this be a case of display list "true"?

Regards


Daya 3 years ago

I have done all the things as directed but still while using the buttons the music player stops with the message "Unfortunately the myMusicPlayer has stopped working"

Can I get some advice as to which section to look at.


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Daya,

Please attach a stacktrace, and I can help you.


Faiza 3 years ago

nice tutorial

Can anyone help me plz. My app browses a text file and show it in textview. Here i have a button and onclick it speaks the whole text and for this i want to add play pause functionality.What should i do regarding this?


Abhishek Bansal 3 years ago

Thanks for nice tutorial. It helped me a lot. Sir I want to ask some questions regarding this tutorial. Well my Questions are:

1. what shall I do for importing my own music and play them in this app?

2. How to run this app in a background as a service?

thanks . I m looking forward for your help and also please reply me on my email id: " abhibansal@live.com "


R_U 3 years ago

i tried it in 4.1.1 and 2.3, and it shows toast with the message "Loaded 0 Tracks", but it shows in 2.3 singe music. what is the wrong?


Bitfield 3 years ago

Is there any way to balance the volume to left..right..in android


Moritz 3 years ago

Nice Tutorial :)

but i have some Problems with the music

i'm running 4.2.2 and all my music is located in /sdcard/music

but if i start the app it shows Loaded 0 Tracks :S

can u help me ?


prasadjacks profile image

prasadjacks 3 years ago from Mumbai, Maharashtra, India

it was great tutorial...

how do i scan d complete sd card for songs instead of just MUSIC directory ?


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@prasadjacks,

As of API level 8, you can use the content management system to collect all of the music on the device. The majority of the population uses API level 9 or above, so it is in your best interest to use the media store API:

http://www.androidsnippets.com/list-all-music-file


sweet angel 3 years ago

great tutorial.....

i need to display the list of all tracks in new activity..help..........!!!!!!!!!!.


sweet angel 3 years ago

great tutorial...........

i need to display the list of tracks in new activity and then play the required track......help.....!!!!!!!


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@sweet angel,

Just serialize your list of tracks and then send it to the next Activity as an Intent Extra.

For example (if called within an Activity):

Intent i = new Intent(this, NextActivity.class);

i.putStringArrayListExtra("SOME_INTENT_EXTRA_NAME", tracksList);


Distant Mind profile image

Distant Mind 3 years ago

This is quite interesting! I will have to build one as well! :)


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@Distant Mind,

Cool! It is a lot of fun!


ud1093 profile image

ud1093 3 years ago from ?

Thanks dude i downloaded the source and android development kit did not know what to do you have inspired me to make something new now ill keep experimenting on his lets see what i come up with


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@ud1093,

Sounds awesome! Let me know if you need any help.


Ali Huseyin 3 years ago

public void click(View view){

int id = view.getId();

switch(id){

case R.id.btnPlay:

synchronized(this){

if(isTuning){

isTuning = false;

btnPlay.setBackgroundResource(R.drawable.play);

track.pause();

} else{

isTuning = true;

btnPlay.setBackgroundResource(R.drawable.pause);

playTrack();

}

}

return;

.

.

.

}

play-pause button doesnt work after the end of the song.


Ali Huseyin 3 years ago

I think loadTrack();

...

} else{

isTuning = true;

btnPlay.setBackgroundResource(R.drawable.pause);

loadTrack(); // working with this

playTrack();

}

...

but pause button should be play button end of the song,

How can ─▒ do it

?


toptengamer profile image

toptengamer 3 years ago from The Game

This is really impressive. Amazing how simple it is after reading this.


ME 3 years ago

Media Player with Audio effects like Re-verb[ Large room , medium room , small room etc ] and Tone please help me


karan trehan 3 years ago

Namaste @Alucard_1990

One of the best tutorials i have come across for an audio player and the biggest advantage is it is highly simplified so we can customize it to the maximum possible. Thank you for the same.

I had only one question, is it possible for me to load tracks from a specific category inside the asset folder? If so how?

Thanks in advance for any help what so ever. Thank you again.


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@karan trehan,

By category, do you mean folder? You could create folders inside the assets folder if you wanted to and then reference them with the correct path.


karan trehan 3 years ago

Namaste @Alucard_1990

Thank you for a prompt reply, i made a folder inside the asset folder and placed a few .oggs there. What i am trying to do is make each class access the .oggs from that folder only and not any other folder.

I would be very much thankful if you help me out in that.

Thank you.


karan trehan 3 years ago

To be more precise i changed the gettracks() function to include the following lines

String[] temp = getAssets().list("FOLDERNAME");

It finds the files but then tells me "Error loading Filename"

Each class access a different subfolder inside asset folder.

Thanks in advance


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@karan trehan,

Just hardcode the path to the folder inside your assets like "special/sample.ogg"


karan trehan 3 years ago

@Alucard_1990

Sorry for being such a noob but I am really not finding a way how i can do that. I tried all the possible coding wizardy i could try but to no avail, if you can show me a code snippet to do the same i would be really very grateful.

The idea is simple: have subfolders in assets and have a separate player class for playing the files of only that folder. There are around 10 files per subfolder.

Thank you for taking out the time for replying.


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@karan trehan,

I have an answer for you here (hubpages wouldn't let me post my comment):

http://technegames.com/comment.html


karan trehan 3 years ago

@Alucard_1990

Namaste and Thank you soo much for your help. Even after all your help, it just did not work for me and I did not want to pester you with more questions so I used a bit of my own brains and found a way out. Using each category with a different extension like .ogg for one category and .mp3 for another and formatting .java file in the same way. It did work for now, but I am planning to work out a stronger way round. Thanks for the help and once I am done with the code i would like to show it to you. Any way i can do that sir?


Alucard_1990 profile image

Alucard_1990 3 years ago from Nashville, TN Author

@karan trehan,

Certainly! Create a Drop Box account if you do not already have one and upload it to the Public folder. Once you do that, simply give me the link to the file and I will check it out and provide you with feedback.


martin321 profile image

martin321 3 years ago from London, United Kingdom

Great hub with lots of technical code :)


tho 3 years ago

its great tutorial !!

i have a problem, my project cant find out any mp3 files in sdcard.

can you tell me anything ?


Newbie 3 years ago

i have a listview and i want to put my file list in "assets" into my listview.

i try many way but i can't. hope you can help me.

thank you in advanced


ashwini patil 3 years ago

Add Your Cot is unable to add tracks from sd card and giving force close on clicking the "play" button..


Geoffrey Shea 2 years ago

Thanks for your effort!

Here's my problem. On emulator or device app crashes when I try to select SD card as source:

12-28 11:11:41.065: W/dalvikvm(8697): threadid=1: thread exiting with uncaught exception (group=0x415aaba8)

12-28 11:11:41.065: E/AndroidRuntime(8697): FATAL EXCEPTION: main

12-28 11:11:41.065: E/AndroidRuntime(8697): Process: com.technegames.mymediaplayer, PID: 8697

12-28 11:11:41.065: E/AndroidRuntime(8697): java.lang.IllegalStateException: Could not execute method of the activity

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.view.View$1.onClick(View.java:3823)

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.view.View.performClick(View.java:4438)

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.view.View$PerformClick.run(View.java:18422)

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.os.Handler.handleCallback(Handler.java:733)

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.os.Handler.dispatchMessage(Handler.java:95)

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.os.Looper.loop(Looper.java:136)

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.app.ActivityThread.main(ActivityThread.java:5017)

12-28 11:11:41.065: E/AndroidRuntime(8697): at java.lang.reflect.Method.invokeNative(Native Method)

12-28 11:11:41.065: E/AndroidRuntime(8697): at java.lang.reflect.Method.invoke(Method.java:515)

12-28 11:11:41.065: E/AndroidRuntime(8697): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)

12-28 11:11:41.065: E/AndroidRuntime(8697): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)

12-28 11:11:41.065: E/AndroidRuntime(8697): at dalvik.system.NativeStart.main(Native Method)

12-28 11:11:41.065: E/AndroidRuntime(8697): Caused by: java.lang.reflect.InvocationTargetException

12-28 11:11:41.065: E/AndroidRuntime(8697): at java.lang.reflect.Method.invokeNative(Native Method)

12-28 11:11:41.065: E/AndroidRuntime(8697): at java.lang.reflect.Method.invoke(Method.java:515)

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.view.View$1.onClick(View.java:3818)

12-28 11:11:41.065: E/AndroidRuntime(8697): ... 11 more

12-28 11:11:41.065: E/AndroidRuntime(8697): Caused by: java.lang.IllegalStateException

12-28 11:11:41.065: E/AndroidRuntime(8697): at android.media.MediaPlayer.isPlaying(Native Method)

12-28 11:11:41.065: E/AndroidRuntime(8697): at com.technegames.mymediaplayer.Music.play(Music.java:45)

12-28 11:11:41.065: E/AndroidRuntime(8697): at com.technegames.mymediaplayer.MyMediaPlayerActivity.playTrack(MyMediaPlayerActivity.java:354)

12-28 11:11:41.065: E/AndroidRuntime(8697): at com.technegames.mymediaplayer.MyMediaPlayerActivity.click(MyMediaPlayerActivity.java:305)

12-28 11:11:41.065: E/AndroidRuntime(8697): ... 14 more


Alucard_1990 profile image

Alucard_1990 2 years ago from Nashville, TN Author

@Geoffrey Shea,

Did you make sure to configure your emulator with an SD card in the AVD options?


Geoffrey Shea 2 years ago

I did not. But I will. Although it had the same effect (crashing) on my device: Nexus 5 with no SD card.


Akram khan 2 years ago

Hey great tutorial, Though needed a bit of help just want to play a set of files rather than all the files on SD Card . can you please help me out . Thanks a lot in advance


simpleminds 2 years ago

thank u for the code......It works.


nancie17 2 years ago

why .apk file is not working in my fone ..it is showing that file unexpectedly stop ..??


Stan Considine profile image

Stan Considine 2 years ago

where do i download the source code?


Jeff 2 years ago

Thank u man!


Faiz 2 years ago

Great man. Can u guide me how to play songs from dropbox??? I'll be very thankful to you.


Johne434 2 years ago

Happy to become one of several customer for this wonder inspiring site D. kkeedbbgcfed


Darryl 2 years ago

Hey, great tutorial but I have to ask: How do you advance to the next track? I was thinking that in the OnCompletion I would add "switchTracks()" then I realized that it just sets the track to the beginning and pauses the player. Than I thought that I'd just add the following in the OnCompletion:

setTrack(1);

loadTrack();

playTrack();

But of course that doesn't work. You mentioned in a comment above that "You will need to send a broadcast to MyMediaPlayerActivity". I assume you meant creating a custom broadcast, but when I tried I got an error saying my GetInstance was not applicable for the arguments Music. Do you have example code of how to create the broadcast to advance to the next track? Thanks.


Roshan Upreti profile image

Roshan Upreti 2 years ago

Hi, First of all, thank you and kudos for this awesome guide. I was wondering, if you could help me out a little. I'm trying to load the "tracklist" as a contentview, instead of images in the app. Could you please give me a little heads up on how to get started with that. help would be much appreciated. Thanks again. :)


Sanjeev Kumar 2 years ago

Great tutorial..working fine...

thnxs


prachi 2 years ago

hi how to get mp3 from url or web services and then use this app in android.


Julia 2 years ago

I love this mediaplayer, but I can't figuere out how to add progress bar, in which class should I do that? Some help would be great, I'm just beginning


Julia 2 years ago

I'm so sad -I customizes the player and tested it, everything worked fine - but my new mp3 files, created with musescore and linuxsampler it won't load them. It's not the device, as other mediaplayer on that device play the files.


Ronak Godhania 8 weeks ago

Hey..firstly..Amazing code....Awesome idea..I have implemented it..but..I have made new project in which assets folder is not there..so no files can be put to play...I can run the project..But no music is there..!!! So how to put music files into my project..plz rply fast..!!!THANK YOU.

ronakgodhania1996@gmail.com

    Sign in or sign up and post using a HubPages Network account.

    0 of 8192 characters used
    Post Comment

    No HTML is allowed in comments, but URLs will be hyperlinked. Comments are not for promoting your articles or other sites.


    Click to Rate This Article
    working