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

在 UI 库中设置一对一呼叫和推送通知

UI 库为使用 Azure 通信服务参与者标识符进行一对一呼叫提供现成的支持。 为了支持一对一呼叫,UI 库提供了来电通知。 你还可以将 Azure 通信服务用作呼叫的 Azure 事件网格事件源。

在本文中,你将了解如何在应用程序中使用 UI 库进行一对一呼叫。

先决条件

设置功能

有关详细信息,请参阅开源 Android UI 库示例应用程序代码

设置推送通知的权限

若要设置推送通知,你需要一个启用了 Firebase Cloud Messaging (FCM) 的 Firebase 帐户。 FCM 服务必须连接到 Azure 通知中心实例。 有关详细信息,请参阅通信服务通知。 你还需要使用 Android Studio 3.6 或更高版本来构建应用程序。

Android 应用程序要想从 FCM 接收通知消息,它需要一组权限。 在 AndroidManifest.xml 文件中,在 <manifest ...></application> 标记后添加以下权限集。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

向移动应用添加来电通知

Azure 通信服务与 Azure 事件网格Azure 通知中心集成,因此你可以向 Azure 中的应用添加推送通知

注册/注销通知中心推送通知

若要注册推送通知,应用程序需要使用设备注册令牌在 CallComposite 实例上调用 registerPushNotification()

若要获取设备注册令牌,请将 Firebase SDK 添加到应用程序模块的 build.gradle 实例。 若要从 Firebase 接收通知,请按照通信服务通知中的说明来集成 Azure 通知中心。

    val deviceRegistrationToken = "" // From Firebase
    callComposite.registerPushNotification(deviceRegistrationToken).whenComplete { _, throwable ->
        if (throwable != null) {
            // Handle error
        }
    }

处理从事件网格或通知中心收到的推送通知

若要接收来电推送通知,请使用有效负载在 CallComposite 实例上调用 handlePushNotification

若要从 FCM 获取有效负载,请首先创建一个新服务(“文件”>“新建”>“服务”>“服务”),以扩展 FirebaseMessagingService Firebase SDK 类并重写 onMessageReceived 方法。 此方法是在 FCM 将推送通知传递到应用程序时调用的事件处理程序。

    // On Firebase onMessageReceived
    val pushNotification = CallCompositePushNotification(remoteMessage.data)
    callComposite.handlePushNotification(pushNotification).whenComplete { _, throwable ->
        if (throwable != null) {
            // Handle error
        }
    }

注册来电通知

若要在 handlePushNotification 之后接收来电通知,请订阅 CallCompositeIncomingCallEventCallCompositeIncomingCallCancelledEventCallCompositeIncomingCallEvent 包含来电 callId 和呼叫方信息。 CallCompositeIncomingCallCancelledEvent 包含 callId 和呼叫取消代码 在 Azure 通信服务中进行故障排除

    private var incomingCallEvent: IncomingCallEvent? = null
    private var incomingCallCancelledEvent: IncomingCallCancelledEvent? = null

    class IncomingCallEvent : CallCompositeEventHandler<CallCompositeIncomingCallEvent> {
        override fun handle(eventArgs: CallCompositeIncomingCallEvent?) {
            // Display incoming call UI to accept/decline a call
            // CallCompositeIncomingCallEvent contains call id and caller information
        }
    }

    class IncomingCallCancelledEvent : CallCompositeEventHandler<CallCompositeIncomingCallCancelledEvent> {
        override fun handle(eventArgs: CallCompositeIncomingCallCancelledEvent?) {
            // Call-ended event when a call is declined or not accepted
        }
    }

    // Event subscription
    incomingCallEvent = IncomingCallEvent()
    callComposite.addOnIncomingCallEventHandler(incomingCallEvent)

    incomingCallCancelledEvent = IncomingCallCancelledEvent()
    callComposite.addOnIncomingCallCancelledEventHandler(incomingCallEndEvent)

    // Event unsubscribe
    callComposite.removeOnIncomingCallEventHandler(incomingCallEvent)
    callComposite.removeOnIncomingCallCancelledEventHandler(incomingCallEndEvent)

处理呼叫

若要接受呼叫,请调用 accept。 若要拒绝呼叫,请调用 reject

// Accept call
callComposite.accept(applicationContext, incomingCallId, localOptions)

// Decline call
callComposite.reject(incomingCallId)

向其他参与者拨号

若要开始与其他参与者的通话,请从 CommunicationIdentitylaunch 使用参与者的原始 ID 创建 CallCompositeStartCallOptions

    val participants: List<CommunicationIdentifier> // participants to dial
    callComposite.launch(context, participants, localOptions)

有关详细信息,请参阅开源 iOS UI 库示例应用程序代码

设置推送通知

移动推送通知是在移动设备中收到的弹出通知。 本文重点介绍了 Internet 语音协议 (VoIP) 推送通知。

