Quickstart: Add voice calling to your app
Get started with Azure Communication Services by using the Communication Services Calling SDK to add voice and video calling to your app.
Important
Azure Communication Services supports emergency calling to emergency numbers in the United States, Puerto Rico, Canada, and the United Kingdom only.
Azure Communication Services voice calling (PSTN) can be used to dial emergency number 911 in the United States, Puerto Rico, and Canada, and to dial emergency numbers 999 and 112 in the United Kingdom. Azure Communication Services doesn't currently support dialing those emergency numbers from outside those countries or regions, or dialing emergency services in other countries or regions.
Important
Functionality described in this document is currently in public preview. This preview version is provided without a service-level agreement, and we don't recommend it for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
In this quickstart, you learn how to start a call using the Azure Communication Services Calling SDK for Windows.
UWP sample code
You can download the sample app from GitHub.
Prerequisites
To complete this tutorial, you need the following prerequisites:
An Azure account with an active subscription. Create an account for free.
Install Visual Studio 2019 with Universal Windows Platform development workload.
A deployed Communication Services resource. Create a Communication Services resource. You need to record your connection string for this quickstart.
A User Access Token for your Azure Communication Service. You can also use the Azure CLI and run the command with your connection string to create a user and an access token.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
For details, see Use Azure CLI to Create and Manage Access Tokens.
Setting up
Creating the project
In Visual Studio, create a new project with the Blank App (Universal Windows) template to set up a single-page Universal Windows Platform (UWP) app.
Install the package
Right select your project and go to Manage Nuget Packages
to install Azure.Communication.Calling
1.0.0-beta.33 or superior. Make sure Include Preleased is checked.
Request access
Go to Package.appxmanifest
and select Capabilities
.
Check Internet (Client & Server)
to gain inbound and outbound access to the Internet. Check Microphone
to access the audio feed of the microphone.
Set up the app framework
We need to configure a basic layout to attach our logic. In order to place an outbound call, we need a TextBox
to provide the User ID of the callee. We also need a Start Call
button and a Hang Up
button.
Open the MainPage.xaml
of your project and add the Grid
node to your Page
:
<Page
x:Class="CallingQuickstart.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CallingQuickstart"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Width="800" Height="600">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60*"/>
<RowDefinition Height="200*"/>
<RowDefinition Height="60*"/>
</Grid.RowDefinitions>
<TextBox x:Name="CalleeTextBox" Text="Who would you like to call?" TextWrapping="Wrap" VerticalAlignment="Center" Grid.Row="0" Height="40" Margin="10,10,10,10" />
<Grid Grid.Row="1">
</Grid>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Button x:Name="CallButton" Content="Start Call" Click="CallButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="200"/>
<Button x:Name="HangupButton" Content="Hang Up" Click="HangupButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="200"/>
<TextBlock x:Name="State" Text="Status" TextWrapping="Wrap" VerticalAlignment="Center" Margin="40,0,0,0" Height="40" Width="200"/>
</StackPanel>
</Grid>
</Page>
Open to App.xaml.cs
(right click over the file and choose View Code) and add this line to the top:
using CallingQuickstart;
Open the MainPage.xaml.cs
and replace the content with following implementation:
using Azure.Communication.Calling;
using Azure.WinRT.Communication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace CallingQuickstart
{
public sealed partial class MainPage : Page
{
CallAgent callAgent;
Call call;
DeviceManager deviceManager;
public MainPage()
{
this.InitializeComponent();
Task.Run(() => this.InitCallAgentAndDeviceManagerAsync()).Wait();
}
private async Task InitCallAgentAndDeviceManagerAsync()
{
// Create and cache CallAgent and optionally fetch DeviceManager
}
private async void CallButton_Click(object sender, RoutedEventArgs e)
{
// Start call
}
private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
// End the current call
}
private async void Call_OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
{
// Update call state
}
}
}
Object model
The next table listed the classes and interfaces handle some of the major features of the Azure Communication Services Calling SDK:
Name | Description |
---|---|
CallClient |
The CallClient is the main entry point to the Calling SDK. |
CallAgent |
The CallAgent is used to start and manage calls. |
CommunicationTokenCredential |
The CommunicationTokenCredential is used as the token credential to instantiate the CallAgent . |
CommunicationUserIdentifier |
The CommunicationUserIdentifier is used to represent the identity of the user, which can be one of the following options: CommunicationUserIdentifier , PhoneNumberIdentifier , CallingApplication . |
Authenticate the client
Initialize a CallAgent
instance with a User Access Token that enables us to make and receive calls, and optionally obtain a DeviceManager instance to query for client device configurations.
In the code, replace <AUTHENTICATION_TOKEN>
with a User Access Token. Refer to the user access token documentation if you don't already have a token available.
Add the code to the InitCallAgentAndDeviceManagerAsync
function.
var callClient = new CallClient();
this.deviceManager = await callClient.GetDeviceManager();
var tokenCredential = new CommunicationTokenCredential("<AUTHENTICATION_TOKEN>");
var callAgentOptions = new CallAgentOptions()
{
DisplayName = "<DISPLAY_NAME>"
};
this.callAgent = await callClient.CreateCallAgent(tokenCredential, callAgentOptions);
Start a call
Add the implementation to the CallButton_Click
to start a call with the callAgent
we created, and hook up call state event handler.
var startCallOptions = new StartCallOptions();
var callees = new ICommunicationIdentifier[1] { new CommunicationUserIdentifier(CalleeTextBox.Text.Trim()) };
this.call = await this.callAgent.StartCallAsync(callees, startCallOptions);
this.call.OnStateChanged += Call_OnStateChangedAsync;
End a call
End the current call when the Hang Up
button is clicked. Add the implementation to the HangupButton_Click to end a call with the callAgent we created, and tear down the call state event handler.
this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());
Track call state
Stay notified about the state of current call.
var state = (sender as Call)?.State;
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
State.Text = state.ToString();
});
Run the code
You can build and run the code on Visual Studio. For solution platforms, we support ARM64
, x64
and x86
.
You can make an outbound call by providing a user ID in the text field and clicking the Start Call
button. Calling 8:echo123
connects you with an echo bot, this feature is great for getting started and verifying your audio devices are working.
WinUI 3 sample code
You can download the sample app from GitHub.
Prerequisites
To complete this tutorial, you need the following prerequisites:
An Azure account with an active subscription. Create an account for free.
Install Visual Studio 2022 and Windows App SDK version 1.2 preview 2.
Basic understanding of how to create a WinUI 3 app. Create your first WinUI 3 (Windows App SDK) project is a good resource to start with.
A deployed Communication Services resource. Create a Communication Services resource. You need to record your connection string for this quickstart.
A User Access Token for your Azure Communication Service. You can also use the Azure CLI and run the command with your connection string to create a user and an access token.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
For details, see Use Azure CLI to Create and Manage Access Tokens.
Setting up
Creating the project
In Visual Studio, create a new project with the Blank App, Packaged (WinUI 3 in Desktop) template to set up a single-page WinUI 3 app.
Install the package
Right click over your project and go to Manage Nuget Packages
to install Azure.Communication.Calling
1.0.0-beta.33 or superior. Make sure Include Preleased is checked.
Request access
Set up the app framework
We need to configure a basic layout to attach our logic. In order to place an outbound call, we need a TextBox
to provide the User ID of the callee. We also need a Start Call
button and a Hang Up
button.
Open the MainWindow.xaml
of your project and add the Grid
node to your Window
:
<Window
x:Class="CallingQuickstart.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CallingQuickstart"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60*"/>
<RowDefinition Height="200*"/>
<RowDefinition Height="60*"/>
</Grid.RowDefinitions>
<TextBox x:Name="CalleeTextBox" Text="Who would you like to call?" TextWrapping="Wrap" VerticalAlignment="Center" Height="40" Margin="10,10,10,10" />
<Grid Grid.Row="1">
</Grid>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Button x:Name="CallButton" Content="Start Call" Click="CallButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="200"/>
<Button x:Name="HangupButton" Content="Hang Up" Click="HangupButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="200"/>
<TextBlock x:Name="State" Text="Status" TextWrapping="Wrap" VerticalAlignment="Center" Margin="40,0,0,0" Height="40" Width="200"/>
</StackPanel>
</Grid>
</Window>
Open the MainWindow.xaml.cs
and replace the content with following implementation:
using Azure.Communication.Calling;
using Azure.WinRT.Communication;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Media.Core;
namespace CallingQuickstart
{
public sealed partial class MainWindow : Window
{
CallAgent callAgent;
Call call;
DeviceManager deviceManager;
public MainWindow()
{
this.InitializeComponent();
Task.Run(() => this.InitCallAgentAndDeviceManagerAsync()).Wait();
}
private async Task InitCallAgentAndDeviceManagerAsync()
{
// Create and cache CallAgent and optionally fetch DeviceManager
}
private async void CallButton_Click(object sender, RoutedEventArgs e)
{
// Start call
}
private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
// End call
}
private async void Call_OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
{
// Update call state
}
}
}
Object model
The following classes and interfaces handle some of the major features of the Azure Communication Services Calling SDK:
Name | Description |
---|---|
CallClient |
The CallClient is the main entry point to the Calling client library. |
CallAgent |
The CallAgent is used to start and join calls. |
Call |
The Call is used to manage placed or joined calls. |
CommunicationTokenCredential |
The CommunicationTokenCredential is used as the token credential to instantiate the CallAgent . |
CommunicationUserIdentifier |
The CommunicationUserIdentifier is used to represent the identity of the user, which can be one of the following options: CommunicationUserIdentifier , PhoneNumberIdentifier or CallingApplication . |
Authenticate the client
Initialize a CallAgent
instance with a User Access Token, which enables us to make and receive calls, and optionally obtain a DeviceManager instance to query for client device configurations.
In the following code, replace <AUTHENTICATION_TOKEN>
with a User Access Token. Refer to the user access token documentation if you don't already have a token available.
Add the following code to the InitCallAgentAndDeviceManagerAsync
function.
var callClient = new CallClient();
this.deviceManager = await callClient.GetDeviceManager();
var tokenCredential = new CommunicationTokenCredential("<AUTHENTICATION_TOKEN>");
var callAgentOptions = new CallAgentOptions()
{
DisplayName = "<DISPLAY_NAME>"
};
this.callAgent = await callClient.CreateCallAgent(tokenCredential, callAgentOptions);
this.callAgent.OnCallsUpdated += Agent_OnCallsUpdatedAsync;
this.callAgent.OnIncomingCall += Agent_OnIncomingCallAsync;
Start a call
Add the implementation to the CallButton_Click
to start a call with the callAgent
we created, and hook up call state event handler.
var startCallOptions = new StartCallOptions();
var callees = new ICommunicationIdentifier[1]
{
new CommunicationUserIdentifier(CalleeTextBox.Text.Trim())
};
this.call = await this.callAgent.StartCallAsync(callees, startCallOptions);
this.call.OnStateChanged += Call_OnStateChangedAsync;
End a call
End the current call when the Hang Up
button is clicked. Add the implementation to the HangupButton_Click to end a call with the callAgent we created, and tear down the call state event handler.
this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());
Track call state
Stay notified about the state of current call.
var state = (sender as Call)?.State;
this.DispatcherQueue.TryEnqueue(() => {
State.Text = state.ToString();
});
Run the code
You can build and run the code on Visual Studio. For solution platforms, we support ARM64
, x64
and x86
.
You can make an outbound call by providing a user ID in the text field and clicking the Start Call
button. Calling 8:echo123
connects you with an echo bot, this feature is great for getting started and verifying your audio devices are working.
In this quickstart, you learn how to start a call using the Azure Communication Services Calling SDK for JavaScript.
Sample code
You can download the sample app from GitHub.
Note
Outbound calling to an Azure Communication Services user can be accessed using the Azure Communication Services UI Library. The UI Library enables developers to add a call client that is VoIP enabled into their application with only a couple lines of code.
Prerequisites
An Azure account with an active subscription. Create an account for free.
Node.js active Long Term Support(LTS) versions are recommended.
An active Communication Services resource. Create a Communication Services resource. You need to record your connection string for this quickstart.
A User Access Token to instantiate the call client. Learn how to create and manage user access tokens. You can also use the Azure CLI and run the command with your connection string to create a user and an access token.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
For details, see Use Azure CLI to Create and Manage Access Tokens.
Setting up
Create a new Node.js application
Open your terminal or command window create a new directory for your app, and navigate to it.
mkdir calling-quickstart && cd calling-quickstart
Run npm init -y
to create a package.json file with default settings.
npm init -y
Install the package
Use the npm install
command to install the Azure Communication Services Calling SDK for JavaScript.
npm install @azure/communication-common --save
npm install @azure/communication-calling --save
The --save
option lists the library as a dependency in your package.json file.
Set up the app framework
This quickstart uses parcel to bundle the application assets. Run the following command to install it and list it as a development dependency in your package.json:
npm install parcel --save-dev
Create an index.html file in the root directory of your project. We'll use this file to configure a basic layout that will allow the user to place a call.
Here's the html, that we need to add to the index.html
file that we created:
<!DOCTYPE html>
<html>
<head>
<title>Communication Client - Calling Sample</title>
</head>
<body>
<h4>Azure Communication Services</h4>
<h1>Calling Quickstart</h1>
<input
id="token-input"
type="text"
placeholder="User access token"
style="margin-bottom:1em; width: 200px;"
/>
</div>
<button id="token-submit" type="button">
Submit
</button>
<input
id="callee-id-input"
type="text"
placeholder="Who would you like to call?"
style="margin-bottom:1em; width: 200px; display: block;"
/>
<div>
<button id="call-button" type="button" disabled="true">
Start Call
</button>
<button id="hang-up-button" type="button" disabled="true">
Hang Up
</button>
</div>
<script src="./app.js" type="module"></script>
</body>
</html>
Create a file in the root directory of your project called app.js to contain the application logic for this quickstart. Add the following code to import the calling client and get references to the DOM elements so we can attach our business logic.
import { CallClient, CallAgent } from "@azure/communication-calling";
import { AzureCommunicationTokenCredential } from '@azure/communication-common';
let call;
let callAgent;
let tokenCredential = "";
const userToken = document.getElementById("token-input");
const calleeInput = document.getElementById("callee-id-input");
const submitToken = document.getElementById("token-submit");
const callButton = document.getElementById("call-button");
const hangUpButton = document.getElementById("hang-up-button");
Object model
The following classes and interfaces handle some of the major features of the Azure Communication Services Calling SDK:
Name | Description |
---|---|
CallClient |
The CallClient is the main entry point to the Calling SDK. |
CallAgent |
The CallAgent is used to start and manage calls. |
AzureCommunicationTokenCredential |
The AzureCommunicationTokenCredential class implements the CommunicationTokenCredential interface, which is used to instantiate the CallAgent . |
Authenticate the client
You need to input a valid user access token for your resource into the text field and click 'Submit'. Refer to the user access token documentation if you don't already have a token available. Using the CallClient
, initialize a CallAgent
instance with a CommunicationTokenCredential
that enables to make and receive calls.
Add the following code to app.js:
submitToken.addEventListener("click", async () => {
const callClient = new CallClient();
const userTokenCredential = userToken.value;
try {
tokenCredential = new AzureCommunicationTokenCredential(userTokenCredential);
callAgent = await callClient.createCallAgent(tokenCredential);
callButton.disabled = false;
submitToken.disabled = true;
} catch(error) {
window.alert("Please submit a valid token!");
}
})
Start a call
Add an event handler to initiate a call when the callButton
is clicked:
callButton.addEventListener("click", () => {
// start a call
const userToCall = calleeInput.value;
// To call an Azure Communication Services communication user, use {communicationUserId: 'ACS_USER_ID'}.
// To call echo bot, use {id: '8:echo123'}.
call = callAgent.startCall(
[{ id: userToCall }],
{}
);
// toggle button states
hangUpButton.disabled = false;
callButton.disabled = true;
});
End a call
Add an event listener to end the current call when the hangUpButton
is clicked:
hangUpButton.addEventListener("click", () => {
// end the current call
call.hangUp({ forEveryone: true });
// toggle button states
hangUpButton.disabled = true;
callButton.disabled = false;
submitToken.disabled = false;
});
The forEveryone
property ends the call for all call participants.
Run the code
Use the command npx parcel index.html
to run your application.
Open your browser and navigate to http://localhost:1234/. You should see the following screen:
You can make an outbound VOIP call by providing a valid user access token and user ID in the corresponding text fields and clicking the Start Call button.
Calling 8:echo123
connects you with an echo bot, which is great for getting started and verifying your audio devices are working. Pass {id: '8:echo123'}
to the CallAgent.startCall() API to call echo bot.
To call an Azure Communication Services communication user, pass {communicationUserId: 'ACS_USER_ID'}
to the CallAgent.startCall()
API.
In this quickstart, you learn how to start a call using the Azure Communication Services Calling SDK for Android.
Sample Code
You can download the sample app from GitHub.
Prerequisites
An Azure account with an active subscription. Create an account for free.
Android Studio, for creating your Android application.
A deployed Communication Services resource. Create a Communication Services resource. You need to record your connection string for this quickstart.
A User Access Token for your Azure Communication Service. You can also use the Azure CLI and run the command with your connection string to create a user and an access token.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
For details, see Use Azure CLI to Create and Manage Access Tokens.
Setting up
Create an Android app with an empty activity
From Android Studio, select Start a new Android Studio project.
Select "Empty Activity" project template under "Phone and Tablet".
Select Minimum SDK of "API 26: Android 8.0 (Oreo)" or greater.
Install the package
Locate your project level build.gradle and make sure to add mavenCentral()
to the list of repositories under buildscript
and allprojects
buildscript {
repositories {
...
mavenCentral()
...
}
}
allprojects {
repositories {
...
mavenCentral()
...
}
}
Then, in your module level build.gradle add the following lines to the dependencies and android sections
android {
...
packagingOptions {
pickFirst 'META-INF/*'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
...
implementation 'com.azure.android:azure-communication-calling:1.0.0-beta.8'
...
}
Add permissions to application manifest
In order to request permissions required to make a call, they must be declared in the Application Manifest (app/src/main/AndroidManifest.xml
). Replace the content of file with the following code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.contoso.acsquickstart">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--Our Calling SDK depends on the Apache HTTP SDK.
When targeting Android SDK 28+, this library needs to be explicitly referenced.
See https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Set up the layout for the app
Two inputs are needed: a text input for the callee ID, and a button for placing the call. These inputs can be added through the designer or by editing the layout xml. Create a button with an ID of call_button
and a text input of callee_id
. Navigate to (app/src/main/res/layout/activity_main.xml
) and replace the content of file with the following code:
<?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/call_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Call"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/callee_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Callee Id"
android:inputType="textPersonName"
app:layout_constraintBottom_toTopOf="@+id/call_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Create the main activity scaffolding and bindings
With the layout created the bindings can be added as well as the basic scaffolding of the activity. The activity handles requesting runtime permissions, creating the call agent, and placing the call when the button is press ed. Each is covered in its own section. The onCreate
method is overridden to invoke getAllPermissions
and createAgent
and to add the bindings for the call button. This event occurs only once when the activity is created. For more information, on onCreate
, see the guide Understand the Activity Lifecycle.
Navigate to MainActivity.java and replace the content with the following code:
package com.contoso.acsquickstart;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.media.AudioManager;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.azure.android.communication.common.CommunicationUserIdentifier;
import com.azure.android.communication.common.CommunicationTokenCredential;
import com.azure.android.communication.calling.CallAgent;
import com.azure.android.communication.calling.CallClient;
import com.azure.android.communication.calling.StartCallOptions;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private CallAgent callAgent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getAllPermissions();
createAgent();
// Bind call button to call `startCall`
Button callButton = findViewById(R.id.call_button);
callButton.setOnClickListener(l -> startCall());
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}
/**
* Request each required permission if the app doesn't already have it.
*/
private void getAllPermissions() {
// See section on requesting permissions
}
/**
* Create the call agent for placing calls
*/
private void createAgent() {
// See section on creating the call agent
}
/**
* Place a call to the callee id provided in `callee_id` text input.
*/
private void startCall() {
// See section on starting the call
}
}
Request permissions at runtime
For Android 6.0 and higher (API level 23) and targetSdkVersion
23 or higher, permissions are granted at runtime instead of when the app is installed. In order to support it, getAllPermissions
can be implemented to call ActivityCompat.checkSelfPermission
and ActivityCompat.requestPermissions
for each required permission.
/**
* Request each required permission if the app doesn't already have it.
*/
private void getAllPermissions() {
String[] requiredPermissions = new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE};
ArrayList<String> permissionsToAskFor = new ArrayList<>();
for (String permission : requiredPermissions) {
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
permissionsToAskFor.add(permission);
}
}
if (!permissionsToAskFor.isEmpty()) {
ActivityCompat.requestPermissions(this, permissionsToAskFor.toArray(new String[0]), 1);
}
}
Note
When designing your app, consider when these permissions should be requested. Permissions should be requested as they are needed, not ahead of time. For more information, see, the Android Permissions Guide.
Object model
The following classes and interfaces handle some of the major features of the Azure Communication Services Calling SDK:
Name | Description |
---|---|
allClient |
The CallClient is the main entry point to the Calling SDK. |
CallAgent |
The CallAgent is used to start and manage calls. |
CommunicationTokenCredential |
The CommunicationTokenCredential is used as the token credential to instantiate the CallAgent . |
CommunicationIdentifier |
The CommunicationIdentifier is used as different type of participant that could be part of a call. |
Create an agent from the user access token
With a user token, an authenticated call agent can be instantiated. Generally this token is generated from a service with authentication specific to the application. For more information on user access tokens, check the User Access Tokens guide.
For the quickstart, replace <User_Access_Token>
with a user access token generated for your Azure Communication Service resource.
/**
* Create the call agent for placing calls
*/
private void createAgent() {
String userToken = "<User_Access_Token>";
try {
CommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);
callAgent = new CallClient().createCallAgent(getApplicationContext(), credential).get();
} catch (Exception ex) {
Toast.makeText(getApplicationContext(), "Failed to create call agent.", Toast.LENGTH_SHORT).show();
}
}
Start a call using the call agent
Placing the call can be done via the call agent, and just requires providing a list of callee IDs and the call options. For the quickstart, the default call options without video and a single callee ID from the text input are used.
/**
* Place a call to the callee id provided in `callee_id` text input.
*/
private void startCall() {
EditText calleeIdView = findViewById(R.id.callee_id);
String calleeId = calleeIdView.getText().toString();
StartCallOptions options = new StartCallOptions();
callAgent.startCall(
getApplicationContext(),
new CommunicationUserIdentifier[] {new CommunicationUserIdentifier(calleeId)},
options);
}
Launch the app and call the echo bot
The app can now be launched using the "Run App" button on the toolbar (Shift+F10). Verify you're able to place calls by calling 8:echo123
. A pre-recorded message plays then repeat your message back to you.
In this quickstart, you learn how to start a call using the Azure Communication Services Calling SDK for iOS.
Sample Code
You can download the sample app from GitHub.
Prerequisites
To complete this tutorial, you need the following prerequisites:
An Azure account with an active subscription. Create an account for free.
A Mac running Xcode, along with a valid developer certificate installed into your Keychain.
A deployed Communication Services resource. Create a Communication Services resource. You need to record your connection string for this quickstart.
A User Access Token for your Azure Communication Service. You can also use the Azure CLI and run the command with your connection string to create a user and an access token.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
For details, see Use Azure CLI to Create and Manage Access Tokens.
Setting up
Creating the Xcode project
In Xcode, create a new iOS project and select the App template. This tutorial uses the SwiftUI framework, so you should set the Language to Swift and the User Interface to SwiftUI. You're not going to create tests during this quick start. Feel free to uncheck Include Tests.
Install the package and dependencies with CocoaPods
To create a Podfile for your application, open the terminal and navigate to the project folder and run:
pod init
Add the following code to the Podfile and save (make sure that "target" matches the name of your project):
platform :ios, '13.0' use_frameworks! target 'AzureCommunicationCallingSample' do pod 'AzureCommunicationCalling', '~> 1.0.0' end
Run
pod install
.Open the
.xcworkspace
with Xcode.
Request access to the microphone
In order to access the device's microphone, you need to update your app's Information Property List with an NSMicrophoneUsageDescription
. You set the associated value to a string
that was 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>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>
Set up the app framework
Open your project's ContentView.swift file and add an import
declaration to the top of the file to import the AzureCommunicationCalling library
. In addition, import AVFoundation
, we need this code for audio permission request in the code.
import AzureCommunicationCalling
import AVFoundation
Replace the implementation of the ContentView
struct with some simple UI controls that enable a user to initiate and end a call. We attach business logic to these controls in this quickstart.
struct ContentView: View {
@State var callee: String = ""
@State var callClient: CallClient?
@State var callAgent: CallAgent?
@State var call: Call?
var body: some View {
NavigationView {
Form {
Section {
TextField("Who would you like to call?", text: $callee)
Button(action: startCall) {
Text("Start Call")
}.disabled(callAgent == nil)
Button(action: endCall) {
Text("End Call")
}.disabled(call == nil)
}
}
.navigationBarTitle("Calling Quickstart")
}.onAppear {
// Initialize call agent
}
}
func startCall() {
// Ask permissions
AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
if granted {
// Add start call logic
}
}
}
func endCall() {
// Add end call logic
}
}
Object model
The following classes and interfaces handle some of the major features of the Azure Communication Services Calling SDK:
Name | Description |
---|---|
CallClient |
The CallClient is the main entry point to the Calling SDK. |
CallAgent |
The CallAgent is used to start and manage calls. |
CommunicationTokenCredential |
The CommunicationTokenCredential is used as the token credential to instantiate the CallAgent . |
CommunicationUserIdentifier |
The CommunicationUserIdentifier is used to represent the identity of the user, which can be one of the following options: CommunicationUserIdentifier ,PhoneNumberIdentifier or CallingApplication. |
Authenticate the client
Initialize a CallAgent
instance with a User Access Token, which enables us to make and receive calls.
In the following code, you need to replace <USER ACCESS TOKEN>
with a valid user access token for your resource. Refer to the user access token documentation if you don't already have a token available.
Add the following code to the onAppear
callback in ContentView.swift:
var userCredential: CommunicationTokenCredential?
do {
userCredential = try CommunicationTokenCredential(token: "<USER ACCESS TOKEN>")
} catch {
print("ERROR: It was not possible to create user credential.")
return
}
self.callClient = CallClient()
// Creates the call agent
self.callClient?.createCallAgent(userCredential: userCredential!) { (agent, error) in
if error != nil {
print("ERROR: It was not possible to create a call agent.")
return
}
else {
self.callAgent = agent
print("Call agent successfully created.")
}
}
Start a call
The startCall
method is set as the action that is performed when the Start Call button is tapped. Update the implementation to start a call with the ASACallAgent
:
func startCall()
{
// Ask permissions
AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
if granted {
// start call logic
let callees:[CommunicationIdentifier] = [CommunicationUserIdentifier(self.callee)]
self.callAgent?.startCall(participants: callees, options: StartCallOptions()) { (call, error) in
if (error == nil) {
self.call = call
} else {
print("Failed to get call object")
}
}
}
}
}
You also can use the properties in StartCallOptions
to set the initial options for the call (that is, it allows starting the call with the microphone muted).
End a call
Implement the endCall
method to end the current call when the End Call button is tapped.
func endCall()
{
self.call!.hangUp(options: HangUpOptions()) { (error) in
if (error != nil) {
print("ERROR: It was not possible to hangup the call.")
}
}
}
Run the code
You can build and run your app on iOS simulator by selecting Product > Run or by using the (⌘-R) keyboard shortcut.
You can make an outbound VOIP call by providing a user ID in the text field and tapping the Start Call button. Calling 8:echo123
connects you with an echo bot, this feature is great for getting started and verifying your audio devices are working.
Note
The first time you make a call, the system will prompt you for access to the microphone. In a production application, you should use the AVAudioSession
API to check the permission status and gracefully update your application's behavior when permission is not granted.
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.
Next steps
For more information, see the following articles:
- Check out our calling hero sample
- Get started with the UI Library
- Learn about Calling SDK capabilities
- Learn more about how calling works
Feedback
Submit and view feedback for