快速入門:將語音電話新增至您的應用程式

使用通訊服務通話 SDK 將語音和視訊通話新增至您的應用程式,開始使用 Azure 通訊服務。

重要

Azure 通訊服務僅支援美國和波多黎各的 911 緊急電話。

Azure 通訊服務的語音通話 (PSTN) 可用於從美國和波多黎各的使用者撥打 911。 不支援從美國波多黎各外部 & 撥動 911,或在美國波多黎各以外的 & 國家/地區撥打緊急服務。

重要事項

本文件中所述的功能目前處於公用預覽。 此預覽版本是在沒有服務等級協定的情況下提供,不建議用於生產工作負載。 可能不支援特定功能,或可能已經限制功能。 如需詳細資訊,請參閱 Microsoft Azure 預覽版增補使用條款

在本快速入門中,您將瞭解如何使用適用于 Windows 的 Azure 通訊服務 呼叫 SDK 來啟動通話。

UWP 範例程式碼

您可以從 GitHub 下載應用程式範例。

必要條件

若要完成本教學課程,您需要下列必要條件:

設定

建立專案

在 Visual Studio 中,使用空白應用程式 (通用 Windows) 範本建立新的專案,以設定單頁通用 Windows 平臺 (UWP) 應用程式。

顯示 Visual Studio 中 [新增 UWP 專案] 視窗的螢幕擷取畫面。

安裝套件

以滑鼠右鍵按一下您的專案,然後移至 Manage Nuget Packages 以安裝 Azure.Communication.Calling1.0.0-Beta.33或更新版本。 請確定已核取 [包含預先發行專案]。

要求存取

移至 , Package.appxmanifest 然後按一下 Capabilities 。 檢查 Internet (Client & Server) 以取得網際網路的輸入和輸出存取權。 檢查 Microphone 以存取麥克風的音訊摘要。

顯示 Visual Studio 中要求存取網際網路和麥克風的螢幕擷取畫面。

設定應用程式架構

我們需要設定基本配置來附加邏輯。 若要撥打輸出通話,我們需要 提供 TextBox 被呼叫者的使用者識別碼。 我們也需要一個 Start Call 按鈕和一個 Hang Up 按鈕。 開啟專案的 , MainPage.xaml 並將 Grid 節點新增至 : 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>

開啟以 App.xaml.cs (按一下滑鼠右鍵,然後選擇 [檢視程式碼]) 並將這一行新增至頂端:

using CallingQuickstart;

開啟 , MainPage.xaml.cs 並以下列實作取代內容:

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
        }
    }
}

物件模型

下列類別和介面會處理Azure 通訊服務呼叫 SDK 的一些主要功能:

名稱 描述
CallClient CallClient 是呼叫 SDK 的主要進入點。
CallAgent CallAgent 是用來啟動和管理通話。
CommunicationTokenCredential CommunicationTokenCredential 可作為用來具現化 CallAgent 的權杖認證。
CommunicationUserIdentifier CommunicationUserIdentifier 可用來代表使用者的身分識別,可以是下列其中一項:CommunicationUserIdentifier/PhoneNumberIdentifier/CallingApplication。

驗證用戶端

CallAgent使用使用者存取權杖初始化 實例,以讓我們進行和接收呼叫,並選擇性地取得 DeviceManager 實例以查詢用戶端裝置組態。

在下列程式碼中,將 取代 <AUTHENTICATION_TOKEN> 為使用者存取權杖。 如果您還沒有可用的權杖,請參閱使用者存取權杖文件。

將下列程式碼新增至 函 InitCallAgentAndDeviceManagerAsync 式。

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);

開始通話

將 實作新增至 CallButton_Click ,以使用我們建立的 callAgent 來啟動呼叫,並連結撥號狀態事件處理常式。

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;

結束通話

按一下按鈕時 Hang Up 結束目前的呼叫。 將 實作新增至 HangupButton_Click,以結束呼叫我們建立的 callAgent,並結束通話狀態事件處理常式。

this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());

追蹤通話狀態

隨時收到目前通話狀態的通知。

var state = (sender as Call)?.State;
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
    State.Text = state.ToString();
});

執行程式碼

您可以在 Visual Studio 上建置和執行程式碼。 請注意,針對支援 ARM64 的解決方案平臺, x64x86

您可以藉由在文字欄位中提供使用者識別碼,然後按一下 Start Call 按鈕來進行輸出呼叫。 呼叫 8:echo123 會將您連線到 Echo Bot,這非常適合用於開始使用和驗證音訊裝置。

