Quickstart: Get started with calling composite

Get started with Azure Communication Services by using the UI Library to quickly integrate communication experiences into your applications. In this quickstart, you'll learn how to integrate the Calling composite into your Android application.

The UI library will render a full communication experience right into your application. It takes care of connecting to the desired call and setting it up behind the scenes. As a developer you just need to worry about where in your experience you want the communication experience to launch. The composite takes the user through setting up their devices, joining the call and participating in it, and rendering other participants.

Important

Functionality described on this document is currently in private preview. Private preview includes access to SDKs and documentation for testing purposes that are not yet available publicly. Apply to become an early adopter by filling out the form for preview access to Azure Communication Services.

Prerequisites

Setting up

Creating an Android app with an empty activity

In Android Studio, create a new project and select the Empty Activity.

Start a new Android Studio Project

Click the Next button and name the project UILibraryQuickStart, set language to Java/Kotlin and select Minimum SDK "API 23: Android 6.0 (Marshmallow)" or greater.

Screenshot showing the 'Finish' button selected in Android Studio.

Click Finish.

Maven repository credentials

Install the packages

In your app level (app folder) build.gradle, add the following lines to the dependencies and android sections.

android {
    ...
    packagingOptions {
        pickFirst  'META-INF/*'
    }
    ...
}
dependencies {
    ...
    implementation 'com.azure.android:azure-communication-ui:1.0.0-alpha.1'
    ...
}

In your project setting level (app folder) settings.gradle, add the following lines to the repositories.

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        ...
        maven {
            url "https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1"
        }
        maven {
            name='github'
            url = 'https://maven.pkg.github.com/Azure/communication-preview'
            credentials {
                username '<your GitHub user name>'
                password '<your personal access token>'
            }
        }
        ...
    }
}

Sync project with gradle files. (Android Studio -> File -> Sync Project With Gradle Files)

Add a button to the activity_main

Go to the layout file (app/src/main/res/layout/activity_main.xml). Here we'll drop the following code to create a button to start composite.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/startButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Launch"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Initialize composite

Go to MainActivity. Here we'll drop the following code to initialize our Composite Components for Calling. Replace "GROUP_CALL_ID" with your group ID for your call, "DISPLAY_NAME" with your name, and "<USER_ACCESS_TOKEN>" with your token.

package com.example.uilibraryquickstart

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import com.azure.android.communication.common.CommunicationTokenCredential
import com.azure.android.communication.common.CommunicationTokenRefreshOptions
import com.azure.android.communication.ui.CallCompositeBuilder
import com.azure.android.communication.ui.CallComposite
import com.azure.android.communication.ui.GroupCallOptions
import java.util.UUID

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        val startButton: Button = findViewById(R.id.startButton)
        startButton.setOnClickListener { l -> startCallComposite() }
    }

    private fun startCallComposite() {
        val communicationTokenRefreshOptions = CommunicationTokenRefreshOptions({ fetchToken() }, true)
        val communicationTokenCredential = CommunicationTokenCredential(communicationTokenRefreshOptions)
        val options = GroupCallOptions(
            this,
            communicationTokenCredential,
            "DISPLAY_NAME",
            UUID.fromString("GROUP_CALL_ID")
        )

        val callComposite: CallComposite = CallCompositeBuilder().build()
        callComposite.launch(options)
    }

    private fun fetchToken(): String? {
        return "USER_ACCESS_TOKEN"
    }
}

Run the code

Build and start application from Android Studio.

  • Click Launch.
  • Accept audio permissions and select device, mic, and video settings.
  • Click Join Call.

Sample application code can be found here

Launch

Object Model

The following classes and interfaces handle some of the major features of the Azure Communication Services Android UI:

Name Description
CallComposite Composite component that renders a call experience with participant gallery and controls.
CallCompositeBuilder Builder to build CallComposite with options.
GroupCallOptions Passed in CallComposite launch to start group call.
TeamsMeetingOptions Passed to CallComposite launch to join Teams meeting meeting.
ThemeConfiguration Injected as optional in CallCompositeBuilder to change primary color of composite.

UI Library functionality

Create Call Composite

Initialize a CallCompositeBuilder instance and a CallComposite instance inside the startCallComposite function.

val callComposite: CallComposite = CallCompositeBuilder().build()

Setup authentication

Initialize a CommunicationTokenCredential instance inside the startCallComposite function. Replace "<USER_ACCESS_TOKEN>" with your token.

val callComposite: CallComposite = CallCompositeBuilder().build()

val communicationTokenRefreshOptions = CommunicationTokenRefreshOptions(this::fetchToken, true)

