This is my Firebase Database structure我对 Android 开发
和 Firebase
非常陌生。我在 JavaFX
方面有一些经验。我正在尝试构建一个小应用程序,用户可以一起同步听音乐。我使用 MediaPlayer
库从 Firebase 存储传输音乐。但为了播放音乐(MediaPlayer 对象),必须初始化 MediaPlayer 对象。每当我尝试播放音乐时,都会收到运行时错误,指出由于 Firebase 延迟,MediaPlayer 对象尚未初始化。这是因为 Firebase 方法是异步的。我想要一个实际启动音乐的方法,等待 MediaPlayer 对象初始化。我见过一些内部接口(interface)回调机制。但我没能做到。
这是我的代码:
DatabaseReference myRef;
String myUri="https://firebasestorage.googleapis.com/v0/b/listentest-1297.appspot.com/o/Musics%2Fsong.mp3?alt=media&token=23626e51-e062-469e-9204-8405a14051fd";
MediaPlayer mediaPlayer;
boolean isFirstTimePlayClick = true;
int isPlayingFirebase = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
myRef = FirebaseDatabase.getInstance().getReference("MusicRooms");
/*
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("gs://listentest-1297.appspot.com/Musics/song.mp3");
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
myUri = uri.toString();
}
});*/
myRef.child(secondActivity.musicRoomID).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
isPlayingFirebase = dataSnapshot.getValue(MusicRoom.class).getIsPlaying();
playResume();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
public void playPauseBtn(View view) {
if (isPlayingFirebase == 1) {
myRef.child(secondActivity.musicRoomID).child("isPlaying").setValue(0);
} else {
myRef.child(secondActivity.musicRoomID).child("isPlaying").setValue(1);
}
}
public void playResume() {
if (isFirstTimePlayClick) {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(myUri);
mediaPlayer.prepare();
mediaPlayer.start();
isFirstTimePlayClick = false;
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
} else{
if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
else{
mediaPlayer.start();
}
}
}
最佳答案
为了能够使用来自异步操作的 isPlayingFirebase
对象,您需要将其传递给 内的
像这样:playResume()
方法onDataChange()
playResume(isPlayingFirebase);
现在你的方法的声明应该如下所示:
public void playResume(boolean isPlayingFirebase) { //See the argument
if (isFirstTimePlayClick) {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(myUri);
mediaPlayer.prepare();
mediaPlayer.start();
isFirstTimePlayClick = false;
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
} else{
if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
else{
mediaPlayer.start();
}
}
}
关于java - 如何等待方法直到从 Firebase 数据库接收到数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57325118/