Skip to content

Commit 42b8820

Browse files
feat: Android handle incoming call when the app is closed
1 parent 458b0d4 commit 42b8820

File tree

4 files changed

+34
-40
lines changed

4 files changed

+34
-40
lines changed

android/src/main/java/com/hoxfon/react/RNTwilioVoice/CallNotificationManager.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void createMissedCallNotification(ReactApplicationContext context, String
105105
/*
106106
* Create the notification shown in the notification drawer
107107
*/
108-
String title = context.getString(R.string.call_missed);
108+
String title = context.getString(R.string.call_missed_title);
109109
NotificationCompat.Builder notification =
110110
new NotificationCompat.Builder(context, VOICE_CHANNEL)
111111
.setGroup(MISSED_CALLS_GROUP)
@@ -115,7 +115,7 @@ public void createMissedCallNotification(ReactApplicationContext context, String
115115
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
116116
.setSmallIcon(R.drawable.ic_call_missed_white_24dp)
117117
.setContentTitle(title)
118-
.setContentText(callFrom + " called")
118+
.setContentText(callFrom + context.getString(R.string.call_missed_from))
119119
.setAutoCancel(true)
120120
.setShowWhen(true)
121121
.setExtras(extras)
@@ -128,9 +128,9 @@ public void createMissedCallNotification(ReactApplicationContext context, String
128128
inboxStyle = new NotificationCompat.InboxStyle();
129129
inboxStyle.setBigContentTitle(title);
130130
} else {
131-
inboxStyle.setBigContentTitle(String.valueOf(missedCalls) + " missed calls");
131+
inboxStyle.setBigContentTitle(String.valueOf(missedCalls) + context.getString(R.string.call_missed_title_plural));
132132
}
133-
inboxStyle.addLine("last call from: " +callFrom);
133+
inboxStyle.addLine(context.getString(R.string.call_missed_more) +callFrom);
134134
sharedPrefEditor.putInt(MISSED_CALLS_GROUP, missedCalls);
135135
sharedPrefEditor.commit();
136136

android/src/main/java/com/hoxfon/react/RNTwilioVoice/TwilioVoiceModule.java

+13-30
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@
6969
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_CONNECTION_DID_CONNECT;
7070
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_CONNECTION_DID_DISCONNECT;
7171
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_DEVICE_DID_RECEIVE_INCOMING;
72-
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_CALL_INVITE_CANCELLED;
7372
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_DEVICE_NOT_READY;
7473
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_DEVICE_READY;
7574
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_CALL_STATE_RINGING;
75+
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_CALL_INVITE_CANCELLED;
7676
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_CONNECTION_IS_RECONNECTING;
7777
import static com.hoxfon.react.RNTwilioVoice.EventManager.EVENT_CONNECTION_DID_RECONNECT;
7878

@@ -111,7 +111,7 @@ public class TwilioVoiceModule extends ReactContextBaseJavaModule implements Act
111111
private AudioFocusRequest focusRequest;
112112
private HeadsetManager headsetManager;
113113
private EventManager eventManager;
114-
private int callInviteIntent;
114+
private int existingCallInviteIntent;
115115

116116
public TwilioVoiceModule(ReactApplicationContext reactContext,
117117
boolean shouldAskForMicPermission) {
@@ -170,8 +170,8 @@ public void onHostResume() {
170170
if (BuildConfig.DEBUG) {
171171
Log.d(TAG, "Module creation "+action+". Intent "+ intent.getExtras());
172172
}
173-
if (action.equals(ACTION_ACCEPT) && callInviteIntent != currentCallInviteIntent) {
174-
callInviteIntent = currentCallInviteIntent;
173+
if (action.equals(ACTION_ACCEPT) && currentCallInviteIntent != existingCallInviteIntent) {
174+
existingCallInviteIntent = currentCallInviteIntent;
175175
handleIncomingCallIntent(intent);
176176
}
177177
}
@@ -189,6 +189,11 @@ public void onHostDestroy() {
189189
unsetAudioFocus();
190190
}
191191

192+
@Override
193+
public String getName() {
194+
return TAG;
195+
}
196+
192197
@Override
193198
public void onNewIntent(Intent intent) {
194199
// This is called only when the App is in the foreground
@@ -198,11 +203,6 @@ public void onNewIntent(Intent intent) {
198203
handleIncomingCallIntent(intent);
199204
}
200205

201-
@Override
202-
public String getName() {
203-
return TAG;
204-
}
205-
206206
private RegistrationListener registrationListener() {
207207
return new RegistrationListener() {
208208
@Override
@@ -698,26 +698,11 @@ public void connect(ReadableMap params) {
698698
twiMLParams.put(key, params.getString(key));
699699
break;
700700
default:
701-
Log.d(TAG, "Could not convert with key: " + key + ".");
701+
Log.d(TAG, "Could not convert key: " + key + ". ReadableType: "+ readableType.toString());
702702
break;
703703
}
704704
}
705705

706-
// Set<IceServer> iceServers = new HashSet<>();
707-
// iceServers.add(new IceServer("stun:global.stun.twilio.com:3478?transport=udp"));
708-
// iceServers.add(new IceServer("turn:global.turn.twilio.com:3478?transport=udp","8e6467be547b969ad913f7bdcfb73e411b35f648bd19f2c1cb4161b4d4a067be","n8zwmkgjIOphHN93L/aQxnkUp1xJwrZVLKc/RXL0ZpM="));
709-
// iceServers.add(new IceServer("turn:global.turn.twilio.com:3478?transport=tcp","8e6467be547b969ad913f7bdcfb73e411b35f648bd19f2c1cb4161b4d4a067be","n8zwmkgjIOphHN93L/aQxnkUp1xJwrZVLKc/RXL0ZpM="));
710-
// iceServers.add(new IceServer("turn:global.turn.twilio.com:443?transport=tcp","8e6467be547b969ad913f7bdcfb73e411b35f648bd19f2c1cb4161b4d4a067be","n8zwmkgjIOphHN93L/aQxnkUp1xJwrZVLKc/RXL0ZpM="));
711-
//
712-
// IceOptions iceOptions = new IceOptions.Builder()
713-
// .iceServers(iceServers)
714-
// .build();
715-
//
716-
// ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
717-
// .iceOptions(iceOptions)
718-
// .enableDscp(true)
719-
// .params(twiMLParams)
720-
// .build();
721706
ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
722707
.enableDscp(true)
723708
.params(twiMLParams)
@@ -807,7 +792,7 @@ private void setAudioFocus() {
807792
}
808793
savedAudioMode = audioManager.getMode();
809794
// Request audio focus before making any device switch
810-
if (Build.VERSION.SDK_INT >= 26) {
795+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
811796
AudioAttributes playbackAttributes = new AudioAttributes.Builder()
812797
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
813798
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
@@ -845,7 +830,7 @@ private void unsetAudioFocus() {
845830
return;
846831
}
847832
audioManager.setMode(savedAudioMode);
848-
if (Build.VERSION.SDK_INT >= 26) {
833+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
849834
if (focusRequest != null) {
850835
audioManager.abandonAudioFocusRequest(focusRequest);
851836
}
@@ -864,9 +849,7 @@ private void requestPermissionForMicrophone() {
864849
return;
865850
}
866851
if (ActivityCompat.shouldShowRequestPermissionRationale(getCurrentActivity(), Manifest.permission.RECORD_AUDIO)) {
867-
// Snackbar.make(coordinatorLayout,
868-
// "Microphone permissions needed. Please allow in your application settings.",
869-
// SNACKBAR_DURATION).show();
852+
// TODO
870853
} else {
871854
ActivityCompat.requestPermissions(getCurrentActivity(), new String[]{Manifest.permission.RECORD_AUDIO}, MIC_PERMISSION_REQUEST_CODE);
872855
}

android/src/main/java/com/hoxfon/react/RNTwilioVoice/fcm/VoiceFirebaseMessagingService.java

+12-5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void onNewToken(String token) {
5050

5151
// Notify Activity of FCM token
5252
Intent intent = new Intent(ACTION_FCM_TOKEN);
53-
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
53+
LocalBroadcastManager.getInstance(this.getBaseContext()).sendBroadcast(intent);
5454
}
5555

5656
/**
@@ -86,12 +86,19 @@ public void run() {
8686
ReactInstanceManager mReactInstanceManager = ((ReactApplication) getApplication()).getReactNativeHost().getReactInstanceManager();
8787
ReactContext context = mReactInstanceManager.getCurrentReactContext();
8888

89+
// initialise appImportance to the highest possible importance in case context is null
90+
int appImportance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
91+
8992
// if the app is closed or not visible, create a heads-up notification
90-
int appImportance = callNotificationManager.getApplicationImportance((ReactApplicationContext)context);
91-
if (BuildConfig.DEBUG) {
92-
Log.d(TAG, "CONTEXT present appImportance = " + appImportance);
93+
if (context != null) {
94+
appImportance = callNotificationManager.getApplicationImportance((ReactApplicationContext)context);
95+
if (BuildConfig.DEBUG) {
96+
Log.d(TAG, "context is present, appImportance = " + appImportance);
97+
}
9398
}
94-
if (context == null || appImportance > ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
99+
100+
// when the app is not started or in the background
101+
if (appImportance > ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
95102
handleInvite(callInvite, notificationId);
96103
return;
97104
}

android/src/main/res/values/values.xml

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@
55
<string name="hangup" translatable="false">Hang up</string>
66
<string name="call_in_progress" translatable="false">Call in progress</string>
77
<string name="call_incoming" translatable="false">Incoming call</string>
8-
<string name="call_missed" translatable="false">Missed call</string>
8+
<string name="call_missed_title" translatable="false">Missed call</string>
9+
<string name="call_missed_more" translatable="false">last call from: </string>
10+
<string name="call_missed_from" translatable="false"> called</string>
11+
<string name="call_missed_title_plural" translatable="false"> missed calls</string>
12+
913
</resources>

0 commit comments

Comments
 (0)