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=".LoggedInActivity"/>
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/activity_logged_in.xml
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter callee name" />
<EditText
android:id="@+id/calleeIdEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Callee name" />
<Button
android:id="@+id/callButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Call" />
</LinearLayout>
- Inside SinchService's binder implementation add a method that uses call client to initiate the call:
app/src/main/java/com/sinch/rtc/demovvsdk/SinchService.kt
inner class SinchServiceBinder : Binder() {
fun callUser(username: String): Call? {
return sinchClient?.callClient?.callUser(username)
}
}
- 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/demovvsdk/LoggedInActivity.kt
binding.callButton.setOnClickListener {
val call = serviceBinder?.
callUser(binding.calleeIdEditText.text.toString())
call?.addCallListener(LoggedInCallListener())
}
private inner class LoggedInCallListener: CallListener {
override fun onCallProgressing(p0: Call?) {
Log.d(TAG, "onCallProgressing")
}
override fun onCallEstablished(p0: Call?) {
Log.d(TAG, "onCallEstablished")
}
override fun onCallEnded(call: Call?) {
Log.d(TAG, "onCallEnded ${call?.details?.endCause}")
}
}
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"/>
- Once the user presses the call button, ask for the permission explicitly and invoke binder's
callUser
method only if it was granted.
app/src/main/java/com/sinch/rtc/demovvsdk/LoggedInActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Layout initialization
binding.callButton.setOnClickListener {
requestPermissions(
arrayOf(Manifest.permission.RECORD_AUDIO),
REQUEST_CODE
)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions,
grantResults)
if (requestCode == REQUEST_CODE && grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
val call = serviceBinder?.callUser(
binding.calleeIdEditText.text.toString()
)
call?.addCallListener(LoggedInCallListener()
)
} else {
//Adopt UI to handle non granted permissions
}
}
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.