onStop() fragment doesnt stop mediaplayer - android

I tried to stop my song from playing when going from Fragmant A to Fragment B with the use of onStop() but i cant get it to work.
This is the debugging result:
My mediaplayer variable is getting the song properties but skipping the --> mediaplayer.isPlaying statement.
When im inside my Fragment B it still continue to play the song.
What am i doing wrong?
NOTE: I dont play my music from my Fragment A (i just add the songs inside here). I play the songs from my custom adapter. Dont know if that may be the case but if so --> then i cant call onStop() inside my adapter.
EDITED:
This is my adapter class:
public class ListViewAdapter extends BaseAdapter {
//Create variables
MediaPlayer mediaPlayer;
int layout;
Song currentSong;
ArrayList<Song> arrayList;
Context context;
//Constructor
public ListViewAdapter(int layout, ArrayList<Song> arrayList, Context context) {
this.layout = layout;
this.arrayList = arrayList;
this.context = context;
}
//ViewHolder class holding my views
private class Viewholder {
TextView artistTxt, songNameTxt;
ImageView playB, stopB;
CircleImageView artistImg;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
//Create viewholder variable
final Viewholder viewholder;
//Check if view is null
if (view == null) {
//Create new ViewHolder object
viewholder = new Viewholder();
//Inflate my view
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.listview_customlayout, null);
//Find my view id's
viewholder.artistImg = (CircleImageView) view.findViewById(R.id.artistImgBackgroundDetail);
viewholder.artistTxt = (TextView) view.findViewById(R.id.artistTxt);
viewholder.songNameTxt = (TextView) view.findViewById(R.id.songNameTxt);
viewholder.playB = (ImageView) view.findViewById(R.id.playB);
viewholder.stopB = (ImageView) view.findViewById(R.id.stopB);
//Set my view to viewholder
view.setTag(viewholder);
} else {
viewholder = (Viewholder) view.getTag();
}
//Assign song to my arraylist
final Song song = arrayList.get(position);
//Set my views to their resources
viewholder.artistImg.setImageResource(song.getArtistImg());
viewholder.artistTxt.setText(song.getArtist());
viewholder.songNameTxt.setText(song.getSongName());
//get all songs
mediaPlayer = MediaPlayer.create(context, song.getSong());
//Play button click performed
viewholder.playB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Checks if my current song is null and creates a new song
if (currentSong == null) {
mediaPlayer = MediaPlayer.create(context, song.getSong());
}
//if mediaplayer is not null and my current song is not equal to the new song i clicked on
if (mediaPlayer != null && currentSong != song) {
//resets the mediaplayer and creates a new song from the position in the list
mediaPlayer.reset();
mediaPlayer = MediaPlayer.create(context, song.getSong());
viewholder.playB.setImageResource(R.drawable.play_black);
mediaPlayer.start();
viewholder.playB.setImageResource(R.drawable.pause_black);
} else {
mediaPlayer.pause();
viewholder.playB.setImageResource(R.drawable.play_black);
}
//check if current song is null or the newly clicked song is equal to my current song
//if true then assign the newly clicked song as my CURRENT one
//--so it doesnt play the same song for every single one
if (currentSong == null || song != currentSong) {
currentSong = song;
}
}
});
//Stop song when click performed
viewholder.stopB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//stops my current song and make it null
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null;
viewholder.playB.setImageResource(R.drawable.play_black);
}
}
});
return view;
}
}

You could try to add a method to stop the media player in your adapter:
public void stop() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null
}
}
And call the method when the fragment is stopping:
#Override
public void onStop() {
super.onStop();
adapter.stop();
}

mediaPlayer = MediaPlayer.create(...)
.
.
.
mediaPlayer.stop()
You create a new player and then stop it. You never stop the one that was playing already.

Related

Changing of Listview Button State when pressed for position

