react-native-callkeep
react-native-callkeep copied to clipboard
RNCallKeep is not working on app background and Inactive States
Bug report
- I've checked the(https://github.com/react-native-webrtc/react-native-callkeep/tree/master/example) to reproduce the issue.
Description
I have implemented RNCallKeep features in such a way that when a push notification arrives, then it tries to display an incoming UI through RNCallKeepDisplayIncomingUI()
. When the app is in foreground as per the logic If I click on answer button, it is redirecting to a specific page; howsoever, the functionality that I am mentioning wasn't working as expected when the app goes to background or inactive state.
In background state, on click of answer button, the expected behaviour is that app should change its state to foreground, open the app automatically and redirect to the specific screen. The navigation logic is working fine but it is not opening the app and behave according to the logic.
Help will be appreciated.
Versions
- Callkeep: 3.0.12
- React Native: 0.59.9
- iOS: 10.15.2
- Android: android 9.0
- Phone model: Nokia 5.1 plus
Same here. Killed an app. Calling to this device — no reaction.
@pavanMude Figured out — need to configure, for example, Firebase background messaging (https://bit.ly/3ej3hoN — react-native-firebase v5 docs NOT THE LATEST, but just my case).
Then you need to register headless task.
AppRegistry.registerHeadlessTask(
'RNFirebaseBackgroundMessage',
() => CallMessagingManager.backgroundMessageHandler
)
Inside this backgroundMessageHandler
it's important to call methods:
RNCallKeep.setup(YOUR_OPTIONS)
RNCallKeep.setAvailable(true)
// rest of your call answer logic
After this at some moment (onAnswer, for example) you need to use something like that — react-native-invoke-app to return your app from background.
@isnifer in the backgroundMessageHandler i setup Callkeep and display incomming call and after i call RNCallKeep.setCurrentCallActive(callUUID); i can't recive event endcall when i pressButtom endcall in screen ui can you tell me why and how i can catch event endcall? test in android
Hi @JustinBeBoy, to receive an event when someone hangup via callkeep, you have to register a listener.
@manuquentin I registered all the events, when I test your example, I still get the endcall event, but when I process the notification in the background firebase, I don't get the endcall event when I click the end call button i test in nexsus 5x android 8.1 react native : 0.62
@JustinBeBoy can you explain what youre trying to do a bit clearer please? We can't help you unless you give us more information to go on
@danjenkins code in file index.js: `function HeadlessCheck({ isHeadless }) { if (isHeadless) { // App has been launched in the background by iOS, ignore return null; }
return <App />;
}
registerMessing()
AppRegistry.registerComponent(appName, () => HeadlessCheck);`
this is my registerMessing function:
export const registerMessing = () => { messaging().setBackgroundMessageHandler(async remoteMessage => { console.log('Message handled in the background!', remoteMessage); try { const messData = remoteMessage.data ?? {} const type = messData.type ?? "" const data = messData.data if (type == NotiType.call) { const objectNoti = JSON.parse(data) console.log('Parse Object', objectNoti) await handlerCall(objectNoti) } console.log('Message handled in the background!', remoteMessage); } catch (err) { console.log('backgoundMessageHandler-error: ', err) } }); }
handlerCall function:
`const handlerCall = (object) => { return new Promise(async (resolve, reject) => { if (object.callStatus == CallStatus.end) { resolve() }
let client = new StringeeClientCustoms()
let stringeeCa = new StringeeCallCustoms()
let mediaConnected = false
let answered = false
const callDidChangeSignalingState = ({ callId, code, reason, sipCode, sipReason }) => {}
const callDidChangeMediaState = ({ callId, code, description }) => {}
const callDidReceiveLocalStream = ({ callId }) => {
console.log("CallScreen-callDidReceiveLocalStream: callID=" + callId);
// updateHasReceivedLocalStream(true)
};
const callDidReceiveRemoteStream = ({ callId }) => {
console.log("CallScreen-callDidReceiveRemoteStream: callID=" + callId);
// updateHasReceivedRemoteStream(true)
};
const didReceiveDtmfDigit = ({ callId, dtmf }) => {
console.log("CallScreen-didReceiveDtmfDigit: callId=" + callId + " -- dtmf=" + dtmf);
};
const didReceiveCallInfo = ({ callId, data }) => {
console.log("CallScreen-didReceiveCallInfo: callId=" + callId + " -- data=" + data);
};
const didHandleOnAnotherDevice = ({ callId, code, description }) => {
console.log("CallScreen-didHandleOnAnotherDevice: callId=" + callId + " -- code=" + code + " -- des=" + description);
if (code == 2 || code == 3 || code == 4) {
// Answered || Busy || End
console.log("CallScreen-endCallAndDismissView")
// endCallAndDismissView();
}
};
const callEventHandlers = {
onChangeSignalingState: callDidChangeSignalingState,
onChangeMediaState: callDidChangeMediaState,
onReceiveLocalStream: callDidReceiveLocalStream,
onReceiveRemoteStream: callDidReceiveRemoteStream,
onReceiveDtmfDigit: didReceiveDtmfDigit,
onReceiveCallInfo: didReceiveCallInfo,
onHandleOnAnotherDevice: didHandleOnAnotherDevice
};
const clientDidConnect = ({ userId }) => {
console.log("_clientDidConnect - " + userId);
}
const clientDidDisConnect = () => {
console.log("_clientDidDisConnect");
};
const clientDidFailWithError = () => {
console.log("_clientDidFailWithError");
};
const clientRequestAccessToken = () => {
console.log("_clientRequestAccessToken");
// Token để kết nối tới Stringee server đã hết bạn. Bạn cần lấy token mới và gọi connect lại ở đây
// this.refs.client.connect("NEW_TOKEN");
};
// Call events
const callIncomingCall = ({ callId, from, to, fromAlias, toAlias, callType, isVideoCall, customDataFromYourServer }) => {
console.log("-----------_callIncomingCall---------------", callId)
stringeeCa.init(callEventHandlers)
stringeeCa.initAnswer(object.callId, (status, code, message) => {
console.log("initAnswer=======>", message);
});
};
const clientEventHandlers = {
onConnect: clientDidConnect,
onDisConnect: clientDidDisConnect,
onFailWithError: clientDidFailWithError,
onRequestAccessToken: clientRequestAccessToken,
onIncomingCall: callIncomingCall
};
const answerCall = ({ callUUID }) => {
stringeeCa.answer(object.callId, (status, code, message) => {
console.log("xxxxxxx" + message);
RNCallKeep.startCall(callUUID, "LockApp", "Test")
//@ts-ignore
RNCallKeep.setCurrentCallActive(callUUID);
})
}
const didReceiveStartCallAction = ({ handle }) => {
console.log("didReceiveStartCallAction")
};
const didPerformSetMutedCallAction = ({ muted, callUUID }) => {
console.log("didPerformSetMutedCallAction")
};
const didToggleHoldCallAction = ({ hold, callUUID }) => {
console.log("didToggleHoldCallAction")
};
const endCall = ({ callUUID }) => {
console.log("END CALL:=========")
stringeeCa.hangup(object.callId, (status, code, message) => {
console.log("CallScreen-callDidChangeSignalingState-hangup: status=3, mess=" + message);
resolve()
});
};
RNCallKeep.addEventListener('answerCall', answerCall);
RNCallKeep.addEventListener('didReceiveStartCallAction', didReceiveStartCallAction);
RNCallKeep.addEventListener('didPerformSetMutedCallAction', didPerformSetMutedCallAction);
RNCallKeep.addEventListener('didToggleHoldCallAction', didToggleHoldCallAction);
RNCallKeep.addEventListener('endCall', endCall);
client.init(clientEventHandlers)
client.connect(userTest)
let uuid4 = uuidv4()
RNCallKeep.displayIncomingCall(uuid4, "LockApp", "Test")
})
}`
when i call this code:
RNCallKeep.startCall(callUUID, "LockApp", "Test") //@ts-ignore RNCallKeep.setCurrentCallActive(callUUID);
screen call system show, but when i press button endcall in screen i don't get event endcall in RNCallKeep.addEventListener('endCall', endCall);
i test in nexsus 5x
android 8.1
react native : 0.62
@JustinBeBoy It is because that you are passing different callUUID
to end call(). Remember you must pass same UUID on RNCallKeep DisplayUI (), which also be given in end call() as well. This will surely work.
const endCall = ({ callUUID }) => {
console.log("END CALL:=========")
stringeeCa.hangup(object.callId, (status, code, message) => {
console.log("CallScreen-callDidChangeSignalingState-hangup: status=3, mess=" + message);
resolve()
});
};
Same here. Killed an app. Calling to this device — no reaction.
@pavanMude Figured out — need to configure, for example, Firebase background messaging (https://bit.ly/3ej3hoN — react-native-firebase v5 docs NOT THE LATEST, but just my case).
Then you need to register headless task.
AppRegistry.registerHeadlessTask( 'RNFirebaseBackgroundMessage', () => CallMessagingManager.backgroundMessageHandler )
Inside this
backgroundMessageHandler
it's important to call methods:RNCallKeep.setup(YOUR_OPTIONS) RNCallKeep.setAvailable(true) // rest of your call answer logic
After this at some moment (onAnswer, for example) you need to use something like that — react-native-invoke-app to return your app from background.
Just a question, This apply to android only right?
RNCallKeep.setAvailable(true)
this part ended 2 days of suffering with RN a big TY!
I am trying to handle the calling when the app is in kille state. I tested the features in the foreground state and the listeners are working perfectly fine, but when the app is killed, the UI is shown but nothing happens when buttons are pressed, no callbacks in listeners are invoked.