views:

389

answers:

3

I have this problem, I have some audio I wish to play...

And I have two buttons for it, 'Play' and 'Stop'...

Problem is, after I press the stop button, and then press the Play button, nothing happens. -The stop button stops the song, but I want the Play button to play the song again (from the start) Here is my code:

final MediaPlayer mp = MediaPlayer.create(this, R.raw.megadeth);

And then the two public onclicks:

(For playing...)

 button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click
             button.setText("Playing!");
             try {
     mp.prepare();
    } catch (IllegalStateException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
             mp.start();
             //
            }
        });

And for stopping the track...

    final Button button2 = (Button) findViewById(R.id.cancel);
    button2.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

         mp.stop();
         mp.reset();

        }
    });

Can anyone see the problem with this? If so could you please fix it... (For suggest)

Thanks alot...

James

A: 

You need to call prepare() or preparAsync() before start().

See the API for details (look at the state diagram).

JRL
Look what I put...'mp.prepare' then some ifs... Then 'mp.start' so why isn't it working?
James Rattray
@James Rattray: Change the line that reads `mp.reset()` to `mp.prepare()` in your button2 code. Reset requires resetting the datasource and calling prepare again - it's to recover from an error.
JRL
So no mp.reset at all? Just mp.stop and then mp.prepare()? -Nope... that doesn't work =/
James Rattray
Quick fix: mp.pause(); then... mp.Seekto(0); This works, but on i'm guessing this is inefficient?
James Rattray
A: 

This is what I have working in my program. It releases the media player each time as I use different sounds each time it is called, however it should work as a work-around for your usage.

Creation:

    public MediaPlayer mp=null;

Starting:

    if (mp!=null){ 
            mp.reset();
            mp.release();
    }
            mp = MediaPlayer.create(test.this, soundResource);
            mp.start();

Stopping:

        mp.stop();

Also note that you do not require to use prepare because the create method already calls prepare for you (API REF).

stealthcopter
A: 

There is a bug in the Android documentation, in this page it is said that you could stop() a "raw resource" mediaplayer, and then replay it just by calling reset() and prepare() before calling start() again. This doesn't work, as you have noticed.

The problem is that reset() clears the audio source and returns to the initial state, so you must set again the data source. Unfortunatelly you can't set a "raw resource" data source, because there is no API for this besides create().

I don't know a clean way of solving this issue. stealthcopter's way works great, but is a pain for your design, as you need the context for each start() call :( And involves destroying and creating a complex object, which has a price for realtime apps like games...

Another way that ensures that context will only be needed for the create() call, is to stop the media player this way:

stop()
prepare()

but if you call start() now, it won't restart from the beginning. You could call seekTo(0), but the sound will have a bit of noise from the previous play position.

I keep investigating on this. There must be a clean and efficient way of stopping and restarting the mediaplayer when created on a raw resource...

Ruben