顯示執行 UWP 快速入門應用程式的螢幕擷取畫面

WinUI 3 範例程式碼

您可以從 GitHub 下載應用程式範例。

必要條件

若要完成本教學課程,您需要下列必要條件:

設定

建立專案

在 Visual Studio 中,使用 [ 桌面]) 範本中的 [已封裝] ([WinUI 3] 範本建立新的專案,以設定單頁 WinUI 3 應用程式。

顯示 Visual Studio 中 [新增 WinUI 專案] 視窗的螢幕擷取畫面。

安裝套件

以滑鼠右鍵按一下您的專案,然後移至 Manage Nuget Packages 以安裝 Azure.Communication.Calling1.0.0-Beta.33或更新版本。 請確定已核取 [包含預先發行專案]。

要求存取

顯示 Visual Studio 中要求存取網際網路和麥克風的螢幕擷取畫面。

設定應用程式架構

我們需要設定基本版面配置來附加邏輯。 為了撥打輸出通話,我們需要 提供 TextBox 被呼叫者的使用者識別碼。 我們也需要 Start Call 按鈕和 Hang Up 按鈕。 MainWindow.xaml開啟專案的 ,並將 Grid 節點新增至 : 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>

開啟 , MainWindow.xaml.cs 並以下列實作取代內容:

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
        }
    }
}

物件模型

下列類別和介面會處理Azure 通訊服務呼叫 SDK 的一些主要功能:

名稱 描述
CallClient CallClient 是呼叫 SDK 的主要進入點。
CallAgent CallAgent 是用來啟動和管理通話。
CommunicationTokenCredential CommunicationTokenCredential 可作為用來具現化 CallAgent 的權杖認證。
CommunicationUserIdentifier CommunicationUserIdentifier 可用來代表使用者的身分識別,可以是下列其中一項:CommunicationUserIdentifier/PhoneNumberIdentifier/CallingApplication。

驗證用戶端

CallAgent使用使用者存取權杖初始化實例,以允許我們進行和接收呼叫,並選擇性地取得 DeviceManager 實例來查詢用戶端裝置組態。

在下列程式碼中,以使用者存取權杖取代 <AUTHENTICATION_TOKEN> 。 如果您還沒有可用的權杖,請參閱使用者存取權杖文件。

將下列程式碼新增至 InitCallAgentAndDeviceManagerAsync 函式。

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;

開始通話

將 實作新增至 CallButton_Click ,以啟動我們建立的 callAgent 呼叫,並連結撥號狀態事件處理常式。

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;

結束通話

按一下按鈕時 Hang Up 結束目前的呼叫。 將實作新增至 HangupButton_Click,以結束呼叫我們建立的 callAgent,並結束通話狀態事件處理常式。

this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());

追蹤通話狀態

隨時收到目前通話狀態的通知。

var state = (sender as Call)?.State;
this.DispatcherQueue.TryEnqueue(() => {
    State.Text = state.ToString();
});

執行程式碼

您可以在 Visual Studio 上建置和執行程式碼。 請注意,針對我們支援 ARM64 的解決方案平臺, x64x86

您可以藉由在文字欄位中提供使用者識別碼,然後按一下 Start Call 按鈕來進行輸出通話。 呼叫 8:echo123 會將您連線到 Echo Bot,這非常適合用於開始使用和驗證音訊裝置。

顯示執行 WinUI 快速入門應用程式的螢幕擷取畫面

在本快速入門中,您將瞭解如何使用適用于 JavaScript 的Azure 通訊服務呼叫 SDK 來開始呼叫。

範例程式碼

您可以從 GitHub 下載應用程式範例。

注意

您可以使用 Azure 通訊服務UI 程式庫來存取對Azure 通訊服務使用者的輸出呼叫。 UI 程式庫可讓開發人員只使用幾行程式碼,將已啟用 VoIP 的呼叫用戶端新增至其應用程式中。

必要條件

設定

建立新的 Node.js 應用程式

開啟您的終端機或命令視窗,為您的應用程式建立新的目錄,並瀏覽至該目錄。

mkdir calling-quickstart && cd calling-quickstart

執行 npm init -y 以使用預設設定建立 package.json 檔案。

npm init -y

安裝套件

npm install使用 命令來安裝 Azure 通訊服務呼叫適用于 JavaScript 的 SDK。

