@@ -7,19 +7,74 @@ import {
77 TouchableHighlight ,
88 DeviceEventEmitter ,
99 Image ,
10+ PermissionsAndroid ,
11+ AppState ,
1012} from 'react-native' ;
1113import RNBootSplash from 'react-native-bootsplash' ;
1214import messaging from '@react-native-firebase/messaging' ;
1315import Clipboard from '@react-native-community/clipboard' ;
1416import IncomingCall from 'react-native-incoming-call' ;
17+ import RNCallKeep from 'react-native-callkeep' ;
1518
16- export function handleRemoteMessage ( remoteMessage ) {
19+ const USE_CALLKEEP = false ;
20+
21+ const PRIMARY_COLOR = USE_CALLKEEP ? '#1AD1EC' : '#8271FC' ;
22+ const SECONDARY_COLOR = USE_CALLKEEP ? '#F55994' : '#FDDA97' ;
23+ const BTN_LABEL_COLOR = USE_CALLKEEP ? '#FFFFFF' : '#21346E' ;
24+
25+ function setupCallKeep ( ) {
26+ const options = {
27+ android : {
28+ alertTitle : 'Permissions Required' ,
29+ alertDescription :
30+ 'This application needs to access your phone calling accounts to make calls' ,
31+ cancelButton : 'Cancel' ,
32+ okButton : 'ok' ,
33+ imageName : 'ic_launcher' ,
34+ additionalPermissions : [ PermissionsAndroid . PERMISSIONS . READ_CONTACTS ] ,
35+ } ,
36+ } ;
37+
38+ try {
39+ RNCallKeep . setup ( options ) ;
40+ RNCallKeep . setAvailable ( true ) ; // Only used for Android, see doc above.
41+ } catch ( err ) {
42+ console . error ( 'initializeCallKeep error:' , err . message ) ;
43+ }
44+ }
45+
46+ USE_CALLKEEP && setupCallKeep ( ) ;
47+
48+ export function handleRemoteMessage ( remoteMessage , isHeadless ) {
1749 if ( remoteMessage ?. notification ?. title === 'Incoming call' ) {
18- IncomingCall . display (
19- '123' ,
20- 'Quocs' ,
21- 'https://avatars3.githubusercontent.com/u/16166195' ,
22- ) ;
50+ console . log ( 'ready...' ) ;
51+ const callUUID = '23727631' ;
52+ if ( USE_CALLKEEP ) {
53+ setupCallKeep ( ) ;
54+ RNCallKeep . displayIncomingCall (
55+ callUUID ,
56+ 57+ 'Quoc Khanh' ,
58+ 'email' ,
59+ true ,
60+ ) ;
61+ RNCallKeep . addEventListener ( 'answerCall' , ( { callUUID : uuid } ) => {
62+ RNCallKeep . setCurrentCallActive ( uuid ) ;
63+ if ( isHeadless ) {
64+ RNCallKeep . openAppFromHeadlessMode ( uuid ) ;
65+ } else {
66+ console . log ( uuid ) ;
67+ RNCallKeep . backToForeground ( ) ;
68+ }
69+ } ) ;
70+ } else {
71+ IncomingCall . display (
72+ callUUID ,
73+ 'Quocs' ,
74+ 'Video Call' ,
75+ 'https://avatars3.githubusercontent.com/u/16166195' ,
76+ ) ;
77+ }
2378 // Could also persist data here for later uses
2479 }
2580}
@@ -38,6 +93,10 @@ const App = () => {
3893 return setDeviceToken ( token ) ;
3994 } ) ;
4095
96+ AppState . addEventListener ( 'change' , state =>
97+ console . log ( 'state change' , state ) ,
98+ ) ;
99+
41100 // Listen to whether the token changes
42101 return messaging ( ) . onTokenRefresh ( token => {
43102 setDeviceToken ( token ) ;
@@ -71,8 +130,43 @@ const App = () => {
71130 } ) ;
72131 }
73132
133+ async function handleCallKeep ( ) {
134+ const extras = await RNCallKeep . getExtrasFromHeadlessMode ( ) ;
135+
136+ if ( extras ) {
137+ console . log ( 'getExtrasFromHeadlessMode' , extras ) ;
138+ }
139+
140+ const scs = await RNCallKeep . supportConnectionService ( ) ;
141+
142+ console . log ( 'supportConnectionService: ' , scs ) ;
143+
144+ RNCallKeep . addEventListener ( 'answerCall' , payload => {
145+ // Do your normal `Answering` actions here.
146+ setCallPayload ( payload ) ;
147+ console . log ( 'answerCall' , payload ) ;
148+ RNCallKeep . backToForeground ( ) ;
149+ } ) ;
150+
151+ RNCallKeep . addEventListener ( 'endCall' , payload => {
152+ // Do your normal `Hang Up` actions here
153+ setCallPayload ( payload ) ;
154+ console . log ( 'endCall' , payload ) ;
155+ } ) ;
156+
157+ RNCallKeep . addEventListener ( 'didDisplayIncomingCall' , payload => {
158+ // you might want to do following things when receiving this event:
159+ // - Start playing ringback if it is an outgoing call
160+ console . log ( 'didDisplayIncomingCall' , payload ) ;
161+ } ) ;
162+ }
163+
74164 useEffect ( ( ) => {
75- handleIncomingCall ( ) ;
165+ if ( USE_CALLKEEP ) {
166+ handleCallKeep ( ) ;
167+ } else {
168+ handleIncomingCall ( ) ;
169+ }
76170 } , [ ] ) ;
77171
78172 function handleCopyToken ( ) {
@@ -87,7 +181,10 @@ const App = () => {
87181 return (
88182 < View style = { styles . wrapper } >
89183 < Text style = { styles . appTitle } > RNCall</ Text >
90- < Text style = { styles . appDesc } > example for react-native-incoming-call</ Text >
184+ < Text style = { styles . appDesc } >
185+ example for{ ' ' }
186+ { ! USE_CALLKEEP ? 'react-native-incoming-call' : 'react-native-callkeep' }
187+ </ Text >
91188 < View style = { styles . container } >
92189 { callPayload ? (
93190 < >
@@ -106,10 +203,7 @@ const App = () => {
106203 </ >
107204 ) : deviceToken ? (
108205 < >
109- < Image
110- style = { styles . image }
111- source = { require ( './images/waiting-call.jpg' ) }
112- />
206+ < Image style = { styles . image } source = { { uri : 'ic_launcher' } } />
113207 < Text style = { styles . header } > FCM Device Token</ Text >
114208 < Text style = { styles . text } > { deviceToken } </ Text >
115209 < TouchableHighlight
@@ -136,7 +230,7 @@ const App = () => {
136230const styles = StyleSheet . create ( {
137231 wrapper : {
138232 flex : 1 ,
139- backgroundColor : '#8271FC' ,
233+ backgroundColor : PRIMARY_COLOR ,
140234 } ,
141235 appTitle : {
142236 textAlign : 'center' ,
@@ -184,15 +278,15 @@ const styles = StyleSheet.create({
184278 borderRadius : 10 ,
185279 paddingHorizontal : 20 ,
186280 bottom : - 25 ,
187- backgroundColor : '#FDDA97' ,
281+ backgroundColor : SECONDARY_COLOR ,
188282 justifyContent : 'center' ,
189283 alignItems : 'center' ,
190284 alignSelf : 'center' ,
191285 elevation : 5 ,
192286 } ,
193287 btnLabel : {
194288 fontSize : 14 ,
195- color : '#21346E' ,
289+ color : BTN_LABEL_COLOR ,
196290 fontFamily : 'monospace' ,
197291 fontWeight : '700' ,
198292 } ,
0 commit comments