Before using Stringee Call API for the first time, you must have a Stringee account.
If you do not have a Stringee account, sign up for free here: https://developer.stringee.com/account/register
Create a Project on Stringee Dashboard

Buy a Number (optional)
For app-to-phone, phone-to-app calling, buy a Number from Dashboard. If you only need app-to-app calling, skip this step.

Configure answer_url
For more information about answer_url, read Stringee Call API Overview. You can view the answer_url sample code.

If you do not have answer_url, you can use the following Project's answer_url to accelerate the process:
Project's answer_url for App-to-App call:
https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=false
Project's answer_url for App-to-Phone call:
https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=true
(Source code: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/project_answer_url.php)
When building an application, you should use your own answer_url.

If you do not have answer_url, you can use the following Number's answer_url to accelerate the process:
Number's answer_url for Phone-to-App call (The call is routed to Your App which authenticated by USER_ID):
https://developer.stringee.com/scco_helper/simple_number_answer_url?record=true&phoneToPhone=false&to_number=USER_ID
Number's answer_url for Phone-to-Phone call (The call is routed to TO_NUMBER):
https://developer.stringee.com/scco_helper/simple_number_answer_url?record=true&phoneToPhone=true&stringeeNumber=STRINGEE_NUMBER&to_number=TO_NUMBER
(Source code: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/number_answer_url.php)
In your terminal (Command Prompt in Windows), change into your React Native project's directory
In your terminal (Command Prompt in Windows), run $ npm install stringee-react-native-v2@^1.1.0
The latest package requires React Native 0.60 or later, JDK 17, Android minSdk 21 or later, and iOS 13.0 or later. Because the package contains native modules, Expo projects must use a development or production build; Expo Go is not supported.
Permissions
The Stringee Android SDK requires some permissions from your AndroidManifest
android/app/src/main/AndroidManifest.xml<!--Internet-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--Record-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--Audio-->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!--Camera-->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<!--Bluetooth-->
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!--Require for android 12 or higher-->
<uses-feature
android:name="android.hardware.bluetooth"
android:required="false" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="false" />
<!-- Graphic -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="false" />
Request camera, microphone, and BLUETOOTH_CONNECT at runtime on Android versions where they are dangerous permissions. The package already resolves Stringee Android SDK 2.1.13 and WebRTC 144.7559.09, so do not add separate Stringee or WebRTC dependencies to the host app.
ProGuard/R8 rules for Stringee and WebRTC are included in the package. Keep your application's existing minification configuration; you do not need to enable minification specifically for Stringee.
In your terminal, change into your iOS directory and run the following command:
pod install --repo-update
After running CocoaPods, open the generated .xcworkspace file instead of .xcodeproj.
Right-click the information property list file (Info.plist) and select Open As -> Source Code. Then insert the following XML snippet into the body of your file just before the final element:
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) uses Camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) uses Microphone</string>
To connect to Stringee Server, third-party authentication is required as described in Client authentication.
For testing, go to Dashboard -> Tools -> Generate Access token and generate an access_token. In production, the access_token should be generated by your server. See the access token examples.
Initialize StringeeClient:
import {StringeeCall, StringeeClient, StringeeClientListener} from 'stringee-react-native-v2';
...
const stringeeClient: StringeeClient = new StringeeClient();
let incomingCall: StringeeCall | null = null;
Register the client's events
// Listen for the StringeeClient event
const stringeeClientListener: StringeeClientListener = new StringeeClientListener();
// Invoked when the StringeeClient is connected
stringeeClientListener.onConnect = (stringeeClient, userId) => {
console.log('onConnect: ', userId);
}
// Invoked when the StringeeClient is disconnected
stringeeClientListener.onDisConnect = (stringeeClient) => {
console.log('onDisConnect');
}
// Invoked when the StringeeClient connection fails
stringeeClientListener.onFailWithError = (stringeeClient, code, message) => {
console.log('onFailWithError: ', message);
}
// Invoked when your token is expired
stringeeClientListener.onRequestAccessToken = (stringeeClient) => {
console.log('onRequestAccessToken');
}
// Invoked when an incoming StringeeCall is received
stringeeClientListener.onIncomingCall = (stringeeClient, stringeeCall) => {
incomingCall = stringeeCall;
console.log('onIncomingCall: ', JSON.stringify(stringeeCall));
}
// Invoked when an incoming StringeeCall2 is received
stringeeClientListener.onIncomingCall2 = (stringeeClient, stringeeCall2) => {
console.log('onIncomingCall2: ', JSON.stringify(stringeeCall2));
}
stringeeClient.setListener(stringeeClientListener);
Connect
...
const token: string = 'PUT YOUR TOKEN HERE';
...
stringeeClient.connect(token);
After the client connects to Stringee server, follows these steps to make a call:
Initialize StringeeCall
import {StringeeCallListener} from 'stringee-react-native-v2';
...
const stringeeCall = new StringeeCall({
stringeeClient: stringeeClient, /// stringeeClient using to connect
from: 'caller_userId', /// caller identifier
to: 'callee_userId', /// callee identifier
});
Register the call's events
// Listen for the StringeeCall event
const stringeeCallListener: StringeeCallListener = new StringeeCallListener();
// Invoked when the call's signaling state changes
stringeeCallListener.onChangeSignalingState = (stringeeCall, signalingState, reason, sipCode, sipReason) => {
console.log('onChangeSignalingState', signalingState);
}
// Invoked when the call's media state changes
stringeeCallListener.onChangeMediaState = (stringeeCall, mediaState, description) => {
console.log('onChangeMediaState', mediaState);
}
// Invoked when receive call info
stringeeCallListener.onReceiveCallInfo = (stringeeCall, callInfo) => {
console.log('onReceiveCallInfo', callInfo);
}
// Invoked when an incoming call is handle on another device
stringeeCallListener.onHandleOnAnotherDevice = (stringeeCall, signalingState, description) => {
console.log('onHandleOnAnotherDevice', signalingState);
}
// Invoked when local stream in video call is ready to play
stringeeCallListener.onReceiveLocalStream = (stringeeCall) => {
console.log('onReceiveLocalStream');
}
// Invoked when remote stream in video call is ready to play
stringeeCallListener.onReceiveRemoteStream = (stringeeCall) => {
console.log('onReceiveRemoteStream');
}
// Invoked when the current audio device changes in android
stringeeCallListener.onAudioDeviceChange = (stringeeCall, selectedAudioDevice, availableAudioDevices) => {
console.log('onAudioDeviceChange', selectedAudioDevice);
}
stringeeCall.setListener(stringeeCallListener);
Make a call
stringeeCall.makeCall()
.then(() => {
console.log('makeCall success');
})
.catch(console.error);
After stringeeClientListener.onIncomingCall receives an incoming StringeeCall object and saves it to incomingCall, follow these steps:
Initialize the answer
if (!incomingCall) {
return;
}
incomingCall.setListener(stringeeCallListener);
incomingCall.initAnswer()
.then(() => {
console.log('initAnswer success');
})
.catch(console.error);
Answer
if (!incomingCall) {
return;
}
incomingCall.answer()
.then(() => {
console.log('answer success');
})
.catch(console.error);
isVideoCall property to true before calling makeCall().
stringeeCall.isVideoCall = true;Receive and display the local video and the remote video
Using our StringeeVideoView to display the video
import {StringeeVideoView} from 'stringee-react-native-v2';
...
// Invoked when local stream in video call is ready to play
stringeeCallListener.onReceiveLocalStream = (stringeeCall) => {
console.log('onReceiveLocalStream');
this.setState({hasReceivedLocalStream: true});
}
// Invoked when remote stream in video call is ready to play
stringeeCallListener.onReceiveRemoteStream = (stringeeCall) => {
console.log('onReceiveRemoteStream');
this.setState({hasReceivedRemoteStream: true});
}
...
render () {
return (
<View>
...
{stringeeCall.isVideoCall &&
this.state.hasReceivedLocalStream && (
<StringeeVideoView
style={styles.localView}
uuid={stringeeCall.uuid}
local={true}
/>
)
}
{stringeeCall.isVideoCall &&
this.state.hasReceivedRemoteStream && (
<StringeeVideoView
style={{flex: 1}}
uuid={stringeeCall.uuid}
local={false}
/>
)
}
...
</View>
);
}
In Steps 8-13, invoke the methods on the active StringeeCall object. The snippets use the outgoing stringeeCall created in Step 5; for an incoming call, invoke the same methods on incomingCall.
Hang up a call:
stringeeCall.hangup()
.then(() => {
console.log('hangup success');
})
.catch(console.error);
Reject a call:
stringeeCall.reject()
.then(() => {
console.log('reject success');
})
.catch(console.error);
Mute the local sound:
const mute = true; // true: mute, false: unmute
stringeeCall.mute(mute)
.then(() => {
console.log('mute success');
})
.catch(console.error);
Switch to speakerphone or earpiece:
const isSpeaker = true; // true: speakerphone, false: earpiece
stringeeCall.setSpeakerphoneOn(isSpeaker)
.then(() => {
console.log('setSpeakerphoneOn success');
})
.catch(console.error);
Switch the local camera:
stringeeCall.switchCamera()
.then(() => {
console.log('switchCamera success');
})
.catch(console.error);
Turn on/off video:
const enableVideo = true; // true: turn on, false: turn off
stringeeCall.enableVideo(enableVideo)
.then(() => {
console.log('enableVideo success');
})
.catch(console.error);
You can view a full version of this sample app on GitHub: CallSampleHook