I have a list in which each element on a player. When I click on "start" and a song starts playing strip seekbar starts moving. when click on the "stop" the song stops playing and the strip stops. But if while moving the strip I scroll list and it goes off the screen, it starts to move another strip that is on the same position in the visible area of the screen.
public class RecordAdapter extends BaseAdapter {
private MediaPlayer mediaPlayer;
private LayoutInflater inflater;
private ArrayList<RecordBean> recordBeans;
private final Handler handler = new Handler();
private Context ctx;
private int global_position;
...
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
if (convertView == null) {
view = inflater.inflate(R.layout.recorditem, parent, false);
holder = new ViewHolder();
holder.date = (TextView) view.findViewById(R.id.recordate);
holder.seekBar = (SeekBar) view.findViewById(R.id.seekBar);
holder.start = (Button) view.findViewById(R.id.btnStart);
holder.stop = (Button) view.findViewById(R.id.btnStop);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.date.setText(" " + recordBeans.get(position).getDate());
holder.start.setTag(position);
holder.stop.setTag(position);
holder.seekBar.setTag(position);
holder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(final SeekBar seekBar, final int i, boolean b) {
if (b && (Integer)seekBar.getTag()==global_position) {
mediaPlayer.seekTo(i);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
holder.start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
releaseMP();
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(recordBeans.get((Integer) v.getTag()).getFile());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
global_position = position;
holder.start.setTextColor(Color.RED);
holder.seekBar.setMax(mediaPlayer.getDuration());
startPlayProgressUpdater(holder.seekBar,holder.start);
}
});
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
if (mediaPlayer == null) {
return;
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
Log.d("LOG_TAG", "onCompletion");
holder.start.setTextColor(Color.WHITE);
}
});
}
});
holder.stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer == null)
return;
if ((Integer) v.getTag() == global_position) {
mediaPlayer.stop();
}
}
});
return view;
}
private void releaseMP() {
if (mediaPlayer != null) {
try {
mediaPlayer.release();
mediaPlayer = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static class ViewHolder {
TextView date;
SeekBar seekBar;
Button start;
Button stop;
}
public void startPlayProgressUpdater(final SeekBar seek, final Button start) {
seek.setProgress(mediaPlayer.getCurrentPosition());
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater(seek,start);
}
};
handler.postDelayed(notification, 1000);
} else {
mediaPlayer.pause();
seek.setProgress(0);
}
}
}
EDIT:
I added geter and seter in recordBean
public int getSeekPos() {
return SeekPos;
}
public void setSeekPos(int seekPos) {
SeekPos = seekPos;
}
and
holder.seekBar.setProgress(recordBeans.get(position).getSeekPos());
holder.date.setText(" " + recordBeans.get(position).getDate());
and
#Override
public void onProgressChanged(final SeekBar seekBar, final int i, boolean b) {
if (b && (Integer)seekBar.getTag()==global_position) {
// mediaPlayer.seekTo(i);
recordBeans.get(position).setSeekPos(i);
}
}
but I think it left something extra in my code
The list item is being recycled when it leaves the screen.
You could try to call this in getView:
holder.seekBar.clearFocus();
This is a tricky process, but you can do this in the following way, as I have seen that you have created a List of RecordBean class. So what you can do is you have to create a Getter Setter in RecordBean for storing the position of you SeekBar like:
public void setSeekPos(int pos) {
this.pos = pos;
}
public int getSeekPos() {
return pos;
}
In your adapter below the line
holder.date.setText(" " + recordBeans.get(position).getDate());
set the progress of seekBar like this: holder.seekBar.setProgress(recordBeans.get(position).getSeekPos());
and inside the onProgressChanged add the following line recordBeans.get(position).setSeekPos(i);
This will resolve your issue.
Please let me know if it's working or not.
Thanks
Related
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.
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.
I have a SeekBar and some MediaFiles fetched from sd card. Below is the code I wrote to play MediaFile and to progress SeekBar according to MediaFile position, but when I click on the item in the ListView, it does nothing and nothing starts. I don't know whats wrong with this code. Help!! Let me know if you want other information.
songAdapter1.setOnItemClickListener(new songAdapter.OnItemClickListener() {
#Override
public void onItemClick(RecyclerView.ViewHolder holder, View view, final songInfo obj, int position) {
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}else {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(obj.getSongUrl());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
seekBar.setProgress(0);
seekBar.setMax(mediaPlayer.getDuration());
Log.d("Prog", "run: " + mediaPlayer.getDuration());
}
});
}catch (Exception e){}
}
};
myHandler.postDelayed(runnable,100);
}
}
});
checkUserPermission();
Thread t = new runThread();
t.start();
return rootView;
}
class runThread extends Thread {
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("Runwa", "run: " + 1);
if (mediaPlayer != null) {
seekBar.post(new Runnable() {
#Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
});
Log.d("Runwa", "run: " + mediaPlayer.getCurrentPosition());
}
}
}
}
package com.example.murarilal.atry;
public class songAdapter extends RecyclerView.Adapter<songAdapter.SongHolder> {
private Context context;
MediaMetadataRetriever metaRetriver;
byte[] art;
MediaPlayer m;
Handler mHandler;
private OnItemClickListener mOnItemClickListener;
private ArrayList<songInfo> _songs = new ArrayList<songInfo>();
SeekBar seekbar;
Handler handler;
MediaPlayer mp;
public songAdapter(Context context, ArrayList<songInfo> songs) {
this.context = context;
this._songs = songs;
}
public interface OnItemClickListener {
void onItemClick(RecyclerView.ViewHolder holder, View view, songInfo obj, int position);
//void onItemClick(Button b, View view, songInfo obj, int position);
}
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mOnItemClickListener = mItemClickListener;
}
#Override
public SongHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View myView = LayoutInflater.from(context).inflate(R.layout.card, viewGroup, false);
return new SongHolder(myView);
}
#Override
public void onBindViewHolder(final SongHolder songHolder, final int i) {
final songInfo s = _songs.get(i);
metaRetriver = new MediaMetadataRetriever();
metaRetriver.setDataSource(_songs.get(i).getId());
try {
art = metaRetriver.getEmbeddedPicture();
Bitmap songImage = BitmapFactory.decodeByteArray(art, 0, art.length);
songHolder.album_art.setImageBitmap(songImage);
} catch (Exception e) {
// Drawable resId;
//resId = R.drawable.music;
songHolder.album_art.setBackgroundResource(R.drawable.music);
}
setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(RecyclerView.ViewHolder holder, View view, songInfo obj, int position) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(songHolder, view, s, i);
}
}
});
//final String filename = "android.resource://" + this.context + "/raw/test0";
songHolder.tvSongName.setText(_songs.get(i).getSongName());
songHolder.tvSongArtist.setText(_songs.get(i).getArtistName());
songHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
#Override
public int getItemCount() {
return _songs.size();
}
public class SongHolder extends RecyclerView.ViewHolder {
TextView tvSongName,tvSongArtist;
ImageView album_art;
public SongHolder(View itemView) {
super(itemView);
tvSongName = (TextView) itemView.findViewById(R.id.songName);
tvSongArtist = (TextView) itemView.findViewById(R.id.artistName);
album_art = (ImageView) itemView.findViewById(R.id.albumArt);
seekbar=itemView.findViewById(R.id.seekBar);
}
}
public void setSearchResult(List<songInfo> result) {
_songs = (ArrayList<songInfo>) result;
notifyDataSetChanged();
}
}
You haven't added properly added code for updating your seekbar value. Try with the below code
private Runnable UpdateSongTime = new Runnable() {
public void run() {
startTime = mediaPlayer.getCurrentPosition();
tx1.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes((long) startTime),
TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
toMinutes((long) startTime)))
);
seekbar.setProgress((int)startTime);
}
};
Also you don't have to add prepared listener method inside the runnable. Place that method outside of runnable and simply call the above runnable code from the PreparedListener method
To call the handler use the below code
myHandler.postDelayed(UpdateSongTime , 100);
I am developing an app with audio player.I want to add next song play button and previous song play button. Following is my code which is working but in this code i want to add next track play and previous track play button.Help me!!
//MainActivity.java
public class MainActivity extends ListActivity {
private static final int UPDATE_FREQUENCY = 500;
private static final int STEP_VALUE = 4000;
private TextView selectedfile = null;
private SeekBar seekBar = null;
private MediaPlayer player = null;
private ImageButton prev = null;
private ImageButton play = null;
private ImageButton next = null;
private MediaCursorAdapter adapter = null;
private boolean isStarted = true;
private String currentFile = "";
private boolean isMovingSeekBar = false;
private final Handler handler = new Handler();
private final Runnable updatePositinRunnable = new Runnable() {
#Override
public void run() {
updatePosition();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selectedfile = (TextView) findViewById(R.id.selecteditem);
seekBar = (SeekBar) findViewById(R.id.seekBar);
prev = (ImageButton) findViewById(R.id.previous);
play = (ImageButton) findViewById(R.id.play);
next = (ImageButton) findViewById(R.id.next);
player = new MediaPlayer();
player.setOnCompletionListener(onCompletion);
player.setOnErrorListener(onError);
seekBar.setOnSeekBarChangeListener(seekBarChanged);
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.
INTERNAL_CONTENT_URI, null, null, null, null);
if (null != cursor) {
cursor.moveToFirst();
adapter = new MediaCursorAdapter(this, R.layout.item, cursor);
setListAdapter(adapter);
prev.setOnClickListener(OnButtonClick);
play.setOnClickListener(OnButtonClick);
next.setOnClickListener(OnButtonClick);
}
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
currentFile = (String) v.getTag();
startPlay(currentFile);
}
private void startPlay(String file) {
Log.i("Selected: ", file);
selectedfile.setText(file);
seekBar.setProgress(0);
player.stop();
player.reset();
try {
player.setDataSource(file);
player.prepare();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
seekBar.setMax(player.getDuration());
play.setImageResource(android.R.drawable.ic_media_pause);
updatePosition();
isStarted = true;
}
private void stopPlay() {
player.stop();
player.reset();
play.setImageResource(android.R.drawable.ic_media_play);
handler.removeCallbacks(updatePositinRunnable);
seekBar.setProgress(0);
isStarted = false;
}
#Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(updatePositinRunnable);
player.stop();
player.reset();
player.release();
player = null;
}
private void updatePosition() {
handler.removeCallbacks(updatePositinRunnable);
seekBar.setProgress(player.getCurrentPosition());
handler.postDelayed(updatePositinRunnable, UPDATE_FREQUENCY);
}
private View.OnClickListener OnButtonClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play: {
if (player.isPlaying()) {
handler.removeCallbacks(updatePositinRunnable);
player.pause();
play.setImageResource(android.R.drawable.ic_media_play);
} else {
if (isStarted) {
player.start();
play.setImageResource(android.R.drawable.ic_media_pause);
updatePosition();
} else {
startPlay(currentFile);
}
}
break;
}
case R.id.next: {
int seekto = player.getCurrentPosition() + STEP_VALUE;
if (seekto > player.getDuration())
seekto = player.getDuration();
player.pause();
player.seekTo(seekto);
player.start();
break;
}
case R.id.previous: {
int seekto = player.getCurrentPosition() - STEP_VALUE;
if (seekto < 0)
seekto = 0;
player.pause();
player.seekTo(seekto);
player.start();
break;
}
}
}
};
private MediaPlayer.OnCompletionListener onCompletion = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
stopPlay();
}
;
};
private MediaPlayer.OnErrorListener onError = new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
};
private SeekBar.OnSeekBarChangeListener seekBarChanged =
new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (isMovingSeekBar) {
player.seekTo(progress);
Log.i("OnSeekBarChangeListener", "OnProgressChanged");
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
isMovingSeekBar = true;
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
isMovingSeekBar = false;
}
};
}
//MediaCursorAdapter.java
public class MediaCursorAdapter extends SimpleCursorAdapter {
public MediaCursorAdapter(Context context, int layout, Cursor c) {
super(context, layout, c, new String[]{MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.TITLE,MediaStore.Audio.AudioColumns.DURATION},
new int[]{R.id.displayname, R.id.title, R.id.duration});
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView title = (TextView) view.findViewById(R.id.title);
TextView name = (TextView) view.findViewById(R.id.displayname);
TextView duration = (TextView) view.findViewById(R.id.duration);
name.setText(cursor.getString(cursor.getColumnIndex(
MediaStore.MediaColumns.DISPLAY_NAME)));
title.setText(cursor.getString(cursor.getColumnIndex(
MediaStore.MediaColumns.TITLE)));
long durationInMS = Long.parseLong(cursor.getString(
cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION)));
double durationInMin = ((double) durationInMS / 1000.0) / 60.0;
durationInMin = new BigDecimal(Double.toString(durationInMin)).
setScale(2, BigDecimal.ROUND_UP).doubleValue();
duration.setText("" + durationInMin);
view.setTag(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.item, parent, false);
bindView(v, context, cursor);
return v;
}
}
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.