MediaPlayer not being stopped in RecyclerView - android

I am working with a RecyclerView which takes ArrayList of integer value of drawables and mp3 files from raw. The MediaPlayer in the recyclerview adapter is working fine but when the user goes back and opens the activity again, the player is playing in the background and there are new list items of mp3 files, not played. I am attaching the code. Help me out, thanks.
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
MediaPlayer mediaPlayer = MediaPlayer.create(context,sounds.get(position));
if (mediaPlayer != null && mediaPlayer.isPlaying()){
holder.play.setImageResource(R.drawable.ic_play);
mediaPlayer.stop();
mediaPlayer.release();
}
holder.play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()){
holder.play.setImageResource(R.drawable.ic_play);
mediaPlayer.pause();
} else {
mediaPlayer.start();
holder.play.setImageResource(R.drawable.ic_puase);
mediaPlayer.setLooping(true);
}
}
});

You can call a method from your activity's onStop or onDestroy on your adapter and handle the stopping of the mediaplayer and clearing resources.
In your activity
#Override
protected void onStop() {
super.onStop();
mAdapter.clearMediaPlayer(); // calling the method inside your adapter
}
in your adapter..
public void clearMediaPlayer() {
if(mp!=null){
mp.stop();
mp.release();// this will clear memory
mp = null;
}
}
I would strongly suggest you to implement your mediaplayer in your activity if you were to play only a single recyclerview item at a time.

Related

Android: MediaPlayer not getting released as expected

So I have an application with a ListView that plays audio in one of the fragments. The issue is, that some users are reporting that the application stops playing audio after a certain amount of clicks. I know this is an issue that has to do with the MediaPlayer not being released correctly, but I cannot find a place where I am not releasing it. Hopefully you guys can help.
Here is where MediaPlayer is being used in MyAudioFragment.java. I am fairly certain that the issue is located in these lines of code.
MyAudioFragment.java
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if(MainActivity.mediaPlayer != null && MainActivity.mediaPlayer.isPlaying()){
MainActivity.mediaPlayer.release();
MainActivity.mediaPlayer = new MediaPlayer();
}
MainActivity.mediaPlayer = MediaPlayer.create(getContext(), MainActivity.hashMap.get(adapterView.getItemAtPosition(i)));
MainActivity.mediaPlayer.start();
}
});
Here is where I deal with MediaPlayer in MainActivity.java
//...
public static MediaPlayer mediaPlayer;
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
//Layout stuff
mediaPlayer = new MediaPlayer();
//Setting up fragment stuff
//...
}
#Override
public void onPause(){
super.onPause();
mediaPlayer.stop();
mediaPlayer.release();
}
#Override
public void onResume(){
super.onResume();
mediaPlayer = new MediaPlayer();
}
Edit: Could it possibly be that I am not releasing it "OnCompletion" ?
On onCompletion, you must do release();

Android Media player onClick issue

I'm using MediaPlayer for playing sounds onClick. Until the sound is finished the click event is not play the sound again. How can it play the sound again on click, when the sound is currently playing?
final MediaPlayer mistake = MediaPlayer.create(getActivity(), R.raw.mistake);
tv_mistake.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mistake.start();
}
});
You must create a new MediaPlayer object to play the sound again like so.
tv_mistake.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mistake != null) {
mistake.release();
mistake = MediaPlayer.create(getActivity(), R.raw.mistake);
}
mistake.start();
}
});
You can read more about MediaPlayer in the following links.
Also a quite similar question
MediaPlayer, MediaPlayer Tutorial, MediaPlayer Tutorial From Google
Most of the errors in MediaPlayer comes due to improper handling of different states of its object.
You should release MediaPlayer object after completing playback or before calling start() again.
It is also recommended that once a MediaPlayer object is no longer being used, call release() immediately so that resources used by the internal player engine associated with the MediaPlayer object can be released immediately.
Create a MediaPlayer object as:
Mediaplayer mediaPlayer = null;
And call playMistakeSound() on button click:
tv_mistake.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playMistakeSound()
}
});
Implement playMistakeSound() as:
void playMistakeSound() {
try {
// releases MediaPlayer object before calling create() again while previous is still playing
if (mediaPlayer != null){
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
mediaPlayer = MediaPlayer.create(getActivity() /*Context*/, R.raw.mistake);
// this will release MediaPlayer as soon as it completes
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (mp != null) {
mp.reset();
mp.release();
mediaPlayer = null;
}
}
});
mediaPlayer.start();
} catch (Exception e) {
// log exception and handle
e.printStackTrace();
}
}

