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();
Related
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.
I am creating a game, I want to play a background music for one activity only(For main menu of game), my code shown below, The problem is that the music plays more than one time, I want to play the same music also when activity Resumes.
public class Menu extends Activity {
MediaPlayer mp
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
mp = MediaPlayer.create(Menu.this, R.raw.adalante);
if(!mp.isPlaying()) {
mp.start();
}
public void play(View ButtonClicked) {
mp.stop();
mp.release();
//mp = MediaPlayer.create(Menu.this, R.raw.l);
//mp.start();
goToActivity(Game.class);
}
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
//coins
coin.setText(data.getString("coin"));
mp = MediaPlayer.create(Menu.this, R.raw.adalante);
if(!mp.isPlaying()) {
mp.start();
}
//mps.release();
}
In your onResume don't initialise MediaPlayer again and again. It creates new instance every time when you come to onResume. So add a check in onResume like this :
#Override
protected void onResume() {
super.onResume();
if (mp==null)
mp=MediaPlayer.create(MainActivity.this,R.raw.adalante);
if (!mp.isPlaying())
mp.start();
}
and additionally add this for prevention to play when activity goes to onPause
#Override
protected void onPause() {
super.onPause();
mp.pause();
}
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);
}
}
I am new to Android programming and i have a problem that i can not solve without your help...Please, give me a hand... ;-)
When i start playing my audio file, i can not stop it. Instead, I am quitting the application.
I play audio file with this code:
public class Word1Audio extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.word1video);
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.lige);
mediaPlayer.start();
}
}
HOWEVER, when i try to stop it when the back button is pressed by this piece of code
#Override
public void onBackPressed() {
// do something on back.
return;
}
my applications closes down and audio continues to play...
Do you have an idea why the application closes down? And how can i just stop the music and go back to the previous page...??
Thank you for your time and help... :-)
you could try
MediaPlayer mediaPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.word1video);
mediaPlayer = MediaPlayer.create(this, R.raw.lige);
mediaPlayer.start();
}
#Override
public void onBackPressed() {
if( mediaPlayer.isPlaying() ) {
mediaPlayer.stop();
}
super.onBackPressed();
}
I'm displaying a ListView of files to be played, read from an array in Strings.xml.
Everything works fine, however I can't figure out how to implement an Event which would stop the playback on Click or Touch anywhere on the screen, so the audio file can be interrupted and there's no need to wait until the whole file is played.
Please advise.
public class ViewSounds extends ListActivity {
MediaPlayer mp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Get Button Labels
String[] lex_names = getResources().getStringArray(R.array.lex_names);
// Get File Names
final String[] lex_files = getResources().getStringArray(R.array.lex_files);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_sounds, lex_names));
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final int playFile = getResources().getIdentifier(lex_files[position], "raw", getPackageName());
mp = MediaPlayer.create(getApplicationContext(), playFile);
mp.start();
while (mp.isPlaying()) {
// ...
};
mp.release();
}
});
}
}
Instead of playing the media in the onItemClick(), create an AsyncTask to start it in the background, then flag the background thread to stop when the user indicates they want to stop (clicking a button say). Alternatively control the player through a Service and make calls to stop/start the player through that, as you really don't want the player to be running on the UI thread.
Here's an example using AsyncTask that will stop playing when the user clicks a button (R.id.stop_playing):
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final MediaPlayerAsyncTask player = new MediaPlayerAsyncTask(R.raw.my_media);
Button stopPlaying = (Button) findViewById(R.id.stop_playing);
stopPlaying.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
player.stopPlayer();
}
});
setVolumeControlStream(AudioManager.STREAM_MUSIC);
player.execute((Void []) null);
}
private class MediaPlayerAsyncTask extends AsyncTask<Void, Void, Void> {
private boolean stopPlayer;
MediaPlayer mp;
MediaPlayerAsyncTask(int playFile) {
mp = MediaPlayer.create(TestStuff.this, playFile);
}
#Override
protected Void doInBackground(Void... params) {
stopPlayer = false;
mp.start();
while (!stopPlayer && mp.isPlaying()) {
SystemClock.sleep(1000);
}
mp.stop();
return null;
}
public void stopPlayer() {
stopPlayer = true;
}
}