tencent cloud

云联络中心

Flutter

下载
聚焦模式
字号
最后更新时间: 2026-09-18 16:40:42

效果展示



安装

flutter pub add tccc_user_call_sdk

平台要求

Flutter >= 3.7.0(Dart >= 2.19.6
Android minSdk 21
iOS 13.0

权限

使用前,请完成权限申请。
Android
iOS
编辑 AndroidManifest.xml,在权限部分,增加如下权限声明
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
编辑 Info.plist,增加如下权限声明
<key>NSMicrophoneUsageDescription</key>
<string>用于语音通话</string>
<key>NSCameraUsageDescription</key>
<string>音频通话 SDK 链接了相机能力,本应用仅用于语音通话</string>
<key>UIBackgroundModes</key>
<array><string>audio</string></array>

快速开始

后续使用的参数说明
参数
类型
必填
说明
sdkAppId
number
腾讯云联络中心的 SDKAppId。
userId
string
业务侧用户 ID,不能为空且不能包含 @ 字符。若使用邮箱作为用户标识,请替换为 URL 安全的标识符。
userSig
string
用户身份签名,获取流程可 前置准备 > 步骤4:获取 userSig 签名
userClientData
string
如调用接口 CreateUserSig 获取 userSig 时指定了参数 ClientData 需一并传入,具体可 前置准备 > 步骤4:获取 userSig 签名

含 UI 集成

为方便您的使用,减少开发成本,SDK 内置一套通话 UI 界面,使用方式如下所示:
1. 注册 navigatorKey。
import 'package:flutter/material.dart';
import 'package:tccc_user_call_sdk/tccc_user_call_sdk.dart';
import 'package:tccc_user_call_sdk/ui.dart';

final navigatorKey = GlobalKey<NavigatorState>();

void main() {
WidgetsFlutterBinding.ensureInitialized();
// navigatorKey 的全局注册
TcccCallUI.install(navigatorKey: navigatorKey);
// 把 navigatorKey 配置进 MaterialApp
runApp(MaterialApp(navigatorKey: navigatorKey, home: const HomePage()));
}
2. 监听 events 并发起通话。
final userCallInstance = TcccUserCall.instance;

// 先订阅 ready,再 init
userCallInstance.events.listen((event) async {
switch (event.type) {
case 'ready':
// 发起呼叫(只传 channelId)
final started = await userCallInstance.startAudioCall(
channelId,
showUI: true, // 默认值为 true
);
final session = started.data!;
session.events.listen((event) {
if (event.type == 'ended') {
userCallInstance.unInit();
}
});
case 'connecting':
case 'connected':
case 'disconnected':
case 'error':
break;
default:
break;
}
});
3. 创建用户。
userCallInstance.createUser(
sdkAppId: sdkAppId,
userId: userId,
userSig: userSig,
);
4. 初始化。
userCallInstance.init();

无 UI 集成

您可以基于 TcccUserCallSession 的接口和事件回调,自实现通话页面。
1. 监听 events 并发起通话。
final userCallInstance = TcccUserCall.instance;

// 先订阅 ready,再 init
userCallInstance.events.listen((event) async {
switch (event.type) {
case 'ready':
// 发起呼叫(传 showUI: false)
final started = await userCallInstance.startAudioCall(
channelId,
showUI: false,
);
final session = started.data;
session.events.listen((event) {
switch (event.type) {
case 'warning':
// (event as TcccWarningEvent).code / .serverType.trtc → TRTC 警告码文档
break;
case 'newDTMF':
// (event as TcccNewDTMFEvent).tone / originator / duration
break;
case 'muted':
case 'unmuted':
// muted / unmuted
break;
case 'error':
// 可见下方错误码表格
break;
case 'networkquality':
// 当前值也在 status.uplinkQuality / downlinkQuality
break;
case 'disconnected':
case 'connecting':
case 'connected':
break;
case 'loginExpired':
break;
case 'onRoomEntered':
break;
case 'progress':
// (event as TcccProgressEvent).response.statusCode / reasonPhrase
break;
case 'accepted':
// SIP 200。(event as TcccAcceptedEvent).response.statusCode
break;
case 'confirmed':
// 当对方已接听并且本地协议栈确认后(发送了 ack 信令)会触发该事件。无事件对象参数。
break;
case 'ended':
case 'failed':
// (event as TcccEndedEvent / TcccFailedEvent).cause / .originator
user.unInit();
break;
default:
break;
}
});
case 'connecting':
case 'connected':
case 'disconnected':
// connecting.attempts;disconnected.error / .code / .reason
break;
case 'error':
// 可见下方错误码表格
break;
default:
break;
}
});
2. 创建用户。
userCallInstance.createUser(
sdkAppId: sdkAppId,
userId: userId,
userSig: userSig,
);
3. 初始化。
await userCallInstance.init();
4. 通话中操作。
// 以下是通话中需要使用的方法, 请按需调用
await session.muteAudio(true);
await session.setAudioRoute(TcccAudioRoute.speakerphone);
await session.sendDTMFTone('1');
await session.terminate();

方法及事件说明

TcccUserCall 方法

TcccUserCall.instance 是单例。

createUser

创建 user。
参数
类型
必填
说明
sdkAppId
int
腾讯云联络中心 SDKAppId。
userId
String
不能为空、不能含 @。
userSig
String
业务侧后台签发。
userClientData
String
CreateUserSig 带了 ClientData 时必填且一致;否则不要指定。
返回值: TcccResult<TcccUserCall>
final userCallInstance = TcccUserCall.instance;
final created = userCallInstance.createUser(
sdkAppId: 1400000000,
userId: userId,
userSig: userSig,
);

init

初始化 SDK。
返回值: TcccOutcome
final userCallInstance = TcccUserCall.instance;
final ready = userCallInstance.init();

updateUserSig

替换已绑定的 userSig。
参数
类型
必填
说明
userSig
String
业务侧后台签发的新 userSig。
userClientData
String?
同时替换时传入;不传则保持原值。CreateUserSig 带了 ClientData 时须与签发一致。
返回值: TcccOutcome
final userCallInstance = TcccUserCall.instance;
userCallInstance.updateUserSig(userSig);

unInit

反初始化 SDK,并清掉 createUser 接口创建的 user 的身份。通话结束后或页面销毁时调用。
返回值: TcccOutcome
final userCallInstance = TcccUserCall.instance;
userCallInstance.unInit();

startAudioCall

发起音频呼叫。
说明:
请在 ready event 触发之后调用。
参数
类型
必填
说明
audioChannelId
String
渠道 ID。
showUI
bool
是否弹出内置通话 UI。默认 true。
peerDisplayName
String?
对端展示名(内置 UI)。
peerSubtitle
String?
对端子标题(内置 UI)。
ringback
TcccRingback
默认 builtIn;none 则不播放内置回铃。
返回值: TcccResult<Session>
final userCallInstance = TcccUserCall.instance;
final started = await userCallInstance.startAudioCall(channelId);
final session = started.data;

TcccUserCall 事件

事件名
类型
触发时机
connecting / connected / disconnected
TcccConnectingEvent / TcccConnectedEvent / TcccDisconnectedEvent
首次 init 为 connecting → connected → ready。
ready
TcccReadyEvent
第一次 init 成功,只一次。
error
TcccErrorEvent
createUser / init / 占座失败。
warning
TcccWarningEvent
仅 -11001(未安装内置 UI 仍外呼)。

Session 方法

startAudioCall 成功后返回的会话实例。

terminate

挂断当前通话。已接通发挂断,未接通则取消。
返回值: TcccOutcome
await session.terminate();

muteAudio

静音 / 取消静音本地麦克风。
参数
类型
必填
说明
mute
bool
true 静音,false 取消静音。
返回值: TcccOutcome
await session.muteAudio(true);
await session.muteAudio(false);

sendDTMFTone

发送单个 DTMF(IVR 按键)。连续调用会排队。
参数
类型
必填
说明
tone
String
单个字符:0–9、#、*、A–D。
duration
int?
INFO Duration=,毫秒。默认 100,夹取 70–6000。
interToneGap
int?
与 Web 相同:队列间隔为 duration + interToneGap。默认 500,下限 50。
返回值: TcccOutcome
await session.sendDTMFTone('1');
await session.sendDTMFTone('#', duration: 160);
// await session.sendDTMFTone('1', duration: 160, interToneGap: 500);

setAudioRoute

切换听筒 / 扬声器。
参数
类型
必填
说明
route
TcccAudioRoute
earpiece 听筒;speakerphone 扬声器。
返回值: TcccOutcome
await session.setAudioRoute(TcccAudioRoute.speakerphone);
// await session.setAudioRoute(TcccAudioRoute.earpiece);

Session 事件

会话事件, 明细如下表所示.
事件名
类型
触发时机
progress
TcccProgressEvent
18x。originator、response.statusCode / reasonPhrase
warning
TcccWarningEvent
警告,通话继续。
newDTMF
TcccNewDTMFEvent
DTMF 发送成功。
muted / unmuted
TcccMutedEvent / TcccUnmutedEvent
本地静音变化。audio;当前值也在 isMuted().audio
error
TcccErrorEvent
进房后错误等(通话继续或已接通后的非终态错误)。进房后 TRTC onError 的 serverType 为 trtc,其余为 tccc。
networkquality
TcccNetworkQualityEvent
质量变化。uplinkNetworkQuality / downlinkNetworkQuality;当前值也在 status。
connecting / connected / disconnected
TcccConnectingEvent / TcccConnectedEvent / TcccDisconnectedEvent
TRTC。serverType 为 trtc。
loginExpired
TcccLoginExpiredEvent
换票失败。
onRoomEntered
TcccOnRoomEnteredEvent
TRTC 进房成功。纯 IVR 不发。
accepted
TcccAcceptedEvent
SIP 200。originator、response.statusCode / reasonPhrase。
confirmed
TcccConfirmedEvent
INVITE 2xx 已 ACK。Web demo 此时切到通话中。originator 主叫 ACK 为 local。可通话仍看 status.state == accepted。
ended
TcccEndedEvent
已接通后结束。cause / originator / 可选 failure。同时完成 session.ended。
failed
TcccFailedEvent
未接通失败(拒接、取消、刷票失败、TRTC 踢房等)。cause / originator。同时完成 session.ended。不另发 fatal error。
示例代码:
session.events.listen((event) {
switch (event.type) {
case 'ended':
case 'failed':
break;
default:
break;
}
});

结束原因 ended.cause

值(cause / cause.value)
含义
terminated / Terminated
已接通后挂断。originator.local 本地,remote 对端 BYE。ended.success == true。
canceled / Canceled
未接通取消。originator.local 本地,remote 对端。
busy / Busy
486、600。
rejected / Rejected
403、603。
notFound / Not Found
404、604。
unavailable / Unavailable
480、410、408、430。
noAnswer / No Answer
TcccConfig.noAnswerTimeout:第一次 18x 后仍无 200。默认不设上限。
expires / Expires
Session Timer 超时。
requestTimeout / Request Timeout
信令事务超时(不是 SIP 408)。
connectionError / Connection Error
WSS / 网络。
sipFailureCode / SIP Failure Code
其它 SIP 失败。
internalError / Internal Error
内部错误(含 18x 无媒体 20002)。
authenticationError / Authentication Error
userSig / 换票失败;SIP 401、407。
webRtcError / WebRTC Error
TRTC 进房失败或踢房(Rtc.KickedOut 走 failed)。
addressIncomplete / Address Incomplete
484、424。
redirected / Redirected
300、301、302、305、380。
incompatibleSdp / Incompatible SDP
488、606。
dialogError / Dialog Error
Dialog 错误。
userDeniedMediaAccess / User Denied Media Access
麦克风被拒。
rtpTimeout / RTP Timeout
媒体超时。

错误码

错误码
错误码类型
来源
触发时机
-11010
ErrorCode.User.instanceExists
返回值
未 unInit 再 createUser。
-11004
ErrorCode.User.notReady
返回值
未 createUser / 未 init。
-11002
ErrorCode.User.invalidParam
返回值
sdkAppId / userSig / channelId 空或非法。
20003
ErrorCode.User.invalidUserId
返回值
userId 或 channelId 非法。
-11003
ErrorCode.User.disconnected
返回值或 ended
init 握手失败;或通话中重连耗尽。
-10004
ErrorCode.User.cannotReset
返回值
通话中 unInit。
-11005
ErrorCode.User.callInProgress
仅返回值
已有一路呼叫。
-11006
ErrorCode.Session.invalidState
仅返回值
已结束的通话上再操作。
-11007
ErrorCode.Session.endedBeforeMilestone
里程碑 Future
通话已结束,该 sent / ringing / accepted 没走到。
-10002
ErrorCode.User.invalidUserSig
ended
空 userSig / 空 jwt / sdkLogin bizCode -2014 / 二次 401。
-10003
ErrorCode.Cgi.bizError
ended
sdkLogin HTTP 成功但 errorCode != 0(-2014 除外)。failure.detail 有 bizCode / httpStatus / requestId。
-10001
ErrorCode.Cgi.error
ended
鉴权网络失败或 HTTP 4xx/5xx。failure.detail 有 bizCode / httpStatus / requestId。
20002
ErrorCode.Session.answerFailure
ended
18x 无可用媒体。
-3301
ErrorCode.Rtc.joinRoomFailed
ended
进房失败。
-3325
ErrorCode.Rtc.kickedOut
ended(failed)
被踢 / 房间解散。
100–699
SIP 状态(failure.sipStatusCode 同值)
ended
对端 SIP。忙/拒/找不到看 ended.cause,不要按码硬编码。
20006
ErrorCode.Dtmf.invalidState
仅返回值
未接通发 DTMF。
20005
ErrorCode.Dtmf.invalidParam
返回值 + session.events error
DTMF 字符非法。
-11008
ErrorCode.Dtmf.queueFull
仅返回值
DTMF 队列满。
20004
ErrorCode.Dtmf.sendFailed
返回值 + session.events error
DTMF INFO 发送抛错,或队列 drain 时已无 InviteSession。
20007
ErrorCode.Dtmf.timeout
返回值 + session.events error
DTMF INFO 超时或 408。
20008
ErrorCode.Dtmf.transportError
返回值 + session.events error
DTMF INFO 传输层失败。
20009
ErrorCode.Dtmf.dialogError
返回值 + session.events error
DTMF INFO 481 或无 dialog。
20010
ErrorCode.Dtmf.responseError
返回值 + session.events error
DTMF INFO 对端 4xx/5xx(非 408/481)。
-1332
ErrorCode.Rtc.audioRouteFail
仅返回值
setAudioRoute 异常。
-13xx / -33xx
ErrorCode.Rtc.*(除 -3301 / -3325)
session.events error
进房后 TRTC onError 原样,通话继续。具体查看 TRTC 错误码


帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