你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

快速入门:UI 库入门

开始使用 Azure 通信服务 UI 库,以将通信体验快速集成到你的应用程序中。 在本快速入门中,了解如何将 UI 库复合组件集成到应用程序中,并为应用用户设置体验。

通信服务 UI 库呈现应用程序中的完整通信体验。 它负责连接到呼叫,并在幕后设置用户参与呼叫。 开发人员只需考虑在应用的用户体验中的哪个位置启动通信体验。 该组件会引导用户设置其设备、加入和参与通话以及呈现其他参与者。

查看此视频了解概况:

注意

有关 Web UI 库的详细文档和快速入门,请访问 Web UI 库 Storybook

先决条件

可访问以下快速入门

在开源 Azure 通信服务 UI Library for Android 中获取本快速入门的示例 Android 应用程序。

先决条件

设置项目

完成以下部分以设置快速入门项目。

创建新的 Android 项目

在 Android Studio 中,创建新的项目:

  1. 在“文件”菜单中,依次选择“新建”>“新建项目”。

  2. 在“新建项目”中,选择“空活动”项目模板。

    Screenshot that shows the New Project dialog in Android Studio with Empty Activity selected.

  3. 选择下一步

  4. 在“空活动”中,将项目命名为 UILibraryQuickStart。 对于语言,请选择“Java/Kotlin”。 对于“最低 SDK”,选择“API 21: Android 5.0 (Lollipop)”或更高版本。

  5. 选择完成

    Screenshot that shows new project options and the Finish button selected.

安装包

完成以下部分以安装所需的应用程序包。

添加依赖项

在应用级 UILibraryQuickStart/app/build.gradle 文件中(在应用文件夹中),添加以下依赖项:

dependencies {
    ...
    implementation 'com.azure.android:azure-communication-ui-calling:+'
    ...
}

添加 Maven 存储库

需要使用两个 Maven 存储库来集成库:

  • MavenCentral
  • Azure 包存储库

添加存储库:

  1. 在项目 Gradle 脚本中,确保添加了以下存储库。 对于 Android Studio (2020.*),repositories 位于 dependencyResolutionManagement(Gradle version 6.8 or greater) 下的 settings.gradle 中。 对于早期版本的 Android Studio (4.*),repositories 位于 allprojects{} 下的项目级别 build.gradle 中。

    // dependencyResolutionManagement
    repositories {
        ...
        mavenCentral()
        maven {
            url "https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1"
        }
        ...
    }
    
  2. 将项目与 Gradle 文件同步。 若要同步项目,请在“文件”菜单上,选择“将项目与 Gradle 文件同步”。

向 Activity_main.xml 添加按钮

在 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/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>

初始化复合组件

初始化复合组件:

  1. 转到 MainActivity

  2. 添加以下代码来初始化用于通话的复合组件。 将 "GROUP_CALL_ID" 替换为通话群组 ID。 将 "DISPLAY_NAME" 替换为自己的名称。 将 "USER_ACCESS_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.calling.CallComposite
import com.azure.android.communication.ui.calling.CallCompositeBuilder
import com.azure.android.communication.ui.calling.models.CallCompositeGroupCallLocator
import com.azure.android.communication.ui.calling.models.CallCompositeJoinLocator
import com.azure.android.communication.ui.calling.models.CallCompositeRemoteOptions
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 locator: CallCompositeJoinLocator = CallCompositeGroupCallLocator(UUID.fromString("GROUP_CALL_ID"))
        val remoteOptions = CallCompositeRemoteOptions(locator, communicationTokenCredential, "DISPLAY_NAME")

        val callComposite: CallComposite = CallCompositeBuilder().build()
        callComposite.launch(this, remoteOptions)
    }

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

运行代码

在 Android Studio 中,生成并启动应用程序:

  1. 选择“启动”。
  2. 接受权限,然后选择设备、麦克风和视频设置。
  3. 选择“加入通话”。

GIF animation that shows an example of how the project runs on an Android device.

对象模型

以下类和接口处理 Azure 通信服务 Android UI 的某些关键功能:

“属性” 说明
CallComposite 用于呈现参与者库和控件的通话体验的复合组件
CallCompositeBuilder 生成附带选项的 CallComposite 的生成器
CallCompositeJoinMeetingLocator 传入 CallComposite 启动以启动群组通话
CallCompositeTeamsMeetingLinkLocator 传递给 CallComposite 启动以加入 Microsoft Teams 会议
CallCompositeLocalizationOptions 作为可选项注入 CallCompositeBuilder 中,以设置复合组件的语言

