Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Twilio Voice Android SDK 5 #142

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 10 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# react-native-twilio-programmable-voice
This is a React Native wrapper for Twilio Programmable Voice SDK that lets you make and receive calls from your ReactNatvie App. This module is not curated nor maintained, but inspired by Twilio.
This is a React Native wrapper for Twilio Programmable Voice SDK that lets you make and receive calls from your React Native App. This module is not affiliated with or maintained by the Twilio team. This is maintained by contributions from the community.

# Twilio Programmable Voice SDK

- Android 2.1.0 (bundled within this library)
- Android 5.0.2 (bundled within this library)
- iOS 2.1.0 (specified by the app's own podfile)

## Breaking changes in v4.0.0
@@ -45,7 +45,9 @@ ReactNative success is directly linked to its module ecosystem. One way to make
## Installation

Before starting, we recommend you get familiar with [Twilio Programmable Voice SDK](https://www.twilio.com/docs/api/voice-sdk).
It's easier to integrate this module into your react-native app if you follow the Quick start tutorial from Twilio, because it makes very clear which setup steps are required.
It's easier to integrate this module into your react-native app if you follow the Quick start tutorial from Twilio, because it makes very clear which setup steps are required. On RN 0.60+, this module can be auto-linked (Android still requires FCM setup below).

### Manual Linking


```
@@ -120,16 +122,17 @@ It contains keys and settings for all your applications under Firebase. This lib
buildscript {
...
dependencies {
classpath 'com.google.gms:google-services:3.1.2'
classpath 'com.google.gms:google-services:3.1.2' // use a newer version
}
}

...

dependencies {
...
// on React Native 0.60+, this module can be auto-linked and doesn't need a manual entry here

compile project(':react-native-twilio-programmable-voice')
implementation project(':react-native-twilio-programmable-voice')
}

// this plugin looks for google-services.json in your project
@@ -156,22 +159,12 @@ In your `AndroidManifest.xml`
</intent-filter>
</service>
<!-- [END fcm_listener] -->
<!-- [START instanceId_listener] -->
<service
android:name="com.hoxfon.react.RNTwilioVoice.fcm.VoiceFirebaseInstanceIDService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<!-- Twilio Voice -->

.....

```

In `android/settings.gradle`
In `android/settings.gradle` (not necessary if auto-linking on RN 0.60+)

```gradle
...
@@ -180,7 +173,7 @@ include ':react-native-twilio-programmable-voice'
project(':react-native-twilio-programmable-voice').projectDir = file('../node_modules/react-native-twilio-programmable-voice/android')
```

Register module (in `MainApplication.java`)
Register module (in `MainApplication.java`) (not necessary if auto-linking on RN 0.60+ unless you want to control microphone permission)

```java
import com.hoxfon.react.RNTwilioVoice.TwilioVoicePackage; // <--- Import Package
3 changes: 1 addition & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@ buildscript {
repositories {
google()
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
@@ -51,7 +50,7 @@ dependencies {
def supportLibVersion = rootProject.hasProperty('supportLibVersion') ? rootProject.supportLibVersion : DEFAULT_SUPPORT_LIB_VERSION

implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.twilio:voice-android:4.5.0'
implementation 'com.twilio:voice-android:5.0.2'
implementation "com.android.support:appcompat-v7:$supportLibVersion"
implementation 'com.facebook.react:react-native:+'
implementation 'com.google.firebase:firebase-messaging:17.+'
2 changes: 2 additions & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
@@ -15,3 +15,5 @@ org.gradle.jvmargs=-Xmx1536m
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useAndroidX=true
android.enableJetifier=true
Original file line number Diff line number Diff line change
@@ -15,35 +15,35 @@
import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import androidx.core.app.NotificationCompat;
import android.util.Log;
import android.view.WindowManager;

import androidx.core.app.NotificationCompat;

import com.facebook.react.bridge.ReactApplicationContext;
import com.twilio.voice.CallInvite;
import com.twilio.voice.CancelledCallInvite;

import java.util.List;

import static android.content.Context.ACTIVITY_SERVICE;

import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.TAG;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.ACTION_ANSWER_CALL;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.ACTION_REJECT_CALL;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.ACTION_CLEAR_MISSED_CALLS_COUNT;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.ACTION_HANGUP_CALL;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.ACTION_INCOMING_CALL;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.ACTION_MISSED_CALL;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.ACTION_REJECT_CALL;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.CALL_SID_KEY;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.CLEAR_MISSED_CALLS_NOTIFICATION_ID;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.HANGUP_NOTIFICATION_ID;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.INCOMING_CALL_INVITE;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.INCOMING_CALL_NOTIFICATION_ID;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.NOTIFICATION_TYPE;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.CALL_SID_KEY;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.INCOMING_NOTIFICATION_PREFIX;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.MISSED_CALLS_GROUP;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.MISSED_CALLS_NOTIFICATION_ID;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.HANGUP_NOTIFICATION_ID;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.NOTIFICATION_TYPE;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.PREFERENCE_KEY;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.ACTION_CLEAR_MISSED_CALLS_COUNT;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.CLEAR_MISSED_CALLS_NOTIFICATION_ID;
import static com.hoxfon.react.RNTwilioVoice.TwilioVoiceModule.TAG;


public class CallNotificationManager {
@@ -52,7 +52,8 @@ public class CallNotificationManager {

private NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();

public CallNotificationManager() {}
public CallNotificationManager() {
}

public int getApplicationImportance(ReactApplicationContext context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
@@ -116,10 +117,9 @@ public Intent getLaunchIntent(ReactApplicationContext context,
public void createIncomingCallNotification(ReactApplicationContext context,
CallInvite callInvite,
int notificationId,
Intent launchIntent)
{
Intent launchIntent) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "createIncomingCallNotification intent "+launchIntent.getFlags());
Log.d(TAG, "createIncomingCallNotification intent " + launchIntent.getFlags());
}
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);

@@ -180,7 +180,7 @@ public void createIncomingCallNotification(ReactApplicationContext context,
notificationBuilder.addAction(R.drawable.ic_call_white_24dp, "ANSWER", pendingAnswerIntent);

notificationManager.notify(notificationId, notificationBuilder.build());
TwilioVoiceModule.callNotificationMap.put(INCOMING_NOTIFICATION_PREFIX+callInvite.getCallSid(), notificationId);
TwilioVoiceModule.callNotificationMap.put(INCOMING_NOTIFICATION_PREFIX + callInvite.getCallSid(), notificationId);
}

public void initCallNotificationsChannel(NotificationManager notificationManager) {
@@ -246,7 +246,7 @@ public void createMissedCallNotification(ReactApplicationContext context, CallIn
} else {
inboxStyle.setBigContentTitle(String.valueOf(missedCalls) + " missed calls");
}
inboxStyle.addLine("from: " +callInvite.getFrom());
inboxStyle.addLine("from: " + callInvite.getFrom());
sharedPrefEditor.putInt(MISSED_CALLS_GROUP, missedCalls);
sharedPrefEditor.commit();

@@ -334,7 +334,7 @@ public void removeIncomingCallNotification(ReactApplicationContext context,
if (notificationId != 0) {
notificationManager.cancel(notificationId);
} else if (callInvite != null) {
String notificationKey = INCOMING_NOTIFICATION_PREFIX+callInvite.getCallSid();
String notificationKey = INCOMING_NOTIFICATION_PREFIX + callInvite.getCallSid();
if (TwilioVoiceModule.callNotificationMap.containsKey(notificationKey)) {
notificationId = TwilioVoiceModule.callNotificationMap.get(notificationKey);
notificationManager.cancel(notificationId);
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.hoxfon.react.RNTwilioVoice;

import androidx.annotation.Nullable;
import android.util.Log;

import androidx.annotation.Nullable;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
@@ -11,29 +12,27 @@

public class EventManager {

private ReactApplicationContext mContext;

public static final String EVENT_PROXIMITY = "proximity";
public static final String EVENT_WIRED_HEADSET = "wiredHeadset";

public static final String EVENT_DEVICE_READY = "deviceReady";
public static final String EVENT_DEVICE_NOT_READY = "deviceNotReady";
public static final String EVENT_CONNECTION_DID_CONNECT = "connectionDidConnect";
public static final String EVENT_CONNECTION_DID_DISCONNECT = "connectionDidDisconnect";
public static final String EVENT_DEVICE_DID_RECEIVE_INCOMING = "deviceDidReceiveIncoming";
private ReactApplicationContext mContext;

public EventManager(ReactApplicationContext context) {
mContext = context;
}

public void sendEvent(String eventName, @Nullable WritableMap params) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "sendEvent "+eventName+" params "+params);
Log.d(TAG, "sendEvent " + eventName + " params " + params);
}
if (mContext.hasActiveCatalystInstance()) {
mContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
} else {
if (BuildConfig.DEBUG) {
Log.d(TAG, "failed Catalyst instance not active");
Original file line number Diff line number Diff line change
@@ -16,11 +16,10 @@

public class HeadsetManager {

private BroadcastReceiver wiredHeadsetReceiver;
private static final String ACTION_HEADSET_PLUG = (android.os.Build.VERSION.SDK_INT >= 21)
? AudioManager.ACTION_HEADSET_PLUG
: Intent.ACTION_HEADSET_PLUG;

? AudioManager.ACTION_HEADSET_PLUG
: Intent.ACTION_HEADSET_PLUG;
private BroadcastReceiver wiredHeadsetReceiver;
private EventManager eventManager;

public HeadsetManager(EventManager em) {
Original file line number Diff line number Diff line change
@@ -151,9 +151,9 @@ public void startProximitySensor() {
// SensorManager.SENSOR_DELAY_UI(60 ms),
// SensorManager.SENSOR_DELAY_NORMAL(200 ms)
sensorManager.registerListener(
proximityListener,
proximitySensor,
SensorManager.SENSOR_DELAY_NORMAL
proximityListener,
proximitySensor,
SensorManager.SENSOR_DELAY_NORMAL
);
}
}
Original file line number Diff line number Diff line change
@@ -7,8 +7,8 @@

public class SoundPoolManager {

private boolean playing = false;
private static SoundPoolManager instance;
private boolean playing = false;
private Ringtone ringtone = null;

private SoundPoolManager(Context context) {
Loading