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);
Related
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 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.
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
i am new to android development. In my app ive implemented an audio player, it plays soounds from teh sd card. i want it to play and show the list of only those audio files that i provide in a folder the app workspace (like the images we give in drawable)
here is the code. Thank you in advance
Play.java
public class Play extends ListActivity {
private static final int UPDATE_FREQUENCY = 500;
private static final int STEP_VALUE = 4000;
private MediaCursorAdapter mediaAdapter = null;
private TextView selelctedFile = null;
private SeekBar seekbar = null;
private MediaPlayer player = null;
private ImageButton playButton = null;
private ImageButton prevButton = null;
private ImageButton nextButton = null;
private boolean isStarted = true;
private String currentFile = "";
private boolean isMoveingSeekBar = false;
private final Handler handler = new Handler();
private final Runnable updatePositionRunnable = new Runnable() {
public void run() {
updatePosition();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play);
selelctedFile = (TextView)findViewById(R.id.selectedfile);
seekbar = (SeekBar)findViewById(R.id.seekbar);
playButton = (ImageButton)findViewById(R.id.play);
prevButton = (ImageButton)findViewById(R.id.prev);
nextButton = (ImageButton)findViewById(R.id.next);
player = new MediaPlayer();
player.setOnCompletionListener(onCompletion);
player.setOnErrorListener(onError);
seekbar.setOnSeekBarChangeListener(seekBarChanged);
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
if(null != cursor)
{
cursor.moveToFirst();
mediaAdapter = new MediaCursorAdapter(this, R.layout.list, cursor);
setListAdapter(mediaAdapter);
playButton.setOnClickListener(onButtonClick);
nextButton.setOnClickListener(onButtonClick);
prevButton.setOnClickListener(onButtonClick);
}
}
#Override
protected void onListItemClick(ListView list, View view, int position, long id) {
super.onListItemClick(list, view, position, id);
currentFile = (String) view.getTag();
startPlay(currentFile);
}
#Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(updatePositionRunnable);
player.stop();
player.reset();
player.release();
player = null;
}
private void startPlay(String file) {
Log.i("Selected: ", file);
selelctedFile.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());
playButton.setImageResource(android.R.drawable.ic_media_pause);
updatePosition();
isStarted = true;
}
private void stopPlay() {
player.stop();
player.reset();
playButton.setImageResource(android.R.drawable.ic_media_play);
handler.removeCallbacks(updatePositionRunnable);
seekbar.setProgress(0);
isStarted = false;
}
private void updatePosition(){
handler.removeCallbacks(updatePositionRunnable);
seekbar.setProgress(player.getCurrentPosition());
handler.postDelayed(updatePositionRunnable, UPDATE_FREQUENCY);
}
private 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.list, parent, false);
bindView(v, context, cursor);
return v;
}
}
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(updatePositionRunnable);
player.pause();
playButton.setImageResource(android.R.drawable.ic_media_play);
}
else
{
if(isStarted)
{
player.start();
playButton.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.prev:
{
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) {
// returning false will call the OnCompletionListener
return false;
}
};
private SeekBar.OnSeekBarChangeListener seekBarChanged = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
isMoveingSeekBar = false;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
isMoveingSeekBar = true;
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
if(isMoveingSeekBar)
{
player.seekTo(progress);
Log.i("OnSeekBarChangeListener","onProgressChanged");
}
}
};
}
play.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#android:id/list"
android:layout_weight="1.0"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:drawable/screen_background_light"
android:padding="10dip">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/selectedfile"
android:text="Not file selected"
android:textColor="#android:color/black"
android:gravity="center_horizontal"
android:singleLine="true"
android:ellipsize="middle"/>
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/seekbar"
android:max="100"
android:paddingBottom="10dip"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#android:drawable/screen_background_light">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/prev"
android:src="#android:drawable/ic_media_previous"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/play"
android:src="#android:drawable/ic_media_play"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/next"
android:src="#android:drawable/ic_media_next"/>
</LinearLayout>
</LinearLayout>
You need to put your music to assets directory (ie. create subfolder titled 'sounds') and then list the contents of it by method:
myContext.getAssets().list(”sounds");
Then you have to attach the asset to MediaPlayer object:
mediaPlayer.setDataSource(myContext.getAssets().openFd(soundPathInAssets));
You should also see this thread (because the bit of code I presented to you would play whole directory): Play audio file from the assets directory
EDIT: Code from example project (in case of deleting file on my dropbox):
MainActivity.java
public class MainActivity extends Activity {
MediaPlayer mMediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView list = (ListView) findViewById(R.id.listView1);
mMediaPlayer = new MediaPlayer();
Button playPause = (Button) findViewById(R.id.play);
playPause.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mControl.isPlaying()){
mControl.pause();
} else {
mControl.start();
}
}
});
try {
list.setAdapter(new MyAdapter(getAssets().list("music")));
} catch (IOException e) {
e.printStackTrace();
}
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
String path = (String) list.getAdapter().getItem(position);
try {
AssetFileDescriptor fd = getAssets().openFd("music/"+path);
mMediaPlayer.reset();
mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
class MyAdapter extends BaseAdapter {
private String[] content;
public MyAdapter(String[] content){
this.content=content;
}
#Override
public int getCount() {
return content.length;
}
#Override
public Object getItem(int position) {
return content[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
convertView = new TextView(getApplicationContext());
TextView cv = (TextView) convertView;
cv.setTextSize(18);
cv.setPadding(8, 8, 8, 8);
}
TextView v = (TextView) convertView;
v.setText(content[position]);
return v;
}
}
MediaPlayerControl mControl = new MediaPlayerControl() {
public void start() {
mMediaPlayer.start();
}
public void pause() {
mMediaPlayer.pause();
}
public int getDuration() {
return mMediaPlayer.getDuration();
}
public int getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
public void seekTo(int i) {
mMediaPlayer.seekTo(i);
}
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
public int getBufferPercentage() {
return 0;
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
};
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="vertical">
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="#+id/play"
android:background="#drawable/btn_transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="PlayPause" />
</LinearLayout>