Flutter VoIP通信插件flutter_voip_kit的使用
Flutter VoIP通信插件 flutter_voip_kit
的使用
flutter_voip_kit
是一个用于在Flutter应用中实现VoIP(Voice over Internet Protocol)通信的插件。它利用iOS的CallKit和Android的Telecom库来创建和接收具有原生功能的呼叫,例如在用户的锁屏界面上弹出呼叫通知。
开始使用
添加依赖
首先,在你的pubspec.yaml
文件中添加flutter_voip_kit
作为依赖项:
dependencies:
flutter_voip_kit: ^latest_version
记得替换^latest_version
为最新的版本号。
设置
iOS设置
- 在Xcode中为项目添加VoIP后台模式:
- 打开Xcode项目。
- 选择你的项目目标。
- 转到“Signing & Capabilities”选项卡。
- 点击左上角的“+ Capability”按钮。
- 添加“Background Modes”,然后勾选“Voice over IP”。
Android设置
-
在
AndroidManifest.xml
中添加权限:<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.CALL_PHONE" />
-
添加服务声明:
<service android:name="com.example.flutter_voip_kit.VoipConnectionService" android:label="VoipConnectionService" android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"> <intent-filter> <action android:name="android.telecom.ConnectionService" /> </intent-filter> </service>
API 使用
初始化插件
初始化flutter_voip_kit
插件,并传入一个处理所有VOIP事件的回调函数:
FlutterVoipKit.init(callStateChangeHandler: callStateChangeHandler);
示例回调函数
下面是一个处理不同呼叫状态的示例回调函数:
Future<bool> myCallStateChangeHandler(Call call) async {
dev.log("call state changed listener: $call");
switch (call.callState) {
case CallState.connecting:
await Future.delayed(const Duration(seconds: 3));
return true;
case CallState.active:
return true;
case CallState.ended:
return true;
case CallState.failed:
return true;
case CallState.held:
return true;
default:
return false;
}
}
监听活跃呼叫列表
监听活跃呼叫列表的变化,并更新UI:
FlutterVoipKit.callListStream.listen((allCalls) {
setState(() {
calls = allCalls;
});
});
报告来电
报告设备收到一个新的来电:
FlutterVoipKit.reportIncomingCall(handle: "1234567890", uuid: Uuid().v4());
启动呼叫
启动一个新的外呼:
FlutterVoipKit.startCall("1234567890");
结束呼叫
结束当前呼叫:
call.end();
持有/恢复呼叫
将呼叫置于保持状态或从中恢复:
call.hold(onHold: !(call.callState == CallState.held));
完整示例Demo
以下是完整的示例代码,展示了如何集成flutter_voip_kit
插件并实现基本的VoIP功能:
import 'dart:developer' as dev;
import 'dart:math';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_voip_kit/call.dart';
import 'package:flutter_voip_kit/flutter_voip_kit.dart';
import 'package:uuid/uuid.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
[@override](/user/override)
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<Call> calls = [];
bool hasPermission = false;
[@override](/user/override)
void initState() {
super.initState();
FlutterVoipKit.init(callStateChangeHandler: callStateChangeHandler);
checkPermissionsUntilGranted();
FlutterVoipKit.callListStream.listen((allCalls) {
setState(() {
calls = allCalls;
});
});
}
Future<bool> callStateChangeHandler(Call call) async {
dev.log("call state changed listener: $call");
setState(() {});
switch (call.callState) {
case CallState.connecting:
dev.log("---------------> Call connecting");
await Future.delayed(const Duration(seconds: 3));
return true;
case CallState.active:
dev.log("---------> Call active");
return true;
case CallState.ended:
dev.log("---------> Call ended");
await Future.delayed(const Duration(seconds: 1));
return true;
case CallState.failed:
dev.log("---------> Call failed");
return true;
case CallState.held:
dev.log("---------> Call held");
return true;
default:
return false;
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Voip Kit Example'),
),
body: !hasPermission
? Center(
child: ElevatedButton(
child: Text("Grant Phone Permissions"),
onPressed: () {
FlutterVoipKit.checkPermissions(openSettings: true)
.then((value) => setState(() {
hasPermission = value;
}));
},
),
)
: SafeArea(
child: Column(
children: [
ElevatedButton(
child: Text("Simulate incoming call"),
onPressed: () {
Future.delayed(const Duration(seconds: 2)).then((value) {
FlutterVoipKit.reportIncomingCall(
handle: "${Random().nextInt(10)}" * 9,
uuid: Uuid().v4());
});
},
),
ElevatedButton(
child: Text("Start outgoing call"),
onPressed: () {
FlutterVoipKit.startCall(
"${Random().nextInt(10)}" * 9,
);
},
),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
final call = calls[index];
return Container(
color: call.callState == CallState.active
? Colors.green[300]
: call.callState == CallState.held
? Colors.yellow[800]
: (call.callState == CallState.connecting
? Colors.yellow[200]
: Colors.red),
padding: EdgeInsets.all(16.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Text("Number: ${call.address}"),
),
if (call.callState == CallState.connecting)
CircularProgressIndicator(),
if (call.callState != CallState.connecting &&
call.callState != CallState.incoming)
ElevatedButton(
onPressed: () {
call.hold(
onHold: !(call.callState ==
CallState.held));
},
child: Text(call.callState == CallState.held
? "Resume"
: "Hold"),
),
if (call.callState == CallState.active) ...[
IconButton(
icon: Icon(
Icons.phone_disabled_sharp,
size: 30,
color: Colors.red,
),
onPressed: () {
call.end();
},
),
IconButton(
icon: Icon(
call.muted ? Icons.mic : Icons.mic_off,
size: 30,
),
onPressed: () {
call.mute(muted: !call.muted);
})
]
],
),
);
},
itemCount: calls.length,
),
)
],
),
),
);
}
void checkPermissionsUntilGranted() {
Future.delayed(const Duration(milliseconds: 100)).then((value) async {
hasPermission =
await FlutterVoipKit.checkPermissions(openSettings: false);
bool first = true;
while (!hasPermission) {
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("No Permissions"),
content: Text(
"You need to allow this app to use your phone and add it to the phone list in settings."),
actions: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Ok"),
)
],
);
},
);
hasPermission =
await FlutterVoipKit.checkPermissions(openSettings: !first);
first = false;
if (!hasPermission) {
await Future.delayed(const Duration(seconds: 1));
}
}
setState(() {});
});
}
}
更多关于Flutter VoIP通信插件flutter_voip_kit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复