问题描述
我的应用程序中有一个部分,可在回收者视图中用url加载媒体播放器。
有时使用url mp3播放不是有效文件,但我需要在没有播放mp3文件的情况下显示它,因为它已经无效。
我的问题是使用prepareAsync
时媒体播放器无法正常工作,即使它是有效的mp3文件,也无法正常工作,我知道这是因为重新加载相同的文件有时会工作,有时会无法工作。只要所有文件均有效,prepare
方法就可以正常工作并且prepareAsync无法正常工作。这是我的recyclerview bindview持有人代码
@Override
public void onBindViewHolder(AudioRecycleViewAdapter.ViewHolder viewHolder,final int position) {
final MediaPlayer mp = new MediaPlayer();
try {
// Get the data model based on position
final PlayAudioModel model = mVisitHistory.get(position);
// Set item views based on your views and data model
final ImageView playControllerImageView = viewHolder.playControllerImageView;
final ProgressBar playProgressBar = viewHolder.playProgressBar;
CircleImageView userImageView = viewHolder.userImageView;
TextView timeTextView = viewHolder.timeTextView;
final TextView durationTextView = viewHolder.durationTextView;
if (model.getSenderType().equals("doctor")) {
Glide.with(mContext).load(Constants.SERVER_IP + Constants.GET_DOCTOR_IMAGE_FOR_VISIT_HISTORY
.replace("{visitRequestId}","" + model.getVisitRequestId())
.replace("{doctorId}","" + model.getDoctorId())
).into(userImageView);
userImageView.setBorderColor(mContext.getResources().getColor(R.color.black));
} else {
Glide.with(mContext).load(Constants.SERVER_IP + Constants.GET_PATIENT_IMAGE
).into(userImageView);
userImageView.setBorderColor(mContext.getResources().getColor(R.color.colorPrimary));
}
timeTextView.setText(DateHelper.convertStringUtcToLocalDate(model.getTime()));
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp,int what,int extra) {
System.out.println();
return false;
}
});
mp.setDataSource(Constants.SERVER_IP + Constants.PLAY_AUDIO
.replace("{recordId}","" + model.getVoiceRecordId()));
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(final MediaPlayer mp) {
playProgressBar.setMax(mp.getDuration());
double mins = Math.floor((mp.getDuration() % (1000 * 60 * 60)) / (1000 * 60));
double secs = Math.floor((mp.getDuration() % (1000 * 60)) / 1000);
durationTextView.setText((int) mins + ":" + (int) secs);
final CountDownTimer mpTimer = new CountDownTimer(mp.getDuration(),1) {
@Override
public void onTick(long millisUntilFinished) {
playProgressBar.setProgress(mp.getDuration() - (int) millisUntilFinished);
}
@Override
public void onFinish() {
playControllerImageView.setImageDrawable(mContext.getDrawable(R.drawable.ic_play_circle));
playProgressBar.setProgress(0);
}
};
playControllerImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mp.isPlaying()) {
mpTimer.start();
mp.start();
playControllerImageView.setImageDrawable(mContext.getDrawable(R.drawable.ic_pause));
} else {
mp.pause();
mpTimer.cancel();
playProgressBar.setProgress(0);
playControllerImageView.setImageDrawable(mContext.getDrawable(R.drawable.ic_play_circle));
}
}
});
}
});
mp.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
解决方法
我通过在模型中创建媒体播放器来解决此问题,该模型在RecyclerView
中使用,并且由于回收者视图重新创建了整个对象,因此我在模型中执行了所有操作,例如错误监听器和prepareAsync,问题,prepareAsync
现在像魅力一样工作!,请注意,我在回收者视图中保留了onPrepared
回调,而我做了类似的事情
musics.get(position).getMediaPlayer().setOnPreparedListener(...)