I know similar questions have been asked before but none of them could solve my problem. I'm making a music player and wish to automate the Seekbarwhen a song is played. I'm using a RecyclerViewand the following snippet exists in the onBindViewHolder section.
public class ListViewPopulator extends
RecyclerView.Adapter<ListViewPopulator.ViewHolder>{
List<String> musicName;
List<String> musicAdd;
Context context;
MediaPlayer mediaPlayer;
Button media_play;
Button media_stop;
SeekBar seekBar;
final Handler mhandler=new Handler();
TextView timer;
public ListViewPopulator(Activity context, List<String> musicName, List<String> musicAdd)
{
this.context=context;
this.musicName=musicName;
this.musicAdd=musicAdd;
media_play= (Button)context.findViewById(R.id.play);
media_stop=(Button)context.findViewById(R.id.pause);
seekBar= (SeekBar) context.findViewById(R.id.seekbar);
timer=(TextView) context.findViewById(R.id.timer);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.listview,parent,false);
return new ViewHolder(v);
}
void something(String s)
{
try{mediaPlayer.stop();}catch (NullPointerException e){e.printStackTrace();}
//To fetch the location of audio files on disk
mediaPlayer=MediaPlayer.create(context, Uri.fromFile(new File(s)));
mediaPlayer.start();
//seekBar.setProgress(0);
//seekBar.setMax(mediaPlayer.getDuration());
} int temp=0;
int i=0;
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final String s = musicAdd.get(position);
final String v = musicName.get(position);
holder.data.setText(v);
seeker();
cont_seek();
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
temp = position + 1;
something(s);
seekBar.setProgress(0);
seekBar.setMax(mediaPlayer.getDuration());
// mediaPlayer.reset();
change();
op();
}
});
media_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mediaPlayer.start();
Log.d("click", "Kuch bhi");
} catch (NullPointerException e) {
e.printStackTrace();
}
}
});
media_stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mediaPlayer.pause();
Log.d("click2", "Kuch bhi2");
} catch (NullPointerException e) {
e.printStackTrace();
}
}
});
}
void cont_seek(){
Log.d("auto","seek");
Runnable runnable=new Runnable() {
#Override
public void run() {
String time;
if((mediaPlayer != null) && mediaPlayer.isPlaying()){
int progress = mediaPlayer.getCurrentPosition();
int min = (progress / 1000) / 60;
Log.d("auto","seek");
int sec = (progress / 1000) % 60;
if (sec < 10)
time = "0" + sec;
else
time = "" + sec;
String elapsedTime = min + ":" + time + "";
timer.setText(elapsedTime);
seekBar.setMax(mediaPlayer.getDuration());
seekBar.setProgress(progress);
mhandler.postDelayed(this, 1000);
}
}
};
mhandler.postDelayed(runnable,1000);
}
void seeker(){
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int seek_progress;
String time_sec;
#Override
public void onProgressChanged(final SeekBar seekBar, int progress, boolean fromUser) {
seek_progress=progress;
//seek_progress=seek_progress*1000;
new Runnable() {
#Override
public void run() {
int min=(seek_progress/1000)/60;
int sec=(seek_progress/1000)%60;
if(sec<10)
time_sec="0"+sec;
else
time_sec=""+sec;
String elapsedTime=min+":"+time_sec+"";
timer.setText(elapsedTime);
//mediaPlayer.seekTo(seek_progress);
new Handler().postDelayed(this,1000);
}
}.run();
if(fromUser) {
Log.d("blah","blah");
new Runnable() {
#Override
public void run() {
int min=(seek_progress/1000)/60;
int sec=(seek_progress/1000)%60;
if(sec<10)
time_sec="0"+sec;
else
time_sec=""+sec;
String elapsedTime=min+":"+time_sec+"";
timer.setText(elapsedTime);
//mediaPlayer.seekTo(seek_progress);
new Handler().postDelayed(this,1000);
}
}.run();
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if(mediaPlayer!=null){mediaPlayer.seekTo(seek_progress);}
}
});
}
int h=0;
void change(){
try{mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if(temp!=musicAdd.size())
something(musicAdd.get(temp));
temp=temp+1;
seekBar.setProgress(0);
seekBar.setMax(mediaPlayer.getDuration());
change();
}
});
}catch(Throwable throwable){throwable.printStackTrace();}}
void op()
{
Sensey.getInstance().startFlipDetection(new FlipDetector.FlipListener() {
#Override
public void onFaceUp() {
if (i == 0) {
try {
mediaPlayer.start();
i = 1;
h=1;
}catch (NullPointerException e){e.printStackTrace();}
}
}
#Override
public void onFaceDown() {
if (i == 1) {
try {
mediaPlayer.pause();
i = 0;
h=0;
}catch (NullPointerException e){e.printStackTrace();}
}
}
});
Sensey.getInstance().startShakeDetection(15, new ShakeDetector.ShakeListener() {
#Override
public void onShakeDetected() {
try {
if(h==1)
something(musicAdd.get(randomG(musicAdd.size()-1,0)));
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
});
}
int randomG(int max,int min)
{
Random random=new Random();
return random.nextInt((max-min)+1);
}
#Override
public int getItemCount() {
return musicName.size();
}
public class ViewHolder extends RecyclerView.ViewHolder
{
TextView data;
public ViewHolder(View itemView) {
super(itemView);
data=(TextView)itemView.findViewById(R.id.data);
}
}
}
I am pretty sure the logic is right and have checked the Log, the code doesn't seem to be executing. Can somebody explain why?
In your recycler view adapter you can use something like this:
#Override
public VoiceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return VoiceViewHolder.createVoiceViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.lecture_voice_item_recycler, parent, false));
}
#Override
public void onBindViewHolder(VoiceViewHolder holder, int position) {
holder.bindHolderToVoice(10000, "your path");
}
public static class VoiceViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
TextView voiceDuration;
ImageView voiceView;
ImageButton mPlayButton;
MediaPlayer mPlayer;
RelativeLayout layoutVoice;
RelativeLayout layoutVoiceNotFound;
boolean isPlaying;
TextView voiceDurationPlayer;
double timeElapsed = 0, finalTime = 0;
Handler durationHandler = new Handler();
Runnable updateSeekBarTime;
SeekBar seekBarDuration;
private VoiceViewHolder(final View itemView) {
super(itemView);
}
public static VoiceViewHolder createVoiceViewHolder(View convertView) {
VoiceViewHolder holder = new VoiceViewHolder(convertView);
holder.voiceDuration = (TextView) convertView.findViewById(R.id.voice_duration);
holder.cardView = (CardView) convertView.findViewById(R.id.card_view);
holder.voiceView = (ImageView) convertView.findViewById(R.id.voiceView);
holder.mPlayButton = (ImageButton) convertView.findViewById(R.id.playButton);
holder.layoutVoice = (RelativeLayout) convertView.findViewById(R.id.layoutVoice);
holder.layoutVoiceNotFound = (RelativeLayout) convertView.findViewById(R.id.layoutVoiceNotFound);
holder.voiceDurationPlayer = (TextView) convertView.findViewById(R.id.voiceDurationPlayer);
holder.seekBarDuration = (SeekBar) convertView.findViewById(R.id.seekBarDuration);
holder.isPlaying = false;
holder.mPlayer = new MediaPlayer();
return holder;
}
public void bindHolderToVoice(final long duration, final String path) {
final Context context = itemView.getContext();
if (duration >= 60000) {
voiceDuration.setText(String.format("%d %s, %d %s", TimeUnit.MILLISECONDS.toMinutes(duration), context.getString(R.string.min),
TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)),
context.getString(R.string.sec)));
} else {
voiceDuration.setText(String.format("%d %s",
TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)),
context.getString(R.string.sec)));
}
finalTime = duration;
seekBarDuration.setMax((int) finalTime);
seekBarDuration.setClickable(false);
seekBarDuration.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (mPlayer.isPlaying()) {
SeekBar sb = (SeekBar) v;
mPlayer.seekTo(sb.getProgress());
}
return false;
}
});
updateSeekBarTime = new Runnable() {
public void run() {
if (mPlayer != null) {
if (mPlayer.isPlaying()) {
timeElapsed = mPlayer.getCurrentPosition();
seekBarDuration.setProgress((int) timeElapsed);
voiceDurationPlayer.setText(String.format("%02d:%02d", TimeUnit.MILLISECONDS.toMinutes((long) timeElapsed), TimeUnit.MILLISECONDS.toSeconds((long) timeElapsed) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeElapsed))));
durationHandler.postDelayed(this, 100);
} else {
mPlayer.pause();
isPlaying = false;
}
}
}
};
File voiceFile = new File(path);
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
isPlaying = false;
}
});
mPlayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!isPlaying) {
isPlaying = true;
try {
mPlayer = new MediaPlayer();
mPlayer.setDataSource(path);
mPlayer.prepare();
} catch (IOException e) {
Log.e("tag", "Start playing prepare() failed");
isPlaying = false;
}
mPlayer.start();
timeElapsed = mPlayer.getCurrentPosition();
seekBarDuration.setProgress((int) timeElapsed);
durationHandler.postDelayed(updateSeekBarTime, 100);
} else {
isPlaying = false;
mPlayer.pause();
}
}
});
}
}
The layout lecture_voice_item_recycler.xml is something like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lecture_voice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/lecture_voice__margin_card">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/lecture_voice__margin_card"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/lecture_voice__margin_card"
android:layout_marginBottom="#dimen/lecture_voice__margin_card">
<LinearLayout
android:id="#+id/layoutVoiceInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/grid_annotation_margin"
android:orientation="horizontal">
<TextView
android:id="#+id/voice_duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<RelativeLayout
android:id="#+id/layoutVoice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/layoutVoiceInfo"
android:gravity="center_vertical"
android:layout_marginLeft="#dimen/activity_horizontal_margin">
<ImageButton
android:id="#+id/playButton"
android:layout_width="#dimen/lecture_voice_icon"
android:layout_height="#dimen/lecture_voice_icon"
android:background="#android:color/transparent"
android:scaleType="fitXY"
android:src="#drawable/ic_play" />
<LinearLayout
android:id="#+id/layoutVoiceSeekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_toRightOf="#+id/playButton"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginTop="#dimen/activity_horizontal_margin">
<SeekBar
android:id="#+id/seekBarDuration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin" />
<TextView
android:id="#+id/voiceDurationPlayer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00"
android:layout_gravity="right"
android:layout_marginRight="#dimen/lecture_voice_text_duration_margin_right"/>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/layoutVoiceNotFound"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/layoutVoiceInfo"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:visibility="gone">
<ImageView
android:id="#+id/voiceView"
android:layout_width="#dimen/lecture_voice_icon"
android:layout_height="#dimen/lecture_voice_icon"
android:src="#drawable/voice_not_found"
android:scaleType="fitXY" />
<TextView
android:id="#+id/voiceNotFound"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/voiceView"
android:layout_centerInParent="true"
android:text="#string/voice_not_found"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
strings.xml
<string name="min">min</string>
<string name="sec">sec</string>
Note: some dimensions or drawables could be lost in the example. You should use your own dimension if no compile.
You need to use your Handler & Runnable as follows:
final Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
//YOUR CODE GOES HERE
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 0);
Found a solution for this.
Runnable runnable=new Runnable() {
#Override
public void run() {
String time;
Log.d(TAG, "run");
while(mediaPlayer != null && mediaPlayer.isPlaying()){
final int progress = mediaPlayer.getCurrentPosition();
int min = (progress / 1000) / 60;
Log.d("auto","seek");
int sec = (progress / 1000) % 60;
if (sec < 10)
time = "0" + sec;
else
time = "" + sec;
final String elapsedTime = min + ":" + time + "";
context.runOnUiThread(new Runnable() {
#Override
public void run() {
timer.setText(elapsedTime);
seekBar.setMax(mediaPlayer.getDuration());
seekBar.setProgress(progress);
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
The main problem here is that once mediaplayer.start() is called the media file begins loading in the player before that completes the cont_seek function is called which has the condition
if(mediaplayer!=null && mediaplayer.isplaying())
Since the media hasn't started playing yet, the condition fails and the function is never executed.
Fixed it by running the runnable in a different thread.
Related
I code a simple music player. all works fine but when I click next button the max value of seekbar becomes the previous track's duration.though Player is working fine and music is being streamed fine but I am having trouble in setting the seekbar to work. I am assuming that seekbar is directly related to getting correct duration through getDuration. how can I solve this?
Here is my code:
public class PlayerActivity extends AppCompatActivity {
AppCompatButton playbtn, pausebtn, nxtbtn, prevbtn, fastfrwrdbtn, rewindbtn;
TextView txtStrt, txtStop, txtSnName;
SeekBar musicSeek;
BarVisualizer barVisualizer;
String sname;
static MediaPlayer mediaPlayer;
int position;
ArrayList mySongs, mySongUri, mySongAlbumArtUri;
ImageView imageView;
Thread updateSeek;
String currentTime;
AudioManager mAudioManager;
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
if (barVisualizer != null) {
barVisualizer.release();
}
super.onDestroy();
}
int ii = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
getSupportActionBar().setTitle("Now Playing");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
playbtn = findViewById(R.id.playBtn);
nxtbtn = findViewById(R.id.nxtBtn);
prevbtn = findViewById(R.id.previousBtn);
fastfrwrdbtn = findViewById(R.id.forwardBtn);
rewindbtn = findViewById(R.id.rewaindBtn);
mAudioManager = null;
txtStrt = findViewById(R.id.txtstart);
txtStop = findViewById(R.id.txtend);
txtSnName = findViewById(R.id.txtsn);
musicSeek = findViewById(R.id.seekbar);
barVisualizer = findViewById(R.id.blast);
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
Intent i = getIntent();
Bundle bundle = i.getExtras();
mySongs = (ArrayList) bundle.getParcelableArrayList("songs");
mySongUri = (ArrayList) bundle.getParcelableArrayList("uri");
mySongAlbumArtUri = (ArrayList) bundle.getParcelableArrayList("uriArt");
String songName = i.getStringExtra("songName");
position = bundle.getInt("position", 0);
txtSnName.setSelected(true);
Uri uri = Uri.parse(mySongUri.get(position).toString());
getSupportActionBar().setTitle(songName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
sname = mySongs.get(position).toString();
txtSnName.setText(sname);
imageView = findViewById(R.id.imageView);
//imageView.setImageURI(uriart);
mediaPlayer = MediaPlayer.create(getApplicationContext(), uri);
mediaPlayer.start();
String endTime = creatTime(mediaPlayer.getDuration());
txtStop.setText(endTime);
int audioSessionId = mediaPlayer.getAudioSessionId();
if (audioSessionId != -1) {
barVisualizer.setAudioSessionId(audioSessionId);
}
threading();
final Handler handler = new Handler();
final int delay = 1000;
handler.postDelayed(new Runnable() {
#Override
public void run() {
String currentTime = creatTime(mediaPlayer.getCurrentPosition());
txtStrt.setText(currentTime);
handler.postDelayed(this, delay);
}
}, delay);
setUpdateSeek();
nxt();
prev();
playbtn.setOnClickListener(v -> {
if (mediaPlayer.isPlaying()) {
playbtn.setBackgroundResource(R.drawable.ic_play_button);
mediaPlayer.pause();
} else {
playbtn.setBackgroundResource(R.drawable.ic_pause);
mediaPlayer.start();
}
});
fastfrwrdbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition() + 10000);
}
}
});
rewindbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition() - 10000);
}
}
});
countinue();
}
public void startAnimation(View view) {
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360);
animator.setDuration(1000);
AnimatorSet animationSet = new AnimatorSet();
animationSet.playTogether(animator);
animationSet.start();
}
public void startAnimationBack(View view) {
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "rotation", 360, 0f);
animator.setDuration(1000);
AnimatorSet animationSet = new AnimatorSet();
animationSet.playTogether(animator);
animationSet.start();
}
public String creatTime(int duration) {
String time = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
time += min + ":";
if (sec < 10) {
time += "0";
}
time += sec;
return time;
}
public void setUpdateSeek() {
updateSeek.start();
musicSeek.setMax(mediaPlayer.getDuration());
musicSeek.getProgressDrawable().setColorFilter(getResources().getColor(R.color.black), PorterDuff.Mode.MULTIPLY);
musicSeek.getThumb().setColorFilter(getResources().getColor(R.color.black), PorterDuff.Mode.SRC_IN);
musicSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
mediaPlayer.seekTo(position);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mediaPlayer.seekTo(seekBar.getProgress());
seekBar.setMax(mediaPlayer.getDuration());
}
});
}
#Override
public void onBackPressed() {
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
}
public void countinue() {
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
nxtbtn.performClick();
//musicSeek.setMax(mediaPlayer.getDuration());
}
});
}
public void nxt() {
nxtbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mediaPlayer.stop();
mediaPlayer.release();
position = ((position + 1) % mySongs.size());
Uri u = Uri.parse(mySongUri.get(position).toString());
mediaPlayer = MediaPlayer.create(getApplicationContext(), u);
sname = mySongs.get(position).toString();
txtSnName.setText(sname);
String endTime1 = creatTime(mediaPlayer.getDuration());
txtStop.setText(endTime1);
playbtn.setBackgroundResource(R.drawable.ic_pause);
startAnimation(imageView);
int audioSessionId = mediaPlayer.getAudioSessionId();
if (audioSessionId != -1) {
barVisualizer.setAudioSessionId(audioSessionId);
}
musicSeek.setMax(mediaPlayer.getDuration());
mediaPlayer.start();
countinue();
}
});
}
public void prev() {
prevbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mediaPlayer.stop();
mediaPlayer.release();
position = ((position + 1) < 0) ? (mySongs.size() - 1) : (position - 1);
Uri u = Uri.parse(mySongUri.get(position).toString());
mediaPlayer = MediaPlayer.create(getApplicationContext(), u);
int i = mediaPlayer.getDuration();
String c = Integer.toString(i);
Toast.makeText(PlayerActivity.this, c, Toast.LENGTH_SHORT).show();
musicSeek.setMax(i);
sname = mySongs.get(position).toString();
txtSnName.setText(sname);
String endTime12 = creatTime(mediaPlayer.getDuration());
txtStop.setText(endTime12);
playbtn.setBackgroundResource(R.drawable.ic_pause);
startAnimationBack(imageView);
int audioSessionId = mediaPlayer.getAudioSessionId();
if (audioSessionId != -1) {
barVisualizer.setAudioSessionId(audioSessionId);
}
musicSeek.setMax(mediaPlayer.getDuration());
mediaPlayer.start();
countinue();
}
});
}
public void threading() {
updateSeek = new Thread() {
#Override
public void run() {
int totalDuration = mediaPlayer.getDuration();
int currentPosition = 0;
while (currentPosition < totalDuration) {
try {
sleep(500);
currentPosition = mediaPlayer.getCurrentPosition();
musicSeek.setProgress(currentPosition);
} catch (InterruptedException | IllegalStateException e) {
e.printStackTrace();
}
}
}
};
}
}
can anyone please guide me to solve the issue?
public class SongPlayerActivity extends AppCompatActivity implements MediaPlayer.OnCompletionListener {
static MediaPlayer mediaPlayer;
TextView songName, artistName, albumName, durationPlayed, totalDuration;
ImageView next, previous, songImage, shuffle, repeat;
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
SeekBar seekBar;
FloatingActionButton floatingActionButton;
List<Song> songList = new ArrayList<>();
Handler handler = new Handler();
Thread playPauseThread, nextThread, previousThread;
private Uri uri;
private int position;
boolean shuffleBoolean, repeatBoolean;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_song_player);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
songList = getIntent().getParcelableArrayListExtra("songsList");
position = getIntent().getIntExtra("position", 0);
songImage = findViewById(R.id.album_cover);
songName = findViewById(R.id.music_name);
albumName = findViewById(R.id.album_name);
artistName = findViewById(R.id.artist_name);
seekBar = findViewById(R.id.seek_bar);
durationPlayed = findViewById(R.id.played_duration);
totalDuration = findViewById(R.id.music_duration);
repeat = findViewById(R.id.repeat);
shuffle = findViewById(R.id.shuffle);
floatingActionButton = findViewById(R.id.play_pause);
next = findViewById(R.id.next);
previous = findViewById(R.id.previous);
playMusic();
mediaPlayer.setOnCompletionListener(this);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (mediaPlayer != null && fromUser) {
mediaPlayer.seekTo(progress * 1000);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
SongPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
seekBar.setProgress(currentPosition);
durationPlayed.setText(durationConversion(currentPosition));
}
handler.postDelayed(this, 200);
}
});
if (sharedPreferences.getBoolean("playerShuffle", false)) {
shuffle.setImageResource(R.drawable.ic_baseline_shuffle_24);
shuffleBoolean = true;
}
else {
shuffle.setImageResource(R.drawable.ic_baseline_shuffle_off_24);
shuffleBoolean = false;
}
if (sharedPreferences.getBoolean("playerRepeat", false)) {
repeat.setImageResource(R.drawable.ic_baseline_repeat_24);
repeatBoolean = true;
}
else {
repeat.setImageResource(R.drawable.ic_baseline_repeat_24_off);
repeatBoolean = false;
}
shuffle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (sharedPreferences.getBoolean("playerShuffle", false)) {
editor = sharedPreferences.edit();
editor.putBoolean("playerShuffle", false);
editor.commit();
shuffleBoolean = false;
shuffle.setImageResource(R.drawable.ic_baseline_shuffle_off_24);
Toast.makeText(getApplicationContext(), R.string.shuffle_off, Toast.LENGTH_SHORT).show();
} else {
editor = sharedPreferences.edit();
editor.putBoolean("playerShuffle", true);
editor.commit();
shuffleBoolean = true;
shuffle.setImageResource(R.drawable.ic_baseline_shuffle_24);
Toast.makeText(getApplicationContext(), R.string.shuffle_on, Toast.LENGTH_SHORT).show();
}
}
});
repeat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (sharedPreferences.getBoolean("playerRepeat", false)) {
editor = sharedPreferences.edit();
editor.putBoolean("playerRepeat", false);
editor.commit();
repeatBoolean = false;
repeat.setImageResource(R.drawable.ic_baseline_repeat_24_off);
Toast.makeText(getApplicationContext(), R.string.repeat_off, Toast.LENGTH_LONG).show();
} else {
editor = sharedPreferences.edit();
editor.putBoolean("playerRepeat", true);
editor.commit();
repeatBoolean = true;
repeat.setImageResource(R.drawable.ic_baseline_repeat_24);
Toast.makeText(getApplicationContext(), R.string.repeat_on, Toast.LENGTH_LONG).show();
}
}
});
}
public String durationConversion(int songDuration) {
long s = songDuration % 60;
long m = (songDuration / 60) % 60;
long h = (songDuration / (60 * 60)) % 24;
return String.format("%02d:%02d:%02d", h, m, s);
}
void playPauseButton() {
playPauseThread = new Thread() {
#Override
public void run() {
super.run();
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
floatingActionButton.setImageResource(R.drawable.ic_baseline_play_arrow_24);
seekBar.setMax(mediaPlayer.getDuration() / 1000);
SongPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
seekBar.setProgress(currentPosition);
}
handler.postDelayed(this, 200);
}
});
} else {
mediaPlayer.start();
floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
seekBar.setMax(mediaPlayer.getDuration() / 1000);
SongPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
seekBar.setProgress(currentPosition);
}
handler.postDelayed(this, 200);
}
});
}
}
});
mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
}
};
playPauseThread.start();
}
private void nextButton() {
nextThread = new Thread() {
#Override
public void run() {
super.run();
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
if(shuffleBoolean && !repeatBoolean)
position = random(songList.size()-1);
else if (!shuffleBoolean && !repeatBoolean)
position++;
if (position == songList.size())
position = 0;
mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
metaDataRetriever(Uri.parse(songList.get(position).path));
seekBar.setMax(mediaPlayer.getDuration() / 1000);
SongPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
seekBar.setProgress(currentPosition);
}
handler.postDelayed(this, 200);
}
});
floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
} else {
mediaPlayer.stop();
mediaPlayer.release();
if(shuffleBoolean && !repeatBoolean)
position = random(songList.size()-1);
else if (!shuffleBoolean && !repeatBoolean)
position++;
if (position == songList.size())
position = 0;
mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
metaDataRetriever(Uri.parse(songList.get(position).path));
seekBar.setMax(mediaPlayer.getDuration() / 1000);
SongPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
seekBar.setProgress(currentPosition);
}
handler.postDelayed(this, 200);
}
});
floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
}
mediaPlayer.start();
}
});
}
};
nextThread.start();
}
private void previousButton() {
previousThread = new Thread() {
#Override
public void run() {
super.run();
previous.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
if(shuffleBoolean && !repeatBoolean)
position = random(songList.size()-1);
else if (!shuffleBoolean && !repeatBoolean)
position--;
if (position < 0)
position = 0;
mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
metaDataRetriever(Uri.parse(songList.get(position).path));
seekBar.setMax(mediaPlayer.getDuration() / 1000);
SongPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
seekBar.setProgress(currentPosition);
}
handler.postDelayed(this, 200);
}
});
mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
} else {
mediaPlayer.stop();
mediaPlayer.release();
if(shuffleBoolean && !repeatBoolean)
position = random(songList.size()-1);
else if (!shuffleBoolean && !repeatBoolean)
position--;
if (position < 0)
position = 0;
mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
metaDataRetriever(Uri.parse(songList.get(position).path));
seekBar.setMax(mediaPlayer.getDuration() / 1000);
SongPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
seekBar.setProgress(currentPosition);
}
handler.postDelayed(this, 200);
}
});
mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
}
mediaPlayer.start();
}
});
}
};
previousThread.start();
}
private int random(int i) {
Random random = new Random();
return random.nextInt(i+1);
}
public void metaDataRetriever(Uri uri) {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(uri.getPath());
byte[] bytes = mediaMetadataRetriever.getEmbeddedPicture();
final LinearLayout linearLayout = findViewById(R.id.linear_layout);
Bitmap bitmap;
if (bytes != null) {
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
layoutAnimation(getApplicationContext(), songImage, bitmap);
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
#Override
public void onGenerated(#Nullable Palette palette) {
Palette.Swatch swatch = Objects.requireNonNull(palette).getDominantSwatch();
if (swatch != null) {
GradientDrawable gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, new int[]{0xff000000, swatch.getRgb()});
linearLayout.setBackground(gradientDrawable);
songName.setTextColor(swatch.getTitleTextColor());
albumName.setTextColor(swatch.getTitleTextColor());
artistName.setTextColor(swatch.getTitleTextColor());
durationPlayed.setTextColor(Color.WHITE);
totalDuration.setTextColor(Color.WHITE);
floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
floatingActionButton.getBackground().setTint(Color.WHITE);
next.setImageResource(R.drawable.ic_baseline_skip_next_white_24);
previous.setImageResource(R.drawable.ic_baseline_skip_previous_white_24);
seekBar.getThumb().setTint(Color.WHITE);
}
}
});
} else {
layoutAnimation(getApplicationContext(), songImage, null);
linearLayout.setBackgroundResource(R.drawable.gradient_brown);
songName.setTextColor(Color.DKGRAY);
albumName.setTextColor(Color.DKGRAY);
artistName.setTextColor(Color.DKGRAY);
floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
next.setImageResource(R.drawable.ic_baseline_skip_next_24);
previous.setImageResource(R.drawable.ic_baseline_skip_previous_24);
seekBar.getThumb().setTint(getResources().getColor(R.color.colorYellow));
durationPlayed.setTextColor(getResources().getColor(R.color.colorYellow));
totalDuration.setTextColor(getResources().getColor(R.color.colorYellow));
}
songName.setText(songList.get(position).songName);
albumName.setText(songList.get(position).albumName);
artistName.setText(songList.get(position).artistName);
totalDuration.setText(Song.durationConversion(songList.get(position).songDuration));
}
public void playMusic() {
if (songList != null) {
floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
uri = Uri.parse(songList.get(position).path);
}
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
mediaPlayer = MediaPlayer.create(getApplicationContext(), uri);
mediaPlayer.start();
metaDataRetriever(uri);
seekBar.setMax(mediaPlayer.getDuration() / 1000);
}
public void layoutAnimation(final Context context, final ImageView imageView, final Bitmap bitmap) {
final Animation animationIn = AnimationUtils.loadAnimation(context, android.R.anim.fade_in);
Animation animationOut = AnimationUtils.loadAnimation(context, android.R.anim.fade_out);
if (bitmap != null)
animationOut.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
Glide.with(context).load(bitmap).into(imageView);
animationIn.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
imageView.startAnimation(animationIn);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
else
animationOut.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
Glide.with(context).load(R.drawable.album_cover).into(imageView);
animationIn.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
imageView.startAnimation(animationIn);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
imageView.startAnimation(animationOut);
}
#Override
protected void onResume() {
super.onResume();
playPauseButton();
nextButton();
previousButton();
}
#Override
public void onCompletion(MediaPlayer mp) {
nextButton();
position++;
if(position >= songList.size())
position = 0;
if (mediaPlayer != null) {
mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
seekBar.setMax(mediaPlayer.getDuration() / 1000);
metaDataRetriever(Uri.parse(songList.get(position).path));
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(this);
}
}
}
I have two problems here:
is that when the current playing music finish onCompletionListener() called which is call nextButton()
which checks if shuffleBoolean and repeatBoolean states are true or not, the problem here is that when shuffleBoolean and repeatBoolean are true the SongList keeps playing serially Regardless of shuffleBoolean and repeatBoolean states, but if i pressed next or previous buttons it checks for repeatBoolean and shuffleBoolean states and play next song correctly according to the states.
sometimes when i move seekBar to any position (seconds) in the bar, the songlist stops playing at the end of current playing song
my description maybe too long for the first problem but i meant to be clear and thanks in advance.
The solution is to call next.performClick() in onCompltition() and remove all the other lines.
I don't know the reason that the firs way don't work but i thought of it as i need to call onClickListener() without clicking the button.
I am making a music player application in android. The application has
MainActivity.java (with corresponding XML File:activity_main): This Activity has a listview that displays the list of all songs available.
PlayerScreen.java (with corresponding XML File:activity_player_screen): When a song is clicked on the first activity, this activity is launched and it plays that particular song. This activity has 3 Buttons (Play/Pause, NextSong, PreviousSong) and a seekbar.
Now this is where I am facing the problem
I have created a separate class (SeekBarThread.java) for implementing seekbar of the activity_player_screen using Threading.
The Problem is that when I call the start method for my thread class from PlayerScreen.java, nothing happens. No exception is thrown. The song keeps on playing but the widgets of the activity_player_screen stop working i.e. I can't pause the song aur play the next song. The seekbar also doesn't work.
I think I am not able to link the activity_player_screen file with both PlayerScreen.java and SeekBarThread.java properly.
This is the call to the Thread class from PlayerScreen.java
mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();
I don't really have an idea to get rid of the anomaly so I passed the seekbar object and mediaplayer object reference and the current context reference to the SeekBarThread class. But it didn't work.
Here is the SeekBarThread.java class code:
public class SeekBarThread implements Runnable{
private PlayerScreen myPlayerScreen;
private SeekBar seekBar;
private MediaPlayer mp;
private Context context;
public SeekBarThread(Context context, SeekBar seekBar, MediaPlayer mp) {
this.context = context;
this.seekBar = seekBar;
this.mp = mp;
}
public void run() {
((Activity)context).setContentView(R.layout.activity_player_screen);
seekBar.setMax(mp.getDuration());
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mp.seekTo(seekBar.getProgress());
}
});
int totalduration = mp.getDuration();
int currentposition = 0;
while(currentposition < totalduration) {
try {
sleep(500);
currentposition = mp.getCurrentPosition();
seekBar.setProgress(currentposition);
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
activity_player_screen XML File:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_player_screen"
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"
tools:context="prakhar.simplemusicplayer20.PlayerScreen">
<Button
android:id="#+id/play_pause"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:background="#drawable/pause" />
<Button
android:id="#+id/next_song"
android:layout_height="42dp"
android:layout_width="42dp"
android:background="#drawable/next"
android:layout_marginEnd="25dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true" />
<Button
android:id="#+id/prev_song"
android:layout_height="42dp"
android:layout_width="42dp"
android:background="#drawable/previous"
android:layout_marginStart="25dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />
<Button
android:text="F"
android:layout_width="42dp"
android:layout_height="42dp"
android:id="#+id/forward_song"
android:layout_alignParentBottom="true"
android:layout_toStartOf="#+id/next_song"
android:layout_marginEnd="22dp" />
<Button
android:text="R"
android:layout_width="42dp"
android:layout_height="42dp"
android:id="#+id/rewind_song"
android:layout_marginEnd="23dp"
android:layout_alignParentBottom="true"
android:layout_toStartOf="#+id/play_pause" />
<SeekBar
android:id="#+id/seek_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginBottom="26dp"
android:layout_above="#+id/play_pause"
android:layout_alignParentStart="true" />
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="146dp"
android:id="#+id/details_text_view" />
</RelativeLayout>
Here is the PlayerScreen.java class:
public class PlayerScreen extends AppCompatActivity implements View.OnClickListener{
private Button playPause, nextSong, prevSong;
public SeekBar mySeekBar;
private int count = 0;
public MediaPlayer mediaPlayer;
private Bundle newBundle = new Bundle();
private Intent newIntent;
private int pos;
private ArrayList<String> name;
private ArrayList<String> path;
private SeekBarThread mySeekBarThread;
private Thread myThread;
private TextView detailsTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player_screen);
playPause = (Button)findViewById(R.id.play_pause);
nextSong = (Button)findViewById(R.id.next_song);
prevSong = (Button)findViewById(R.id.prev_song);
mySeekBar = (SeekBar)findViewById(R.id.seek_bar);
detailsTextView = (TextView)findViewById(R.id.details_text_view);
playPause.setOnClickListener(this);
nextSong.setOnClickListener(this);
prevSong.setOnClickListener(this);
newIntent = this.getIntent();
newBundle = newIntent.getExtras();
name = newBundle.getStringArrayList("title");
path = newBundle.getStringArrayList("songpath");
pos = newBundle.getInt("post");
detailsTextView.setText(name.get(pos));
mediaPlayer = new MediaPlayer();
setMediaPlayer(pos);
}
public void setMediaPlayer(int position) {
mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();
File mySong = new File(path.get(pos));
mediaPlayer = new MediaPlayer();
FileInputStream is = null;
try {
is = new FileInputStream(mySong);
}
catch(FileNotFoundException ex) {
ex.printStackTrace();
}
try {
mediaPlayer.setDataSource(is.getFD());
}
catch(IOException ex) {
ex.printStackTrace();
}
try {
mediaPlayer.prepare();
}
catch(IOException ex) {
ex.printStackTrace();
}
finally {
if(is != null) {
try {
is.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
}
}
mediaPlayer.start();
}
#Override
protected void onPause() {
super.onPause();
mediaPlayer.pause();
}
#Override
protected void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.play_pause:
count++;
if(count%2 == 0) {
v.setBackgroundResource(R.drawable.pause);
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
mediaPlayer.start();
}
else {
v.setBackgroundResource(R.drawable.play);
mediaPlayer.pause();
}
break;
case R.id.next_song:
mediaPlayer.stop();
pos = pos + 1;
setMediaPlayer(pos);
break;
case R.id.prev_song:
mediaPlayer.stop();
pos = pos - 1;
setMediaPlayer(pos);
break;
}
}
}
Most of the onCreate() code for this is class is dealing with which song to play based on the user's choice from the previous activity. And since the song is being played, i don't think there is a problem in that part of the code.
#prakhar, Going through the code, I have found the following issues:
1) In SeekBarThread class in run() method setContentView() should not set,as it is already set in the activity class, as your are not reinitializing the click listeners.
2) Also the seekbarchangeListener should not be set in run() method and should be set in the main activity itself, as it doesn't need reinitalizing all the time.
3) The important point here is that your are initializing the SeekBarThread class before the initialization of MediaPlayer and hence there is no action even after seeking the seekbar.
A detailed code with the above modifications rectified.
public class PlayerScreen extends AppCompatActivity implements View.OnClickListener {
private Button playPause, nextSong, prevSong;
public SeekBar mySeekBar;
private int count = 0;
public MediaPlayer mediaPlayer;
private Bundle newBundle = new Bundle();
private Intent newIntent;
private int pos;
private ArrayList<String> name;
private ArrayList<String> path;
private SeekBarThread mySeekBarThread;
private Thread myThread;
private TextView detailsTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playPause = (Button) findViewById(R.id.play_pause);
nextSong = (Button) findViewById(R.id.next_song);
prevSong = (Button) findViewById(R.id.prev_song);
mySeekBar = (SeekBar) findViewById(R.id.seek_bar);
detailsTextView = (TextView) findViewById(R.id.details_text_view);
playPause.setOnClickListener(this);
nextSong.setOnClickListener(this);
prevSong.setOnClickListener(this);
mySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mediaPlayer.seekTo(seekBar.getProgress());
}
});
newIntent = this.getIntent();
newBundle = newIntent.getExtras();
name = newBundle.getStringArrayList("title");
pos = newBundle.getInt("post");
detailsTextView.setText(name.get(pos));
mediaPlayer = new MediaPlayer();
setMediaPlayer(pos);
}
public void setMediaPlayer(int position) {
File mySong = new File(path.get(pos));
mediaPlayer = new MediaPlayer();
FileInputStream is = null;
try {
is = new FileInputStream(mySong);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
try {
mediaPlayer.setDataSource(is.getFD());
} catch (IOException ex) {
ex.printStackTrace();
}
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepare();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
is.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
mediaPlayer.start();
mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();
}
#Override
protected void onPause() {
super.onPause();
mediaPlayer.pause();
}
#Override
protected void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play_pause:
count++;
if (count % 2 == 0) {
v.setBackgroundResource(R.drawable.pause);
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
mediaPlayer.start();
} else {
v.setBackgroundResource(R.drawable.play);
mediaPlayer.pause();
}
break;
case R.id.next_song:
mediaPlayer.stop();
pos = pos + 1;
setMediaPlayer(pos);
break;
case R.id.prev_song:
mediaPlayer.stop();
pos = pos - 1;
setMediaPlayer(pos);
break;
}
}
}
public class SeekBarThread implements Runnable{
private SeekBar seekBar;
private MediaPlayer mp;
private Context context;
public SeekBarThread(Context context, SeekBar seekBar, MediaPlayer mp) {
this.context = context;
this.seekBar = seekBar;
this.mp = mp;
}
public void run() {
seekBar.setMax(mp.getDuration());
int totalduration = mp.getDuration();
int currentposition = 0;
while(currentposition < totalduration) {
try {
sleep(500);
currentposition = mp.getCurrentPosition();
seekBar.setProgress(currentposition);
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
I have the problem with the seekbar thumb, although I have added every necessary codes for it to work. still the seekbar thumb doesn't play from the point dragged by the user. instead the thumb positioned itself back to the point it was last playing though. Any help will be appreciated.
plus = (ImageButton) findViewById(R.id.imageButton2);
minus = (ImageButton) findViewById(R.id.imageButton4);
player = MediaPlayer.create(this, R.raw.songnames);
player.setLooping(false);
im = (ImageButton) this.findViewById(R.id.imageButton3);
seekbar = (SeekBar) findViewById(R.id.mantraProgressBar);
seekbar.setVisibility(ProgressBar.VISIBLE);
seekbar.setProgress(0);
seekbar.setMax(player.getDuration());
new Thread(this).start();
im.setOnClickListener(this);
player.start();
im.setImageResource(R.drawable.pause_tran);
Toast.makeText(this, isPlaying, Toast.LENGTH_LONG).show();
plus.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int cu = player.getCurrentPosition();
player.seekTo(cu - 5000);
}
});
minus.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int cu = player.getCurrentPosition();
player.seekTo(cu + 5000);
}
});
}
#Override
public void onClick(View arg0) {
if (arg0.getId() == R.id.imageButton3) {
if (player.isPlaying()) {
player.pause();
Toast.makeText(this, notPlaying, Toast.LENGTH_LONG).show();
ImageButton img1 = (ImageButton) this.findViewById(R.id.imageButton3);
img1.setImageResource(R.drawable.play_tran);
} else {
player.start();
Toast.makeText(this, isPlaying, Toast.LENGTH_LONG).show();
ImageButton img1 = (ImageButton) this.findViewById(R.id.imageButton3);
img1.setImageResource(R.drawable.pause_tran);
}
}
}
#Override
public void run() {
int currentPosition = 0;
String s;
int total = player.getDuration();
while (player != null && currentPosition < total) {
try {
Thread.sleep(1000);
currentPosition = player.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
seekbar.setProgress(currentPosition);
}
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
player.seekTo(progress);
seekbar.setProgress(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
public class MainActivity extends AppCompatActivity {
private MyVideoView mVV;
private Handler mhandler;
private SeekBar seekbar;
private int duration;
private int backPositon = 0;
private int currentPosition;
private SharedPreferences sp;
private MediaController controller;
private TextView tv_curr;
private TextView tv_duration;
private Handler handler;
private boolean mExit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mVV = (MyVideoView) findViewById(R.id.vv);
seekbar = (SeekBar) findViewById(R.id.seekbar);
tv_curr = (TextView) findViewById(R.id.tv_currtime);
tv_duration = (TextView) findViewById(R.id.tv_duration);
//get duration of video
getDuration();
//video start
playVideo();
//get current time
getCurrentDuration();
//listener
initEvent();
}
private void initHanlder() {
handler=new Handler(){
#Override
public void handleMessage(Message msg) {
if (msg.what==0x123){
tv_curr.setText(timeFormat(mVV.getCurrentPosition()));
seekbar.setProgress(mVV.getCurrentPosition());
}
if(msg.what==0x133){
int changedProgress = msg.arg1;
tv_curr.setText(timeFormat(changedProgress));
mVV.seekTo(changedProgress);
seekbar.setProgress(changedProgress);
mVV.start();
}
}
};
new Thread(new Runnable() {
#Override
public void run() {
while (mVV.getCurrentPosition()<duration){
Message message = Message.obtain();
message.what=0x123;
handler.sendMessage(message);
SystemClock.sleep(1000);
if(mExit){
break;
}
}
}
}).start();
}
private void getDuration() {
mVV.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
duration = mVV.getDuration();
timeFormat(duration);
Log.d("TAG", "---duration" + timeFormat(duration));
seekbar.setMax(duration);
//TextView time
tv_duration.setText(timeFormat(duration));
//init handler
initHanlder();
}
});
}
private String timeFormat(int time) {
StringBuilder mFormatBuilder;
Formatter mFormatter;
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
int totalSeconds = time / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours > 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
private void playVideo() {
File file = new File(Environment.getExternalStorageDirectory(), "cgx_video/db.mp4");
if (!file.exists()) {
file.mkdir();
}
Log.d("TAG", file.toString());
mVV.setVideoPath(file.getPath());
mVV.start();
}
private void initEvent() {
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
currentPosition=progress;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
mVV.pause();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if(handler!=null){
Message message = Message.obtain();
message.what=0x133;
message.arg1=currentPosition;
handler.sendMessage(message);
}
}
});
}
#Override
protected void onPause() {
super.onPause();
Log.d("TAG", "---onPause");
mVV.pause();
backPositon = mVV.getCurrentPosition();
Log.d("TAG", "backPositon:" + backPositon);
}
#Override
protected void onStop() {
super.onStop();
Log.d("TAG", "---onStop");
}
#Override
protected void onResume() {
super.onResume();
Log.d("TAG", backPositon + "---backPositon");
mVV.seekTo(backPositon);
mVV.start();
}
#Override
protected void onDestroy() {
//in case of leak of memeroy
mExit=true;
super.onDestroy();
}
}
I need to get the progress time of the video that is played in "VideoView"(ie the time shown in the left hand side in progress bar).
Any help will really be appreciated.
Thanks.
You can get the Duration of the Video by mVideoView.getDuration(), set the Progress bar to 0 initially and then get the currentProgress of Video by mVideoView.getCurrentPosition(); and increase the Progress Bar status based on the CurrentProgress of Video in Percentage(%) by (current * 100 / duration). I tried it out using AsyncTask checkout this complete Example.
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<VideoView android:id="#+id/my_Video_View"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
/>
<ProgressBar android:layout_alignParentBottom="true"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="fill_parent"
android:layout_height="10dp"
android:id="#+id/Progressbar"/>
</RelativeLayout>
VideoPlayActivity.java
public class VideoPlayActivity extends Activity {
ProgressBar mProgressBar;
VideoView mVideoView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String path = Environment.getExternalStorageDirectory().toString();
String filename = "/hr.3gp";
mProgressBar = (ProgressBar) findViewById(R.id.Progressbar);
mProgressBar.setProgress(0);
mProgressBar.setMax(100);
mVideoView = (VideoView) findViewById(R.id.my_Video_View);
mVideoView.setVideoURI(Uri.parse(path+filename));
new MyAsync().execute();
}
private class MyAsync extends AsyncTask<Void, Integer, Void>
{
int duration = 0;
int current = 0;
#Override
protected Void doInBackground(Void... params) {
mVideoView.start();
mVideoView.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
duration = mVideoView.getDuration();
}
});
do {
current = mVideoView.getCurrentPosition();
System.out.println("duration - " + duration + " current- "
+ current);
try {
publishProgress((int) (current * 100 / duration));
if(mProgressBar.getProgress() >= 100){
break;
}
} catch (Exception e) {
}
} while (mProgressBar.getProgress() <= 100);
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
System.out.println(values[0]);
mProgressBar.setProgress(values[0]);
}
}
}
You can use Thread for this purpose like below:
videoView.start();
videoView.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
running = true;
final int duration = videoView.getDuration();
new Thread(new Runnable() {
public void run() {
do{
textView.post(new Runnable() {
public void run() {
int time = (duration - videoView.getCurrentPosition())/1000;
textView.setText(time+"");
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!running) break;
}
while(videoView.getCurrentPosition()<duration);
}
}).start();
}
});
You can use getCurrentPosition() and getDuration()to calculate the progress.
I accomplished it such way
private void playVideo() {
setViewNotVisibility();
final String videoSource = "android.resource://" + getPackageName() + File.separator + R.raw.moviiegood;
videoView.setKeepScreenOn(true);
videoView.setVideoURI(Uri.parse(videoSource));
videoView.setMediaController(null);
videoView.setOnCompletionListener(myVideoViewCompletionListener);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
startVideo();
setDuration();
timerCounter();
}
}
);
}
private Timer timer;
private void timerCounter(){
timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
updateUI();
}
});
}
};
timer.schedule(task, 0, 1000);
}
private int duration = 0;
private void setDuration(){
duration = videoView.getDuration();
}
private void updateUI(){
if (pbVideoView.getProgress() >= 100) {
timer.cancel();
}
int current = videoView.getCurrentPosition();
int progress = current * 100 / duration;
pbVideoView.setProgress(progress);
}
If you have a questions feel free to ask