npm install @azure/communication-common --save
npm install @azure/communication-calling --save

--save 選項會在您的 package.json 檔案中,將程式庫列為相依性。

設定應用程式架構

本快速入門會使用元件來組合應用程式資產。 執行下列命令來安裝它,並將它列為 package.json中的開發相依性:

npm install parcel --save-dev

在專案的根目錄中建立 index.html 檔案。 我們將使用此檔案來設定基本配置,讓使用者能夠撥打電話。

以下是我們需要新增至我們建立的 index.html 檔案的 html:

<!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>
      &nbsp;
      <button id="hang-up-button" type="button" disabled="true">
        Hang Up
      </button>
    </div>
    <script src="./app.js" type="module"></script>
  </body>
</html>

在名為 app.js 的專案根目錄中建立檔案,以包含本快速入門的應用程式邏輯。 新增下列程式碼以匯入通話用戶端,並取得 DOM 元素的參考,以便可以附加我們的商務邏輯。

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");

物件模型

下列類別和介面會處理Azure 通訊服務呼叫 SDK 的一些主要功能:

名稱 描述
CallClient CallClient 是呼叫 SDK 的主要進入點。
CallAgent CallAgent 是用來啟動和管理通話。
AzureCommunicationTokenCredential AzureCommunicationTokenCredential 類別會實作 CommunicationTokenCredential 介面,用來具現化 CallAgent。

驗證用戶端

您必須將資源的有效使用者存取權杖輸入至文字欄位,然後按一下 [提交]。 如果您還沒有可用的權杖,請參閱使用者存取權杖文件。 使用 , CallClient 使用 初始化 CallAgent 實例 CommunicationTokenCredential ,以允許我們進行和接收呼叫。

將下列程式碼新增到 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!");
    }
})

開始通話

新增事件處理常式,以在按一下 callButton 時起始通話:

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;
});

結束通話

新增事件接聽程式,以在按一下 hangUpButton 時結束目前的通話:

hangUpButton.addEventListener("click", () => {
  // end the current call
  call.hangUp({ forEveryone: true });

  // toggle button states
  hangUpButton.disabled = true;
  callButton.disabled = false;
  submitToken.disabled = false;
});

forEveryone 屬性會結束所有通話參與者的通話。

執行程式碼

使用 命令 npx parcel index.html 來執行您的應用程式。

開啟瀏覽器並流覽至 http://localhost:1234/. 您應該會看見下列內容:

已完成的 JavaScript 應用程式螢幕擷取畫面。

您可以藉由在對應的文字欄位中提供有效的使用者存取權杖和使用者識別碼,然後按一下 [ 開始通話 ] 按鈕,來進行輸出 VOIP 通話。

呼叫 8:echo123 會與回應 Bot 連線,這非常適合您開始使用並驗證音訊裝置是否正常運作。 傳遞 {id: '8:echo123'} 至 CallAgent.startCall () API 以呼叫 echobot。 若要呼叫Azure 通訊服務通訊使用者,請傳遞 {communicationUserId: 'ACS_USER_ID'}CallAgent.startCall() API。

在本快速入門中,您將瞭解如何使用適用于 Android 的Azure 通訊服務呼叫 SDK 來開始通話。

範例程式碼

您可以從 GitHub 下載應用程式範例。

必要條件

設定

建立具有空白活動的 Android 應用程式

在 Android Studio 中,選取 [啟動新的 Android Studio 專案]。

顯示在 Android Studio 中選取 [啟動新的 Android Studio 專案] 按鈕的螢幕擷取畫面。

選取 [手機和平板電腦] 底下的 [空白活動] 專案範本。

顯示在 [專案範本] 畫面中選取 [空白活動] 選項的螢幕擷取畫面。

選取 [API 26:Android 8.0 (Oreo) ] 或更新版本的最低 SDK。

顯示在 [專案範本] 畫面中選取 [空白活動] 選項的螢幕擷取畫面 2。

安裝套件

找出您的專案層級 build.gradle,並務必將 mavenCentral() 新增至 buildscriptallprojects 下的存放庫清單

buildscript {
    repositories {
    ...
        mavenCentral()
    ...
    }
}
allprojects {
    repositories {
    ...
        mavenCentral()
    ...
    }
}

然後,在您的模組層級 build.gradle 中,將以下幾行新增至相依性和 android 區段

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'
    ...
}

將權限新增至應用程式資訊清單

