Flutter来电界面集成插件flutter_callkit_incoming的使用

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

Flutter来电界面集成插件flutter_callkit_incoming的使用

🚀 安装与配置

1. 添加依赖

首先,在pubspec.yaml文件中添加flutter_callkit_incoming依赖:

dependencies:
  flutter_callkit_incoming: any

然后运行命令安装插件:

flutter pub add flutter_callkit_incoming

2. 配置项目

Android配置

AndroidManifest.xml中添加以下权限和配置:

<manifest...>
    ...
    <!-- 使用以从互联网加载图像 -->
    <uses-permission android:name="android.permission.INTERNET"/>

    <application ...>
        <activity ...
            android:name=".MainActivity"
            android:launchMode="singleInstance">
            ...
    </application>
</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>

注意:iOS上仅支持真机调试,模拟器不支持CallKit框架。

⭐ 功能特性

  • 显示来电提醒
  • 发起拨号
  • 自定义Android UI / 使用iOS Callkit
  • 支持通过Pushkit/VoIP推送(仅限iOS)

💡 示例代码

下面是一个完整的示例应用程序,展示了如何集成flutter_callkit_incoming插件来处理来电通知:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
import 'package:uuid/uuid.dart';

// 背景消息处理器
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  print("Handling a background message: ${message.messageId}");
  await Firebase.initializeApp(); //确保Firebase已初始化
  showCallkitIncoming(const Uuid().v4());
}

// 展示来电通知
Future<void> showCallkitIncoming(String uuid) async {
  final params = CallKitParams(
    id: uuid,
    nameCaller: 'Hien Nguyen',
    appName: 'Callkit',
    avatar: 'https://i.pravatar.cc/100',
    handle: '0123456789',
    type: 0, // 0 - 音频通话, 1 - 视频通话
    duration: 30000, // 呼叫显示时间(秒)
    textAccept: '接听',
    textDecline: '挂断',
    missedCallNotification: const NotificationParams(
      showNotification: true,
      isShowCallback: true,
      subtitle: '未接来电',
      callbackText: '回拨',
    ),
    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',
      textColor: '#ffffff',
    ),
    ios: const IOSParams(
      iconName: 'CallKitLogo',
      handleType: '',
      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(params);
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  late final Uuid _uuid;
  String? _currentUuid;
  late final FirebaseMessaging _firebaseMessaging;

  @override
  void initState() {
    super.initState();
    _uuid = const Uuid();
    initFirebase();
    WidgetsBinding.instance.addObserver(this);
    checkAndNavigationCallingPage();
  }

  Future<dynamic> getCurrentCall() async {
    var calls = await FlutterCallkitIncoming.activeCalls();
    if (calls is List &amp;&amp; calls.isNotEmpty) {
      print('DATA: $calls');
      _currentUuid = calls[0]['id'];
      return calls[0];
    } else {
      _currentUuid = null;
      return null;
    }
  }

  Future<void> checkAndNavigationCallingPage() async {
    var currentCall = await getCurrentCall();
    if (currentCall != null) {
      // 导航到呼叫页面逻辑
    }
  }

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state == AppLifecycleState.resumed) {
      checkAndNavigationCallingPage();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  Future<void> initFirebase() async {
    await Firebase.initializeApp();
    _firebaseMessaging = FirebaseMessaging.instance;
    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
    FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
      _currentUuid = _uuid.v4();
      showCallkitIncoming(_currentUuid!);
    });
    _firebaseMessaging.getToken().then((token) {
      print('Device Token FCM: $token');
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData.light(),
      home: Scaffold(
        appBar: AppBar(title: Text('Home Page')),
        body: Center(child: Text('Hello World')),
      ),
    );
  }

  Future<void> getDevicePushTokenVoIP() async {
    var devicePushTokenVoIP = await FlutterCallkitIncoming.getDevicePushTokenVoIP();
    print(devicePushTokenVoIP);
  }
}

此示例演示了如何结合Firebase Cloud Messaging (FCM) 和 flutter_callkit_incoming 插件来处理来电通知。当收到推送消息时,会触发showCallkitIncoming方法,从而展示来电界面。

🔗 参考资料

以上就是关于flutter_callkit_incoming插件的基本用法介绍。如果有任何疑问或遇到问题,欢迎随时提问!


更多关于Flutter来电界面集成插件flutter_callkit_incoming的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter来电界面集成插件flutter_callkit_incoming的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中集成并使用flutter_callkit_incoming插件来创建来电界面的代码示例。这个插件允许你在Flutter应用中模拟来电界面,并在设备屏幕上显示来电通知。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加flutter_callkit_incoming依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_callkit_incoming: ^x.y.z  # 请替换为最新版本号

2. 导入插件

在你的Dart文件中(例如main.dart),导入flutter_callkit_incoming插件:

import 'package:flutter/material.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';

3. 配置权限

由于来电界面通常涉及到系统权限,你需要在AndroidManifest.xml中添加必要的权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

对于iOS,需要在Info.plist中添加必要的权限描述,但flutter_callkit_incoming插件通常会处理大部分配置。

4. 初始化插件并显示来电界面

在你的Flutter应用中,你可以通过以下代码初始化插件并显示来电界面:

void main() {
  runApp(MyApp());

  // 初始化插件
  FlutterCallkitIncoming.instance.init(
    appName: "MyApp",
    ios: IOSConfig(
      appName: "MyApp",
      handleType: "generic",
    ),
    android: AndroidConfig(
      isFullScreen: true,
      systemUIVisibility: SystemUiVisibility.lightStatusBars | SystemUiVisibility.hideNavigationBar,
      isRingtonePlaying: true,
    ),
  );

  // 模拟来电
  simulateIncomingCall();
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter CallKit Incoming Example'),
        ),
        body: Center(
          child: Text('Check your device for incoming call notification.'),
        ),
      ),
    );
  }
}

void simulateIncomingCall() {
  // 创建一个新的Call对象
  var callUUID = UUID().uuidString;  // 需要添加 'dart:math' 导入并使用 UUID 类生成唯一标识符
  var newCall = Call(
    uuid: callUUID,
    handle: Handle(
      type: HandleType.phoneNumber,
      value: "1234567890",  // 电话号码
    ),
    hasVideo: false,
    isVideoCall: false,
    localizedCallerName: "John Doe",
    handleType: HandleType.phoneNumber,
    supportsHolding: true,
    supportsDTMF: true,
    supportsGrouping: false,
    supportsConference: false,
    supportsTransferring: false,
  );

  // 显示来电界面
  FlutterCallkitIncoming.instance.displayIncomingCall(newCall).then((_) {
    // 处理来电接听或挂断后的逻辑
    print("Incoming call displayed");
  }).catchError((error) {
    // 处理错误
    print("Error displaying incoming call: $error");
  });
}

注意

  • 上面的代码示例中,UUID().uuidString用于生成唯一的UUID,你需要导入dart:math库并使用UUID类(或者你可以使用任何其他方式生成唯一标识符)。
  • simulateIncomingCall函数模拟了一个来电,并显示来电界面。在实际应用中,你可能需要根据具体情况触发这个函数,例如从服务器接收到来电请求时。
  • 由于flutter_callkit_incoming插件的API可能会随着版本更新而变化,请确保查阅最新的官方文档以获取最新的使用方法和API。

希望这个示例能帮到你!

回到顶部