Media Player start stop start

I am making a new android sound application. I made a clickable button to play sound when I click on it. But I also want it to stop playing sound when I click for the second time. That part works fine now here is the problem, when I click again on button to play sound again, it doesn't play it, Media player is completely stopped. I was looking on forums but I can't seem to find an answer that could help me.
Here is my Activity:
MediaPlayer mpButtonClick1;
MediaPlayer mpButtonClick2;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.prvi);
final MediaPlayer mpButtonClick1 = MediaPlayer.create(this, R.raw.spalshm);
final MediaPlayer mpButtonClick2 = MediaPlayer.create(this, R.raw.splashs);
Button dugme = (Button) findViewById(R.id.dugme);
dugme.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mpButtonClick1.isPlaying()) {
mpButtonClick1.stop();
mpButtonClick1.reset();
}
else {
mpButtonClick1.start();
}
}
});
When I try to write mpButtonClick1.prepare(); I get error Unhandled Exception Type IOE exception
Try to use pause instead of stop.
Reason: if you pause the MediaPlayer, then you can resume it later. However, if you use stop, almost any other method won't work and you will have to prepare the MediaPlayer again (or create a new one).
More info: here and here
PS: don't forget to release the memory when you finish using the resources.
Try this:
You should use only one mediaplayer object
public class PlayaudioActivity extends Activity {
private MediaPlayer mp;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b = (Button) findViewById(R.id.button1);
Button b2 = (Button) findViewById(R.id.button2);
final TextView t = (TextView) findViewById(R.id.textView1);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stopPlaying();
mp = MediaPlayer.create(PlayaudioActivity.this, R.raw.far);
mp.start();
}
});
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stopPlaying();
mp = MediaPlayer.create(PlayaudioActivity.this, R.raw.beet);
mp.start();
}
});
}
private void stopPlaying() {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
}
}
Change your class with below code:
remove reset();.
init well all components:
MediaPlayer mpButtonClick1;
MediaPlayer mpButtonClick2;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.prvi);
mpButtonClick1 = MediaPlayer.create(this, R.raw.spalshm);
mpButtonClick2 = MediaPlayer.create(this, R.raw.splashs);
Button dugme = (Button) findViewById(R.id.dugme);
dugme.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mpButtonClick1.isPlaying()) {
mpButtonClick1.stop();
}
else {
mpButtonClick1.start();
}
}
});
You're calling mpButtonClick1.reset() after mpButtonClick1.stop() - don't do that:
if (mpButtonClick1.isPlaying()) {
mpButtonClick1.stop();
mpButtonClick1.reset(); //<--------- calling reset(), remove this line
}
The docs for reset() say:
Resets the MediaPlayer to its uninitialized state. After calling this method, you will have to initialize it again by setting the data source and calling prepare().
Remove mpButtonClick1.reset() and it should work.
Keep in mind that MediaPlayer works as a state machine, which means that if you call methods in the wrong order, you'll get problems. Please read about MediaPlayer here and here.
Hey please use following
for stop -> media player
mp.seekTo(0);
mp.pause();
again for start just call
mp.start();
In my experience when I need to play multiple times and I may need to stop one play to start another play, (like in the case of multiple buttons), I just create another player, making sure that I release the resources for the previous one. To stop just use
mediaPlayer.stop();
But for play use something like this (adapt the logging to your specific needs) to create/recreate your player:
private boolean createMediaPlayer()
{
if (mediaPlayer!=null)
{
if(mediaPlayer.isPlaying())
{
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer=null;
}
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setVolume(1f, 1f);
try
{
mediaPlayer.setAudioStreamType(Interop.PRIMARY_STREAM);
mediaPlayer.setDataSource(m_soundFile);
mediaPlayer.prepare();
return true;
// Interop.logDebug(TAG + "-loadAudio: SUCCESS" + m_soundFile);
} catch (Exception e)
{
Interop.logError(TAG + "-LoadAudio for Clic Sound: audioPlayer prepare failed for current file: " + m_soundFile);
Interop.logError(TAG + "-Exception: " , e);
return false;
}
}
and than use
if (createMediaPlayer())
mediaPlayer.start();
this will ensure proper release of the resources used by the media player.
A simple solution is to Use pause instead of stop and the seek to the beginning of the song.
I know that this question is quite old but recently while learning Android, I also got stuck at this point and found a very simple solution which I'd like to share with everyone.
Instead of trying to stop or reset the media, you can just seek back to the starting position.
mediaPlayer.seekTo(0);
For reference, I am also posting my code below:
public class MainActivity extends AppCompatActivity {
MediaPlayer mp;
public void play(View view) {
mp.start();
}
public void pause(View view) {
mp.pause();
}
public void stop(View view) {
// this seeks to the beginning of the file
mp.seekTo(0);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mp = MediaPlayer.create(this, R.raw.sample_audio);
}
}

How to stop audio from playing when back button is pressed?

Hi all here is my code:
final ImageView imageView = (ImageView) findViewById(R.id.Image7);
imageView.setImageResource(mFullSizeIds[position]);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaPlayer mp = MediaPlayer.create(Audio.this,mAudio[position]);
mp.start();
}
});
Now this code works fine to play the audio when the user taps the image, however when I want to exit this activity and go to a different activity, the audio track is still playing, even when I press the home key the audio is still playing. How can I prevent this from happening?
Is there a way to stop the track from playing when the user taps the image again or presses the back/home button?
Add
#Override
public void onBackPressed ()
{
if (mp != null)
mp.stop();
super.onBackPressed();
}
and
#Override
public void onPause ()
{
if (mp != null)
{
mp.pause();
mp.stop();
}
super.onPause();
}
Create an onStop in the activity and make mp a class variable although I always create/prefer media player helper class for this sort of stuff. Then call mp.stop()/pause on onStop.
private MediaPlayer mp = null;
#Override
public void onStop() {
super.onStop();
if (mp != null) {
mp.stop();
}
}
then you just create it with removing the MediaPlayer before mp:
mp = MediaPlayer.create(Audio.this,mAudio[position]);
Override the onBackPressed method, and stop your MediaPlayer object, which is mp.

Releasing consumed memory after using MediaPlayer

I'm developing an application containing 100s of sound effects.
after playing some of the sounds the application force closes. I understood that the problem would be consuming all the available space of the memory. I tried using Release() method but after this method is called I'm not able to play the sound again.
I also tried using onDestroy() method to set the object of the mediaplayer to null but since these kind of objects must be final I can't do this.
What is your suggestion?
Here is my code:
final MediaPlayer mp1 = MediaPlayer.create(MainActivity.this, R.raw.a1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (i[0] == false)
{
mp1.start();
Toast.makeText(getBaseContext(), "horn", Toast.LENGTH_SHORT).show();
b1.setBackgroundResource(R.drawable.stop_button);
i[0] = true;
}
else
{
mp1.pause();
mp1.seekTo(0);
b1.setBackgroundResource(R.drawable.horn);
i[0] = false;
}
}
});
mp1.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
b1.setBackgroundResource(R.drawable.horn);
}
});
Have you tried something like this?
You can call release() in OnDestroy() method.
#Override
public void onDestroy(){
super.onDestroy();
mp.release();
}

Categories

Resources