I have a Listview, in which every row has play button. If i clicked on First Play Button it changes to pause but if i pressed second row play button,then first will remain in pause state but i want that if any of button is pressed then the previous button back to its play state and the clicked one changes to pause.
Code is below.
public class RingsAdapter extends BaseAdapter {
private Context context;
private ArrayList<Ringsinfo> data;
private SqlLiteDbHelper db;
private MediaPlayer mediaPlayer;
int pause_button_position = -1;
public RingsAdapter(Context mContext) {
data = new ArrayList<Ringsinfo>();
context = mContext;
initDatabase(context);
mediaPlayer = new MediaPlayer();
}
private void initDatabase(Context c) {
db = new SqlLiteDbHelper(c);
try {
db.CopyDataBaseFromAsset();
db.openDataBase();
} catch (IOException e) {
e.printStackTrace();
}
}
public void AddAll(ArrayList<Ringsinfo> listperson) {
data.clear();
data.addAll(listperson);
notifyDataSetChanged();
}
#Override
public int getCount() {
return this.data.size();
}
#Override
public Object getItem(int position) {
return (Ringsinfo) this.data.get(position);
}
#Override
public long getItemId(int position) {
return (long) position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
HolderView mHolderView;
if (convertView == null) {
mHolderView = new HolderView();
convertView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.row_ringtone_list, parent, false);
mHolderView.btnPlay = (Button) convertView.findViewById(R.id.btnPlay);
mHolderView.btnSetting = (Button) convertView.findViewById(R.id.btnSetting);
mHolderView.tvRingName = (TextView) convertView.findViewById(R.id.tvRingName);
convertView.setTag(mHolderView);
} else {
mHolderView = (HolderView) convertView.getTag();
}
mHolderView.tvRingName.setText(((Ringsinfo) this.data.get(position)).name);
mHolderView.btnSetting.setOnClickListener(new RingDetails(position));
mHolderView.btnPlay.setOnClickListener(new playRingtone(position));
if (position != pause_button_position)
mHolderView.btnPlay.setBackgroundResource(R.mipmap.play);
return convertView;
}
class RingDetails implements View.OnClickListener {
final int val$position;
RingDetails(int i) {
this.val$position = i;
}
public void onClick(View view) {
Intent intent = new Intent(context, RingDetailActivity.class);
intent.putExtra("calls", ((Ringsinfo) data.get(this.val$position)).content);
intent.putExtra("heading", ((Ringsinfo) data.get(this.val$position)).name);
context.startActivity(intent);
}
}
class playRingtone implements View.OnClickListener {
int val$position;
playRingtone(int i) {
val$position = i;
}
public void onClick(View view) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
view.setBackgroundResource(R.mipmap.play);
} else {
view.setBackgroundResource(R.mipmap.pause);
pause_button_position = val$position;
mediaPlayer.start();
}
mediaPlayer.reset();
mediaPlayer = MediaPlayer.create(context, new Builder().scheme("android.resource").authority(context.getPackageName()).appendPath(String.valueOf(context.getResources().getIdentifier(((Ringsinfo) data.get(val$position)).content + BuildConfig.FLAVOR, "raw", context.getPackageName()))).build());
mediaPlayer.start();
}
}
private class HolderView {
private Button btnPlay, btnSetting;
private TextView tvRingName;
}
public void Stop() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.reset();
mediaPlayer.stop();
mediaPlayer.release();
}
}}
You need to write else condition in your Adapter where you change your background for ImageView
if (position != pause_button_position)
mHolderView.btnPlay.setBackgroundResource(R.mipmap.play);
else
mHolderView.btnPlay.setBackgroundResource(R.mipmap.pause);
Also, It would be good if you manage one Boolean list in Adapter to manager your play pause button.
Like your Boolean list is same size of your ArrayList. once user click on 1st play button then you need to set true at 1st position of Boolean List and rest of are false. Same way if user click on 2nd play button then set true at 2nd position of your Boolean List and keep rest of false and notify your Adapter.
and your play pause button background is now based on Boolean List.

In listview I click an audio to start but when I scroll I see other audios has stared too

