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:String
value: 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: Object
object包含的数据属性可参考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
插件的官方文档,以便更好地集成和使用该插件。