I need to have the same short wav file (1 second) play each time the user presses a single button. I have the following code that works for about 30 clicks and then the app "Force closes" on the device. I think what is going on is that new instances of media player are being created and then the instances build up (approx 30 clicks) and the app crashes. So I then added the "release" instance in the hope that on button-click the wav would play and then the mediaplayer would be released. However, it doesnt work that way. With the mp.release() no sound is played possibly becaue the medaiplayer gets released too soon for the user to hear the sound?
Anyone have a good tip to help me getting this to work? Thank you all so much.
Button button2 = (Button) findViewById(R.id.button10);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
mp.start();
mp.release();
Its simple just create the MediaPlayer once, and play it over time.
private MediaPlayer mp;
public void onClick(View v) {
// Perform action on click
if (mp == null){
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
}
mp.start();
}
Why use MediaPlayer, when SoundPool is better suited for small audio files? As a base you could use this:
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 70);
final HashMap<Integer, Integer> soundPoolMap = new HashMap<Integer, Integer>();
final int soundID = 4;
soundPoolMap.put(soundID, soundPool.load(this, R.raw.wav_sound, 4));
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener()
{
public void onLoadComplete(SoundPool soundPool, int sampleId, int status)
{
if (sampleId == 4)
{
soundPool.play(4, 50, 50, 1, 0, 1f);
}
}
});
Here is the simple solution that will work
MediaPlayer mp;
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
public void onClick(View v) {
// Perform action on click
if(mp.isPlaying())
{
mp.stop();
mp.reset();
mp.release();
}
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
mp.start();
This is will check if mediaplayer is already playing..If it already playing it will stop and release it and then initialize that mediaplayer(mp) object and start the mediaplayer.
If it is not playing it will execute the code after the if statement and the start the media player after initialzing the mediaplayer object(mp in this case)
To learn more about MediaPlayer study this http://developer.android.com/reference/android/media/MediaPlayer.html. Study the Mediaplayer life cycle
Related
I simply want to play a mp3 file when I click a button in android studio.
My problem is that with the 2 methods I use the sound is played but for some reason, I hear it like an extremely distorted super slow motion sound. While if I normally open the file it is ok.
!!!!!METHOD 1:
I declared:
SoundPool mySound;
int soungId;
I initialize:
mySound = new SoundPool(1, AudioManager.STREAM_MUSIC,0);
soungId = mySound.load(this, R.raw.asd,1);
Then is use an action listener:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mySound.play(soungId,1,1,1,0,1);
}
});
!!!!!METHOD 2:
I declare:
MediaPlayer mp = null;
I use listener:
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
managerOfSound();
}
});
My managerOfSound mathod :
public void managerOfSound() {
if (mp != null) {
mp.reset();
mp.release();
}
mp = MediaPlayer.create(this, R.raw.www);
mp.reset();
mp.start();
}
It may be because the Soundpool instance of the MaxStreams maximum number (maximum number of concurrent streams) is too low
SoundPool mySound;
mySound = new SoundPool(10, AudioManager.STREAM_MUSIC,0);
try this,
MediaPlayer mp = new MediaPlayer();
// Set data source -
setDataSource("/sdcard/path_to_song");
// Play audio
mp.start();
// Pause audio
mp.pause();
// Reset mediaplayer
mp.reset();
// Get song length duration - in milliseconds
mp.getDuration();
// Get current duration - in milliseconds
mp.getCurrentDuration();
// Move song to particular second - used for Forward or Backward
mp.seekTo(positon); // position in milliseconds
// Check if song is playing or not
mp.isPlaying(); // returns true or false
http://www.androidhive.info/2012/03/android-building-audio-player-tutorial/
I have several GridView items that play a small .ogg file when they are selected. They are played using the SoundPool class, however this class seems very intermittent - sometimes the sound plays, sometimes it doesn't; there is no pattern to this so I am having trouble figuring out why it's doing it.
Here is my code:
public void playSelectionSound(){
SoundPool sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
int soundId = sp.load(this, R.raw.char_select, 1);
sp.play(soundId, 1, 1, 0, 0, 1);
}
I eventually resorted to switching to MediaPlayer instead of SoundPool:
MediaPlayer mp = MediaPlayer.create(this, R.raw.char_select); //open media player
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
mp.start(); //play the sound
Works everytime.
You shouldn't try to play it immediately after the load since the load can take time. Instead, you should use SoundPool.OnLoadCompleteListener() and play it in that callback. Here you can be sure that soundpool has loaded successfully.
I have an android app with a button that plays a sound. the code for playing the sound:
if (mp != null)
{
mp.release();
}
mp = MediaPlayer.create(this, R.raw.match);
mp.start();
mp is a field in the activity:
public class Game extends Activity implements OnClickListener {
/** Called when the activity is first created. */
//variables:
MediaPlayer mp;
//...
The app runs ok, but after clicking the button about 200 times on the emulator, app crashed and gave me this error https://dl.dropbox.com/u/5488790/error.txt (couldn't figure how to post it here so it will appear decently)
i am assuming this is because the MediaPlayer object is consuming up too much memory, but isn't mp.release() supposed to take care of this? What am i doing wrong here?
If you are attaching a sound effect to a button, MediaPlayer in general is far too heavyweight for this operation. You're getting unnecessary latency each time just to load up the sound data into memory. You should look at using SoundPool instead.
In either case, there is no valid reason to release and re-create the MediaPlayer each time. If you decide to use MediaPlayer, control the single instance you have with the button clicks.
MediaPlayer mp;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Other init code
//Create the player this way so it doesn't auto-prepare
mp = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.match);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
}
public void onDestroy() {
super.onDestroy();
//Release it only when no longer needed
mp.release();
mp = null;
}
public void onButtonClick(View v) {
if (mp.isPlaying()) {
mp.stop();
}
//Play the sound
mp.prepare();
mp.start();
}
Hope that Helps, but again, I would highly recommend using SoundPool instead if this sound is just a short effect.
It looks like your code should work, but obviously release() isn't really releasing everything.
Maybe it's because you have to reload R.raw.match every time you want to play the sound. If R.raw.match is just a short sound effect, then you might want to consider using SoundPool instead.
If you use SoundPool you only have to load R.raw.match once which may prevent the memory issues.
This tutorial has a good example on how to use it: http://www.vogella.com/articles/AndroidMedia/article.html#tutorial_soundpool
You pretty much just make one instance of SoundPool then load the sound once and play it when you need it.
Hope this helps!
Edit
If you want to use MediaPlayer...
public class Blah extends Activity implements OnClickListener {
MediaPlayer mp;
#Override
public void onCreate(Bundle b)
{
// blah blah
mp = MediaPlayer.create(R.raw.match);
// blah blah
}
#Override
public void onClick(View v)
{
if (v.getId() == yourButtonID)
{
// play sound from beginning
mp.seekTo(0);
mp.start();
}
}
}
This way you only create one instance and whenever you want to play it, you just rewind it to the beginning then play.
Try
if (mp != null)
{
mp.release();
}
mp = MediaPlayer.create(this, R.raw.match);
mp.prepare(); // not needed
mp.start();
Good luck!!
if you hold the MediaPlayer, release it at the end of the activity
#Override
void onDestroy() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
super.onDestroy();
}
In Adnroid, at first i declare the mediaplayer by
MediaPlayer mpl;
next I have this in the onCreate method
mp = new MediaPlayer();
mp = MediaPlayer.create(this, R.raw.hit );
mp.setVolume(1, 1);
and a function that's supposed to play a sound when called
public void click()
{
mp.start();
}
yet the problem is that if the user calls this function multiple times, before it has stopped playing the last sound, it will die and stop playing any sounds, before the app is reset.
Any ideas how to fix that?
Thanks!
edit - found a solution:
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mpl.release();
}
});
public void click()
{
if( ! mp.isPlaying() ) {
mp.start();
}//if
}//met
you can disable the button.
or you can stop current playing and star
new in onClick()
How do I set up an audiofile to play when a user touches an image.
Where should I store the audio file and what code should I use to actually play the file?
I don't want to bring up the MediaPlayer interface or anything like that.
I was thinking of doing it like this:
foo = (ImageView)this.findViewById(R.id.foo);
foo.setOnClickListener(this);
public void onClick(View v) {
if (foo.isTouched()) {
playAudioFile();
}
}
Thanks
This won't create a bring up the MediaPlayer interface... it will just play the sound you want.
Button boton = (Button) findViewById(R.id.boton);
boton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaPlayer mp = MediaPlayer.create(TestSonido.this, R.raw.slayer);
mp.start();
}
});
In this case, R.raw.slayer represents an audio file called slayer.mp3 that is stored in the res/raw/ folder and once you click the button the droid will rock you...
You can also achieve the same using SoundPool.
MediaPlayer first loads the whole sound data in memory then play, so it produces some lag when we switch among sounds frequently.
SoundPool is a better option with small size sound file and produces better result with .ogg media file.
SoundPool pl = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
// 5 indicates the maximum number of simultaneous streams for this SoundPool object
pl.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// The onLoadComplet method is called when a sound has completed loading.
soundPool.play(sampleId, 1f, 1f, 0, 0, 1);
// second and third parameters indicates left and right value (range = 0.0 to 1.0)
}
});
Button btn = findViewById(R.id.boton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int sound = pl.load(this, R.raw.sound_01, 0);
}
});
public void aud_play(View view) {
if (!mp.isPlaying()) { //If media player is not playing it.
mp = MediaPlayer.create(this, R.raw.audio_name);
mp.start();
} else {// Toast of Already playing ...
}
}