UI 库功能

获取为 Android 应用程序创建关键通信功能的代码。

创建 CallComposite

若要创建 CallComposite,在 startCallComposite 函数内初始化 CallCompositeBuilder 实例和 CallComposite 实例。

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

设置身份验证

若要设置身份验证,在 startCallComposite 函数内初始化 CommunicationTokenCredential 实例。 将 "USER_ACCESS_TOKEN" 替换为访问令牌。

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

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

val communicationTokenCredential = CommunicationTokenCredential(communicationTokenRefreshOptions)

设置群组通话

若要设置群组通话,请初始化 CallCompositeGroupCallLocator 并将其提供给 CallCompositeRemoteOptions 对象。

val locator = CallCompositeGroupCallLocator(UUID.fromString("GROUP_CALL_ID"))

val remoteOptions = CallCompositeRemoteOptions(
    locator,
    communicationTokenCredential,            
    "DISPLAY_NAME",
)

设置 Teams 会议

若要设置 Microsoft Teams 会议,请初始化 CallCompositeTeamsMeetingLinkLocator 并将其提供给 CallCompositeRemoteOptions 对象。

val locator = CallCompositeTeamsMeetingLinkLocator("TEAMS_MEETING_LINK")

val remoteOptions = CallCompositeRemoteOptions(
    locator,
    communicationTokenCredential,            
    "DISPLAY_NAME",
)

设置会议室通话

重要

Azure 通信服务的这一功能目前以预览版提供。

预览版 API 和 SDK 在没有服务级别协议的情况下提供。 建议不要将它们用于生产工作负荷。 某些功能可能不受支持或者已受限。

有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

要设置 Azure 通信服务会议室通话,请初始化 CallCompositeRoomLocator,将其提供给 CallCompositeRemoteOptions 对象,并通过 setRoleHint()CallCompositeParticipantRole 设置为 CallCompositeLocalOptionsCallComposite 将在连接到通话之前使用角色提示。 连接通话后,将从 Azure 通信服务检索实际最新的参与者角色。

有关会议室以及如何创建和管理会议室的详细信息,请参阅会议室快速入门

val locator = CallCompositeRoomLocator("<ROOM_ID>")

val remoteOptions = CallCompositeRemoteOptions(
    locator,
    communicationTokenCredential,            
    "DISPLAY_NAME",
)

val localOptions = CallCompositeLocalOptions().setRoleHint(participantRole)

val callComposite = CallCompositeBuilder().build()
callComposite.launch(context, remoteOptions, localOptions)

启动复合组件

若要启动通话 UI,在 startCallComposite 函数内部,对 CallComposite 实例调用 launch

callComposite.launch(context, remoteOptions)

订阅 CallComposite 错误事件

若要接收错误事件,请使用 CallComposite 调用 setOnErrorHandler

可将以下 errorCode 值发送到错误处理程序:

  • CallCompositeErrorCode.CALL_JOIN_FAILED
  • CallCompositeErrorCode.CALL_END_FAILED
  • CallCompositeErrorCode.TOKEN_EXPIRED
  • CallCompositeErrorCode.CAMERA_FAILURE
  • CallCompositeErrorCode.MICROPHONE_PERMISSION_NOT_GRANTED
  • CallCompositeErrorCode.NETWORK_CONNECTION_NOT_AVAILABLE

以下示例显示了失败的复合事件的错误事件:

callComposite.addOnErrorEventHandler { callCompositeErrorEvent ->
    println(callCompositeErrorEvent.errorCode)
}

应用主题配置

若要更改复合组件的原色,请使用 AzureCommunicationUICalling.Theme 作为父主题,在 src/main/res/values/themes.xml 和 src/main/res/values-night/themes.xml 中创建新的主题样式。 若要应用主题,请在 CallCompositeBuilder 中注入主题 ID:

<style name="MyCompany.CallComposite" parent="AzureCommunicationUICalling.Theme">
    <item name="azure_communication_ui_calling_primary_color">#27AC22</item>
    <item name="azure_communication_ui_calling_primary_color_tint10">#5EC65A</item>
    <item name="azure_communication_ui_calling_primary_color_tint20">#A7E3A5</item>
    <item name="azure_communication_ui_calling_primary_color_tint30">#CEF0CD</item>