I have a ListView of audios which have seek bar in it . When I click the play button of one of audios, it starts but when I scroll down I see that some other seekbars are also playing and when I scroll up again the first item that I clicked is no paused. I have searched a lot and it seems that there is a problem with position of item in list , the only solution I found was to use viewholder in adapter but it didn't work . does any one have a solution? thanks.
public class AudioAdapter extends ArrayAdapter<News> {
Context context;
boolean isPLaying = false;
public AudioAdapter(Context context, ArrayList<News> array) {
super(context, R.layout.list_item_news, array);
this.context = context;
}
public static class ViewHolder {
TextView txtTitle;
SeekBar seekBar;
TextView audioDuration;
ImageView btnPlayStop;
MediaPlayer mp;
Handler seekHandler;
int audioCurrentPosition;
}
public View getView(final int position, View convertView, ViewGroup parent) {
final News news = getItem(position);
final ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext())
.inflate(R.layout.list_item_audio, parent, false);
viewHolder.txtTitle = (TextView) convertView.findViewById(R.id.audioTitle);
viewHolder.seekBar = (SeekBar) convertView.findViewById(seek_bar);
viewHolder.audioDuration = (TextView) convertView.findViewById(R.id.txtDuration);
viewHolder.btnPlayStop = (ImageView) convertView.findViewById(R.id.btnPlayStop);
viewHolder.mp = new MediaPlayer();
viewHolder.seekHandler = new Handler();
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.txtTitle.setText(news.getTitle());
viewHolder.mp = MediaPlayer.create(context, R.raw.team);
viewHolder.audioCurrentPosition = news.getAudioPosition();
viewHolder.mp.seekTo(viewHolder.audioCurrentPosition * 1000);
viewHolder.audioDuration.setText(ms);
viewHolder.btnPlayStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ( !isPLaying) {
viewHolder.mp.seekTo(viewHolder.audioCurrentPosition * 1000);
//play
isPLaying = true;
viewHolder.btnPlayStop.setImageResource(ic_media_pause);
viewHolder.mp.start();
viewHolder.seekBar.setMax( viewHolder.mp.getDuration() / 1000);
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
if ( viewHolder.mp != null && viewHolder.mp.isPlaying()) {
int mCurrentPosition = viewHolder.mp.getCurrentPosition() / 1000;
viewHolder.seekBar.setProgress(mCurrentPosition);
viewHolder.seekHandler.postDelayed(this, 1000);
news.setAudioPosition( viewHolder.mp.getCurrentPosition() / 1000);
}
}
});
} else {
//pause
isPLaying = false;
viewHolder.btnPlayStop.setImageResource(ic_media_play);
viewHolder.audioCurrentPosition = viewHolder.mp.getCurrentPosition() / 1000;
viewHolder.mp.pause();
}
}
});
viewHolder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if ( viewHolder.mp != null && fromUser) {
//Change the seekbar with finger
viewHolder.mp.seekTo(progress * 1000);
viewHolder.audioCurrentPosition = progress * 1000;
}
}
});
viewHolder.mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//When mediaplayer finishes
isPLaying = false;
viewHolder.btnPlayStop.setImageResource(ic_media_play);
viewHolder.audioCurrentPosition = 0;
}
});
return convertView;
}
}
Since you are using ViewHolder pattern, your views are being recycled and hence, your playing-indicator gets reused too...
Release your old MediaPlayer when you a new instance is started. For example:
protected void mediaplayerMethod(String filepath) {
Log.d(TAG, "mediaplayerMethod audio file path " + filepath);
if(mp != null){
mp.release();
}
mp = null;
mp = new MediaPlayer();
mp.setOnCompletionListener(AudioAdapter.this); // Important
seekBar.setOnSeekBarChangeListener(AudioAdapter.this);
utils = new Utilities();
playSong(filepath);
}
EDIT 1
You can try the below code
public class SoundTest extends Activity {
private ListView lv1;
private String lv_arr[]={"test 1","test 2","test 3","test 4","test 5"};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv1=(ListView)findViewById(R.id.ListView01);
lv1.setAdapter(new ArrayAdapter<String>(this,R.layout.list_item, lv_arr));
lv1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
if (lv1.getItemAtPosition(position)=="test 1") {
MediaPlayer mp = MediaPlayer.create(getApplicationContext(),R.raw.sound1);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
if (lv1.getItemAtPosition(position)=="test 2") {
MediaPlayer mp = MediaPlayer.create(getApplicationContext(),R.raw.sound2);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
//And the rest of the audio 3,4,5.
}
});
}
}
The global variable MediaPlayer needs to be set private static. This has caught me several times.

Play/pause buttons in Listview are not updating

