I have a list of songs i put manually inside my app and it currently have 3 functions: start, pause and stop (using ImageViews).
The problem is that i can play multiple songs at the same time that is not supposed to be like that. I really cant find the issue here and hope someone can help.
This is a demonstration on my problem
I want it to STOP currently playing song when another song is being clicked on.
Here is my code for my play button:
viewholder.playB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (currentSong == null || song != currentSong) {
currentSong = song;
mediaPlayer = MediaPlayer.create(context, song.getSong());
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewholder.playB.setImageResource(R.drawable.play_black);
} else {
mediaPlayer.start();
viewholder.playB.setImageResource(R.drawable.pause_black);
}
}
});
Instead of always creating a new instance of MediaPlayer every time the event onClick is called, you should create a single instance and reused it.
To play a new song don't forget to reset your player first. Here is an example:
mPlayer.reset();
mPlayer.setDataSource(context, song.getSong());
Related
I am developing a music player on android and the app has two activities (MainActivity and PlayActivity). In the MainActivity I have a listview with a list of songs and in the PlayActivity I have a button to listen and pause the music. The problem is that when go back to MainActivity and I select a new song from the listview, the first one keeps playing on background while the second one also starts playing. How can I stop the first song when I select a new one?
(I don't want to stop mediaplayer onBackPressed, I just want to stop the music when another song it's selected from listview and play a fresh song in PlayActivity)
EDIT: I'm using AsyncTask to start mediaplayer on PlayActivity: mp.prepareAsync();
You could try to stop MediaPlayer when onBackPressed()
MediaPlayer mp ; // mp is your MediaPlayer
#Override
public void onBackPressed() {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
super.onBackPressed();
}
private void playMusic() {
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
mp.release();
MediaPlayer copyMp = new MediaPlayer();
try {
copyMp.setDataSource("/path");
mp = copyMp;
mp.prepare();
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
From here
MediaPlayer is not thread-safe. Creation of and all access to player
instances should be on the same thread.
That means you have to maintain one media player instance throughout your whole application(As per your requirement). I don't know how you implemented the media player(Service/AsyncTask etc.). When you select a new song, you need to access that instance and replace the existing song with the selected one.
Im a newbie to android studio (programming at general) but i want to build a mediaplayer for learning purposes.
I have a a list of local music in a listView that contains 2 images 'play, pause and stop button'.
This is how my app works:
Click on playbutton -> start music
Click on pausebutton -> pause music
Click on stopbutton -> stop music
Very simple. BUT! the thing is -> when i pause a song and want to play another song in my list then it just resume the first song i clicked on.
I want it to release the first song and start the other one i click on.
This is my code:
// play music
viewHolder.playB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (flag) {
//get song you clicked on
mediaPlayer = MediaPlayer.create(context, song.getSong());
//set boolean to false so it can get ANOTHER song when
//clicked
flag = false;
Toast.makeText(context, "Playing" + song.getName(),
Toast.LENGTH_LONG).show();
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.playB.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.playB.setImageResource(R.drawable.pause);
}
}
});
// stop
viewHolder.stopB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!flag) {
mediaPlayer.stop();
mediaPlayer.release();
flag = true;
}
viewHolder.playB.setImageResource(R.drawable.play);
}
});
Your logic is a little bit wrong. When you create the MediaPlayer you set flag to false and as long as you do not stop playback flag doesn't change. But your MediaPlayer creation depends on it.
For future improvements (maybe when you're more confident in working with MediaPlayer and Android) you should take a look at a more "self-made" approach instead of MediaPlayer.create(...) cause this method is calling MediaPlayer's prepare() method that is going to eventually make your app extremely slow or crash it when loading big files.
Example according to comments
I assumed songis going to be the class object.
// class variable will hold the currently loaded song
private Song mCurrentSong;
[...]
viewHolder.playB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// MediaPlayer has not been initialized OR clicked song is not the currently loaded song
if (mCurrentSong == null || song != mCurrentSong) {
// Sets the currently loaded song
mCurrentSong = song;
mediaPlayer = MediaPlayer.create(context, song.getSong());
Toast.makeText(context, "Playing" + song.getName(),
Toast.LENGTH_LONG).show();
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.playB.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.playB.setImageResource(R.drawable.pause);
}
}
});
viewHolder.stopB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// If currently loaded song is set the MediaPlayer must be initialized
if (mCurrentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
mCurrentSong = null; // Set back currently loaded song
}
viewHolder.playB.setImageResource(R.drawable.play);
}
});
If i am playing song from a song list and if the other song is already playing then both songs plays simultaneously in android studio. If i just use next or previous buttons then they are working fine. The problem is through song list. I am not getting how to check if media player is playing already or not in this condion. I am doing this code in kotlin and i am new user of android studio.
you can check this way
You can take a global variable of MediaPlayer
public MediaPlayer mediaPlayer;
and then create in onCreate method:
mediaPlayer= MediaPlayer.create(this, R.raw.xxxx);
and thus your play method will be:
public void mediaPlay(View view) {
if(mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
else{
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
}
This question already has answers here:
Media Player start stop start
(8 answers)
Closed 6 years ago.
I have a button when clicked it plays an audio, and while it is playing I can pause it and replay it again and so forth. I have a shake event, where I want to play the audio on shake and replay it when device is shaken again (by first stopping the audio, calling stopAudio?)
I have the following code:
llBtn = (LinearLayout) findViewById(R.id.button);
llBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(MainActivity.this, "LL WAS CLICKED", Toast.LENGTH_SHORT).show();
//IF AUDIO IS NOT PLAYING... PLAY AUDIO
if (tvPS.getText() == "Stop Phrase!") {
StopAudio();
}
else {
PlayAudio();
}
}
});
//the same button is clicked to stop, it is currently setting to Pause.
public void StopAudio() {
mediaPlayer.pause();
Toast.makeText(MainActivity.this, "STOPPED", Toast.LENGTH_SHORT).show();
tvPS.setText("Play Phrase!");
}
public void PlayAudio() {
//stopPlaying(mediaPlayer);
tvPS.setText("Stop Phrase!");
inResId = getResources().getIdentifier("play" , "raw", getPackageName());
mediaPlayer = MediaPlayer.create(getBaseContext(), inResId);
mediaPlayer.seekTo(0);
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//Toast.makeText(MainActivity.this, "Done", Toast.LENGTH_SHORT).show();
tvPS.setText("Play Phrase!");
mediaPlayer.pause();
}
});
}
...
public void onShake() {
// Do stuff!
Toast.makeText(getBaseContext(), "Motion detected",
Toast.LENGTH_SHORT).show();
if (mediaPlayer == null) {
PlayAudio();
}
}
How can I modify the code above to handle Play, and then stop if stopped in the middle and then able to replay it again.
The button click works but I am creating a new instance each time and not recycling. When the device is shaken, it plays the audio twice instead of just once.
First of all create the MediaPlayer in onCreate of the context and not in some listener, and don't forget to release it when done, since it consumes a lot of resources,
mediaPlayer.release();
mediaPlayer = null;
Next thing, stop the audio using the stop() function instead of the pause() on completion of the song.
Steps
If you are using a service/activity to play a video create a MediaPlayer instance before it's usage begins, likely in onCreate.
Later use that instance to play/pause/stop the media.
In the onStop of the Service/Activity release the MediaPlayer instance.
Update your playMusic() function to use the MediaPlayer instance you just created, also in the listener use stop() instead of pause()
To change track of an existing MediaPlayer instance
You can use this:
String path = getExternalFilesDir(null).toString()+"/";
mMediaPlayer.setDataSource(path + mediafile);
Link: Changing data source for audio playback using existing MediaPlayer?
I am working in android. I am creating a mediaPlayer which is running audio files. i have 10 buttons. i have assigned different url to each button. So when i press button1 then song of url with respect to button 1 is playing. and then i click on 2nd button then song of button 2 is also playing with song 1. but i want to stop song of button 1 when i press button 2.
this is the code i am using for this functionality:-
public void onClick(View v)
{
MediaPlayer mediaPlayer=new MediaPlayer();
if (mediaPlayer.isPlaying())
{
mediaPlayer.stop();
mediaPlayer.release();
}
int i = Integer.parseInt((v.getTag()).toString());
String str=urls[i];
try {
mediaPlayer.setDataSource(str);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e)
{
e.printStackTrace();
}
}
please check my code and let me know what is mistake done by me.
you have construct a new MediaPlayer object each time the user click you view
how could it be in the running state !!!
calling release() method on a MediaPlayer object it is in thre End state
Once the MediaPlayer object is in the End state, it can no longer be used and there is no way to bring it back to any other state.
but in case you want to reuse a MediaPlayer object you should call the
call the following method in the same order
reset()
make the mediaPlayer enter the Idle state
setDataSource()
set your data source note : the mediaplayer shoud be in the idle state
prepare()
start()