Flutter来电界面集成插件waterbus_callkit_incoming的使用
Flutter来电界面集成插件waterbus_callkit_incoming的使用
A Flutter 插件用于在您的 Flutter 应用程序中显示来电界面(Android 自定义/Callkit 适用于 iOS)。
⭐ 特性
- 显示来电
- 开始通话
- 自定义 Android/Callkit 适用于 iOS
- 使用 Pushkit/VoIP 的示例
iOS: 仅在真机上工作,模拟器不支持(Callkit 框架在模拟器上不工作)
🚀 安装
1. 安装包
运行以下命令:
flutter pub add flutter_callkit_incoming
在 pubspec.yaml
中添加依赖项:
dependencies:
flutter_callkit_incoming: any
2. 配置项目
Android
在 AndroidManifest.xml
中添加以下权限:
<manifest...>
...
<!--
使用以从互联网加载图像
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
在 proguard-rules.pro
中添加以下规则以避免混淆密钥:
-keep class com.hiennv.flutter_callkit_incoming.** { *; }
iOS
在 Info.plist
中添加以下配置:
<key>UIBackgroundModes</key>
<array>
<string>voip</string>
<string>remote-notification</string>
<string>processing</string> <!-- 如果需要可以添加此条目 -->
</array>
3. 使用
导入
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
接收到来电
this._currentUuid = _uuid.v4();
CallKitParams callKitParams = CallKitParams(
id: _currentUuid,
nameCaller: 'Hien Nguyen',
appName: 'Callkit',
avatar: 'https://i.pravatar.cc/100',
handle: '0123456789',
type: 0,
textAccept: 'Accept',
textDecline: 'Decline',
missedCallNotification: NotificationParams(
showNotification: true,
isShowCallback: true,
subtitle: 'Missed call',
callbackText: 'Call back',
),
duration: 30000,
extra: <String, dynamic>{'userId': '1a2b3c4d'},
headers: <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
android: const AndroidParams(
isCustomNotification: true,
isShowLogo: false,
ringtonePath: 'system_ringtone_default',
backgroundColor: '#0955fa',
backgroundUrl: 'assets/test.png',
actionColor: '#4CAF50',
incomingCallNotificationChannelName: "Incoming Call",
missedCallNotificationChannelName: "Missed Call"
),
ios: IOSParams(
iconName: 'CallKitLogo',
handleType: 'generic',
supportsVideo: true,
maximumCallGroups: 2,
maximumCallsPerCallGroup: 1,
audioSessionMode: 'default',
audioSessionActive: true,
audioSessionPreferredSampleRate: 44100.0,
audioSessionPreferredIOBufferDuration: 0.005,
supportsDTMF: true,
supportsHolding: true,
supportsGrouping: false,
supportsUngrouping: false,
ringtonePath: 'system_ringtone_default',
),
);
await FlutterCallkitIncoming.showCallkitIncoming(callKitParams);
注意:对于 Firebase 消息,请使用 @pragma('vm:entry-point')
请求通知权限(Android 13+)
对于 Android 13 及以上版本,请在调用 showCallkitIncoming
之前请求通知权限:
await FlutterCallkitIncoming.requestNotificationPermission({
"rationaleMessagePermission": "通知权限是必需的,以便显示通知。",
"postNotificationMessageRequired": "通知权限是必需的,请从设置中允许通知权限。"
});
显示未接来电通知
this._currentUuid = _uuid.v4();
CallKitParams params = CallKitParams(
id: _currentUuid,
nameCaller: 'Hien Nguyen',
handle: '0123456789',
type: 1,
textMissedCall: 'Missed call',
textCallback: 'Call back',
extra: <String, dynamic>{'userId': '1a2b3c4d'},
);
await FlutterCallkitIncoming.showMissCallNotification(params);
开始外呼
this._currentUuid = _uuid.v4();
CallKitParams params = CallKitParams(
id: this._currentUuid,
nameCaller: 'Hien Nguyen',
handle: '0123456789',
type: 1,
extra: <String, dynamic>{'userId': '1a2b3c4d'},
ios: IOSParams(handleType: 'generic')
);
await FlutterCallkitIncoming.startCall(params);
结束来电
await FlutterCallkitIncoming.endCall(this._currentUuid);
结束所有来电
await FlutterCallkitIncoming.endAllCalls();
获取活跃的通话
await FlutterCallkitIncoming.activeCalls();
输出:
[{"id": "8BAA2B26-47AD-42C1-9197-1D75F662DF78", ...}]
设置通话已连接状态(仅限 iOS)
await FlutterCallkitIncoming.setCallConnected(this._currentUuid);
在通话被接受或开始通话后调用此函数。通常在 WebRTC/P2P 建立时调用。
获取设备 VoIP 推送令牌
await FlutterCallkitIncoming.getDevicePushTokenVoIP();
输出:
d6a77ca80c5f09f87f353cdd328ec8d7d34e92eb108d046c91906f27f54949cd
确保在 AppDelegate.swift
中使用 SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)
(示例:Example)
func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
print(credentials.token)
let deviceToken = credentials.token.map { String(format: "%02x", $0) }.joined()
// Save deviceToken to your server
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)
}
func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
print("didInvalidatePushTokenFor")
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP("")
}
监听事件
FlutterCallkitIncoming.onEvent.listen((CallEvent event) {
switch (event!.event) {
case Event.actionCallIncoming:
// TODO: 收到来电
break;
case Event.actionCallStart:
// TODO: 开始外呼
// TODO: 在 Flutter 中显示呼叫屏幕
break;
case Event.actionCallAccept:
// TODO: 接受来电
// TODO: 在 Flutter 中显示呼叫屏幕
break;
case Event.actionCallDecline:
// TODO: 拒绝来电
break;
case Event.actionCallEnded:
// TODO: 结束来电
break;
case Event.actionCallTimeout:
// TODO: 未接来电
break;
case Event.actionCallCallback:
// TODO: 仅限 Android - 点击未接来电通知中的“回拨”
break;
case Event.actionCallToggleHold:
// TODO: 仅限 iOS
break;
case Event.actionCallToggleMute:
// TODO: 仅限 iOS
break;
case Event.actionCallToggleDmtf:
// TODO: 仅限 iOS
break;
case Event.actionCallToggleGroup:
// TODO: 仅限 iOS
break;
case Event.actionCallToggleAudioSession:
// TODO: 仅限 iOS
break;
case Event.actionDidUpdateDevicePushTokenVoip:
// TODO: 仅限 iOS
break;
case Event.actionCallCustom:
// TODO: 自定义动作
break;
}
});
从原生代码调用(iOS/Android)
// Swift iOS
var info = [String: Any?]()
info["id"] = "44d915e1-5ff4-4bed-bf13-c423048ec97a"
info["nameCaller"] = "Hien Nguyen"
info["handle"] = "0123456789"
info["type"] = 1
//... 设置更多数据
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(flutter_callkit_incoming.Data(args: info), fromPushKit: true)
// 请确保在 pushRegistry(......, completion: @escaping () -> Void) 调用 completion() 或
// DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { completion() }
// 如果不在 pushRegistry(......, completion: @escaping () -> Void) 调用 completion(),则在接收 VoIP 时可能会导致系统崩溃
// Kotlin/Java Android
FlutterCallkitIncomingPlugin.getInstance().showIncomingNotification(...)
// 或者
let data = flutter_callkit_incoming.Data(id: "44d915e1-5ff4-4bed-bf13-c423048ec97a", nameCaller: "Hien Nguyen", handle: "0123456789", type: 0)
data.nameCaller = "Johnny"
data.extra = ["user": "abc@123", "platform": "ios"]
//... 设置更多数据
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(data, fromPushKit: true)
// 发送自定义事件
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.sendEventCustom(body: ["customKey": "customValue"])
// Kotlin/Java Android
FlutterCallkitIncomingPlugin.getInstance().sendEventCustom(body: Map<String, Any>)
更多关于Flutter来电界面集成插件waterbus_callkit_incoming的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter来电界面集成插件waterbus_callkit_incoming的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
waterbus_callkit_incoming
是一个用于在 Flutter 应用中集成来电界面的插件。它可以帮助你在应用中显示一个类似系统来电的界面,支持接听、挂断等操作。以下是使用 waterbus_callkit_incoming
插件的基本步骤。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 waterbus_callkit_incoming
插件的依赖:
dependencies:
flutter:
sdk: flutter
waterbus_callkit_incoming: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 初始化插件
在你的 Dart 代码中,首先需要初始化插件。通常可以在 main.dart
文件中进行初始化:
import 'package:waterbus_callkit_incoming/waterbus_callkit_incoming.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化插件
await WaterbusCallkitIncoming().initialize();
runApp(MyApp());
}
3. 显示来电界面
当你需要显示来电界面时,可以调用 showCallkitIncoming
方法:
void showIncomingCall() {
WaterbusCallkitIncoming().showCallkitIncoming(
uuid: "123456", // 唯一标识符
nameCaller: "John Doe", // 来电者姓名
handle: "1234567890", // 来电号码
avatar: "https://example.com/avatar.png", // 来电者头像
type: 0, // 0: 来电, 1: 去电
duration: 30000, // 来电持续时间(毫秒)
acceptText: "接听", // 接听按钮文本
declineText: "挂断", // 挂断按钮文本
missedCallNotification: true, // 是否显示未接来电通知
extra: <String, dynamic>{"userId": "1"}, // 额外信息
);
}
4. 监听事件
你可以监听来电的相关事件,例如接听、挂断等:
WaterbusCallkitIncoming().onEvent.listen((event) {
switch (event!.name) {
case EventType.actionCallAccept:
// 用户接听电话
break;
case EventType.actionCallDecline:
// 用户挂断电话
break;
case EventType.actionCallEnded:
// 电话结束
break;
case EventType.actionCallTimeout:
// 来电超时
break;
case EventType.actionCallCallback:
// 用户点击了回调按钮
break;
case EventType.actionCallToggleHold:
// 用户切换了保持状态
break;
case EventType.actionCallToggleMute:
// 用户切换了静音状态
break;
case EventType.actionCallToggleDmtf:
// 用户输入了DTMF
break;
case EventType.actionCallToggleGroup:
// 用户切换了群组通话
break;
case EventType.actionCallToggleAudioSession:
// 用户切换了音频会话
break;
}
});
5. 结束来电
当通话结束时,可以调用 endCall
方法来结束来电界面:
void endCall() {
WaterbusCallkitIncoming().endCall("123456"); // 使用与来电相同的uuid
}
6. 处理未接来电
如果你启用了未接来电通知,可以在 onEvent
中处理未接来电事件,并在需要时显示通知。
7. 权限处理
在 Android 上,你可能需要处理一些权限,例如 READ_PHONE_STATE
和 CALL_PHONE
。确保在 AndroidManifest.xml
中添加相应的权限声明:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />