Precall Setup - Android
Picture this: before diving into the depths of a video call, imagine giving your setup a quick check-up, like a tech-savvy doctor ensuring all systems are a go. That's essentially what a precall experience does- it’s like your extensive debug session before the main code execution—a crucial step in ensuring your app's performance is top-notch.
Why is it necessary?
Why invest time and effort into crafting a precall experience, you wonder? Well, picture this scenario: your users eagerly join a video call, only to encounter a myriad of technical difficulties—muted microphones, pixelated cameras, and laggy connections. Not exactly the smooth user experience you had in mind, right?
By integrating a robust precall process into your app, developers become the unsung heroes, preemptively addressing potential pitfalls and ensuring that users step into their video calls with confidence.
Step-by-Step Guide: Integrating Precall Feature
Step 1: Check and Request Permissions
- Begin by ensuring that your application has the necessary permissions to access user devices, such as the camera, microphone and Bluetooth.
- Utilize the
checkPermissions()
method of theVideoSDK
class to verify if permissions are granted. - If the permissions are not granted, the method will request the required permissions.
PermissionHandler
is used to manage and handle permission-related events (such as granting, denying, or blocking permissions).onGranted()
: This method is called when all requested permissions are granted.onBlocked()
: This method is called when one or more permissions are permanently blocked (i.e., the user has checked "Don't ask again").onDenied()
: This method is called when one or more permissions are denied.onJustBlocked()
: This method is called when one or more permissions are just blocked (i.e., the user has just checked "Don't ask again" for the first time).
- Kotlin
- Java
private fun checkPermissions() {
val permissionList: MutableList<Permission> = ArrayList()
permissionList.add(Permission.audio)
permissionList.add(Permission.video)
permissionList.add(Permission.bluetooth)
val options = Permissions.Options()
.setRationaleDialogTitle("Info")
.setSettingsDialogTitle("Warning")
VideoSDK.checkPermissions(this,
permissionList,
options,
permissionHandler
)
}
private val permissionHandler: PermissionHandler = object : PermissionHandler() {
override fun onGranted() {
Log.d("VideoSDK Permission", "onGranted: All permissions granted")
}
override fun onBlocked(
context: Context,
blockedList: java.util.ArrayList<Permission>
): Boolean {
for (blockedPermission in blockedList) {
Log.d("VideoSDK Permission", "onBlocked: $blockedPermission")
}
return super.onBlocked(context, blockedList)
}
override fun onDenied(
context: Context,
deniedPermissions: java.util.ArrayList<Permission>
) {
for (deniedPermission in deniedPermissions) {
Log.d("VideoSDK Permission", "onDenied: $deniedPermission")
}
super.onDenied(context, deniedPermissions)
}
override fun onJustBlocked(
context: Context,
justBlockedList: java.util.ArrayList<Permission>,
deniedPermissions: java.util.ArrayList<Permission>
) {
for (justBlockedPermission in justBlockedList) {
Log.d("VideoSDK Permission", "onJustBlocked: $justBlockedPermission")
}
super.onJustBlocked(context, justBlockedList, deniedPermissions)
}
}
private void checkPermissions() {
List<Permission> permissionList = new ArrayList<>();
permissionListSDK.add(Permission.audio);
permissionListSDK.add(Permission.video);
permissionListSDK.add(Permission.bluetooth);
Permissions.Options options = new Permissions
.Options()
.setRationaleDialogTitle("Info")
.setSettingsDialogTitle("Warning");
VideoSDK.checkPermissions(this, permissionList, options, permissionHandler);
}
PermissionHandler permissionHandler = new PermissionHandler() {
@Override
public void onGranted() {
Log.d("VideoSDK Permission", "onGranted: All permissions granted")
}
@Override
public boolean onBlocked(Context context, ArrayList<Permission> blockedList) {
for (Permission blockedPermission : blockedList) {
Log.d("VideoSDK Permission", "onBlocked: " + blockedPermission);
}
return super.onBlocked(context, blockedList);
}
@Override
public void onDenied(Context context, ArrayList<Permission> deniedPermissions) {
for (Permission deniedPermission : deniedPermissions) {
Log.d("VideoSDK Permission", "onDenied: " + deniedPermission);
}
super.onDenied(context, deniedPermissions);
}
@Override
public void onJustBlocked(Context context, ArrayList<Permission> justBlockedList, ArrayList<Permission> deniedPermissions) {
for (Permission justBlockedPermission : justBlockedList) {
Log.d("VideoSDK Permission", "onJustBlocked: " + justBlockedPermission);
}
super.onJustBlocked(context, justBlockedList, deniedPermissions);
}
};
Step 2: Render Device Lists
- You can fetch and render lists of available video and audio devices using the
getVideoDevices()
andgetAudioDevices()
methods of the VideoSDK class, respectively.
- Kotlin
- Java
private fun getAudioaDevices() {
val audioDevices: Set<AudioDeviceInfo> = VideoSDK.getAudioDevices()
for (audioDevice in audioDevices) {
Log.d("VideoSDK", "Audio Device's DeviceId " + audioDevice.deviceId)
Log.d("VideoSDK", "Audio Device's Label " + audioDevice.label)
Log.d("VideoSDK", "Audio Device's Kind " + audioDevice.kind)
}
}
private fun getVideoDevices() {
val videoDevices: Set<VideoDeviceInfo> = VideoSDK.getVideoDevices()
for (videoDevice in videoDevices) {
Log.d("VideoSDK", "Video Device's DeviceId " + videoDevice.deviceId)
Log.d("VideoSDK", "Video Device's Label " + videoDevice.label)
Log.d("VideoSDK", "Video Device's Kind " + videoDevice.kind)
}
}
private void getAudioDevices() {
Set<AudioDeviceInfo> audioDevices = VideoSDK.getAudioDevices();
for (AudioDeviceInfo audioDevice:
audioDevices) {
Log.d("VideoSDK", "Audio Device's DeviceId " + audioDevice.getDeviceId());
Log.d("VideoSDK", "Audio Device's Label " + audioDevice.getLabel());
Log.d("VideoSDK", "Audio Device's Kind " + audioDevice.getKind());
}
}
private void getVideoDevices() {
Set<VideoDeviceInfo> videoDevices = VideoSDK.getVideoDevices();
for (VideoDeviceInfo videoDevice:
videoDevices) {
Log.d("VideoSDK", "Video Device's DeviceId " + videoDevice.getDeviceId());
Log.d("VideoSDK", "Video Device's Label " + videoDevice.getLabel());
Log.d("VideoSDK", "Video Device's Kind " + videoDevice.getKind());
}
}
Step 3: Handle Audio Device Changes
- Implement the
onAudioDeviceChanged()
callback of theVideoSDK
class to dynamically re-render audio device lists whenever new devices are attached or removed from the system. - Ensure that users can seamlessly interact with newly connected devices without disruptions.
- Kotlin
- Java
VideoSDK.setAudioDeviceChangeListener(object : VideoSDK.AudioDeviceChangeEvent {
override fun onAudioDeviceChanged(
selectedAudioDevice: AudioDeviceInfo?,
audioDevices: MutableSet<AudioDeviceInfo>?
) {
Log.d(
"VideoSDK",
"Selected Audio Device: " + selectedAudioDevice.label
)
for (audioDevice in audioDevices) {
Log.d("VideoSDK", "Audio Devices" + audioDevice.label)
}
}
})
VideoSDK.setAudioDeviceChangeListener((selectedAudioDevice, audioDevices) -> {
Log.d("VideoSDK", "Selected Audio Device: " + selectedAudioDevice.getLabel());
for (AudioDeviceInfo audioDevice :
audioDevices) {
Log.d("VideoSDK", "Audio Devices" + audioDevice.getLabel());
}
});
Step 4: Ensuring the selected devices are used in the Meeting
- Ensure that the status of all relevant devices, such as the microphone and camera (on/off), as well as the selected devices, are correctly configured and passed into the meeting from the precall screen.
- To select a video device, you can either create a custom track with the chosen
VideoDeviceInfo
and pass it to theinitMeeting
method of theVideoSDK
class, or you can use thesetSelectedVideoDevice()
method of theVideoSDK
class. - To select an audio device, use the
setSelectedAudioDevice()
method of theVideoSDK
class. - By ensuring this integration, users can seamlessly transition from the precall setup to the actual meeting while preserving their preferred settings.
- Kotlin
- Java
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val customTracks: MutableMap<String, CustomStreamTrack> = HashMap()
// Specify the video device to use in the meeting
val videoDeviceInfo: VideoDeviceInfo = selectedVideoDeviceInfo
val videoCustomTrack = VideoSDK.createCameraVideoTrack(
"h720p_w960p", "front", CustomStreamTrack.VideoMode.TEXT, true,
this, VideoSDK.getSelectedVideoDevice()
)
customTracks["video"] = videoCustomTrack
VideoSDK.setSelectedVideoDevice(videoDeviceInfo)
// Specify the audio device to use in the meeting
val audioDeviceInfo: AudioDeviceInfo = selectedAudioDeviceInfo
VideoSDK.setSelectedAudioDevice(audioDeviceInfo)
val meeting: Meeting = VideoSDK.initMeeting(
this@MainActivity, "meetingId", "John Due", true,
true, null, null, false, customTracks, null
);
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Map<String, CustomStreamTrack> customTracks = new HashMap<>();
// Specify the video device to use in the meeting
VideoDeviceInfo videoDeviceInfo = selectedVideoDeviceInfo;
CustomStreamTrack videoCustomTrack = VideoSDK.createCameraVideoTrack(
"h720p_w960p", "front", CustomStreamTrack.VideoMode.TEXT, true,
this, VideoSDK.getSelectedVideoDevice()
);
customTracks.put("video", videoCustomTrack);
VideoSDK.setSelectedVideoDevice(videoDeviceInfo);
// Specify the audio device to use in the meeting
AudioDeviceInfo audioDeviceInfo = selectedAudioDeviceInfo;
VideoSDK.setSelectedAudioDevice(audioDeviceInfo);
Meeting meeting = VideoSDK.initMeeting(
MainActivity.this, "meetingId", "John Due",true,
true, null, null, false, customTracks,null
);
}
}
Step 5: Get Selected Devices
- VideoSDK library provides two methods,
getSelectedVideoDevice()
andgetSelectedAudioDevice()
, which allow us to determine which video and audio devices are currently selected on our Android device.
- Kotlin
- Java
private fun getSelectedVideoDevice(){
Log.d("TAG", "onCreate: " + VideoSDK.getSelectedVideoDevice().label)
}
private fun getSelectedAudioDevice(){
Log.d("TAG", "onCreate: " + VideoSDK.getSelectedAudioDevice().label)
}
private void getSelectedVideoDevice() {
VideoDeviceInfo selectedVideoDevice = VideoSDK.getSelectedVideoDevice();
Log.d("TAG", "Selected Video Device Label: " + selectedVideoDevice.getLabel());
}
private void getSelectedAudioDevice() {
AudioDeviceInfo selectedAudioDevice = VideoSDK.getSelectedAudioDevice();
Log.d("TAG", "Selected Audio Device Label: " + selectedAudioDevice.getLabel());
}
By following these step-by-step instructions, you can seamlessly integrate a precall feature into your application, empowering users to optimize their audio and video setup for a superior communication experience.
You can explore the complete implementation of the Precall feature in the official Android SDK example available here.
API Reference
The API references for all the methods utilized in this guide are provided below.
Got a Question? Ask us on discord