Flutter来电界面集成插件flutter_callkit_incoming的使用
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 && 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
更多关于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。
希望这个示例能帮到你!