Search code examples
androidandroid-mediaplayerplayback

Unable to play next song in Music Player Application


I have seen a few tutorials that indicate that in order to play the next song from a raw folder all I need to do is write some code like:

case R.id.next : mp.next();break;"

However it is not working. What is the right way to implement the "play previous and play next song"?

Here is my code for reference:

public class MainActivity extends Activity implements OnClickListener, OnPreparedListener{

private static final String SAVE_POSITION = "MainActivity.SAVE_POSITION";
public static final int STANDARD_NOTIFICATION = 0x01001;
public static final int EXPANDED_NOTIFICATION = 0x01002;
private static final int REQUEST_NOTIFY_LAUNCH = 0;

//Audio Control buttons
Button media;
Button pause;
Button stop;
Button prev;
Button next;
//Media Player
MediaPlayer mp;
boolean mActivityResumed;
boolean mPrepared;
int mAudioPosition;

//array of songs
private int[] rawFiles = {R.raw.black_banquet,R.raw.door_of_holy_spirits,R.raw.castlevania_prologue};
//random playback
private Random random = new Random();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mPrepared = mActivityResumed = false;
    mAudioPosition = 0;

    if(savedInstanceState != null && savedInstanceState.containsKey(SAVE_POSITION)) {
        mAudioPosition = savedInstanceState.getInt(SAVE_POSITION, 0);
    }

    //button audio playback control
    media = (Button) findViewById(R.id.btMedia);
    media.setOnClickListener(this);
    pause = (Button) findViewById(R.id.pause);
    pause.setOnClickListener(this);
    stop = (Button) findViewById(R.id.stop);
    stop.setOnClickListener(this);
    media = (Button) findViewById(R.id.prev);
    media.setOnClickListener(this);
    media = (Button) findViewById(R.id.next);
    media.setOnClickListener(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()){
    case R.id.btMedia: if (mp == null){
        mp = new MediaPlayer();
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mp.setOnPreparedListener(this);

        //random song
        mp = MediaPlayer.create(this, rawFiles[random.nextInt(rawFiles.length)]);
    }
        //looping one song
        mp.setLooping(true);
        mp.start();
          break;
          case R.id.pause : mp.pause();break;
          case R.id.next : mp.next();break;
          case R.id.stop : mp.stop();mp = null;break;
        }


    // Notification Manager
    NotificationManager mgr = 
            (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

    // Setting the default action.
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    Intent intent = new Intent(this, MainActivity.class);
    PendingIntent pIntent = 
        PendingIntent.getActivity(this, REQUEST_NOTIFY_LAUNCH, intent, 0);
    // Setting the default action.
    builder.setContentIntent(pIntent);
    builder.setSmallIcon(R.drawable.ic_launcher);
    builder.setLargeIcon(BitmapFactory.decodeResource(
        getResources(), R.drawable.ic_launcher));
    builder.setContentTitle("Standard Title");
    builder.setContentText("songTitle");
    mgr.notify(STANDARD_NOTIFICATION, builder.build());

    }


@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if(mp != null) {
        outState.putInt(SAVE_POSITION, mp.getCurrentPosition());
    }
}


@Override
protected void onResume() {
    super.onResume();

    mActivityResumed = true;
    if(mp != null && !mPrepared) {
        mp.prepareAsync();
    } else if(mp != null && mPrepared) {
        mp.seekTo(mAudioPosition);
        mp.start();
    }
}

@Override
protected void onPause() {
    super.onPause();
    mActivityResumed = false;

    if(mp != null && mp.isPlaying()) {
        mp.pause();
    }
}

@Override
protected void onStop() {
    super.onStop();

    if(mp != null && mp.isPlaying()) {
        mp.stop();
        mPrepared = false;
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();

    if(mp != null) {
        mp.release();
    }
}


@Override
public void onPrepared(MediaPlayer mp) {
    // TODO Auto-generated method stub
    mPrepared = true;

    if(mp != null && mActivityResumed) {
        mp.seekTo(mAudioPosition);
        mp.start();
    }

}

Solution

  • For the Android MediaPlayer class there is no next method. What you need to do in order to implement the next functionality is to call mp.reset(), mp.setDataSource() with the next audio file, and mp.prepare().

    E.x.

     case R.id.next : {
         mp.reset();
         mp.setDataSource(**LOCATION OF YOUR AUDIO FILE**) 
         //See http://developer.android.com/reference/android/media/MediaPlayer.html#setDataSource(java.lang.String)
         mp.prepare();
         break;
     }