我在一个片段中有一个FirestoreRecyclerAdapter
。首先,我从FirestoreRecyclerAdapter
填充Firestore
中的项,然后为RecyclerView
中的每个项填充一个Url
到FirebaseStorage
并保存记录音频消息。当用户单击我的RecyclerView
项内的按钮,并且使AsyncTask
与播放此音频相关联时,我如何播放此消息会更新在同一RecyclerView项中找到的SeekBar
?
我已经可以使用MediaPlayer
播放音频,但是无法获取AsyncTask
更新我的UI
。这是我的AsyncTask
:
公共类MyTask扩展了AsyncTask {
private MediaPlayer mPlayer; private Callback mCb; private FirebaseFirestore db; private StorageReference storageRef; private SeekBar seekBar; private Post post; public interface Callback { void onDataLoaded(Integer result); } public MyTask (final Post post, Callback cb, SeekBar seekBar){ this.post = post; this.mCb = cb; this.seekBar = seekBar; // Initialize media player mPlayer = new MediaPlayer(); mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { db = FirebaseFirestore.getInstance(); DocumentReference postRef = db.collection("Posts") .document(post.getPost_Id()); Map<String, Object> map = new HashMap<>(); map.put("score", FieldValue.increment(2)); map.put("listens", FieldValue.increment(1)); postRef.update(map); } }); } @Override protected String doInBackground(String... strings) { mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); try{ mPlayer.setDataSource(strings[0]);} catch (Exception e) {e.printStackTrace();} // wait for media player to get prepare mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); // Get the current audio stats for(int i =0; i<mp.getDuration(); i = mp.getCurrentPosition()) { //int duration = mPlayer.getDuration() / 1000; // In milliseconds //int due = (mPlayer.getDuration() - mPlayer.getCurrentPosition()) / 1000; //int pass = duration - due; int mCurrentPosition = mp.getCurrentPosition(); // In milliseconds //seekBar.setProgress(mCurrentPosition); publishProgress(mCurrentPosition); try { Thread.sleep(1); } catch (Exception e){ e.printStackTrace(); } } } }); mPlayer.prepareAsync(); return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); //Using the callback, I get data logged on the console but the //item on the RecyclerView is not updated mCb.onDataLoaded(values[0]); //Pass the Seekbar to the AsyncTas doesnt update //seekBar.setProgress(values[0]); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); } }
我在Callback
的{{1}}中实现了ViewHolder
接口。这是我的适配器:
FirestoreRecyclerAdapter
private class PostViewHolder extends RecyclerView.ViewHolder implements MyTask.Callback {
private PostViewHolder holder;
private LinearLayout root, llp,;
private RelativeLayout rlp;
private TextView tv_due, tv_pass;
private Button btn_play;
private SeekBar seekBar;
private FirebaseFirestore db;
private final StorageReference storageRef;
public PostViewHolder(@NonNull View itemView) {
super(itemView);
root = itemView.findViewById(R.id.list_root);
llp = root.findViewById(R.id.llp);
rlp = root.findViewById(R.id.rlp);
btn_play = llp.findViewById(R.id.btn_play);
tv_due = rlp.findViewById(R.id.tv_due);
tv_pass = rlp.findViewById(R.id.tv_pass);
seekBar = rlp.findViewById(R.id.seek_bar);
db = FirebaseFirestore.getInstance();
storageRef = FirebaseStorage.getInstance().getReference();
}
@Override
public void onDataLoaded(Integer result) {
Log.d("NEW TAG", result.toString());
holder.seekBar.setProgress(result);
}
void setData(final Post post, final PostViewHolder holder) {
this.holder = holder;
btn_play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (btn_play.getText().equals("Play")) {
playMusic(seekBar, tv_pass, tv_due, post, mPlayer, holder);
}
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(mPlayer!=null && b){
mPlayer.seekTo(i*1000);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
如下:
playMusic()