2

I am using a method to initialize and prepare a MediaPlayer (defined as class variable). It takes a String which is the name of the song as its parameter and it sets the DataSource to that particular path.

public void create_and_prepare_song(String x) {
    if (mp != null)
        mp.release();
    mp = new MediaPlayer();
    String filePath = Environment.getExternalStorageDirectory().getPath() + "/songsfolder/" + x + ".mp3";

    try {
        mp.setDataSource(filePath);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        mp.prepare();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Now, somewhere inside my code I use this method to initialize and prepare "1.mp3". Then, as soon as this song is finished, I use an onCompletionListener so that "2.mp3" is played after, and "3.mp3" then. I use:

create_and_prepare_song("1");
i = 2;
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
    if (i <= 3) {
        String int_to_String = i + "";
        create_and_prepare_song(int_to_String); //1
        mp.setOnCompletionListener(this);
        mp.start();
        i++;
        }    
    }
});
mp.start();

Now, this causes app to stop from working! However, if I just copy and paste the body of the method to the //1 line instead, the app works fine, playing first, second and third song. Why is that so? Thanks a lot

2 Answers2

2

Note that you are creating a new player inside of create_and_prepare_song() but the old one is still referenced inside of the listener.

That's because the global variable and the onCompletion parameter has the same name: mp.

Here's piece of code that works:

package com.example.simon.mplaylist;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import java.io.IOException;

/**
 * Created by Simon on 2014 Jul 20.
 */

public class MainActivity extends Activity {

    static int currentSong;
    static MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (mediaPlayer != null)
            return;

        currentSong = 1;
        create_and_prepare_song(currentSong);

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                if (currentSong++ >= 3) {
                    mediaPlayer = null;
                    return;
                }
                create_and_prepare_song(currentSong);
                mediaPlayer.setOnCompletionListener(this);
                mediaPlayer.start();
            }
        });
        mediaPlayer.start();

    }

    public void create_and_prepare_song(int songNum) {
        if (mediaPlayer != null)
            mediaPlayer.release();
        mediaPlayer = new MediaPlayer();

        String storage = Environment.getExternalStorageDirectory().getPath();
        String filePath = storage + "/songsfolder/" + String.valueOf(songNum) + ".mp3";

        try {
            mediaPlayer.setDataSource(filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            mediaPlayer.prepare();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

NOTE also that I defined the MediaPlayer as static and also am checking @ onCreate for it's presence. That way you avoid multiple songs playing at once if the activity is recreated (e.g. screen rotation).

Simas
  • 43,548
  • 10
  • 88
  • 116
  • @darkchampionz there's a problem with your files then as I tested this and it worked. Also post the log cat, note that it must print something if app "stops working". – Simas Jul 20 '14 at 19:09
  • thing is it is still clear, I don't know what's wrong :/ besides that, your code really helped me a lot, it must be just something else I don't see yet, although I've checked numerous times. I will wait a bit more and I will accept your answer :) –  Jul 20 '14 at 19:48
  • Add a `Log.e("","");` at the start of `onCreate` if the log is still clear then read [this](http://stackoverflow.com/questions/2250112/why-doesnt-logcat-show-anything-in-my-android). – Simas Jul 20 '14 at 20:10
0

You really shouldn't be starting actual playback inside create_and_prepare_song(). It should be started inside onPrepared() since there might be some delay from the call to prepare() and the media being ready to play.

scottt
  • 8,301
  • 1
  • 31
  • 41