我使用WebRTC在Android中实现了视频通话。
如果两个用户自愿进入同一房间,则会拨打电话。
我现在想要实现的是,某人能够输入用户ID并“呼叫”他和另一个用户的电话振铃(因此webRTC实现没有问题,我只想实现振铃行为)。 / p>
到目前为止,我使用Firebase的实时数据库所做的事情是,我定义了一个名为“呼叫”的分支,该分支由以两个用户ID组合命名的房间名称的孩子组成。 (因此,如果user1呼叫user2,则会议室名称将为user1user2)。
如果user1调用user2,它将reqId
设置为1,然后当user2侦听任何更改时。他知道用户1正在呼叫他(并且我显示了来电屏幕),然后它通过将reqId
设置为2进行响应,此对话一直持续到用户2接受或取消呼叫为止。
我正在寻找一种更好的解决方案来实现此目的,因为它似乎不是一种好的方法,并且存在很多问题。
答案 0 :(得分:0)
我找到了解决方案。 好像有人有同样的问题。 我为每个用户创建了一个名为“通话”的分支,负责来电。
这两个功能是我实现执行或监听的功能:
performCall
功能:
private DatabaseReference mDatabase;
private static int count = 0;
private void performCall(String s) {
if(count>0)return;
mDatabase = FirebaseDatabase.getInstance().getReference().child("users/"+"USERIDTOCALL"+"/call");
mDatabase.child("roomName").setValue(s);
mDatabase.child("answer").setValue("none");
mDatabase.child("answer").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
switch (Objects.requireNonNull(dataSnapshot.getValue()).toString()){
case "none":
break;
case "yes":
t.cancel();
t.purge();
count =0;
//The Call Should Begin...
break;
case "no":
t.cancel();
t.purge();
count =0;
//RejectedCall
break;
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
//Declare the timer
t = new Timer();
count =0;
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
mDatabase.child("signal").setValue(new Random().nextInt());
count++;
if(count >= 20){
t.cancel();
t.purge();
count =0;
}
}
}, 0, 2000);
}
和listenForCalls
功能:
private int count =-1;
private boolean isCalling = false;
Runnable runnable = null;
private boolean callingScreenShowed;
AlertDialog alertDialog;
private void listenForCalls() {
mDatabase = FirebaseDatabase.getInstance().getReference().child("users/"+GlobalVars.userName+"/call");
mDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String answer = dataSnapshot.child("answer").getValue().toString();
if(answer == "yes" || answer =="no") return;
count++;
if(count >= 1){
isCalling = true;
}
if(count == 1 ){
callingScreenShowed= false;
//every 5 seconds check if signaling is active
final int interval = 5000;
Handler handler = new Handler();
runnable = () -> {
if(isCalling){
if(!callingScreenShowed){
//Show A dialog for calling
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setMessage("user with id" + dataSnapshot.child("roomName").getValue() + " Is Calling");
dialog.setTitle("Incomming Call");
dialog.setPositiveButton("YES",
(dialog1, which) -> {
mDatabase.child("answer").setValue("yes");
callingScreenShowed =false;
isCalling = false;
count = -1;
handler.removeCallbacks(runnable);
//Start VideoCall
}
);
dialog.setNegativeButton("cancel", (dialog12, which) -> {
mDatabase.child("answer").setValue("no");
callingScreenShowed =false;
isCalling = false;
count = -1;
handler.removeCallbacks(runnable);
//Clling Rejected
});
alertDialog=dialog.create();
alertDialog.show();
callingScreenShowed = true;
}
}
else {
if(callingScreenShowed){
alertDialog.hide();
}
Log.e("Called","Call Request Ended");
count = -1;
handler.removeCallbacks(runnable);
return;
//Hide Calling Screen
}
isCalling = false;
handler.postDelayed(runnable, interval);
};
runnable.run();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}