Flutter VoIP通信插件voip24h_sdk_mobile的使用
Flutter VoIP通信插件voip24h_sdk_mobile的使用
Flutter Voip24h-SDK Mobile #
目录 #
功能 #
| 功能 | 描述 |
|---|---|
| CallKit | • 登录/登出/刷新SIP账户连接 • 拨打电话/接听来电 • 接受/拒绝/挂断来电 • 暂停/恢复通话 • 保持/取消保持通话 • 开启/关闭麦克风 • 获取麦克风状态 • 开启/关闭扬声器 • 获取扬声器状态 • 转接通话 • 发送DTMF音 |
| Graph | • 获取访问令牌 • 请求API(参考https://docs-sdk.voip24h.vn/) |
要求 #
- 操作系统平台:
- Android ->
minSdkVersion: 23 - IOS ->
iOS Deployment Target: 9.0
- Android ->
- 权限:在运行时声明和授权
-
Android: 在文件
AndroidManifest.xml<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECORD_AUDIO"/> -
IOS: 在文件
Info.plist<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key><true/> </dict> <key>NSMicrophoneUsageDescription</key> <string>{Your permission microphone description}</string>
-
安装 #
使用终端:
flutter pub add voip24h_sdk_mobile
关联模块:
- IOS:
- 在
ios/Podfile文件中:... # 声明库 platform :ios, '9.0' source "https://gitlab.linphone.org/BC/public/podspec.git"target ‘Your Project’ do … use_frameworks! use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) # 声明库 pod 'linphone-sdk-novideo' , '5.1.36'end
- 在
ios文件夹打开终端,输入以下命令:rm -rf Pods/ pod install
- 在
模块声明 #
import 'package:voip24h_sdk_mobile/voip24h_sdk_mobile.dart';
import 'package:voip24h_sdk_mobile/callkit/utils/sip_event.dart';
import 'package:voip24h_sdk_mobile/callkit/utils/transport_type.dart';
import 'package:voip24h_sdk_mobile/graph/extensions/extensions.dart';
import 'package:voip24h_sdk_mobile/callkit/model/sip_configuration.dart';
// TODO: 使用模块
CallKit #
-
声明 sipConfiguration: #
var sipConfiguration = SipConfigurationBuilder(extension: "extension", domain: "domain", password: "password") .setKeepAlive(true/false) // 可选参数(布尔值) .setPort(port) // 可选参数(整数) .setTransport(TransportType.Udp/TransportType.Tcp/TransportType.Tls) // 可选参数(枚举类型) .build();
功能 |
方法和参数 (使用异步/等待或.then来获取返回数据) |
返回结果及属性 |
|---|---|---|
| 初始化 | Voip24hSdkMobile.callModule.initSipModule(sipConfiguration) | 无 |
| 获取SIP账户注册状态 | Voip24hSdkMobile.callModule.getSipRegistrationState() | value: String error: String |
| 注销SIP账户 | Voip24hSdkMobile.callModule.unregisterSipAccount() | value: bool error: String |
| 刷新SIP账户 | Voip24hSdkMobile.callModule.refreshSipAccount() | value: bool error: String |
| 拨打电话 | Voip24hSdkMobile.callModule.call(phoneNumber) | value: bool error: String |
| 挂断电话 | Voip24hSdkMobile.callModule.hangup() | value: bool error: String |
| 接听来电 | Voip24hSdkMobile.callModule.answer() | value: bool error: String |
| 拒绝来电 | Voip24hSdkMobile.callModule.reject() | value: bool error: String |
| 转接通话 | Voip24hSdkMobile.callModule.transfer("extension") | value: bool error: String |
| 获取通话ID | Voip24hSdkMobile.callModule.getCallId() | value: String error: String |
| 获取未接来电数量 | Voip24hSdkMobile.callModule.getMissedCalls() | value: int error: String |
| 暂停通话 | Voip24hSdkMobile.callModule.pause() | value: bool error: String |
| 恢复通话 | Voip24hSdkMobile.callModule.resume() | value: bool error: String |
| 开启/关闭麦克风 | Voip24hSdkMobile.callModule.toggleMic() | value: bool error: String |
| 获取麦克风状态 | Voip24hSdkMobile.callModule.isMicEnabled() | value: bool error: String |
| 开启/关闭扬声器 | Voip24hSdkMobile.callModule.toggleSpeaker() | value: bool error: String |
| 获取扬声器状态 | Voip24hSdkMobile.callModule.isSpeakerEnabled() | value: bool error: String |
| 发送DTMF音 | Voip24hSdkMobile.callModule.sendDTMF("number#") | value: bool error: String |
-
SIP事件监听器: #
Voip24hSdkMobile.callModule.eventStreamController.stream.listen((event) { switch (event['event']) { case SipEvent.AccountRegistrationStateChanged: { var body = event['body']; // TODO } break; case SipEvent.Ring: { // TODO } break; case ... break; } });…
@override void dispose() { Voip24hSdkMobile.callModule.eventStreamController.close(); super.dispose(); }
事件名称 |
返回结果及属性 |
属性特性 |
|---|---|---|
| SipEvent.AccountRegistrationStateChanged | body = { registrationState: String, message: String } |
registrationState: SIP连接状态 (None/Progress/Ok/Cleared/Failed) message: 描述状态的字符串 |
| SipEvent.Ring | body = { extension: String, phoneNumber: String callType: String } |
extension: 分机号 phoneNumber: 来电号码 callType: 通话类型(inbound/outbound) |
| SipEvent.Up | body = { callId: String } |
callId: 通话ID |
| SipEvent.Hangup | body = { duration: int } |
duration: 通话时长(毫秒) |
| SipEvent.Paused | 无 | |
| SipEvent.Resuming | 无 | |
| SipEvent.Missed | body = { phoneNumber: String, totalMissed: int } |
phoneNumber: 来电号码 totalMissed: 总未接来电数 |
| SipEvent.Error | body = { message: String } |
message: 错误信息 |
推送通知 #
- IOS: 我们使用Apple Push Notification service (APNs) 进行后台状态下的来电推送通知
- 步骤1: 创建APNs Auth Key
- 访问Apple Developer创建证书

- 选择VoIP Services Certificate

- 选择你的应用ID。每个想使用VoIP服务的应用都需要单独的VoIP服务证书。VoIP服务证书绑定到应用ID上,允许服务器通知(Voip24h)连接到VoIP服务以向你的应用发送推送通知。

- 下载证书并用Keychain Access打开

- 将证书导出为.p12格式

- 将.p12格式的证书转换为.pem格式并提交给Voip24h配置
openssl pkcs12 -in path_your_certificate.p12 -out path_your_certificate.pem -nodes
- 访问Apple Developer创建证书
- 步骤1: 创建APNs Auth Key
-
步骤2: 配置你的项目以接收来电推送通知 -> 从iOS 10开始,使用CallKit + PushKit
- 为了使用CallKit框架+PushKit框架,我们推荐使用库callkeep,在pubspec.yaml中添加:
dependencies: .... callkeep: git: url: https://github.com/Voip24h-Corp/callkeep ref: master然后运行命令:
flutter pub get cd ios pod install- 在你的项目中添加Push Notifications,并选择Voice over IP,Background fetch,Remote notifications,Background processing(Background Modes)。

- 当启动应用时,callkeep会为应用客户生成注册令牌。使用该令牌注册到服务器Voip24h。
import 'package:callkeep/callkeep.dart'; ... callKeep.on<CallKeepPushKitToken>((value) => { tokenPushIOS = value.token ?? "" }); callKeep.setup(context, <String, dynamic>{ 'ios': { 'appName': 'Example', } });// tokenGraph: 通过API Graph生成的访问令牌 // token: 通过pushkit生成的设备令牌 // sipConfiguration: SIP注册时的参数 // isIOS: 默认为false // appId: iOS应用的Bundle ID // isProduction: true(生产环境) / false(开发环境) // deviceMac: 设备MAC地址
Voip24hSdkMobile.pushNotificationModule.registerPushNotification( tokenGraph: tokenGraph, token: tokenPushIOS, sipConfiguration: sipConfiguration, isIOS: true, appId: packageInfo.packageName, isProduction: false, deviceMac: iosDeviceInfo.identifierForVendor ).then((value) => { print(value) }, onError: (error) => { print(error) });
必须在使用推送通知功能前在iOS上授予通知权限。
- 注册接收来自Voip24h服务器的推送通知
• 重要提示: 接收到来自Voip24h服务器的推送通知后,根据上述的Callkit和PushKit机制,你必须首先显示系统的通话界面(假的通话),然后立即重新登录分机以接收来自Voip24h的真实通话信号,此时所有如接听/拒绝等通话操作才能正常工作。
callKeep.on<CallKeepReceivedPushNotification>((value) => { callId = value.callId ?? "", testCallKit() }); callKeep.on<CallKeepPerformAnswerCallAction>((value) => { answer() }); callKeep.on<CallKeepPerformEndCallAction>((value) => { reject() });- 取消注册接收推送通知
Voip24hSdkMobile.pushNotificationModule.unregisterPushNotification( sipConfiguration: sipConfiguration, isIOS: true, appId: packageInfo.packageName ).then((value) => { print(value) }, onError: (error) => { print(error) }); - 在你的项目中添加Push Notifications,并选择Voice over IP,Background fetch,Remote notifications,Background processing(Background Modes)。
- Android: 我们使用Firebase Cloud Messaging (FCM) 进行后台状态下的来电推送通知
- 步骤1: 创建API Token
- 步骤2: 配置你的项目以接收来电推送通知 -> 我们建议你使用库Firebase Messaging
- Flutter包:
flutter pub add firebase_core flutter pub add firebase_messaging根据Firebase Messaging文档配置你的项目
- 当启动应用时,Firebase Messaging会为应用客户生成注册令牌。使用该令牌注册到服务器Voip24h
String? token = await messaging.getToken(); .... if(token != null) { // tokenGraph: 通过API Graph生成的访问令牌 // token: 通过Firebase生成的设备令牌 // sipConfiguration: SIP注册时的参数 // isAndroid: 默认为false // appId: Android应用的包名 // isProduction: true(生产环境) / false(开发环境) // deviceMac: 设备MAC地址Voip24hSdkMobile.pushNotificationModule.registerPushNotification( tokenGraph: tokenGraph, token: token, sipConfiguration: sipConfiguration, isAndroid: true, appId: packageInfo.packageName, isProduction: false, deviceMac: androidDeviceInfo.androidId ).then((value) => { print(value) }, onError: (error) => { print(error) }); }
- 从Android 13 (SDK 32) 开始,接收推送通知需要请求通知权限 https://developer.android.com/develop/ui/views/notifications/notification-permission。请确保在使用前请求POST_NOTIFICATIONS权限。
- 配置接收推送通知。当收到推送通知时,请重新注册分机以接收来电信号
[@pragma](/user/pragma)('vm:entry-point') Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { if(Platform.isAndroid) { print("Handling a background message: ${message.data}"); await Firebase.initializeApp().whenComplete(() => { localNotificationService.initialNotification().then((value) => { // register sip account here }) }); } } - 取消注册接收推送通知
Voip24hSdkMobile.pushNotificationModule.unregisterPushNotification( sipConfiguration: sipConfiguration, isAndroid: true, appId: packageInfo.packageName ).then((value) => { print(value) }, onError: (error) => { print(error) }); - 配置接收推送通知。当收到推送通知时,请重新注册分机以接收来电信号
- 从Android 13 (SDK 32) 开始,接收推送通知需要请求通知权限 https://developer.android.com/develop/ui/views/notifications/notification-permission。请确保在使用前请求POST_NOTIFICATIONS权限。
Graph #
• key和security certificate由
Voip24h提供
• 请求API: 方法,端点。数据主体可参考https://docs-sdk.voip24h.vn/文档功能方法参数说明返回结果返回结果属性获取访问令牌 Voip24hSdkMobile.graphModule.getAccessToken(apiKey: API_KEY, apiSecert: API_SECERT) • apiKey: String,
• secert:Stringvalue: Oauth
error:String• Oauth: 包含的属性 (token, createAt, expired, isLongAlive)
• error: 错误信息请求API Voip24hSdkMobile.graphModule.sendRequest(token: token, endpoint: endpoint, body: body) • method: MethodRequest(MethodRequest.POST, MethodRequest.GET,...)
• endpoint: 请求URL的末尾部分:"call/find", "call/findone",...
• token: 访问令牌
• params: 数据主体对象如 { "offset": "0", "limit": "25" }value: Map<String, dynamic>
error:String• value: 返回结果的形式为键值对
• error: 错误码获取数据对象 value.getData()
(扩展函数形式)无 object: Objectobject包含的数据属性可参考https://docs-sdk.voip24h.vn/文档中的返回结果描述 获取数据对象列表 value.getDataList()
(扩展函数形式)无 List <Object>每个object包含的数据属性可参考https://docs-sdk.voip24h.vn/文档中的返回结果描述 获取状态码 value.statusCode()
(扩展函数形式)无 int状态码 获取消息 value.message()
(扩展函数形式)无 String描述状态的字符串 获取限制 value.limit()
(扩展函数形式)无 int找到数据的数量限制 获取偏移量 value.offset()
(扩展函数形式)无 int找到数据的起始位置 获取总数 value.total()
(扩展函数形式)无 int数据的总数量 获取排序方式 value.isSort()
(扩展函数形式)无 String数据的排序方式
- 为了使用CallKit框架+PushKit框架,我们推荐使用库callkeep,在pubspec.yaml中添加:
更多关于Flutter VoIP通信插件voip24h_sdk_mobile的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter VoIP通信插件voip24h_sdk_mobile的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用voip24h_sdk_mobile插件进行VoIP通信的示例代码。请注意,这只是一个基本的示例,具体实现可能需要根据您的实际需求进行调整。同时,确保您已经按照插件的官方文档完成了必要的配置和权限申请。
首先,您需要在pubspec.yaml文件中添加voip24h_sdk_mobile插件的依赖:
dependencies:
flutter:
sdk: flutter
voip24h_sdk_mobile: ^最新版本号 # 请替换为插件的实际最新版本号
然后,运行flutter pub get来安装依赖。
接下来,我们需要在Flutter项目中初始化VoIP SDK,并进行基本的通话操作。以下是一个示例代码:
import 'package:flutter/material.dart';
import 'package:voip24h_sdk_mobile/voip24h_sdk_mobile.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: VoIPPage(),
);
}
}
class VoIPPage extends StatefulWidget {
@override
_VoIPPageState createState() => _VoIPPageState();
}
class _VoIPPageState extends State<VoIPPage> {
VoIP24hSdk? voipSdk;
@override
void initState() {
super.initState();
// 初始化VoIP SDK
initVoIPSdk();
}
void initVoIPSdk() async {
// 替换为您的API Key和Secret
String apiKey = "YOUR_API_KEY";
String apiSecret = "YOUR_API_SECRET";
voipSdk = VoIP24hSdk(apiKey: apiKey, apiSecret: apiSecret);
// 注册VoIP回调(例如来电、挂断等)
voipSdk?.setCallEventListener((callEvent) {
if (callEvent.type == CallEventType.Incoming) {
// 处理来电
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text("来电"),
content: Text("来自: ${callEvent.callerId}"),
actions: [
TextButton(
onPressed: () {
// 拒绝来电
voipSdk?.rejectCall(callEvent.callId);
Navigator.of(context).pop();
},
child: Text("拒绝"),
),
TextButton(
onPressed: () {
// 接听来电
voipSdk?.acceptCall(callEvent.callId);
Navigator.of(context).pop();
},
child: Text("接听"),
),
],
),
);
} else if (callEvent.type == CallEventType.Ended) {
// 处理通话结束
print("通话结束: ${callEvent.callId}");
}
});
// 注册VoIP服务(确保在后台运行时也能接收来电)
await voipSdk?.registerVoIPService();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("VoIP通信示例"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () async {
// 发起通话(替换为实际的被叫号码)
String calleeId = "callee_id";
await voipSdk?.makeCall(calleeId);
},
child: Text("发起通话"),
),
],
),
),
);
}
@override
void dispose() {
// 注销VoIP服务并释放资源
voipSdk?.unregisterVoIPService();
voipSdk = null;
super.dispose();
}
}
在这个示例中,我们完成了以下操作:
- 在
pubspec.yaml中添加了voip24h_sdk_mobile插件的依赖。 - 在
VoIPPage中初始化了VoIP SDK,并设置了来电回调。 - 提供了发起通话和接听/拒绝来电的基本功能。
- 在
dispose方法中注销了VoIP服务并释放了资源。
请注意,这只是一个基本的示例。在实际应用中,您可能还需要处理更多的细节,如音频管理、UI优化、错误处理等。同时,确保您已经阅读并理解了voip24h_sdk_mobile插件的官方文档,以便更好地集成和使用该插件。




