Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Play sound when button is clicked in Android?

Tags:

android

I'm trying to play a sound file when a button is clicked but keeps getting an error.

The error is:

 "The method create(Context, int) in the type MediaPlayer is not applicable for the arguments (new View.OnClickListener(){}, int)"

Here's my code:

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    Button zero = (Button)this.findViewById(R.id.btnZero);
    zero.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mp = MediaPlayer.create(this, R.raw.mamacita_zero);
        }
    });
}

Any help or tips would be appreciated. Thnx!

like image 678
Grendizer Avatar asked May 02 '10 15:05

Grendizer


People also ask

What procedure do you call in order to play a sound in Android?

mediaPlayer. start(); mediaPlayer. pause(); On call to start() method, the music will start playing from the beginning.

What is sound pool?

A SoundPool is a collection of sound samples that can be loaded into memory from a resource inside the APK or from a file in the file system. The SoundPool library uses the MediaCodec service to decode the audio into raw 16-bit PCM.


2 Answers

There are a few things going on here (disclaimer, this is just how I'm used to using it, there may be a better way):

  • You seem to be doing a lot more work per click than you need to. You're creating and adding a new onClickListener for every click in the Activity's View, not the Button. You only need to set the listener once, and for the Button rather than the overarching View; I tend to do that in the constructor of the Activity.

  • Regarding your error, MediaPlayer works fine for me when the Context I pass it is the overriding Activity. When you pass this, it's passing the onClickListener you are creating, throwing off the MediaPlayer.

  • Finally, to actually play the sound, you have to call start().

So for the constructor in the Activity, you can create the MediaPlayer once, find the Button, and attach an onClickListener that will play the sound from the MediaPlayer you've just created. It would look something like:

public class MyActivity extends Activity {

    public MyActivity(Bundle onSavedStateInstance) {
        // eliding some bookkeepping

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

        Button zero = (Button)this.findViewById(R.id.btnZero);
        zero.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mp.start();
            }
        });
    }
}

Hope that helps!

like image 60
pablo.meier Avatar answered Nov 15 '22 08:11

pablo.meier


I have played around with media-player, and it is easy to get in trouble. I followed the advice of Volodymyr, and SoundPool is much easier to manage.

MediaPlayer does not like to play more than one sound at the time, like for instance when you have lots of quick tabs on your buttons. I managed with the following method:

private void playSound(Uri uri) {
    try {
        mMediaPlayer.reset();
        mMediaPlayer.setDataSource(this, uri);
        mMediaPlayer.prepare();
        mMediaPlayer.start();
    } catch (Exception e) {
        // don't care
    }

}

In the constructor I did:

mMediaPlayer = new MediaPlayer();
mSoundLess = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.less);
mSoundMore = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.more);

On click I would then call playSound(mSoundLess):

Instead I have created a SoundPool helper:

package com.mycompany.myapp.util;

import java.util.HashSet;
import java.util.Set;

import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;

public class SoundPoolHelper extends SoundPool {
    private Set<Integer> mLoaded;
    private Context mContext;

    public SoundPoolHelper(int maxStreams, Context context) {
        this(maxStreams, AudioManager.STREAM_MUSIC, 0, context);
    }

    public SoundPoolHelper(int maxStreams, int streamType, int srcQuality, Context context) {
        super(maxStreams, streamType, srcQuality);
        mContext = context;
        mLoaded = new HashSet<Integer>();
        setOnLoadCompleteListener(new OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                mLoaded.add(sampleId);
            }
        });
    }

    public void play(int soundID) {
        AudioManager audioManager = (AudioManager) mContext.getSystemService( Context.AUDIO_SERVICE);
        float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        float volume = actualVolume / maxVolume;
        // Is the sound loaded already?
        if (mLoaded.contains(soundID)) {
            play(soundID, volume, volume, 1, 0, 1f);
        }
    }
}

Now I init like this:

mSoundPoolHelper = new SoundPoolHelper(1, this);
mSoundLessId = mSoundPoolHelper.load(this, R.raw.less, 1);
mSoundMoreId = mSoundPoolHelper.load(this, R.raw.more, 1);

and play a sound like this:

private void playSound(int soundId) {
    mSoundPoolHelper.play(soundId);
}

Don't forget to call mSoundPoolHelper.release();, for instance in your onDestroy(). Something similar is needed if you use MediaPlayer.

like image 41
Jan Sindberg Avatar answered Nov 15 '22 09:11

Jan Sindberg