val communicationTokenCredential = CommunicationTokenCredential(communicationTokenRefreshOptions)

Setup Group Call or Teams Meeting Options

Depending on what type of Call/Meeting you would like to setup, use the appropriate options object.

Group Call

Initialize a GroupCallOptions instance inside the startCallComposite function.

Replace "GROUP_CALL_ID" with your group ID for your call.

Replace "DISPLAY_NAME" with your name.

val options = GroupCallOptions(
            this,
            communicationTokenCredential,
            "DISPLAY_NAME",
            UUID.fromString("GROUP_CALL_ID")
        )

Teams Meeting

Initialize a TeamsMeetingOptions instance inside the startCallComposite function. Replace "TEAMS_MEETING_LINK" with your group ID for your call.

Replace "DISPLAY_NAME" with your name.

val options = TeamsMeetingOptions(
            this,
            communicationTokenCredential,
            "DISPLAY_NAME",
           "TEAMS_MEETING_LINK"
        )

A Microsoft Teams meeting link can be retrieved using Graph APIs. This process is detailed in Graph documentation.

The Communication Services Call SDK accepts a full Microsoft Teams meeting link. This link is returned as part of the onlineMeeting resource, accessible under the joinWebUrl property You can also get the required meeting information from the Join Meeting URL in the Teams meeting invite itself.

Launch

Call launch on the CallComposite instance inside the startCallComposite function

callComposite.launch(options)

Subscribe to events from CallComposite

To receive events, inject a handler to the CallCompositeBuilder.

val communicationCallComposite: CallComposite =
            CallCompositeBuilder()
                .callCompositeEventsHandler(ApplicationCallCompositeEventsHandler())
                .build()

...

class ApplicationCallCompositeEventsHandler : CallCompositeEventsHandler {
    override fun onException(eventArgs: OnExceptionEventArgs) {
        //...
    }
}

Apply theme configuration

To change the primary color of composite, create a new theme style in src/main/res/values/themes.xml and src/main/res/values-night/themes.xml by considering AzureCommunicationUI.Theme.Calling as parent theme. To apply theme, inject the theme ID in CallCompositeBuilder.

<style name="MyCompany.CallComposite" parent="AzureCommunicationUI.Theme.Calling">
    <item name="azure_communication_ui_calling_primary_color">@color/purple_500</item>
</style>
val communicationCallComposite: CallComposite =
        CallCompositeBuilder()
            .theme(ThemeConfiguration(R.style.MyCompany_CallComposite))
            .build()

Prerequisites

Setting up

Creating the Xcode project

In Xcode, create a new iOS project and select the App template. We will be using UIKit storyboards. You're not going to create tests during this quickstart. Feel free to uncheck Include Tests.

Screenshot showing the New Project template selection within Xcode.

Name the project UILibraryQuickStart and select Storyboard under the Interface dropdown.

Screenshot showing the New Project details within Xcode.

Install the package and dependencies with CocoaPods

  1. Create a Podfile in your project root directory by running pod init.
  2. Add the following to your Podfile:
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/Azure/AzurePrivatePodspecs.git'

platform :ios, '13.0'

target 'UILibraryQuickStart' do
    use_frameworks!
    pod 'AzureCommunicationUI', '1.0.0-alpha.1'
end
  1. Run pod install --repo-update. (This process may take 10-15 min.)
  2. Open the generated .xcworkspace with Xcode.

Request access to the microphone, camera, etc.

To access the device's hardware, update your app's Information Property List. Set the associated value to a string that will be included in the dialog the system uses to request access from the user.

Right-click the Info.plist entry of the project tree and select Open As > Source Code. Add the following lines the top level <dict> section, and then save the file.

<key>NSCameraUsageDescription</key>
<string></string>
<key>NSMicrophoneUsageDescription</key>
<string></string>

Turn off Bitcode

Set Enable Bitcode option to No in the project Build Settings. To find the setting, you have to change the filter from Basic to All, you can also use the search bar on the right.

Screenshot showing the BitCode option in Xcode.

Initialize composite

Go to 'ViewController'. Here we'll drop the following code to initialize our Composite Components for Call. Replace <GROUP_CALL_ID> with either your call group ID or UUID() to generate one. Also replace <DISPLAY_NAME> with your name, and <USER_ACCESS_TOKEN> with your token.

import UIKit
import AzureCommunicationCalling
import CallingComposite

class ViewController: UIViewController {

