25

I'm new to Android development and I have a question/problem.

I'm playing around with the MediaPlayer class to reproduce some sounds/music. I am playing raw resources (res/raw) and it looks kind of easy.

To play a raw resource, the MediaPlayer has to be initialized like this:


MediaPlayer mp = MediaPlayer.create(appContext, R.raw.song);
mp.start();

Until here there is no problem. The sound is played, and everything works fine. My problem appears when I want to add more options to my application. Specifically when I add the "Stop" button/option.

Basically, what I want to do is...when I press "Stop", the music stops. And when I press "Start", the song/sound starts over. (pretty basic!)

To stop the media player, you only have to call stop(). But to play the sound again, the media player has to be reseted and prepared.


mp.reset();
mp.setDataSource(params);
mp.prepare();

The problem is that the method setDataSource() only accepts as params a file path, Content Provider URI, streaming media URL path, or File Descriptor.

So, since this method doesn't accept a resource identifier, I don't know how to set the data source in order to call prepare(). In addition, I don't understand why you can't use a Resouce identifier to set the data source, but you can use a resource identifier when initializing the MediaPlayer.

I guess I'm missing something. I wonder if I am mixing concepts, and the method stop() doesn't have to be called in the "Stop" button. Any help?

Thanks in advance!!!

Deepzz
  • 4,573
  • 1
  • 28
  • 52
arakn0
  • 499
  • 5
  • 11
  • 15
  • do you want just pause the Mediaplayer or stop completely and play again? – Jorgesys Jun 03 '10 at 21:02
  • stop completely and play it again. To pause...you have to call the method pause() and then start() if you want to continue playing. It's easy and works. The problem is when you try to stop completely and play again (like in any music player) – arakn0 Jun 03 '10 at 21:16
  • I have the same "problem". What I currently do is create a new MediaPlayer every time I start a song. I know it fills the memory with resources but I also call mp.release() on the previous used MediaPlayer. I think this solves the memory problem. I don't see any other solution. – Catalin Morosan Aug 05 '10 at 11:40
  • have the same issue, did you address yours somehow? – mishkin Jan 21 '11 at 16:03

7 Answers7

27

Here is what I did to load multiple resources with a single MediaPlayer:

/**
 * Play a sample with the Android MediaPLayer.
 *
 * @param resid Resource ID if the sample to play.
 */
private void playSample(int resid)
{
    AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);

    try
    {   
        mediaPlayer.reset();
        mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
        mediaPlayer.prepare();
        mediaPlayer.start();
        afd.close();
    }
    catch (IllegalArgumentException e)
    {
        Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
    }
    catch (IllegalStateException e)
    {
        Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
    }
    catch (IOException e)
    {
        Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
    }

mediaPlay is a member variable that get created and released at other points in the class. This may not be the best way (I am new to Android myself), but it seems to work. Just note that the code will probably fall trough to the bottom of the method before the mediaPlayer is done playing. If you need to play a series of resources, you will still need to handle this case.

adstro
  • 688
  • 1
  • 9
  • 17
  • AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid); works great on, but it seems not on all the phones. I just got a error report from an user - too bad it does say what phone is that – mishkin Jan 21 '11 at 16:04
16

this is how MediaPlayer.create method works to open a raw file:

    public static MediaPlayer create(Context context, int resid) {
         try {
             AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
             if (afd == null) return null;

             MediaPlayer mp = new MediaPlayer();
             mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
             afd.close();
             mp.prepare();
            return mp;
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
           // fall through
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        }
         return null;
    }
Deepzz
  • 4,573
  • 1
  • 28
  • 52
mishkin
  • 5,932
  • 8
  • 45
  • 64
9

Or, you could access the resource in this way:

mediaPlayer.setDataSource(context, Uri.parse("android.resource://com.package.name/raw/song"));

where com.package.name is the name of your application package

Louis CAD
  • 10,965
  • 2
  • 39
  • 58
4

You can use

mp.pause();
mp.seekTo(0);

to stop music player.

Deepzz
  • 4,573
  • 1
  • 28
  • 52
Rectangle
  • 41
  • 1
3

Finally, the way it works for me:

public class MainStart extends Activity {

    ImageButton buttonImage;
    MediaPlayer mp;
    Boolean playing = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main);

        buttonImage = (ImageButton)findViewById(R.id.ButtonID);


        buttonImage.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                if(playing){
                    mp.stop();
                    playing = false;
                }else{
                    mp = MediaPlayer.create(getApplicationContext(), R.raw.sound_u_want);
                    mp.start();
                    playing = true;
                }
            }
        });
    }
}
DragonWork
  • 2,415
  • 1
  • 18
  • 20
MarcBilbo
  • 51
  • 1
  • 2
0

MR. Rectangle, this message maybe too late for it, but I proudly write these codes to your idea: I have mp for mediaplayer and sescal9 is a button.

....
if(btnClicked.getId() == sescal9_ornek_muzik.getId())
        {
            mp.start();
            mp.seekTo(380);
            mp2.start();
            mp2.seekTo(360);
            mp3.start();
            mp3.seekTo(340);
            ...
            }
Bay
  • 467
  • 7
  • 22
0

Recheck your passing parameters not null

Possible reasons

  1. Context may be null
  2. Your media file may be corrupted
Ranjithkumar
  • 16,071
  • 12
  • 120
  • 159