I want to play a sound. The first time it works well, but if I stop it and want to restart it nothing happens...Any idea?
final MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.sex);
ImageButton andvib = (ImageButton)findViewById(R.id.vib_toggle);
final AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
andvib.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
am.setStreamVolume(AudioManager.STREAM_MUSIC, vol, 0);
Vibrator vibr = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibr.cancel();
if(vibrating==false) {
if(style == 0)
vibr.vibrate(durat, 0);
if(style == 1){
vibr.vibrate(staccato, 0);
}
if(style == 2){
vibr.vibrate(wild, 0);
}
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();
mp.setLooping(true);
vibrating = true;
}
else {
vibrating = false;
mp.stop();
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vibr.cancel();
}
}
});
When using MediaPlayer, you should always refer to the state change diagram that you can see here:
http://developer.android.com/reference/android/media/MediaPlayer.html
As you can see from the diagram, after calling stop() on a MediaPlayer, it goes to the Stopped state and you need to call prepare() again to move it to the Prepared state before calling play().
Remember that preparation may take long, so doing that all the time may cause a poor user experience, especially if you are doing it from the main thread (the UI will freeze while the MediaPlayer is preparing). If you play the sound frequently, you should really only prepare() it once, and then always keep it in the Started, Paused or PlaybackCompleted states.
Bruno Oliveira, Developer Programs Engineer, Google
You may have to call mp.prepare() before you call start() the second time.
Related
I'm loading audio sounds into a listview, I play them.When the audio playing is done, i want to change that specific sound's pause button to play button again.
here is my code to play sounds
soundChild.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
player.setDataSource(url);
// file.close();
player.prepare();
player.setLooping(false);
// player.start();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (player.isPlaying()) {
if (player != null) {
player.pause();
// Changing button image to play button
soundChild.setImageResource(R.drawable.playbutton);
}
} else {
// Resume song
if (player != null) {
player.start();
// Changing button image to pause button
soundChild.setImageResource(R.drawable.pausebutton);
}
}
}
});
player.setOnCompletionListener(new OnCompletionListener() {
#Override public void onCompletion(MediaPlayer mp) { // TODO
// Auto-generated method stub player.release(); player=null;
Toast.makeText(_context, "complete", Toast.LENGTH_LONG).show();
soundChild.setImageResource(R.drawable.playbutton);
player.reset();
} });
But on complete listner the imageview of player button is never changed back to play imageview again. I doin't know where i'm doing wrong, because if onComplete is being called then imageview background should also change.please help.
Usually You have to call requestLayout before:
soundChild.requestLayout();
soundChild.setImageResource(R.drawable.playbutton);
and then after changing the image
soundChild.invalidate();
What else could You try? If it doesn´t work, You can also try:
soundChild.setImageDrawable(context.getResources().getDrawable(R.drawable.playbutton));
Because, like described in the API for setImageResource:
This does Bitmap reading and decoding on the UI thread, which can
cause a latency hiccup
Also, what it is possible, You have to call it in on ui thread:
runOnUiThread(new Runnable() {
#Override
public void run() {
soundChild.setImageResource(R.drawable.playbutton);
}
});
and call this in onCompletion.
Now i develop a game application and as all games on google play, they have a toggle button to switch on/off the sound.
Is there any technique i can use to disable all sounds in the game with one step or i have to disable every sound separately ??
I use MediaPlayer for playing sounds
private int playSound(int file) {
int duration = 1000;
sound = new MediaPlayer();
AssetFileDescriptor fd = getResources().openRawResourceFd(file);
try {
sound.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
sound.prepare();
sound.start();
sound.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// Do the work after completion of audio
Toast.makeText(GameActivity.this, "good", Toast.LENGTH_SHORT).show();
mp.release();
}
});
duration = sound.getDuration();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return duration;
}
try this
media.setVolume(0,0);
I have added two buttons to my app, one to play and one to start. As soon as i start the app the songs starts playing automatically. when i press on stops it stops but when i press on play it doesnt starts again
To stop I have used mediaplayer.stop() which is working fine
To start I have used
mediaplayer.start()
which is not working
According to flow diagram its given we need to use
prepare()
and then
OnPreparedListener.onPrepared()
and then
start()
I don't know how to use these functions. Please help me
Don't call stop() for stopping the mediaplayer use reset() instead. I dont have good reason for that. But, it'll work for sure.
// for stopping it call below statement
if(mediaPlayer.isPlaying())
mediaPlayer.reset();
//for playing it again
mediaPlayer.prepare();
mediaPlayer.start();
For starting media player again use following code.
if (mediaplayer != null) {
mediaplayer.start();
}
and one more thing, instead of using
mediaplayer.stop()
use
mediaplayer.pause();
so it will pause the current song instead of stop.
Just check the condition whether it is null or not.
Try following code on Play Button
mp.reset();
mp.setDataSource(song path);
mp.prepare();
mp.start();
mp.setDataSource(song path); not necessary if you playing same sound again
MediaPlayer mp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.singleitemview);
btnsound=(Button)findViewById(R.id.play_sound);
btnstopsound=(Button)findViewById(R.id.stop_sound);
mp=new MediaPlayer();
btnsound.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
mp.setDataSource(Sound);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
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();
}
mp.start();
mp.setLooping(true);
}
});
btnstopsound.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.setLooping(false);
mp.stop();
}
});
}
I've a problem with seek bar, when i play the audio with mediaplayer the seekbar don't start with it.
i don't understand why the seekbar don't "refresh" progress.
thank you for help.
below i post the code, i don't understand when i wrong.
MediaPlayer player=new MediaPlayer();
SeekBar seekBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
AssetFileDescriptor afd = this.getResources().openRawResourceFd(R.raw.mymp3);
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
player.prepare();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Button pausa=(Button)findViewById(R.id.button2);
pausa.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
player.pause();
}
});
Button vai=(Button)findViewById(R.id.button3);
vai.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
player.start();
}
});
int tutto=player.getDuration();
seekBar = (SeekBar)findViewById(R.id.seekBar1);
seekBar.setMax(tutto);
seekBar.setProgress(player.getCurrentPosition() / 1000);
}
An easy way you can do it is to create a Timer object that fires every second.
Inside the code of the timer you call
seekBar.setProgress(player.getCurrentPosition() / 1000);
Additionally, you may want to implement setOnCompletionListener to get notified when the playback has reached it's end so you can stop the timer. The timer should be stopped either if the playback reached it's end, the applications finishes, or you stop the music manually (in response to a stop button, for example)
Because you set the progress in onCreate() and that gets called only once - you guessed it, when the Activity is created. I'm not very familiar with the MediaPlayer so I don't know if there is some kind of update listener, but you need some kind of timer that updates the progress every second or so.
I'm trying to get this to work the way I want and it just won't I think I had it at some point but I was trying to fix something else and changed a few things and messed it up. Basically I'm this button is a play button. It is supposed to run media player through another thread so that it reacts and buffers faster. Issue is after it plays through to the end and I click play it is ended and keeps running the onCompletion. When I would like it to start over and play from the beginning again.
public void onClick(View v) {
if(playClick%2==0){
song1.setBackgroundResource(R.drawable.button_pause);
try{
if(playClick==0){
playThread();
if(lastPlayedExists){
lastPlayed.release();
}
}
mp.start();
mpExists = true;
playClick++;
lastPlayed = mp;
lastPlayedExists=true;
mp.setOnCompletionListener(new OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer media) {
mp.reset();
song1.setBackgroundResource(R.drawable.button_play);
}
});
}catch (NullPointerException e){
}
}
else if (playClick%2==1){
song1.setBackgroundResource(R.drawable.button_play);
mp.pause();
playClick++;
}
}
}
});
And this is the thread for media player
private void playThread(){
try{
new Thread(new Runnable() {
public void run() {
try {
mp.setDataSource(song);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mp.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}catch(IllegalStateException e){
}
}
I have tried it with the onCompletion having mp.reset(), mp.stop(), and mp.release() along with trying lastPlayed.release() all in different tests. As well as none of them being there and it just being the button change and the progress bar reset. If you know how to fix this and make it replay as it should I would greatly appreciate it. Or if you know how to make the thread stop and restart some how so that I can just make it recall and do the thread over again that would work too (atm when that has been tried it crashes because the thread has already been started). Thanks and I appreciate any input.
mp.setOnCompletionListener(new OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer media) {
playClick=2;
song1.setBackgroundResource(R.drawable.button_play);
}
});