I am new on Android. I have a listview, which have image, text and play/pause button. When I click on a play button in a row and then click on the play button in another row, the background of both buttons remain pause. So I want that when I click on play button in a row and then click on the play button in another row, the background of first button should change to play and background of second should remain pause. Thanks in advance.
public class MyListAdapter extends ArrayAdapter<String> {
private String[] gelenurl;
List<String> gelen_ad;
public static MediaPlayer mPlayer= new MediaPlayer();
private int layout;
public MyListAdapter(Context context, int resource, List<String> objects, String[] arr) {
super(context, resource, objects);
layout=resource;
gelenurl=arr;
gelen_ad=objects;
}
#NonNull
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder mainViewholder;
if(convertView==null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView=inflater.inflate(layout, parent, false);
mainViewholder= new ViewHolder();
convertView.setTag(mainViewholder);
}
else {
mainViewholder = (ViewHolder) convertView.getTag();
}
mainViewholder.img = (ImageView) convertView.findViewById(R.id.list_item_thumbnail);
mainViewholder.img.setImageResource(R.drawable.ic_radio);
mainViewholder.title = (TextView) convertView.findViewById(R.id.list_item_text);
mainViewholder.title.setText(getItem(position));
mainViewholder.button = (ImageButton) convertView.findViewById(R.id.list_item_btn);
mainViewholder.button.setImageResource(R.drawable.transparent_play);
mainViewholder.button.setBackgroundColor(Color.WHITE);
mainViewholder.button.setVisibility(View.VISIBLE);
mainViewholder.stop_button = (ImageButton) convertView.findViewById(R.id.list_item_stop_btn);
mainViewholder.stop_button.setImageResource(R.drawable.transparent_stop);
mainViewholder.stop_button.setBackgroundColor(Color.WHITE);
final ViewHolder vh = mainViewholder;
vh.stop_button.setVisibility(View.INVISIBLE);
mainViewholder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
vh.button.setVisibility(View.INVISIBLE);
vh.stop_button.setVisibility(View.VISIBLE);
try {
radioLinks(gelenurl[position]);
} catch (IOException e) {
e.printStackTrace();
}
}
public void radioLinks(String city) throws IOException {
if(mPlayer.isPlaying()) {
mPlayer.stop();
mPlayer.reset();
}
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(city);
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mPlayer.start();
}
});
}
});
mainViewholder.stop_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
vh.button.setVisibility(View.VISIBLE);
vh.stop_button.setVisibility(View.INVISIBLE);
mPlayer.stop();
mPlayer.reset();
}
});
return convertView;
}
}
You will want to track the currently playing song with a member variable. Something like private String currentCity = null. Inside the onClick handler for play, you'll set that to the selected item, and call notifyDataSetChanged to tell the adapter to refresh everything. Inside the stop callback, you'll probably need to set currentCity = null after stopping and again call notifyDataSetChanged()
try {
currentCity = gelenurl[position];
radioLinks(currentCity);
notifyDataSetChanged();
} catch (IOException e) {
e.printStackTrace();
}
You want to use that information inside getView() to decide what to show.
mainViewholder.img = (ImageView) convertView.findViewById(R.id.list_item_thumbnail);
mainViewholder.img.setImageResource(R.drawable.ic_radio);
mainViewholder.title = (TextView) convertView.findViewById(R.id.list_item_text);
mainViewholder.title.setText(getItem(position));
mainViewholder.button = (ImageButton) convertView.findViewById(R.id.list_item_btn);
mainViewholder.button.setImageResource(R.drawable.transparent_play);
mainViewholder.button.setBackgroundColor(Color.WHITE);
...
if ( getItem(position) == currentCity ) {
// show stop button
} else {
/// show play button
}

notifyDataSetChanged Android ListView and VideoView