以下部分介绍如何注册、处理和取消注册推送通知。 在开始这些任务之前,请先满足以下先决条件:

  1. 在 Xcode 中,转到“签名和功能”。 选择“+功能”来添加一项功能,然后选择“推送通知”
  2. 选择“+功能”来再添加一项功能,然后选择“背景模式”
  3. 在“背景模式”下,选中“IP 语音”和“远程通知”复选框

向移动应用添加来电通知

Azure 通信服务与 Azure 事件网格Azure 通知中心集成,因此你可以向 Azure 中的应用添加推送通知

注册/注销通知中心推送通知

若要注册推送通知,应用程序需要使用设备注册令牌在 CallComposite 实例上调用 registerPushNotifications()

    // to register
    let deviceToken: Data = pushRegistry?.pushToken(for: PKPushType.voIP)
    callComposite.registerPushNotifications(
        deviceRegistrationToken: deviceToken) { result in
        switch result {
            case .success:
                // success
            case .failure(let error):
                // failure
        }
    }

    // to unregister
    callComposite.unregisterPushNotification()

处理从事件网格或通知中心收到的推送通知

若要接收来电推送通知,请使用字典有效负载在 CallComposite 实例上调用 handlePushNotification()

当你使用 handlePushNotification() 并设置了 CallKit 选项时,你会收到一个 CallKit 通知以用于接受或拒绝呼叫。

    // App is in the background
    // push notification contains from/to communication identifiers and event type
    let pushNotification = PushNotification(data: payload.dictionaryPayload)
    let callKitOptions = CallKitOptions(...//CallKit options)
    CallComposite.reportIncomingCall(pushNotification: pushNotification,
                                    callKitOptions: callKitOptions) { result in
        if case .success() = result {
            DispatchQueue.global().async {
                // You don't need to wait for a Communication Services token to handle the push because 
                // Communication Services common receives a callback function to get the token with refresh options
                // create call composite and handle push notification
                callComposite.handlePushNotification(pushNotification: pushNotification)
            }
        }
    }

    // App is in the foreground
    let pushNotification = PushNotification(data: dictionaryPayload)
    callComposite.handlePushNotification(pushNotification: pushNotification) { result in
        switch result {
            case .success:
                // success
            case .failure(let error):
                // failure
        }
    }

在推送处理流程中注册来电通知

若要在 handlePushNotification 之后接收来电通知,请订阅 onIncomingCallonIncomingCallCancelledIncomingCall 包含来电 callId 和呼叫方信息。 IncomingCallCancelled 包含 callId 和呼叫取消代码 在 Azure 通信服务中进行故障排除

    let onIncomingCall: (IncomingCall) -> Void = { [] incomingCall in
        // Incoming call id and caller info
    }
    let onIncomingCallEnded: (IncomingCallCancelled) -> Void = { [] incomingCallCancelled in
        // Incoming call cancelled code with callId
    }
    callComposite.events.onIncomingCall = onIncomingCall
    callComposite.events.onIncomingCallEnded = onIncomingCallEnded

禁用来电的内部推送

若要仅接收来自 EventGridAPNS 的推送通知,请在 CallCompositeOptions 中将 disableInternalPushForIncomingCall 设置为 true。 如果 disableInternalPushForIncomingCall 为 true,则仅当将调用 handlePushNotification 时,才会收到来自 UI 库的推送通知事件。 选项 disableInternalPushForIncomingCall 有助于停止在前台模式下从 CallComposite 接收通知。 此设置不控制 EventGridNotificationHub 设置。

    let options = CallCompositeOptions(disableInternalPushForIncomingCall: true)

在从通话 SDK CallKit 接受的来电上启动复合项

Azure 通信服务通话 iOS SDK 支持 CallKit 集成。 可以通过配置 CallCompositeCallKitOption 的实例在 UI 库中启用此集成。 有关详细信息,请参阅与 CallKit 集成

如果启用了来自调用 SDK 的 CallKit,请订阅 onIncomingCallAcceptedFromCallKit。 接受呼叫时,使用呼叫 ID 启动 callComposite

    let onIncomingCallAcceptedFromCallKit: (callId) -> Void = { [] callId in
        // Incoming call accepted call id
    }
    
    callComposite.events.onIncomingCallAcceptedFromCallKit = onIncomingCallAcceptedFromCallKit

    // launch composite with/without local options
    // Note: as call is already accepted, setup screen will not be displayed
    callComposite.launch(callIdAcceptedFromCallKit: callId)

使用 CallComposite 处理呼叫

若要接受呼叫,请调用 accept。 若要拒绝呼叫,请调用 reject

// Accept call
callComposite.accept(incomingCallId, 
                     ... // CallKit and local options
                     )

// Decline call
callComposite.reject(incomingCallId)

向其他参与者拨号

若要开始与其他参与者的通话,请使用参与者的 CommunicationIdentifier 列表启动 callComposite

    // [CommunicationIdentifier]
    // use createCommunicationIdentifier(fromRawId: "raw id")
    callComposite.launch(participants: <list of CommunicationIdentifier>,
                         localOptions: localOptions)

后续步骤