I have a Fragment with a ListView which is a list of sounds, that is populated in this way:
MediaPlayer mMediaPlayer;
listview.setAdapter(new ListAdapter(getActivity(), tit, desc, songs, filenames, mMediaPlayer));
MediaPlayer is given as parameter because i would like that when back button is pressed or app goes in background, the player would stop playing.
So i have override onPause and onDestroy method in my Fragment, but this just doesn't work. Sound continues playing even if app is closed. This is my code:
#Override
public void onDestroy() {
// TODO Auto-generated method stub
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
super.onDestroy();
}
#Override
public void onPause() {
// TODO Auto-generated method stub
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
super.onPause();
}
I play sounds in my BaseAdapter class, in this way:
public void playSound2(int pos){
if(isPlaying){
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
isPlaying = false;
}
mMediaPlayer = MediaPlayer.create(context, songs[pos]);
mMediaPlayer.start();
isPlaying = true;
}
Do you have any suggestion? Thank you.
My first suggestion is: don't use the adapter to interact with the media player. Instead, attach an item click listener to your listview, like this
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
...
}});
and do whatever you want with the media player in the onItemClick callback.
That being said, you should reset your media player when inside your onclicklistener, like so
try {
mPlayer.reset();
mPlayer.setDataSource(trackToBePlayed); //trackToBePlayed is dependent on the select position
mPlayer.setOnPreparedListener(mPreparedListener);
mPlayer.prepareAsync();
} catch (IOException e) {
} catch(IllegalArgumentException e) {
}
And in the mPreparedListener, when ready, you do
mPreparedListener = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
};
This should be enough to point you in the right direction :)
Related
I use thread to update the SeekBar. If I don't start the thread then this problem does not arise. What can I do now...? I only experience a problem with this part of my project.
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mp != null) {
mp.stop();
mp.release();
toast("Second Time");
}
u = Uri.parse(collectedSong.get(position).toString());
mp = MediaPlayer.create(getApplicationContext(), u);
mp.start();
sb.setMax(mp.getDuration());
**updateSeekBar.start();**
positionNew = position;
}
});
Check out MediaPlayer lifecycle in Android documents:
https://developer.android.com/reference/android/media/MediaPlayer.html
this is how I use media player to play stream Song:
public void onSongClicked(Song song) {
//check if is playing
stopMediaPlayer();
// prepare media player to play sample
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
mMediaPlayer = null;
}
});
try {
mMediaPlayer.setDataSource(song.getPath());
mMediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void stopMediaPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
I hope it helps :)
I have a list of players (ListView). Each item is have two buttons "start" and "stop". When I click on "start" color "Start" button change red and begins to move seekbar. When click on the "stop" button color "start" start is black and seekbar progress becomes zero. when the song ends with the color button "start" also becomes black and seekbar progress becomes zero.
holder.start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
releaseMP();
startPlayProgressUpdater(holder.seekBar, holder.start);
try {
mediaPlayer = new MediaPlayer();
global_position = position;
mediaPlayer.setDataSource(recordBeans.get(global_position).getFile());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
holder.seekBar.setMax(mediaPlayer.getDuration());
mediaPlayer.start();
recordBeans.get(global_position).setPlay(true);
holder.start.setTextColor(Color.RED);
startPlayProgressUpdater(holder.seekBar, holder.start);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
releaseMP();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
This is implemented in this method:
public void startPlayProgressUpdater(final SeekBar seekBar, final Button start) {
if (mediaPlayer != null) {
recordBeans.get(global_position).setSeekPos(mediaPlayer.getCurrentPosition());
if ((Integer) seekBar.getTag() == global_position) {
seekBar.setProgress(recordBeans.get(global_position).getSeekPos());
}
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater(seekBar, start);
}
};
handler.postDelayed(notification, 1000);
} else {
recordBeans.get(global_position).setPlay(false);
start.setTextColor(Color.BLACK);
recordBeans.get(global_position).setSeekPos(0);
seekBar.setProgress(0);
}
}
When I click the "stop" or the song ends, the player becomes the NULL and color button again changes. it is implemented in all of these methods:
holder.stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ((Integer) v.getTag() == global_position && mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
});
and
private void releaseMP() {
if (mediaPlayer != null) {
try {
mediaPlayer.release();
mediaPlayer = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
I want the same functionality if I worked while playing the song click on the "start" another song. ie a new song starts playing, the color buttons "start" becomes A red color and previous button "start" again black.
for this I when you click on "start" call methods:
releaseMP();
startPlayProgressUpdater(holder.seekBar, holder.start);
and the method works but the data is not cleared. but if I click on "Stop" then the data of all previous songs cleared. what I'm doing wrong?
I think you meant to call reset(), not release() in the stop button OnClick. Try to call release() in your main container OnStop()
reset()
This method resets the media player
release()
This method releases any resource attached with MediaPlayer object
I use media player to play sounds on my application. It works just fine.
I am playing sound on a separated thread. Even thought, part of the sound plays before activity appear.
I tried to play sound onCreate method. it didn't work. onStart and
onResume. it has some problems. it plays every time activity resumed.
sometimes while I am not even touching the device!
What is the best way to play sound after activity appears?
public boolean played = false;
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (!played)
Settings.playSound(dvd.titleImageName.replace("png", "mp3"), this);
played = true;
}
public static MediaPlayer mp = null;
public static void playSound(String fileName, Context c)
{
//MediaPlayer mp = MediaPlayer.create(c, resId);
if (mp!=null)
{
mp.stop(); //error
mp.reset();
mp.release();
}
mp = new MediaPlayer();
AssetFileDescriptor descriptor;
try {
descriptor = c.getResources().getAssets().openFd("sounds/" + fileName);
mp.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
mp.prepare();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (mp == null) return;
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
}
});
mp.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
}
});
mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
// TODO Auto-generated method stub
}
});
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
mp.start();
}
}).start();
}
Your played variable only works while activity is alive. If it gets killed, played doesn't retain. For example, rotate your device an you'll hear sound playing again.
save state (played) in onSavedInstanceState bundle and restore it in onCreate
Play in in OnCreate or onResume
i am facing some issue in media player when i use as service.
1. If i initialize Media Player Object in Activity as static and further use in service class then its show me this error (-38, 0) , Attempt to perform seekTo in wrong state: mPlayer=0x0, mCurrentState=0 , start called in state 0.
2. If i initialize Media Player Object in Service class and user in activity for more
action its show's me Null Pointer.
public static MediaPlayer mPlayer = null;
play Click Event
Audio_Player_Play.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
if (mPlayer == null)
{
Intent Play_Intent = new Intent(RDS_Singel_Audio.this,
Audio_Player.class);
startService(Play_Intent);
Audio_Player_Play.setVisibility(View.GONE);
Audio_Player_Pause.setVisibility(View.VISIBLE);
} else
{
// Play_Streaming();
mPlayer.seekTo(mPlayer.getCurrentPosition());
mPlayer.start();
Audio_Player_Play.setVisibility(View.GONE);
Audio_Player_Pause.setVisibility(View.VISIBLE);
}
}
});
Pause Click Event
Audio_Player_Pause.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
// Play_Streaming();
// checking is medai player running
Audio_Player_Play.setVisibility(View.VISIBLE);
Audio_Player_Pause.setVisibility(View.GONE);
// checking is audio playing in background
if (mPlayer != null && mPlayer.isPlaying())
{
mPlayer.pause();
/*
* Intent Pause_Intent = new Intent(RDS_Singel_Audio.this,
* Audio_Player.class); stopService(Pause_Intent);
*/
Audio_Player_Play.setVisibility(View.VISIBLE);
Audio_Player_Pause.setVisibility(View.GONE);
}
}
});
OnResume() - OnPause() -OnDistroy()
#Override
protected void onResume()
{
super.onResume();
}
#Override
protected void onPause()
{
// cleanUp();
if (mPlayer != null && mPlayer.isPlaying())
{
mPlayer.release();
mPlayer = null;
}
super.onPause();
}
#Override
protected void onDestroy()
{
cleanUp();
super.onDestroy();
}
private void cleanUp()
{
if (mPlayer != null)
{
mVisualizerView.release();
mPlayer.release();
mPlayer = null;
}
}
Service.Java
public class Audio_Player extends Service
{
private static final String TAG = "MyService";
// public static MediaPlayer mPlayer;
Function f;
RDS_Singel_Audio sa;
MediaPlayer mPlayer;
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
try
{
sa = new RDS_Singel_Audio();
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG)
.show();
sa.mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
sa.mPlayer.setDataSource(sa.Audio_URL);
sa.mPlayer.prepare();// might take long! (for buffering, etc)
sa.mVisualizerView.link(sa.mPlayer);
sa.mPlayer.start();
sa.addLineRenderer();
sa.mPlayer.setLooping(false); // Set looping
// sa.mPlayer.start();
} catch (Exception e)
{
// TODO: handle exception
Log.d(TAG, "" + e);
}
}
#Override
public void onDestroy()
{
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
super.onDestroy();
if (sa.mPlayer != null)
{
sa.mPlayer.stop();
sa.mPlayer.release();
}
sa.mPlayer = null;
}
#Override
public void onStart(Intent intent, int startid)
{
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
// mPlayer.setDataSource("http://clients.ncrypted.net/riddimapp/images/audio/4/df9919ccb2880933c795f43d735cf9bc.mp3");
}
}
I found some link about same issue but I don't know how solve it.
Well, I see this part of your code, but it is not clear what you are trying to achieve. You are trying to make the player go to its current position, but it is already at that position? You could remove that part then.
// Play_Streaming();
mPlayer.seekTo(mPlayer.getCurrentPosition());
Also, on your onpause you're releasing the player, but not generating it again on your onresume. You can recreate it there with code from that link you provided:
#Override
protected void onResume()
{
super.onResume();
}
#Override
protected void onPause()
{
// cleanUp();
if (mPlayer != null && mPlayer.isPlaying())
{
mPlayer.release();
mPlayer = null;
}
super.onPause();
}
Also, as you seem to be setting the source of the mediaplayer to be an url, you should change the prepare for a prepareAsync in the following part, so that it buffers:
sa.mPlayer.setDataSource(sa.Audio_URL);
sa.mPlayer.prepare();// might take long! (for buffering, etc)
The link you provided already has a lot of suggestions for overcoming these problems above.
Please try the code on that link, especially the ones that suggest prepareAsync and the onprepared listener. Then you can get back here if it does not work.
i have a problem. my media player doesn't stop even activity has stopped. so i confuse why media player doesn't stop. media player immediately playing until a mp3 finish. here my code
public class Isi_TakbiratulIhram extends Activity{
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.isitakbiratulihram);
ImageButton iftitah1=(ImageButton) findViewById (R.id.takbiratulihram1);
iftitah1.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
go();
}
public void go(){
if(mp != null ){
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();
}
mp.seekTo(0);
mp = null;
}
else {
mp=MediaPlayer.create(Isi_TakbiratulIhram.this, R.raw.iftitah1);
mp.start();
}
}});
thanks for help
Override Activity onPause() method for stoping Media Player :
#Override
public void onPause(){
super.onPause();
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
You can override onPause() or onStop() and stop it there:
#Override protected void onPause()
{
if(mp != null ){
mp.stop();
// mp.release(); ??
}
super.onPause();
}
When user stops an Activity the state of activity can go to onStop() state,SO it is required to stop any ongoing tasks like music playing here.So in android programming it's required go handle all states like onRestart(), onResume(), onStop(), onPause(), onDestroy() for proper functioning of the program.
For handling stopping and restarting of activity visit :
http://developer.android.com/training/basics/activity-lifecycle/stopping.html