為了要求進行通話所需的權限,必須先在應用程式資訊清單 (app/src/main/AndroidManifest.xml) 中宣告。 以下列內容取代檔案的內容:

    <?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>
    

設定應用程式的配置

需要兩個輸入:被呼叫者識別碼的文字輸入,以及用來進行呼叫的按鈕。 這些可以透過設計工具或藉由編輯版面配置 xml 來新增。 建立識別碼為 call_button、文字輸入為 callee_id 的按鈕。 瀏覽至 app/src/main/res/layout/activity_main.xml 並且以下列內容取代檔案的內容:

<?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>

建立主要活動 Scaffolding 和繫結

建立版面配置之後,即可新增繫結,以及活動的基本 Scaffolding。 活動會處理要求執行階段權限、建立呼叫代理程式,並且在按下按鈕時進行呼叫。 每個項目會涵蓋在各自的區段中。 onCreate系統會覆寫 方法以叫 getAllPermissions 用 和 , createAgent 並新增呼叫按鈕的系結。 只有在建立活動時,才會發生這種情況。 如需 詳細資訊, onCreate 請參閱 瞭解活動生命週期指南。

瀏覽至 MainActivity.java,然後以下列程式碼取代內容:

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
    }
}

要求執行階段時的權限

針對 Android 6.0 和更新版本 (API 層級 23) 和 targetSdkVersion 23 或更新版本,權限會在執行階段授與,而不是在安裝應用程式時。 為了支援此功能,getAllPermissions 可以實作為呼叫 ActivityCompat.checkSelfPermissionActivityCompat.requestPermissions,以取得每個必要的權限。