</style>
val callComposite: CallComposite =
        CallCompositeBuilder()
            .theme(R.style.MyCompany_CallComposite)
            .build()

应用本地化配置

若更改复合组件的语言,请使用 CallCompositeSupportedLocale 通过 Locale 创建 CallCompositeLocalizationOptions。 要应用语言,请将本地化配置注入到 CallCompositeBuilder。 默认情况下,所有文本标签都使用英文 (en) 字符串。 可以使用 CallCompositeLocalizationOptionslanguage 设置不同的值。 默认情况下,UI 库包含一组可与 UI 组件一起使用的 language 值。 CallCompositeSupportedLocale 提供受支持的区域设置。 例如,若要访问英语区域设置,可以使用 CallCompositeSupportedLocale.ENCallCompositeSupportedLocale.getSupportedLocales() 为受支持的语言提供区域设置对象列表。

import com.azure.android.communication.ui.calling.models.CallCompositeLocalizationOptions
import com.azure.android.communication.ui.calling.models.CallCompositeSupportedLocale

// CallCompositeSupportedLocale provides list of supported locale
val callComposite: CallComposite =
            CallCompositeBuilder().localization(
                CallCompositeLocalizationOptions(CallCompositeSupportedLocale.EN)
            ).build()

订阅 CallComposite 调用状态已更改事件

若要接收调用状态已更改事件,请使用 CallComposite 调用 addOnCallStateChangedEventHandler

以下示例显示了调用状态已更改事件。

callComposite.addOnCallStateChangedEventHandler { callStateChangedEvent ->
    println(callStateChangedEvent.code)
}

关闭 CallComposite 事件并订阅已关闭事件

若要接收关闭事件,请使用 CallComposite 调用 addOnDismissedEventHandler。 若要关闭 CallComposite,请调用 dismiss

以下示例显示了调用状态已更改事件。

callComposite.addOnDismissedEventHandler { callCompositeDismissedEvent ->
    println(callCompositeDismissedEvent.errorCode)
}

callComposite.dismiss()

其他功能

用例列表提供有关其他功能的详细信息。

向移动应用添加通知

Azure 通信服务与 Azure 事件网格Azure 通知中心集成,因此你可以向 Azure 中的应用添加推送通知。 可以使用推送通知将信息从你的应用程序发送到用户的移动设备。 推送通知可显示对话、播放声音或显示传入的通话 UI。

在开源 Azure 通信服务 UI Library for iOS 中获取本快速入门的示例 iOS 应用程序。

先决条件

设置项目

完成以下部分以设置快速入门项目。

创建新的 Xcode 项目

在 Xcode 中创建新项目:

  1. 在“文件”菜单中,选择“新建”>“项目”。

  2. 在“为新项目选择模板”中,选择 iOS 平台并选择“应用”应用程序模板。 快速入门使用 UIKit Storyboard。 快速入门不会创建测试,因此可以清除“包括测试”复选框。

    Screenshot that shows the Xcode new project dialog, with iOS and the App template selected.

  3. 在“为新建项目选择选项”中,在产品名称处输入 UILibraryQuickStart。 请在“界面”处选择“Storyboard”。

    Screenshot that shows setting new project options in Xcode.

安装包和依赖项

  1. (可选)对于 MacBook with M1,请在 Xcode 中安装并启用 Rosetta

  2. 在项目根目录中,运行 pod init 以创建 Podfile。 如果遇到错误,请将 CocoaPods 更新为当前版本。

  3. 请将以下代码添加到 Podfile 中。 将 UILibraryQuickStart 替换为你的项目名称。

    platform :ios, '15.0'
    
    target 'UILibraryQuickStart' do
        use_frameworks!
        pod 'AzureCommunicationUICalling'
    end
    
  4. 运行 pod install --repo-update

  5. 在 Xcode 中,打开生成的 .xcworkspace 文件。

请求访问设备硬件

若要访问设备的硬件(包括麦克风和摄像头),请更新应用的信息属性列表。 将关联的值设置为包含在系统用于向用户请求访问权限的对话框中的字符串。

  1. 右键单击项目树的 Info.plist 条目,然后选择“打开为”>“源代码” 。 将以下代码行添加到顶层 <dict> 节,然后保存文件。

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

    以下是 Xcode 文件中 Info.plist 源代码的示例:

    Screenshot that shows an example of the info plist source code in an Xcode file.

  2. 若要验证是否已正确添加设备权限请求,请选择“打开为”>“属性列表”。 检查信息属性列表是否如下例所示:

    Screenshot that shows the camera and microphone device privacy in Xcode.

