Making an audio call
This guide shows you to how to make an audio call in your Android app. We assume you've already set up your Android app with the In-app Calling Android SDK.
If you haven't already, create an app first. Or, if you want, move on to handling incoming calls.
Setting up the UI
Before you can make a call, you need to set up the app's UI.
The UI part of the rest of the app's functionality (initiating and receiving an audio call) is handled inside another activity:LoggedInActivity
.Start with defining this activity inside your AndroidManifest.xml
file.app/src/main/AndroidManifest.xml
<activity android:name=".PlaceCallActivity"/>
Initiating an audio call
- Similarly as inside
LoginActivity
, create a basic layout containing an edit field for typing the callee username and a button that initates the call.
app/src/main/res/layout/main.xml
...
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_big"
android:layout_marginBottom="@dimen/input_layout_bottom"
android:hint="@string/enter_callee_id"
app:counterMaxLength="50"
app:endIconCheckable="true"
app:startIconDrawable="@android:drawable/presence_audio_online"
app:startIconTint="@color/colorPrimaryDark">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/callName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:imeOptions="actionDone"/>
</com.google.android.material.textfield.TextInputLayout>
...
<com.google.android.material.button.MaterialButton
android:id="@+id/callButton"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="false"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginStart="@dimen/margin_average"
android:layout_marginTop="@dimen/margin_small"
android:layout_marginEnd="@dimen/margin_average"
android:padding="@dimen/margin_base_plus"
android:text="@string/call"
android:textAlignment="center"
android:textColor="@color/white"
app:backgroundTint="@color/sinch_green"
app:icon="@drawable/ic_outline_phone_in_talk_24"
app:iconGravity="textEnd" />
- Inside SinchService's binder implementation add a method that uses call controller to initiate the call:
app/src/main/java/com/sinch/rtc/sample/push/SinchService.kt
fun callUser(userId: String): Call {
val sinchClient = sinchClient ?: throw RuntimeException("Sinch Client is not created")
return sinchClient.callController.callUser(userId, MediaConstraints(false))
}
- Bind the call button with the method and assign a
CallListener
to be notified about the changes of the call state:
app/src/main/java/com/sinch/rtc/sample/push/PlaceCallActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
...
callButton.apply {
isEnabled = false
setOnClickListener(buttonClickListener)
}
}
private fun callButtonClicked() {
val userName = calleeNameEditText.text.toString()
..
val call = sinchServiceInterface?.callUser(userName)
..
startActivity(callScreen)
}
Managing required permissions
If you try to initiate an audio call by pressing the call button at this point the application would crash with the following error output:
Process: com.sinch.rtc.demovvsdk, PID: 876
com.sinch.android.rtc.MissingPermissionException: Requires permission: android.permission.RECORD_AUDIO
Although we already handled some of the permissions in an earlier step (Internet permissions), the difference here is that RECORD_AUDIO permission is an example of a runtime permission that must be handled during the user's interaction with the app.
- Modify the Android Manifest file by decalring usage of the RECORD_AUDIO permission.
app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
- Before the user logs in ask for the permission explicitly and start the client only if it was granted.
app/src/main/java/com/sinch/rtc/sameple/push/BaseActivity.kt
private val messenger = Messenger(object : Handler() {
override fun handleMessage(msg: Message) {
when (msg.what) {
SinchService.MESSAGE_PERMISSIONS_NEEDED -> {
val requiredPermission = msg.data.getString(SinchService.REQUIRED_PERMISSION)
ActivityCompat.requestPermissions(
this@BaseActivity, arrayOf(
requiredPermission,
Manifest.permission.POST_NOTIFICATIONS
), 0
)
}
else -> {}
}
}
})
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<String>,
grantResults: IntArray
) {
...
sinchServiceInterface?.retryStartAfterPermissionGranted()
}
Note:
In depth overview of possible permission grant results and general handling workflow can be found on the offical Android documentation website.
Next steps
Now that you've made a call, you can set up your application to handle incoming calls.