/**
 * 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);
    }
}

注意

在設計您的應用程式時,請考量何時應要求這些權限。 您應該視需要要求權限,而不是提前要求。 如需詳細資訊,請參閱 Android 權限指南

物件模型

下列類別和介面會處理Azure 通訊服務呼叫 SDK 的一些主要功能:

名稱 描述
CallClient CallClient 是呼叫 SDK 的主要進入點。
CallAgent CallAgent 是用來啟動和管理通話。
CommunicationTokenCredential CommunicationTokenCredential 可作為用來具現化 CallAgent 的權杖認證。
CommunicationIdentifier CommunicationIdentifier 會作為可能屬於通話的不同類型的參與者使用。

從使用者存取權杖建立代理程式

透過使用者權杖,可以具現化已驗證的呼叫代理程式。 一般來說,此權杖會從具有應用程式特定驗證的服務產生。 如需使用者存取權杖的詳細資訊,請參閱 使用者存取權杖 指南。

在快速入門中,將 <User_Access_Token> 取代為針對您的 Azure 通訊服務資源所產生的使用者存取權杖。


/**
 * 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();
    }
}

使用呼叫代理程式開始通話

您可以透過呼叫代理程式來進行呼叫,只需要提供被呼叫者識別碼和呼叫選項的清單。 在快速入門中,會使用沒有視訊的預設呼叫選項,以及文字輸入中的單一被呼叫者識別碼。

/**
 * 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);
}

啟動應用程式並呼叫 Echo Bot

應用程式現在可以使用工具列上的 [執行應用程式] 按鈕 (Shift+F10) 來啟動。 藉由呼叫 來確認您能夠撥打電話 8:echo123 。 接著會播放預先錄製的訊息,為您重複訊息。

顯示已完成應用程式的螢幕擷取畫面。

在本快速入門中,您將瞭解如何使用適用于 iOS 的Azure 通訊服務呼叫 SDK 來開始通話。

範例程式碼

您可以從 GitHub 下載應用程式範例。

必要條件

若要完成本教學課程,您需要下列必要條件:

  • 具有有效訂用帳戶的 Azure 帳戶。 免費建立帳戶

  • 執行 Xcode 的 Mac,以及安裝在您 Keychain 中的有效開發人員憑證。

  • 已部署通訊服務資源。 建立通訊服務資源。 您必須記錄本快速入門的 連接字串

  • 針對您的 Azure 通訊服務的使用者存取權杖。 您也可以使用 Azure CLI,並使用連接字串執行下列命令,以建立使用者和存取權杖。

    az communication identity token issue --scope voip --connection-string "yourConnectionString"
    

    如需詳細資訊,請參閱 使用 Azure CLI 建立和管理存取權杖

設定

建立 XCode 專案

在 Xcode 中,建立新的 iOS 專案,然後選取 應用程式 範本。 本教學課程使用 SwiftUI 架構,因此您應將 [語言] 設定為 [Swift],並將 [使用者介面] 設定為 [SwiftUI]。 進行本快速入門期間,您不會建立測試。 您可以取消核取 [包含測試]。

顯示 Xcode 內 [新增專案] 視窗的螢幕擷取畫面。

使用 CocoaPods 安裝套件和相依性

  1. 若要為您的應用程式建立 Podfile,請開啟終端機並流覽至專案資料夾並執行:

    pod init

  2. 將下列程式碼新增至 Podfile 並儲存 (確定 「target」 符合專案的名稱) :

    platform :ios, '13.0'
    use_frameworks!
    
    target 'AzureCommunicationCallingSample' do
      pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  3. 執行 pod install

  4. 使用 Xcode 開啟 .xcworkspace

要求存取麥克風

您必須以 NSMicrophoneUsageDescription 更新應用程式的資訊屬性清單,才能存取裝置的麥克風。 您可以將相關聯的值設定為 string,此值會包含在系統用來向使用者要求存取權的對話中。

以滑鼠右鍵按一下專案樹狀結構的 Info.plist 項目,然後選取 [開啟形式] > [原始程式碼]。 將以下幾行新增至最上層 <dict> 區段中,然後儲存檔案。

<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>

設定應用程式架構

開啟專案的 ContentView.swift 檔案,並且將 import 宣告新增至檔案頂端,以匯入 AzureCommunicationCalling library。 此外,匯入 AVFoundation,我們需要這個項目以便在程式碼中進行音訊權限要求。

import AzureCommunicationCalling
import AVFoundation

使用一些簡單的 UI 控制項來取代 ContentView 結構的實作,讓使用者可以起始和結束通話。 在本快速入門中,我們會將商務邏輯附加至這些控制項。

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
    }
}

物件模型

下列類別和介面會處理Azure 通訊服務呼叫 SDK 的一些主要功能:

名稱 描述
CallClient CallClient 是呼叫 SDK 的主要進入點。
CallAgent CallAgent 是用來啟動和管理通話。
CommunicationTokenCredential CommunicationTokenCredential 可作為用來具現化 CallAgent 的權杖認證。
CommunicationUserIdentifier CommunicationUserIdentifier 可用來代表使用者的身分識別,可以是下列其中一項:CommunicationUserIdentifier/PhoneNumberIdentifier/CallingApplication。

驗證用戶端

使用使用者存取權杖來初始化 CallAgent 執行個體,讓我們能夠進行和接收通話。

在下列程式碼中,您必須將 取代 <USER ACCESS TOKEN> 為資源的有效使用者存取權杖。 如果您還沒有可用的權杖,請參閱使用者存取權杖文件。

將下列程式碼新增至 ContentView.swift 中的 onAppear 回撥:

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.")
    }
}

開始通話

startCall 方法會設定為點選 [開始通話] 按鈕時要執行的動作。 更新此實作,以使用 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")
                }
            }
        }
    }
}

您也可以使用 StartCallOptions 中的屬性來設定通話的初始選項 (亦即,允許在麥克風靜音的情況下開始通話)。

結束通話

當點選 [結束通話] 按鈕時,請實作 endCall 方法來結束目前的通話。

func endCall()
{    
    self.call!.hangUp(options: HangUpOptions()) { (error) in
        if (error != nil) {
            print("ERROR: It was not possible to hangup the call.")
        }
    }
}

執行程式碼

您可以選取[產品>執行] 或使用 (⌘-R) 鍵盤快速鍵,在 iOS 模擬器上建置並執行您的應用程式。

快速入門應用程式的最終外觀與風格

您可以在文字欄位中提供使用者識別碼並且點選 [開始通話] 按鈕,以進行外撥 VOIP 通話。 呼叫 8:echo123 會將您連線到 Echo Bot,這非常適合用於開始使用和驗證音訊裝置。

注意

第一次進行通話時,系統會提示您需要麥克風的存取權。 在實際執行環境應用程式中,您應該使用 AVAudioSession API 檢查權限狀態,並在未授與權限時,正常地更新應用程式的行為。

清除資源

如果您想要清除和移除通訊服務訂閱,則可以刪除資源或資源群組。 刪除資源群組也會刪除其關聯的任何其他資源。 深入了解如何清除資源

後續步驟

如需詳細資訊,請參閱下列文章: