Khadija Hameed Khadija Hameed - 3 years ago 116
Android Question

Why seek bar is not updating programmatically in android?

In my app, I am using media play. I want to update the progress of playing audio file on seek bar and for this I am using below code for playing media file

public class AudioPlayer implements MediaPlayer.OnCompletionListener {

private final static int SAMPLE_RATE = 16000;
private final int DELAY_FOR_HANDLER = 1_000;
static final String LOG_TAG = AudioPlayer.class.getSimpleName();
private Context mContext;
private MediaPlayer mPlayer;
private AudioTrack mProgressTone;
private MediaPlayerStatusCallbacks mMediaPlayerStatusCallBacks;
private Handler mHandler;
private PlayerUpdater mPlayerUpdater;
private SeekBar mSeekBar;

public AudioPlayer(SeekBar seekBar, Context context, MediaPlayerStatusCallbacks mediaPlayerStatusCallbacks) {
mPlayer = new MediaPlayer();
mPlayer.setOnCompletionListener(this);
mMediaPlayerStatusCallBacks = mediaPlayerStatusCallbacks;
mHandler = new Handler();
mContext = context;
mSeekBar = seekBar;
}

private void startSendingProgress() {
mPlayerUpdater = new PlayerUpdater();
((MessagingActivity) mContext).runOnUiThread(mPlayerUpdater);

}

private class PlayerUpdater implements Runnable {
@Override
public void run() {
if(mPlayer != null){
int currentProgress = mPlayer.getCurrentPosition() / 1000;
mSeekBar.setProgress(currentProgress);
}
mHandler.postDelayed(this, DELAY_FOR_HANDLER);
}
}

public static String getMediaDuration(String path) {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(path);
String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
mmr.release();
return duration;
}

public void playAudio(String path) throws IOException {
mPlayer.reset();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(path);
mPlayer.prepare();
mSeekBar.setMax(mPlayer.getDuration());
mPlayer.start();
startSendingProgress();
}

public void stopAudio() {
if (mPlayer != null) {
mPlayer.stop();
}
}

public MediaPlayer getMediaPlayer() {
return mPlayer;
}

@Override
public void onCompletion(MediaPlayer mp) {
mMediaPlayerStatusCallBacks.onMediaCompleted();
mHandler.removeCallbacks(mPlayerUpdater);
}


}

And below is the code I am using in View Holder of my recycler view

public class AudioViewHolder extends RecyclerView.ViewHolder {
public View mView;
public QuickContactBadge qcbProfileImage;
public ImageView ivPlay, ivDeliveryStatus;
public SeekBar sbAudioPlayer;
public TextView tvDateTime, tvDuration;
public VoipMessage mItem;
public MyAudioViewsClickListener myAudioViewsClickListener;

public AudioViewHolder(View itemView) {
super(itemView);
mView = itemView;
qcbProfileImage = (QuickContactBadge) itemView.findViewById(R.id.img_view_user);
ivPlay = (ImageView) itemView.findViewById(R.id.iv_play);
sbAudioPlayer = (SeekBar) itemView.findViewById(R.id.sb_audio_player);
ivDeliveryStatus = (ImageView) itemView.findViewById(R.id.img_view_message_status);
tvDateTime = (TextView) itemView.findViewById(R.id.txt_view_duration);
tvDuration = (TextView) itemView.findViewById(R.id.txt_view_time);

myAudioViewsClickListener = new MyAudioViewsClickListener();
ivPlay.setOnClickListener(myAudioViewsClickListener);
}

private class MyAudioViewsClickListener implements View.OnClickListener {

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_play:
try {
playAndPauseAudio(getAdapterPosition());
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}

private void playAndPauseAudio(int adapterPosition) throws IOException {
VoipMessage currentMessage = mMessages.get(adapterPosition);
RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForLayoutPosition(adapterPosition);
final AudioViewHolder audioViewHolder = (AudioViewHolder) holder;

String audioPath = currentMessage.getMediaReference();
AudioPlayer audioPlayer = new AudioPlayer(audioViewHolder.sbAudioPlayer, mContext, new AudioPlayer.MediaPlayerStatusCallbacks() {
@Override
public void onMediaCompleted() {
ivPlay.setImageResource(R.drawable.ic_audio_play);
}

@Override
public void onUpdatedMediaProgress(int progress) {
//audioViewHolder.sbAudioPlayer.setProgress(progress);
Logger.e("test","progress in adapter " + progress);
//sbAudioPlayer.setProgress(progress);

}

@Override
public void setDuration(int duration) {
//audioViewHolder.sbAudioPlayer.setMax(duration);
//sbAudioPlayer.setMax(duration);
}
});

if (audioPlayer.getMediaPlayer().isPlaying()) {
audioPlayer.stopAudio();
ivPlay.setImageResource(R.drawable.ic_audio_play);
} else {
audioPlayer.playAudio(audioPath);
ivPlay.setImageResource(R.drawable.ic_audio_pause);
}
}
}


I am passing seek bar reference from ViewHolder to the Audio Player class. I am using thread for updating seek bar. Thread is calculating progress and setting that progress to seek bar but the problem is seek bar is not updating on UI. For clear understanding I am attaching image of UI.
enter image description here

My my seek bar is not updating any help. I have spent many hours but could not solve this problem.

Answer Source

Try mSeekBar.setMax(mPlayer.getDuration() / 1000); instead of mSeekBar.setMax(mPlayer.getDuration());, because You set current process in seconds:

int currentProgress = mPlayer.getCurrentPosition() / 1000;
mSeekBar.setProgress(currentProgress);

but max value is in milliseconds and progress is less than 1 px.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download