Using the Android SDK
Using the SDK
- Initialize the SDK
- Register Voice User
- SDK state
- Request runtime permissions
- Place a call
- Mid-call features
- Call updates
- Receive a Call
- Update contact information
- Audio control
- Update push token and phone number
- Unregister Voice User
- Proguard Rules
- Shared Preferences
Initialize the SDK
To initialize the Voice SDK add the following in the onCreate
function of your Application class.
To listen to Voice SDK logs, pass the class that implements the VoiceLogListener
:
class MyApplication: Application(), VoiceLogListener {
...
val voice = Voice.getInstance()
override fun onCreate() {
super.onCreate()
voice.init(this, this)
...
}
override fun onLog(log: VoiceLog) {
// Handle SDK logs
}
...
}
The Voice SDK sends log information to the application.
Note: References to Voice in this document pertain to the
voice
object.
Register and Activate a Voice User
In order for the Voice SDK to function correctly, you need to add Voice user information to make and receive calls. Use the following for user data:
val userConfiguration = userConfiguration {
accountId = "YOUR_ACCOUNT_ID"
userId = "YOUR_USER_ID"
msisdn = "YOUR_DEVICE_NUMBER"
jwtToken = "YOUR_JWT_TOKEN"
displayName = "YOUR_NAME"
deviceId = "UNIQUE_DEVICE_IDENTIFIER"
}
Note:
*
msisdn
is optional.
*ThedeviceId
is the device unique identifier, preferably FirebaseInstanceId. Please refer to Work with instance IDs and GUIDs for more information.
The Voice SDK also requires application information in the setup. Use the following for application data:
val sessionConfiguration = sessionConfiguration {
applicationId = BuildConfig.APPLICATION_ID
baseUrl = "VOICE_BASE_URL"
pushToken = "YOUR_PUSH_TOKEN"
}
Note: The Voice URL is provided by the console when you request access to the Voice SDK.
Once you have the configurations ready, use them to activate the Voice SDK. For example:
configuration {
userConfiguration = userConfig
sessionConfiguration = sessionConfig
failureListener = Configuration.FailureListener { exception ->
Log.i(TAG, "Registration failed - $exception")
}
successListener = Configuration.SuccessListener {
Log.i(TAG, "Registration succeeded")
}
}
voice.activate(configuration)
Upon activation, the application is ready to make and receive calls.
To check if the user is registered and activated, use
voice.isActivated()
Note: Use the result of this function to determine whether or not the user requires activation.
SDK state
The Voice SDK allows you to get updates about sdk state
. You can observe it using the following LiveData
object:
voice.state.observe(lifecycleOwner) { state ->
// Handle the state
}
Request runtime permissions
The Voice SDK requires access to READ_PHONE_STATE
and RECORD_AUDIO
permissions in order to successfully place and receive calls. To find out which permissions are not granted, call:
voice.setOnPermissionsListener { permissions ->
ActivityCompat.requestPermissions(this, permissions, YOUR_REQUEST_CODE)
}
Note: The Voice SDK needs phone and mic permission in order to make and receive calls. If you have not enabled access to these required permissions, you will receive them once per application lifecycle. An application lifecycle is defined as the time that an application has started until it is removed or killed.
Place a call
In order to place a call, the Voice SDK requires the callee contact information. Use the VoiceContact
object from the Voice SDK to create the callee information.
Once the contact
object is ready you can place a call using the following:
voice.placeCall(activity, contact, object : CallCompletionHandler {
override fun onSuccess(call: VoiceCall) {
Log.d(TAG, "Outgoing call succeeded: $call")
// Handle call
}
override fun onFailure(call: VoiceCall?, exception: VoiceException) {
Log.e(TAG, "Outgoing call failed: $exception")
// Handle exception
}
})
Note: Passing activity is optional. This is required for the Voice SDK to prompt the user for permissions that are not granted while placing the call. When not provided, placing a call could fail with a
PermissionNotGranted
exception.
Mid-call features
The Voice SDK provides APIs to interact with an active VoiceCall
. These actions are:
accept()
reject()
endAndAccept()
hangup()
mute()
unmute()
hold()
resume()
You can also query the state of incoming calls such as isIncoming
, isPeerOnHold
, isMuted
, and callStartTime
.
The Voice SDK allows a user to have a second incoming call while a call is in progress. Notifications happens via the VoiceCallUpdateListener
. The Voice SDK provides functionality to end the ongoing call and accept an incoming call using the endAndAccept
action. The default accept
behavior is to put the ongoing call on hold and accept the incoming call.
Call updates
In order to receive call updates use addOnVoiceCallUpdateListener
which takes the implementation of VoiceCallUpdateListener
:
voice.addOnVoiceCallUpdateListener(this)
Once the listener is set up, call updates are received by the following callbacks:
override fun onCallAdded(call: VoiceCall) {
// Call recently added
}
override fun onCallRemoved(call: VoiceCall) {
// Call failed or finished.
}
override fun onCallUpdated(call: VoiceCall?) {
// Call that's recently updated.
}
override fun onCallFailed(call: VoiceCall?, exception: Exception) {
// Call that failed with an exception.
}
override fun onCallHoldUpdated(call: VoiceCall?) {
// Call that has been moved on hold because of accepting another incoming call.
}
When it is not longer needed:
voice.removeOnVoiceCallUpdateListener(this)
Receive a call
The application needs to receive push notifications via FCM. If you are not using FCM on your project refer to this Firebase topic.
The application receives a push notification via the FirebaseMessagingService
object as an indication of an incoming call. Once the application receives the push notification, it needs to check if the notification is for an incoming call. Use:
val isVoiceNotification = voice.isVoiceNotification(data)
If the notification is for an incoming call, it is passed along with its context to the Voice SDK. To process an incoming call the Voice SDK starts a Foreground Service which requires a notification to be displayed by the application. The notification is displayed for a very short time and may display text such as Incoming call. This notification can be replaced by another notification with Accept and Reject actions as soon as updates are received.
If you wish to present a view as soon as the incoming call is connected, use:
voice.setOnCallActionListener {
when (it) {
CallAction.PRESENT_INCOMING_CALL -> // Show Incoming Call Notification and UI
CallAction.MUTE_INCOMING_CALL -> // Mute Incoming Call Notification
}
}
Note: Set the
CallActionListener
before thereceiveCall
in order to present your notification or view.
Once the notification is ready, use the following:
voice.receiveCall(data, notification, object : CallCompletionHandler {
override fun onSuccess(call: VoiceCall) {
// Handle incoming call
}
override fun onFailure(call: VoiceCall?, exception: VoiceException) {
// Handle failure
}
})
Update contact information
For any active call, you can update the contact information by using the following:
val contact = VoiceContact("CONTACT_ID", "CONTACT_NAME", "CONTACT_AVATAR_URL", "CONTACT_PHONE_NUMBER")
voice.updateContact(call.uuid, contact)
Audio control
The Voice SDK allows you to switch your audio output during a call by using the following:
voice.setVoiceAudioOption(audioOption)
In order to receive audio updates use addOnVoiceCallAudioOptionListener
which takes the implementation of VoiceCallAudioOptionListener
:
voice.addOnVoiceCallAudioOptionListener(this)
Once the listener is set up, call updates are received by the following callbacks:
override fun onAudioChanged(audioOption: VoiceCallAudioOption) {
// Handle audio option
}
And when it is no longer needed:
voice.removeOnVoiceCallAudioOptionListener(this)
The SDK allows you to easily toggle between audio options. It follows the following:
VoiceCallAudioOption.EARPIECE
to VoiceCallAudioOption.SPEAKER
,
VoiceCallAudioOption.SPEAKER
to VoiceCallAudioOption.EARPIECE
,
VoiceCallAudioOption.BLUETOOTH
to VoiceCallAudioOption.EARPIECE
To toggle between audio options use:
voice.toggleAudioOption()
Note:
audioOption
is of the typeVoiceCallAudioOption
which consists of the values ofBLUETOOTH
,SPEAKER
, andEARPIECE
.
Update push notification token and phone number
After registration the push token and phone number that are provided during activation can be reconfigured.
To update the push token, add the following to the class which extends FirebaseMessagingService
:
override fun onNewToken(token: String) {
super.onNewToken(token)
...
voice.updatePushToken(token, object: CompletionHandler {
override fun onSuccess() {
// Handle success
}
override fun onFailure(e: ExceptionType) {
// Handle failure
}
})
}
To update the phone number, use the following:
voice.updatePhoneNumber(number, object : CompletionHandler {
override fun onSuccess() {
// Handle success
}
override fun onFailure(e: ExceptionType) {
// Handle faailure
}
})
Unregister and Deactivate Voice User
To deactivate or unregister a user, use the following method:
voice.deactivate(object : CompletionHandler {
override fun onSuccess() {
// Handle success
}
override fun onFailure(e: ExceptionType) {
// Handle failure
}
})
Proguard Rules
If minifyEnabled
is set to true
in your application:
- Add the following in your
proguard-rules.pro
file:
#noinspection ShrinkerUnresolvedReference
-keep class com.eght.voice.sdk.** { *; }
-keep class com.eght.sip.** { *; }
-keep class com.eght.call.** { *; }
- If the compiler complains about
META-INF/*
file collision after adding the proguard rules, you must add the following to your app-levelbuild.gradle
:
android {
...
packagingOptions {
pickFirst '**'
}
}
Shared Preferences
In order to persist data, it is recommended that the Voice SDK is excluded from allowBackup. If your application needs the attribute android:allowBackup="true"
in your AndroidManifest.xml
file, we recommend doing the following:
- Create an
xml
file under thexml
resource directory. We'll call itbackup_rules.xml
:<?xml version="1.0" encoding="utf-8"?> <full-backup-content> <exclude domain="sharedpref" path="voice-sdk-preferences.xml"/> </full-backup-content>
- Add the following attribute to your
AndroidManifest.xml
:<application ... android:fullBackupContent="@xml/backup_rules"> ... </application>
Note: If you have
android:allowBackup="false"
, you do not need to add this file nor add thefullBackupContent
attribute.
Updated about 2 years ago