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.
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"/>
- 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)
}
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()
}
In depth overview of possible permission grant results and general handling workflow can be found on the offical Android documentation website.
Now that you've made a call, you can set up your application to handle incoming calls.