My app has a ListView and each row contains a TextView running a timer and a video player (ExoMediaPlayer) in each row
I refresh each row by listAdapter.notifyDataSetChanged() to update the timer TextView every second. It works fine as shown in the below code.
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
updateTextView();
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
private void updateTextView() {
if (listView != null) {
for (int i = 0; i <= listView.getListChildCount(); i++) {
View v = listView.getListChildAt(i);
if (v != null) {
for(int x=firstVisibleRow;i<=lastVisibleRow;i++)
{
HomeListItem data;
data = listMockData.get(i);
HListAdapter.notifyDataSetChanged();
TextView t = (TextView) v.findViewById(R.id.tvTimer);
t.setText(data.getElapsedTime());
}
}
}
}
}
Adapter
public HListAdapter(Context context, ArrayList<HomeListItem> listData) {
c = context;
layoutInflater = LayoutInflater.from(context);
this.listData = listData;
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return listData.indexOf(getItem(position));
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
newsItem = listData.get(position);
if (convertView == null) {
holder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.location_list_row, null);
holder.timer= (TextView) convertView.findViewById(R.id.timer);
holder.videoPlayer = (EMVideoView) convertView.findViewById(R.id.videoPlayer);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
newsItem = listData.get(position);
holder.timer.setText(newsItem.getElapsedTime());
String videolink = "http://www.someurl.com/";
holder.videoPlayer.setVideoURI(Uri.parse(videolink ));
holder.videoPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
holder.videoPlayer.start();
}
});
return convertView;
}
static class ViewHolder {
TextView timer;
EMVideoView videoPlayer;
}
Problem
The above code works good and the timer TextView updates the time every second.
But the problem i am facing is the VideoPlayer is being reloaded every second, the video does not play due to HListAdapter.notifyDataSetChanged();
if i remove the notifyDataSetChanged() video plays on the listview but the timer TextView does not get updated.
Any possibility to refresh/update the TextView timer only every second.
Any logic or method to solve the problem and make the video play and also the timer to be updated every second?
I think your logic in updateTextView method is wrong. See my comments
private void updateTextView() {
if (listView != null) {
for (int i = 0; i <= listView.getListChildCount(); i++) {
View v = listView.getListChildAt(i);
if (v != null) {
for(int x=firstVisibleRow;i<=lastVisibleRow;i++) // what is x here ?!!
{
HomeListItem data;
data = listMockData.get(i);
HListAdapter.notifyDataSetChanged();
TextView t = (TextView) v.findViewById(R.id.tvTimer);
t.setText(data.getElapsedTime()); // here you are setting the same text over and over
}
}
}
}
}
Instead go with this
private void updateTextView() {
if (listView != null) {
for (int i = 0; i < listView.getListChildCount(); i++) {
View v = listView.getListChildAt(i);
HomeListItem data;
data = listMockData.get(firstVisibleRow + i);
TextView t = (TextView) v.findViewById(R.id.tvTimer);
t.setText(data.getElapsedTime());
}
}
}
no need of notifyDataSetChanged()

Android: Playing one media file at one time from listview

i have create one listview which contain 4 media file to play.If i am select 1st song to play,it is playing but if i select socond song on listview to play then both are playing so i want that if second will be select to play then first need to be stop and only second song need to be play. Kindly help me solve such issue...Thank in advance.
Below is my code.
Main Activity
public class MainActivity extends Activity implements AdapterView.OnItemClickListener {
private ArrayList<String> audioList;
private File file;
private ListView lvAudio;
private Context context;
private Adapter Adaptr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
audioList = new ArrayList<String>();
String root_sd = Environment.getExternalStorageDirectory().toString();
file = new File( root_sd + "/EmoticApp/AudioFile/" ) ;
File list[] = file.listFiles();
for( int i=0; i< list.length; i++)
{
audioList.add( list[i].getName() );
}
getid();
setListner();
Adaptr = new Adapter(MainActivity.this,audioList);
lvAudio.setAdapter(Adaptr);
}
private void setListner() {
lvAudio.setOnItemClickListener(this);
}
private void getid() {
lvAudio =(ListView)findViewById(R.id.lvAudio);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
Adapter code:
public class Adapter extends BaseAdapter {
ArrayList<String> audioList;
Context context;
private static LayoutInflater inflater = null;
public boolean flag =false;
public Adapter(MainActivity mainActivity, ArrayList<String> audioList) {
this.context = mainActivity;
this.audioList = audioList;
}
#Override
public int getCount() {
return audioList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder {
private ImageView imgIcon, imgPlay, imgPause, imgStop;
private MediaPlayer mediaPlayer;
private SeekBar seekbar;
private TextView tvTotalTime,duration;
private double timeElapsed = 0, finalTime = 0;
private int forwardTime = 2000, backwardTime = 2000;
private Handler durationHandler = new Handler();
//handler to change seekBarTime
private Runnable updateSeekBarTime = new Runnable() {
public void run() {
//get current position
timeElapsed = mediaPlayer.getCurrentPosition();
//set seekbar progress
seekbar.setProgress((int) timeElapsed);
tvTotalTime.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) finalTime), TimeUnit.MILLISECONDS.toSeconds((long) finalTime)));
//set time remaing
double timeRemaining = finalTime - timeElapsed;
duration.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining), TimeUnit.MILLISECONDS.toSeconds((long) timeRemaining) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining))));
//repeat yourself that again in 100 miliseconds
durationHandler.postDelayed(this, 100);
}
};
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View myView = convertView;
final Holder holder;
if (myView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
myView = inflater.inflate(R.layout.video_adapter, null);
holder = new Holder();
holder.imgPlay = (ImageView) myView.findViewById(R.id.imgPlay);
holder.imgPause = (ImageView) myView.findViewById(R.id.imgPause);
holder.imgStop = (ImageView) myView.findViewById(R.id.imgStop);
holder.seekbar =(SeekBar)myView.findViewById(R.id.seekbar);
holder.tvTotalTime =(TextView)myView.findViewById(R.id.tvTotalTime);
holder.duration =(TextView)myView.findViewById(R.id.duration);
holder.seekbar.setClickable(true);
holder.seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
holder.mediaPlayer.seekTo(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
String fileName = audioList.get(position);
String path="/EmoticApp/AudioFile/";
Log.e("Checking File:", "Checking=======:" + fileName);
flag =true;
holder.mediaPlayer = MediaPlayer.create(context, Uri.parse(Environment.getExternalStorageDirectory().getPath()+path + fileName));
holder.imgPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (flag == true) {
holder.mediaPlayer.start();
if (holder.mediaPlayer.isPlaying()) {
Toast.makeText(context, "Playing", Toast.LENGTH_LONG).show();
holder.imgPlay.setVisibility(View.INVISIBLE);
holder.imgPause.setVisibility(View.VISIBLE);
holder.timeElapsed = holder.mediaPlayer.getCurrentPosition();
holder.seekbar.setProgress((int) holder.timeElapsed);
holder.durationHandler.postDelayed(holder.updateSeekBarTime, 100);
holder.finalTime = holder.mediaPlayer.getDuration();
holder.seekbar.setMax((int) holder.finalTime);
Toast.makeText(context,"Playing",Toast.LENGTH_SHORT).show();
}
}
}
});
holder.imgPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.mediaPlayer.pause();
holder.imgPause.setVisibility(View.INVISIBLE);
holder.imgPlay.setVisibility(View.VISIBLE);
}
});
holder.mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
holder.imgPause.setVisibility(View.INVISIBLE);
holder.imgPlay.setVisibility(View.VISIBLE);
}
});
myView.setTag(holder);
return myView;
}
return myView;
}
}
Use this lines of code:
MediaPlayer mp = new MediaPlayer();
playMySong(String songPath)
{
mp.reset();
mp.setDataSource(songPath);
mp.prepare();
mp.start();
}
Don't create MediaPlayer instance for individual row of list. Let it be property of Adapter because this will help us to detect whether this media player is playing some song currently or not
So do this
public class MyAdapter{
private MediaPlayer mediaPlayer=new MediaPlayer();// I am ignoring exact constructor
//now in your getView method do like this
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
//.............prev code
holder.imgPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
holder.imgPause.setVisibility(View.INVISIBLE);
holder.imgPlay.setVisibility(View.VISIBLE);
}else{
mp.reset();
mp.setDataSource(Uri.parse(Environment.getExternalStorageDirectory().getPath()+path + fileName));
mp.prepare();
mp.start();
//set other things
}
}
});
//......some code below
}
}
Hope this will help you !!!!
As you progress in your application, you will find out that there would be other activities or fragment which may try to play some music and you will fall in same circumstances, Otherwise you might think that you just want to stop music as you come out of this list activity.
instead of going though the hustle of managing the instance of MediaPlayer make just make it once in the Application inside a class which will handle your business for playing the music, in your current case what is happening is the MediaPlayer API of android keep getting the request for playing music and by no means that these API can't handle multiple request so they will keep on playing as you command them,
in your custom class you gotta check if your MediaPlayer instance is still playing or not like this...
player.isPlaying()
if it is playing than stop it, like this
player.stop()
and give it some new data what you want it to play.

Categories

Resources