Android: Playing one media file at one time from listview - android

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.

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.

Mediafile and SeekBar are not playing

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);

How to stop old song when new song is playing in Android?

I am new to Android development and currently I am developing a simple mediaplayer application.
According to my project I have define three fragments. First fragment is a Player fragment which displays the mediaplayer control and plays the song. Second fragment is a Playlist which contains songlist. Third fragment is a recent playlist which contains recently played songs.
My question is how to stop old song playing when new song is selected from the Playlist fragment?
PLAYER FRAGMENT.
public class Player extends Fragment implements SeekBar.OnSeekBarChangeListener{
private ImageButton btnPlay;
private ImageButton btnForward;
private ImageButton btnBackward;
private ImageButton btnNext;
private ImageButton btnPrevious;
private ImageButton btnRepeat;
private ImageButton btnShuffle;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
// Media Player
public static MediaPlayer mp,mp2;
VisualizerView mVisualizerView;
SliderView sl;
private Visualizer mVisualizer;
// Handler to update UI timer, progress bar etc,.
private Handler mHandler = new Handler();;
private SongsManager songManager;
private Utilities utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
private ArrayList<SongModel> songsList = new ArrayList<SongModel>();
int songIndex;
SongAdapter songAdapter;
public Player(int position) {
songIndex = position;
}
public Player() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View android = inflater.inflate(R.layout.player, container, false);
/*ClickWheel wheel = (ClickWheel) android.findViewById(R.id.wheel);
wheel.getModel().addListener(this);*/
// variable initialization for button
return android;
}
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
btnPlay = (ImageButton)getView().findViewById(R.id.btnPlay);
btnForward = (ImageButton) getView().findViewById(R.id.btnForward);
btnBackward = (ImageButton) getView().findViewById(R.id.btnBackward);
btnNext = (ImageButton) getView().findViewById(R.id.btnNext);
btnPrevious = (ImageButton) getView().findViewById(R.id.btnPrevious);
btnRepeat = (ImageButton) getView().findViewById(R.id.btnRepeat);
btnShuffle = (ImageButton) getView().findViewById(R.id.btnShuffle);
songProgressBar = (SeekBar) getView().findViewById(R.id.songProgressBar);
songTitleLabel = (TextView) getView().findViewById(R.id.songTitle);
songTitleLabel.setSelected(true);
songTitleLabel.setEllipsize(TextUtils.TruncateAt.MARQUEE);
songTitleLabel.setSingleLine(true);
songCurrentDurationLabel = (TextView) getView().findViewById(R.id.songCurrentDurationLabel);
songTotalDurationLabel = (TextView) getView().findViewById(R.id.songTotalDurationLabel);
mp = new MediaPlayer();
songManager = new SongsManager();
utils = new Utilities();
songProgressBar.setOnSeekBarChangeListener(this);
songsList = songManager.getPlayList();
if (songIndex == 0) {
playSong(0);
} else {
playSong(songIndex);
}
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// check for already playing
if (mp.isPlaying()) {
if (mp != null) {
mp.pause();
btnPlay.setImageResource(R.drawable.btn_play);
}
} else {
// Resume song
if (mp != null) {
mp.start();
btnPlay.setImageResource(R.drawable.btn_pause);
}
}
}
});
btnForward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
int currentPosition = mp.getCurrentPosition();
if(currentPosition + seekForwardTime <= mp.getDuration()){
mp.seekTo(currentPosition + seekForwardTime);
}else{
mp.seekTo(mp.getDuration());
}
}
});
btnBackward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
int currentPosition = mp.getCurrentPosition();
if(currentPosition - seekBackwardTime >= 0){
mp.seekTo(currentPosition - seekBackwardTime);
}else{
mp.seekTo(0);
}
}
});
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if(currentSongIndex < (songsList.size() - 1)){
playSong(currentSongIndex + 1);
currentSongIndex = currentSongIndex + 1;
}else{
playSong(0);
currentSongIndex = 0;
}
}
});
btnPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if(currentSongIndex > 0){
playSong(currentSongIndex - 1);
currentSongIndex = currentSongIndex - 1;
}else{
playSong(songsList.size() - 1);
currentSongIndex = songsList.size() - 1;
}
}
});
btnRepeat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if(isRepeat){
isRepeat = false;
Toast.makeText(getActivity().getApplicationContext(), "Repeat is OFF", Toast.LENGTH_SHORT).show();
btnRepeat.setImageResource(R.drawable.btn_repeat);
}else{
isRepeat = true;
Toast.makeText(getActivity().getApplicationContext(), "Repeat is ON", Toast.LENGTH_SHORT).show();
isShuffle = false;
btnRepeat.setImageResource(R.drawable.btn_repeat_focused);
btnShuffle.setImageResource(R.drawable.btn_shuffle);
}
}
});
btnShuffle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if(isShuffle){
isShuffle = false;
Toast.makeText(getActivity().getApplicationContext(), "Shuffle is OFF", Toast.LENGTH_SHORT).show();
btnShuffle.setImageResource(R.drawable.btn_shuffle);
}else{
isShuffle= true;
Toast.makeText(getActivity().getApplicationContext(), "Shuffle is ON", Toast.LENGTH_SHORT).show();
isRepeat = false;
btnShuffle.setImageResource(R.drawable.btn_shuffle_focused);
btnRepeat.setImageResource(R.drawable.btn_repeat);
}
}
});
}
public void playSong(int songIndex) {
try {
Log.e("playSong()...", "....is called");
mp.reset();
mp.setDataSource(songsList.get(songIndex).getSongPath());
mp.prepare();
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
String songTitle = songsList.get(songIndex).getSongTitle();
songTitleLabel.setText(songTitle);
btnPlay.setImageResource(R.drawable.btn_pause);
mp.start();
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = mp.getDuration();
long currentDuration = mp.getCurrentPosition();
songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));
songCurrentDurationLabel.setText("" + utils.milliSecondsToTimer(currentDuration));
int progress =(int)(utils.getProgressPercentage(currentDuration, totalDuration));
songProgressBar.setProgress(progress);
mHandler.postDelayed(this, 100);
}
};
private void updateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
public void onStartTrackingTouch(SeekBar seekBar) {
mHandler.removeCallbacks(mUpdateTimeTask);
}
public void onStopTrackingTouch(SeekBar seekBar) {
mHandler.removeCallbacks(mUpdateTimeTask);
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);
mp.seekTo(currentPosition);
updateProgressBar();
}}
PLAYLIST FRAGMENT
public class Playlists extends ListFragment {
EditText edtSearch;
SongAdapter songAdapter;
ArrayList<SongModel> songList = new ArrayList<SongModel>();
SongsManager songsManager = new SongsManager();
// Songs list
public ArrayList<SongModel> songsList = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View windows = inflater.inflate(R.layout.playlist, container, false);
return windows;
}
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
getListView().setFastScrollEnabled(true);
//ListView animation
LayoutAnimationController controller
= AnimationUtils.loadLayoutAnimation(
getActivity(), R.anim.list_layout_controller);
getListView().setLayoutAnimation(controller);
edtSearch = (EditText)getView().findViewById(R.id.search);
final ArrayList<SongModel> songsListData = songsManager.songList;
Log.i("songsListData...",""+songsListData.size());
SongsManager plm = new SongsManager();
// get all songs from sdcard
this.songsList = plm.getPlayList();
// looping through playlist
for (int i = 0; i < songsListData.size(); i++) {
// creating new HashMap
SongModel song = songsListData.get(i);
// adding HashList to ArrayList
songsListData.add(song);
}
songAdapter = new SongAdapter(getActivity(),songsList);
setListAdapter(songAdapter);
// selecting single ListView item
ListView lv = getListView();
// listening to single listitem click
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View arg0,
int position, long id) {
Log.i("Index", "..." + position);
songAdapter.setSelectedIndex(position);
Intent i = new Intent(getActivity().getApplicationContext(),Main.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
SongModel songModel = (SongModel) songAdapter.getItem(position);
int indexOfSong = songAdapter.songsList.indexOf(songModel);
// Sending songIndex to PlayerActivity
i.putExtra("songIndex", indexOfSong);
getActivity().setResult(100, i);
startActivityForResult(i, 100);
/*Player.mp.stop();
Player.mp.release();*/
//putting song in recentSongList arraylist
SongModel model = (SongModel) songAdapter.getItem(position);
model.setSongTitle(songModel.getSongTitle());
model.setSongPath(songModel.getSongPath());
Constant.recentSongList.add(model);
Log.i("recentSongList...","..."+Constant.recentSongList.size());
getActivity().finish();
}
});
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
removeItemFromList(position);
return true;
}
private void removeItemFromList(int position) {
final int deletePosition = position;
AlertDialog.Builder alert = new AlertDialog.Builder(
getActivity());
alert.setTitle("Delete");
alert.setMessage("Do you want delete this song?");
alert.setPositiveButton("YES", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TOD O Auto-generated method stub
// main code on after clicking yes
songsList.remove(deletePosition);
songAdapter.notifyDataSetChanged();
songAdapter.notifyDataSetInvalidated();
}
});
alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
alert.show();
}
});
edtSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence cs, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
String text = edtSearch.getText().toString().toLowerCase(Locale.getDefault());
songAdapter.filter(text);
}
});
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (this.isVisible()) {
// If we are becoming invisible, then...
Log.d("setUserVisibleHint()...", "PlayList...Visible");
if (!isVisibleToUser) {
Log.d("setUserVisibleHint()...", "PlayList...notVisible");
// TODO stop audio playback
}
}
}
If anyone know how to do this, help me.
In your playlist fragment remove this Player.mp.release();
Edit your Listview onItemCLickListner like this
#Override
public void onItemClick(AdapterView<?> parent, View arg0,
int position, long id) {
Log.i("Index", "..." + position);
songAdapter.setSelectedIndex(position);
Intent i = new Intent(getActivity().getApplicationContext(),Main.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
SongModel songModel = (SongModel) songAdapter.getItem(position);
int indexOfSong = songAdapter.songsList.indexOf(songModel);
// Sending songIndex to PlayerActivity
i.putExtra("songIndex", indexOfSong);
getActivity().setResult(100, i);
startActivityForResult(i, 100);
Player.mp.stop();
//putting song in recentSongList arraylist
SongModel model = (SongModel) songAdapter.getItem(position);
model.setSongTitle(songModel.getSongTitle());
model.setSongPath(songModel.getSongPath());
Constant.recentSongList.add(model);
Log.i("recentSongList...","..."+Constant.recentSongList.size());
getActivity().finish();
}
});
I hope this work...

correctly displays a seekbar in custom adapter

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

Categories

Resources