Я реализовал видеозвонок в Android с помощью WebRTC.
Звонок будет сделан, если два пользователя по своему желанию войдут в одну и ту же комнату.
Теперь я хочу добиться того, чтобы кто-то мог ввести идентификатор пользователя и «вызвать» ему и звонку телефона другого пользователя (поэтому нет проблем с реализацией webRTC, я просто хочу реализовать поведение звонка).
Что я сделал до сих пор, используя базу данных Firebase Realtime, так это то, что я определил ветвь под названием «вызовы», состоящую из дочернего имени комнаты с комбинацией двух идентификаторов пользователей. (поэтому, если пользователь1 звонит пользователю2, имя комнаты будет пользователем1пользователь2).
Если пользователь1 вызывает пользователя2, он устанавливает reqId
в 1, а затем, когда пользователь2 прослушивает любые изменения. он понимает, что ему звонит пользователь1 (и я показываю экран входящего вызова), а затем отвечает, устанавливая reqId
на 2, этот разговор продолжается до тех пор, пока пользователь2 не примет или не отменит вызов.
Я ищу лучшее решение для достижения этой цели, потому что это не кажется таким хорошим методом и имеет много проблем.
@BlackBlind в моем ответе предоставлен полный и рабочий код.
я нашел решение. как будто у кого-то есть такой же вопрос. для каждого пользователя я создал ветку под названием «вызов», которая отвечает за входящие звонки.
и эти две функции - это то, что я реализовал для выполнения или прослушивания вызова:
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) {
}
});
}
Вы можете поделиться со мной своим кодом?