Flutter通话界面集成插件karmm_callkit的使用
Flutter通话界面集成插件karmm_callkit的使用
Disclaimer
此插件不是原始插件创建者的官方或附属产品。它是基于原始插件进行修复和改进的衍生作品。
版权:请注意版权限制。如果connectycube-flutter-call-kit有许可证,请确保您的许可证兼容。您不能简单地复制他们的README。 归属:如果合适,请考虑提及connectycube-flutter-call-kit作为原始来源,并提供指向其仓库的链接(如果公开可用)。
Karmm Call Kit 插件
该插件是原始karmm_callkit插件的分支。
这是一个Flutter插件,用于在应用程序处于后台或终止状态时显示通话屏幕。它提供了实现应用内背景通话功能的复杂解决方案,包括获取令牌和显示来电屏幕。
支持平台
- Android
- iOS
功能
- 访问设备令牌(FCM用于Android,VoIP用于iOS)
- 通过回调通知应用令牌刷新
- 当推送通知送达设备时显示来电屏幕
- 通知应用用户在来电屏幕上执行的操作(接受、拒绝、静音(仅限iOS))
- 提供手动管理来电屏幕的方法,包括手动显示来电屏幕
- 在通话期间获取当前通话的数据
- 根据您的应用需求进行一些自定义(铃声、应用图标、强调色(仅限Android))
- 检查并更改对
Manifest.permission.USE_FULL_SCREEN_INTENT
权限的访问(仅限Android 14及以上版本)
配置您的项目
此插件不需要复杂的配置,只需像平常一样将其连接到您的应用,并执行以下简单的操作:
准备Android
- 将Google服务配置文件
google-services.json
添加到路径your_app/android/app/
- 在路径
your_app/android/app/build.gradle
的文件末尾添加以下字符串:
apply plugin: 'com.google.gms.google-services'
如果您的应用目标为targetSdkVersion 31
及以上版本,并且您需要通过点击接受
按钮启动应用,则应首先请求用户授予SYSTEM_ALERT_WINDOW
权限。为此,您可以使用插件permission_handler
。
如果您的应用目标为targetSdkVersion 33
及以上版本,您应该首先请求用户授予POST_NOTIFICATIONS
权限。
准备iOS
- 将以下字符串添加到路径
your_app/ios/Runner/Info.plist
的文件中:
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
<string>voip</string>
</array>
API 和回调
获取令牌
插件返回iOS平台的VoIP令牌和Android平台的FCM令牌。
从系统获取令牌:
ConnectycubeFlutterCallKit.getToken().then((token) {
// 使用收到的令牌订阅推送通知
});
监听刷新令牌事件:
ConnectycubeFlutterCallKit.onTokenRefreshed = (token) {
// 使用刷新后的令牌重新订阅
};
自定义插件
我们添加了一个有助于根据您的需求自定义插件的方法。目前,您可以自定义铃声、应用程序图标、通知小图标(仅限Android)和通知强调色(仅限Android)。使用以下方法:
ConnectycubeFlutterCallKit.instance.updateConfig(
ringtone: 'custom_ringtone',
icon: Platform.isAndroid ? 'default_avatar' : 'CallKitIcon', // 用于Android的占位符图标和iOS的应用图标
color: '#07711e');
Android专属的通知图标定制
您可以为音频和视频通话设置不同的图标,将合适的资源添加到您的android/app/src/main/AndroidManifest.xml
文件的application
部分:
<meta-data
android:name="com.karmm.callkit.audio_call_notification_icon"
android:resource="@drawable/ic_notification_audio_call" />
<meta-data
android:name="com.karmm.callkit.video_call_notification_icon"
android:resource="@drawable/ic_notification_video_call" />
如果不需要这些图标,只需添加默认通知图标:
<meta-data
android:name="com.karmm.callkit.app_notification_icon"
android:resource="@drawable/ic_notification" />
显示来电通知
P2PCallSession incomingCall; // 来电信息
CallEvent callEvent = CallEvent(
sessionId: incomingCall.sessionId,
callType: incomingCall.callType,
callerId: incomingCall.callerId,
callerName: 'Caller Name',
opponentsIds: incomingCall.opponentsIds,
callPhoto: 'https://i.imgur.com/KwrDil8b.jpg',
userInfo: {'customParameter1': 'value1'});
ConnectycubeFlutterCallKit.showCallNotification(callEvent);
监听来电屏幕上的用户操作
前景监听
在初始化插件时添加监听器:
ConnectycubeFlutterCallKit.instance.init(
onCallAccepted: _onCallAccepted,
onCallRejected: _onCallRejected,
onCallIncoming: _onCallIncoming,
);
Future<void> _onCallAccepted(CallEvent callEvent) async {
// 通话被接受
}
Future<void> _onCallRejected(CallEvent callEvent) async {
// 通话被拒绝
}
Future<void> _onCallRejected(CallEvent callEvent) async {
// 来电屏幕/通知显示给用户
}
后台或终止状态监听(仅限Android):
ConnectycubeFlutterCallKit.onCallRejectedWhenTerminated = onCallRejectedWhenTerminated;
ConnectycubeFlutterCallKit.onCallAcceptedWhenTerminated = onCallAcceptedWhenTerminated;
ConnectycubeFlutterCallKit.onCallIncomingWhenTerminated = onCallIncomingWhenTerminated;
注意:函数onCallRejectedWhenTerminated
、onCallAcceptedWhenTerminated
和onCallIncomingWhenTerminated
必须是顶级函数,不能是匿名函数。使用@pragma(‘vm:entry-point’)
标记这些回调以允许从原生代码中使用它们。
监听iOS上CallKit屏幕上的操作:
监听静音/取消静音通话
ConnectycubeFlutterCallKit.onCallMuted = onCallMuted;
Future<void> onCallMuted(bool mute, String uuid) async {
// [mute] - `true` - 通话在CallKit屏幕上被静音,`false` - 通话未被静音
// [uuid] - 静音/取消静音通话的id
}
获取通话状态
var callState = await ConnectycubeFlutterCallKit.getCallState(sessionId: sessionId);
获取通话数据
ConnectycubeFlutterCallKit.getCallData(sessionId: sessionId).then((callData) {
});
获取最新通话的ID
在某些情况下,了解最后一次收到的通话的ID是有帮助的。可以通过以下方式获取:
var sessionId = await ConnectycubeFlutterCallKit.getLastCallId();
然后可以使用getCallState
获取此通话的状态。
通知插件有关通话相关的用户操作
对于取消来电屏幕(或CallKit)的通知,您应该通知插件这些事件。 使用以下函数:
ConnectycubeFlutterCallKit.reportCallAccepted(sessionId: uuid);
ConnectycubeFlutterCallKit.reportCallEnded(sessionId: uuid);
通知插件有关通话的静音/取消静音(仅限iOS):
var muted = true; // 如果通话被静音则设置为`true`,否则设置为`false`
ConnectycubeFlutterCallKit.reportCallMuted(sessionId: uuid, muted: muted);
清除通话数据
通话结束后,您可以清除与该通话相关的所有插件数据。调用以下代码:
await ConnectycubeFlutterCallKit.clearCallData(sessionId: sessionId);
管理锁屏上的应用可见性(仅限Android)
如果您需要在从锁屏接受通话后显示您的应用,可以使用以下方法:
ConnectycubeFlutterCallKit.setOnLockScreenVisibility(isVisible: true);
通话结束后,您应该在锁屏下隐藏您的应用,通过以下方法实现:
ConnectycubeFlutterCallKit.setOnLockScreenVisibility(isVisible: false);
检查Manifest.permission.USE_FULL_SCREEN_INTENT
权限状态(Android 14及以上版本)
var canUseFullScreenIntent = await ConnectycubeFlutterCallKit.canUseFullScreenIntent();
请求Manifest.permission.USE_FULL_SCREEN_INTENT
权限(Android 14及以上版本)
ConnectycubeFlutterCallKit.provideFullScreenIntentAccess();
该函数将用户带到特定设置页面,您可以在那里授予或拒绝此权限。
通过推送通知显示来电屏幕
如果您希望自动通过推送通知显示来电屏幕,可以轻松实现。为此,发起者应向所有通话成员发送推送通知。此推送通知应包含一些必需参数。如果您使用的是Connectycube Flutter SDK
,可以使用以下代码实现:
CreateEventParams params = CreateEventParams();
params.parameters = {
'message': "Incoming ${currentCall.callType == CallType.VIDEO_CALL ? "Video" : "Audio"} call",
'call_type': currentCall.callType,
'session_id': currentCall.sessionId,
'caller_id': currentCall.callerId,
'caller_name': callerName,
'call_opponents': currentCall.opponentsIds.join(','),
'photo_url': 'https://i.imgur.com/KwrDil8b.jpg'
'signal_type': 'startCall',
'ios_voip': 1,
};
params.notificationType = NotificationType.PUSH;
params.environment = CubeEnvironment.DEVELOPMENT; // 不重要
params.usersIds = currentCall.opponentsIds.toList();
createEvent(params.getEventForRequest()).then((cubeEvent) {
// 事件已创建
}).catchError((error) {
// 创建事件时出错
});
要通过推送通知隐藏来电屏幕,使用类似的请求但signal_type
不同,它可以是’endCall’
或’rejectCall’
。
Android 14 特性
从Android Build.VERSION_CODES.UPSIDE_DOWN_CAKE
开始,应用程序可能没有使用Manifest.permission.USE_FULL_SCREEN_INTENT
的权限。如果权限被拒绝,通话通知将在锁屏上显示为扩展的头部通知。插件提供了检查访问状态的API,并将用户带到系统设置以启用它。请参阅以下代码片段以管理它:
var canUseFullScreenIntent = await ConnectycubeFlutterCallKit.canUseFullScreenIntent();
if (!canUseFullScreenIntent){
ConnectycubeFlutterCallKit.provideFullScreenIntentAccess();
}
更多关于Flutter通话界面集成插件karmm_callkit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter通话界面集成插件karmm_callkit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中集成并使用karmm_callkit
插件来创建通话界面的示例代码。karmm_callkit
插件允许你在Flutter应用中实现类似原生应用的通话界面和功能。
首先,确保你的Flutter环境已经配置好,并且你的项目已经创建。然后,按照以下步骤进行集成:
1. 添加依赖
在你的pubspec.yaml
文件中添加karmm_callkit
依赖:
dependencies:
flutter:
sdk: flutter
karmm_callkit: ^最新版本号 # 替换为最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置Android和iOS
Android
在android/app/src/main/AndroidManifest.xml
中添加必要的权限(如果需要):
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
iOS
在ios/Runner/Info.plist
中添加必要的权限配置(如果需要)。此外,确保你的Xcode项目配置正确,包括背景模式等。
3. 初始化插件
在你的main.dart
文件中初始化karmm_callkit
插件:
import 'package:flutter/material.dart';
import 'package:karmm_callkit/karmm_callkit.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter CallKit Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CallKitDemo(),
);
}
}
class CallKitDemo extends StatefulWidget {
@override
_CallKitDemoState createState() => _CallKitDemoState();
}
class _CallKitDemoState extends State<CallKitDemo> {
late CallKit callKit;
@override
void initState() {
super.initState();
// 初始化CallKit
callKit = CallKit();
// 配置CallKit(示例配置,具体配置根据你的需求调整)
callKit.configure(
providerId: 'your_provider_id',
localizedName: 'Your App Name',
supportsVideo: false,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter CallKit Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 开始通话
startCall();
},
child: Text('Start Call'),
),
),
);
}
void startCall() async {
// 开始一个新的通话
bool result = await callKit.startCall(
handle: 'caller_handle',
handleType: CallHandleType.phoneNumber,
hasVideo: false,
localizedCallerName: 'Caller Name',
);
if (result) {
print('Call started successfully.');
} else {
print('Failed to start call.');
}
}
}
4. 处理通话事件
为了处理通话事件(如接听、挂断等),你需要监听CallKit
提供的事件流。这通常涉及到在状态管理中处理这些事件,并更新UI。
以下是一个简单的示例,展示如何监听通话状态变化:
class _CallKitDemoState extends State<CallKitDemo> {
late CallKit callKit;
CallState? currentCallState;
@override
void initState() {
super.initState();
callKit = CallKit();
callKit.configure(
providerId: 'your_provider_id',
localizedName: 'Your App Name',
supportsVideo: false,
);
// 监听通话状态变化
callKit.callStateStream.listen((state) {
setState(() {
currentCallState = state;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter CallKit Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
startCall();
},
child: Text('Start Call'),
),
SizedBox(height: 20),
if (currentCallState != null)
Text('Current Call State: ${currentCallState!.toString()}'),
],
),
),
);
}
// ... (startCall 方法保持不变)
}
在这个示例中,我们创建了一个简单的Flutter应用,它使用karmm_callkit
插件来初始化通话界面,并处理基本的通话事件。你可以根据实际需求进一步扩展这个示例,比如添加接听、挂断、保持通话等功能。
请注意,karmm_callkit
插件的具体API和使用方法可能会随着版本的更新而变化,因此请参考最新的官方文档和示例代码来获取最准确的信息。