    private var callComposite: CallComposite?

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(frame: CGRect(x: 100, y: 100, width: 200, height: 50))
        button.contentEdgeInsets = UIEdgeInsets(top: 10.0, left: 20.0, bottom: 10.0, right: 20.0)
        button.layer.cornerRadius = 10
        button.backgroundColor = .systemBlue
        button.setTitle("Start Experience", for: .normal)
        button.addTarget(self, action: #selector(startCallComposite), for: .touchUpInside)

        button.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(button)
        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

    @objc private func startCallComposite() {
        let callCompositeOptions = CallCompositeOptions()

        callComposite = CallComposite(withOptions: callCompositeOptions)

        let communicationTokenCredential = try! CommunicationTokenCredential(token: "<USER_ACCESS_TOKEN>")

        let options = GroupCallOptions(communicationTokenCredential: communicationTokenCredential,
                                       displayName: "<DISPLAY_NAME>",
                                       groupId: "<GROUP_CALL_ID>")
        callComposite?.launch(with: options)
    }
}

Run the code

You can build and run your app on iOS simulator by selecting Product > Run or by using the (⌘-R) keyboard shortcut.

  1. Tap Start Experience.
  2. Accept audio permissions and select device, mic, and video settings.
  3. Tap Start Call.

Final look and feel of the quick start app

Sample application code can be found here

Object Model

The following classes and interfaces handle some of the major features of the Azure Communication Services UI client library:

Name Description
CallComposite The composite renders a call experience with participant gallery and controls.
CallCompositeOptions Includes options such as the theme configuration and the events handler.
CallCompositeEventsHandler Allows you to receive events from composite.
GroupCallOptions The options for joining a group call, such as groupId.
TeamsMeetingOptions The options for joining a Team's meeting, such as the meeting link.
ThemeConfiguration Allows you to customize the theme.

UI Library functionality

Create call composite

Initialize a CallCompositeOptions instance and a CallComposite instance inside the startCallComposite function.

@objc private func startCallComposite() {
    let callCompositeOptions = CallCompositeOptions()

    callComposite = CallComposite(withOptions: callCompositeOptions)
}

Setup authentication

Initialize a CommunicationTokenCredential instance inside the startCallComposite function. Replace <USER_ACCESS_TOKEN> with your token.

let communicationTokenCredential = try! CommunicationTokenCredential(token: "<USER_ACCESS_TOKEN>")

Refer to the user access token documentation if you don't already have a token available.

Setup group call or Teams meeting options

Depending on what type of Call/Meeting you would like to setup, use the appropriate options object.

Group call

Initialize a GroupCallOptions instance inside the startCallComposite function. Replace <GROUP_CALL_ID> with your group ID for your call and <DISPLAY_NAME> with your name.

let options = GroupCallOptions(communicationTokenCredential: communicationTokenCredential,
                               displayName: displayName,
                               groupId: uuid)

Teams meeting

Initialize a TeamsMeetingOptions instance inside the startCallComposite function. Replace <TEAMS_MEETING_LINK> with your group ID for your call and <DISPLAY_NAME> with your name.

let options = TeamsMeetingOptions(communicationTokenCredential: communicationTokenCredential,
                                  displayName: displayName,
                                  meetingLink: link)

A Microsoft Teams meeting link can be retrieved using Graph APIs. This process is detailed in Graph documentation. The Communication Services Calling SDK accepts a full Microsoft Teams meeting link. This link is returned as part of the onlineMeeting resource, accessible under the joinWebUrl property You can also get the required meeting information from the Join Meeting URL in the Teams meeting invite itself.

Launch

Call launch on the CallComposite instance inside the startCallComposite function

callComposite?.launch(with: options)

Subscribe to events from CallComposite

You can implement the closures from CallCompositeEventsHandler to act on the events and pass the implementation to CallCompositeOptions. An event for when the composite ended with an error is an example.

let handler = CallCompositeEventsHandler(didFail: { error in
            print("didFail with error:\(error)")
        })
let callCompositeOptions = CallCompositeOptions(callCompositeEventsHandler: handler)

Apply theme configuration

You can customize the theme by creating a custom theme configuration that implements the ThemeConfiguration protocol. You then include an instance of that new class in your CallCompositeOptions.

class CustomThemeConfiguration: ThemeConfiguration {
   var primaryColor: UIColor {
       return UIColor.red
   }
}
let callCompositeOptions = CallCompositeOptions(themeConfiguration: CustomThemeConfiguration())

Clean up resources

If you want to clean up and remove a Communication Services subscription, you can delete the resource or resource group.

Deleting the resource group also deletes any other resources associated with it. Learn more about cleaning up resources.