Issue
I am making a video call app. I want to make a reconnection scenario just like whatsapp i.e. if the user or remote user internet disconnects after waiting for 10-15 seconds call should end for both. here is my code:
private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
@Override
public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (AppSharedPreferences.getUser(context).getUserTypeId() == 2) {
updateDoctorStatus("3");
}
Log.e("Agora", "Join channel success, uid: " + (uid & 0xFFFFFFFFL));
}
});
}
@Override
public void onFirstRemoteVideoDecoded(final int uid, int width, int height, int elapsed) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("Agora", "First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
reconnectingView.setVisibility(View.GONE);
timerRunning = true;
appointmentStarted = true;
if (reconnecting) {
timeLeftInMillis = AppSharedPreferences.getCallTimer(VideoChatViewActivity.this);
countDownTimer.cancel();
}
callingView.setVisibility(View.GONE);
handler.removeCallbacks(runnableCode);
callHandler.removeCallbacks(runnableforCalling);
startMeeting();
updateAppointmentStatus();
setupRemoteVideo(uid);
}
});
}
@Override
public void onUserOffline(final int uid, final int reason) {
Log.e("Agora", "User offline, reason: " + reason);
ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo nInfo = cm.getActiveNetworkInfo();
boolean connected = nInfo != null && nInfo.isAvailable() && nInfo.isConnected();
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("Agora", "User offline, uid: " + (uid & 0xFFFFFFFFL));
if (reason == 0) {
onRemoteUserLeft();
endCall();
} else {
timerRunning = false;
reconnecting = true;
reconnectingView.setVisibility(View.VISIBLE);
reconnectingText.setText("Reconnecting....");
Toast.makeText(VideoChatViewActivity.this, "Doctor internet disconnected", Toast.LENGTH_LONG).show();
reconnectingHandler.postDelayed(() -> {
if (reconnecting) {
onRemoteUserLeft();
endCall();
}
}, 10000);
}
}
});
}
@Override
public void onUserMuteVideo(final int uid, final boolean muted) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("Agora", "User Muted, uid: " + (uid & 0xFFFFFFFFL));
Log.e("Agora", "User Muted,: " + muted);
if (muted)
remote_off.setVisibility(View.VISIBLE);
else
remote_off.setVisibility(View.GONE);
}
});
}
@Override
public void onRejoinChannelSuccess(String channel, int uid, int elapsed) {
super.onRejoinChannelSuccess(channel, uid, elapsed);
reconnecting = false;
Toast.makeText(VideoChatViewActivity.this, "Reconnected", Toast.LENGTH_LONG).show();
}
@Override
public void onNetworkQuality(int uid, final int txQuality, final int rxQuality) {
runOnUiThread(() -> {
// Log.e("Quality", rxQuality + "");
if (rxQuality == Quality.VBAD) {
signals.setImageDrawable(getResources().getDrawable(R.drawable.signal1));
}
if (rxQuality == Quality.BAD) {
signals.setImageDrawable(getResources().getDrawable(R.drawable.signal2));
}
if (rxQuality == Quality.POOR) {
signals.setImageDrawable(getResources().getDrawable(R.drawable.signal3));
}
if (rxQuality == Quality.GOOD) {
signals.setImageDrawable(getResources().getDrawable(R.drawable.signal4));
}
if (rxQuality == Quality.EXCELLENT) {
signals.setImageDrawable(getResources().getDrawable(R.drawable.signal5));
}
});
}
@Override
public void onConnectionStateChanged(int state, int reason) {
Log.d(TAG, "Connection state changes to "
+ state + " reason: " + reason);
}
};
Any help will be appreciated. In the code above there is a problem, I have used a handler in onUserOffline method which will end call after 10 seconds of user offline, but if the user reconnects within 10 seconds the handler still works and the call ends after 10 seconds.
Solution
Instead of using handler, I’d prefer you to use CountDownTimer
. In this, you can also stop it in the middle. You can refer the code below:
//In your class
CountDownTimer mCountDownTimer;
//when the network goes
mCountDownTimer = new CountDownTimer((10 * 1000), (1 * 1000)){ // multiple the number of seconds by thousand to get the appropriate results. Here 10 * 1000 = 10000(10 seconds) and 1 * 1000 = 1000(1 second)
@Override
public void onTick(long millisInFuture){}
@Override
public void onFinish(){
//10 seconds have finished. Drop the call.
}
}.start();
//If the internet comes back
if(mCountDownTimer != null)
mCountDownTimer.cancel();
Answered By – Sambhav Khandelwal
Answer Checked By – Marie Seifert (BugsFixing Admin)