Please check out the following if you are new to Twilio's Programmable Voice or React Native.
When following the React Native environment setup guide, please ensure that "React Native CLI" is selected.
To get started on Android, you will need a Firebase project and a google-services.json file generated for that project. Place this file in the android/app/ folder of your React Native project.
For more information on Firebase and Push Credentials, please see the Twilio Programmable Voice Android Quickstart: https://github.com/twilio/voice-quickstart-android#quickstart
You will also need to add the Google Services Gradle Plugin as a dependency in your Gradle build files.
In your android/build.gradle:
buildscript {
// excluded for brevity
...
dependencies {
// excluded for brevity
...
classpath("com.google.gms:google-services:4.4.1")
}
}
And in your android/app/build.gradle:
apply plugin: "com.google.gms.google-services"
The native Android layer of the SDK exposes several helper classes that will need to be invoked in your existing native Android code.
React Native 0.73 made Kotlin the default for
MainActivity/MainApplication, and the SDK's own test application intest/app/android/app/src/main/java/com/example/twiliovoicereactnativeis Kotlin only. This guide is preserved for applications that still ship JavaMainActivity.java/MainApplication.java. If you are starting from a recent template, use the Kotlin guide instead.
The following sections detail the Java changes you will need to make in your application.
Within your MainActivity.java file, you will need to instantiate a VoiceActivityProxy and "hook" its methods into your application's MainActivity.
Here is an example of how to instantiate the VoiceActivityProxy class:
public class MainActivity extends ReactActivity {
private final VoiceActivityProxy voiceActivityProxy = new VoiceActivityProxy(
this,
permission -> {
if (Manifest.permission.RECORD_AUDIO.equals(permission)) {
Toast.makeText(
MainActivity.this,
"Microphone permissions needed. Please allow in your application settings.",
Toast.LENGTH_LONG).show();
} else if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) &&
Manifest.permission.BLUETOOTH_CONNECT.equals(permission)) {
Toast.makeText(
MainActivity.this,
"Bluetooth permissions needed. Please allow in your application settings.",
Toast.LENGTH_LONG).show();
} else if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) &&
Manifest.permission.POST_NOTIFICATIONS.equals(permission)) {
Toast.makeText(
MainActivity.this,
"Notification permissions needed. Please allow in your application settings.",
Toast.LENGTH_LONG).show();
}
});
// Excluded for brevity
...
}Note that you can customize the permissions toasts at this point for internationalization purposes.
Here is an example of how to "hook" the onCreate method:
public class MainActivity extends ReactActivity {
// Excluded for brevity
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
voiceActivityProxy.onCreate(savedInstanceState);
}
}You will need to hook the following Android lifecycle methods:
onCreateonDestroyonNewIntent
VoiceActivityProxy exposes these three methods and no others; the older
guidance to also hook onStart and onStop is stale and no such methods exist
on the proxy.
You will need to instantiate a VoiceApplicationProxy which will need to be "hooked" into the Android application lifecycle methods:
public class MainApplication extends Application implements ReactApplication {
private final VoiceApplicationProxy voiceApplicationProxy = new VoiceApplicationProxy(this);
// Excluded for brevity
...
}Finally, here is an example of how to hook the VoiceApplicationProxy lifecycle methods onto MainApplication. The example keeps the rest of MainApplication intact and only shows the additions:
public class MainApplication extends Application implements ReactApplication {
// Excluded for brevity
...
@Override
public void onCreate() {
super.onCreate();
voiceApplicationProxy.onCreate();
// your existing onCreate work follows
}
@Override
public void onTerminate() {
// Note: this method is not invoked on real devices; the OS kills the process instead.
voiceApplicationProxy.onTerminate();
super.onTerminate();
}
}The following lifecycle methods need to be hooked:
onCreateonTerminate
React Native templates from 0.71+ generate MainApplication around
DefaultReactNativeHost and no longer initialize Flipper. Whichever shape
your generated MainApplication uses, the two calls above are what the SDK
requires; leave the rest of MainApplication as your template generated it.
Once the above native code has been implemented in your application, the Twilio Voice React Native SDK is ready for usage on Android platforms.
An Access Token is required to make outgoing calls or receive incoming calls. Please check out this page for more details on creating Access Tokens.
For more details on access tokens, please see the iOS and Android quickstart for examples.
The following example demonstrates how to make and receive calls. You will need to implement your own getAccessToken() method.
For more information on the Voice React Native SDK API, refer to the API Docs or see our Reference App.
import { Voice } from '@twilio/voice-react-native-sdk';
const token = getAccessToken(); // you will need to implement this method for your use case
const voice = new Voice();
// Allow incoming calls
await voice.register(token);
// Handle incoming calls
voice.on(Voice.Event.CallInvite, (callInvite) => {
callInvite.accept();
});
// Make an outgoing call
const call = await voice.connect(token, params);