关闭 Bitcode

在 Xcode 项目中的“生成设置”下,将“启用 Bitcode”选项设置为“否”。 若要查找设置,请将筛选器从“基本”更改为“全部”,或使用搜索栏。

Screenshot that shows the Build Settings option to turn off Bitcode.

初始化复合组件

初始化复合组件:

  1. 转到 ViewController

  2. 添加以下代码来初始化用于通话的复合组件。 将 <GROUP_CALL_ID> 替换为通话群组 ID 或 UUID() 以生成通话群组 ID。 将 <DISPLAY_NAME> 替换为自己的名称。 (<DISPLAY_NAME> 的字符串长度限制为 256 个字符。)将 <USER_ACCESS_TOKEN> 替换为访问令牌。

    import UIKit
    import AzureCommunicationCalling
    import AzureCommunicationUICalling
    
    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 remoteOptions = RemoteOptions(for: .groupCall(groupId: UUID(uuidString: "<GROUP_CALL_ID>")!),
                                              credential: communicationTokenCredential,
                                              displayName: "<DISPLAY_NAME>")
            callComposite?.launch(remoteOptions: remoteOptions)
        }
    }
    

运行代码

若要在 iOS 模拟器上生成和运行应用,请选择“产品”>“运行”或使用 (⌘-R) 键盘快捷方式。 然后,请在模拟器上试用通话体验:

  1. 选择“开始体验”。

  2. 接受音频权限,然后选择设备、麦克风和视频设置。

  3. 选择“开始通话”。

GIF animation that demonstrates the final look and feel of the quickstart iOS app.

对象模型

以下类和接口会处理 Azure 通信服务 UI 客户端库的某些关键功能:

名称 说明
CallComposite 用于呈现具有参与者库和控件的通话体验的组件
CallCompositeOptions 主题和事件处理等选项的设置
RemoteOptions 用于发送到 Azure 通信服务以加入群组通话Teams 会议的远程选项。
ThemeOptions 复合主题的自定义选项
LocalizationOptions 复合组件的语言选项

UI 库功能

获取为 iOS 应用程序创建关键通信功能的代码。

创建 CallComposite

若要创建 CallComposite,请在 startCallComposite 函数内初始化 CallCompositeOptions 实例和 CallComposite 实例:

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

    callComposite = CallComposite(withOptions: callCompositeOptions)
}

设置身份验证

若要设置身份验证,在 startCallComposite 函数内初始化 CommunicationTokenCredential 实例。 将 <USER_ACCESS_TOKEN> 替换为访问令牌。

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

如果还没有访问令牌,请创建一个 Azure 通信服务访问令牌

设置群组通话

若要设置群组通话,请在 startCallComposite 函数内为 .groupCall 定位符初始化 RemoteOptions 实例。 将 <GROUP_CALL_ID> 替换为通话群组 ID。 将 <DISPLAY_NAME> 替换为自己的名称。

// let uuid = UUID() to create a new call
let uuid = UUID(uuidString: "<GROUP_CALL_ID>")!
let remoteOptions = RemoteOptions(for: .groupCall(groupId: uuid),
                                  credential: communicationTokenCredential,
                                  displayName: "<DISPLAY_NAME>")

有关使用通话群组 ID 的详细信息,请参阅管理通话

设置 Teams 会议

若要设置 Microsoft Teams 会议,请在 startCallComposite 函数内为 .teamsMeeting 定位符初始化 RemoteOptions 实例。 将 <TEAMS_MEETING_LINK> 替换为通话的 Teams 会议链接。 将 <DISPLAY_NAME> 替换为自己的名称。

let remoteOptions = RemoteOptions(for: .teamsMeeting(teamsLink: "<TEAMS_MEETING_LINK>"),
                                  credential: communicationTokenCredential,
                                  displayName: "<DISPLAY_NAME>")

可以使用 Graph API 获取 Microsoft Teams 会议链接。 Graph 文档中对此过程进行了详细介绍。

通信服务通话 SDK 接受完整的 Microsoft Teams 会议链接。 此链接将作为 onlineMeeting 资源的一部分返回到 joinWebUrl 属性下。 还可以从 Teams 会议邀请本身内的“加入会议”URL 中获取所需的会议信息。

