Flutter通话界面集成插件karmm_callkit的使用

发布于 1周前 作者 itying888 来自 Flutter

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;

注意:函数onCallRejectedWhenTerminatedonCallAcceptedWhenTerminatedonCallIncomingWhenTerminated必须是顶级函数,不能是匿名函数。使用@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

1 回复

更多关于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和使用方法可能会随着版本的更新而变化,因此请参考最新的官方文档和示例代码来获取最准确的信息。

回到顶部