设置会议室通话

重要

Azure 通信服务的这一功能目前以预览版提供。

预览版 API 和 SDK 在没有服务级别协议的情况下提供。 建议不要将它们用于生产工作负荷。 某些功能可能不受支持或者已受限。

有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

要设置 Azure 通信服务会议室通话,请在 startCallComposite 函数中初始化 .roomCall 定位符的 RemoteOptions 实例。 将 <ROOM_ID> 替换为通话的会议室 ID。 使用 roleHint 初始化 LocalOptions 实例。

<DISPLAY_NAME> 替换为自己的名称。

CallComposite 将在连接到通话之前使用角色提示。 连接通话后,将从 Azure 通信服务检索实际最新的参与者角色。

有关会议室以及如何创建和管理会议室的详细信息,请参阅会议室快速入门

let remoteOptions = RemoteOptions(for: .roomCall(roomId: "<ROOM_ID>"),
                                  credential: communicationTokenCredential,
                                  displayName: "<DISPLAY_NAME>")
let localOptions = LocalOptions(roleHint: participantRole)

let callComposite = CallComposite()
callComposite.launch(remoteOptions: remoteOptions, localOptions: localOptions)

启动复合组件

startCallComposite 函数内,对 CallComposite 实例调用 launch

callComposite?.launch(remoteOptions: remoteOptions)

订阅事件

可以实现闭包,以处理复合事件。 可将以下 errorCodes 发送到错误处理程序:

  • callJoin
  • callEnd
  • cameraFailure
  • tokenExpired
  • microphonePermissionNotGranted
  • networkConnectionNotAvailable

以下示例显示了失败的复合事件的错误事件:

callComposite?.events.onError = { error in
    print("CallComposite failed with error:\(error)")
}

应用主题选项

若要自定义应用程序中的通信体验,请创建实现 ThemeOptions 协议的自定义主题选项。 在 CallCompositeOptions 中包含新类的实例:

class CustomThemeOptions: ThemeOptions {
   var primaryColor: UIColor {
       return UIColor.red
   }
}
let callCompositeOptions = CallCompositeOptions(theme: CustomThemeOptions())

有关主题设置工作原理的详细信息,请参阅主题设置指南

应用本地化选项

若要更改复合组件中的语言,请创建自定义本地化选项并将其包含在 CallCompositeOptions 中。 默认情况下,所有文本标签都使用英文 (SupportedLocale.en) 字符串。 可以使用 LocalizationOptionslocale 设置不同的值。 默认情况下,UI 库包含一组可与 UI 组件一起使用的 locale 值。 SupportedLocale.values 提供所有受支持的语言的列表。

在以下示例中,复合组件本地化为法语 (fr):

// Option1: Use IntelliSense to get locales UI Library supports.
let localizationOptions = LocalizationOptions(locale: SupportedLocale.frFR)

// Option2: If UI Library doesn't support the locale you set, the Swift Locale struct defaults to English.
let localizationOptions = LocalizationOptions(locale: Locale(identifier: "fr-FR"))

let callCompositeOptions = CallCompositeOptions(localization: localizationOptions) 

若要详细了解本地化并查看受支持的语言列表,请参阅本地化指南

订阅 CallComposite 调用状态已更改事件

可以实现闭包,以处理复合事件。 调用状态将发送到调用状态已更改处理程序。

以下示例显示了调用状态已更改事件。

callComposite?.events.onCallStateChanged = { callStateEvent in
   print("CallComposite call state changed:\(callStateEvent.requestString)")
}

关闭 CallComposite 事件并订阅已关闭事件

若要关闭 CallComposite,请调用 dismiss。 CallComposite 关闭时将发送以下关闭事件:

callComposite?.events.onDismissed = { dismissed in
   print("CallComposite dismissed:\(dismissed.errorCode)")
}

callComposite.dismiss()

向移动应用添加通知

Azure 通信服务与 Azure 事件网格Azure 通知中心集成,因此你可以向 Azure 中的应用添加推送通知。 可以使用推送通知将信息从你的应用程序发送到用户的移动设备。 推送通知可显示对话、播放声音或显示传入的通话 UI。

清理资源

如果想要清理并删除通信服务订阅,可以删除资源或资源组。

删除资源组同时也会删除与之相关联的任何其他资源。

了解有关清理资源的详细信息。