Flutter来电界面集成插件flutter_callkit_incoming_yoer的使用
Flutter来电界面集成插件flutter_callkit_incoming_yoer的使用
配置插件
首先,我们需要配置 flutter_callkit_incoming_yoer
插件。以下是需要修改的地方:
AndroidManifest.xml
<activity
android:name=".MainActivity"
android:exported="false"
...
build.gradle
确保 compileOptions
和 kotlinOptions
设置为相同的版本:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
完整示例代码
以下是一个完整的示例代码,展示了如何使用 flutter_callkit_incoming_yoer
插件来实现一个简单的来电界面。
main.dart
import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_callkit_incoming_yoer/entities/entities.dart';
import 'package:flutter_callkit_incoming_yoer/flutter_callkit_incoming.dart';
import 'package:flutter_callkit_incoming_example/app_router.dart';
import 'package:flutter_callkit_incoming_example/navigation_service.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,
duration: 30000,
textAccept: 'Accept',
textDecline: 'Decline',
missedCallNotification: const NotificationParams(
showNotification: true,
isShowCallback: true,
subtitle: 'Missed call',
callbackText: 'Call back',
),
extra: {'userId': '1a2b3c4d'},
headers: {'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() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> with WidgetsBindingObserver {
late final Uuid _uuid;
String? _currentUuid;
late final FirebaseMessaging _firebaseMessaging;
[@override](/user/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) {
if (calls.isNotEmpty) {
print('DATA: $calls');
_currentUuid = calls[0]['id'];
return calls[0];
} else {
_currentUuid = "";
return null;
}
}
}
Future<void> checkAndNavigationCallingPage() async {
var currentCall = await getCurrentCall();
if (currentCall != null) {
NavigationService.instance.pushNamedIfNotCurrent(AppRoute.callingPage, args: currentCall);
}
}
[@override](/user/override)
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
print(state);
if (state == AppLifecycleState.resumed) {
// 检查从后台唤醒应用时是否有正在进行的通话
checkAndNavigationCallingPage();
}
}
[@override](/user/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 {
print('Message title: ${message.notification?.title}, body: ${message.notification?.body}, data: ${message.data}');
_currentUuid = _uuid.v4();
showCallkitIncoming(_currentUuid!);
});
_firebaseMessaging.getToken().then((token) {
print('Device Token FCM: $token');
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
onGenerateRoute: AppRoute.generateRoute,
initialRoute: AppRoute.homePage,
navigatorKey: NavigationService.instance.navigationKey,
navigatorObservers: [NavigationService.instance.routeObserver],
);
}
Future<void> getDevicePushTokenVoIP() async {
var devicePushTokenVoIP = await FlutterCallkitIncoming.getDevicePushTokenVoIP();
print(devicePushTokenVoIP);
}
}
更多关于Flutter来电界面集成插件flutter_callkit_incoming_yoer的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter来电界面集成插件flutter_callkit_incoming_yoer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_callkit_incoming
是一个用于在 Flutter 应用中集成来电界面的插件,特别是在 VoIP 应用中非常有用。它提供了与 iOS 的 CallKit 和 Android 的自定义来电界面的集成。
以下是使用 flutter_callkit_incoming
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 flutter_callkit_incoming
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_callkit_incoming: ^1.4.0
然后,运行 flutter pub get
来安装依赖。
2. 导入插件
在需要使用插件的 Dart 文件中导入插件:
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
3. 初始化插件
在应用启动时初始化插件,通常可以在 main()
函数中完成:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化插件
await FlutterCallkitIncoming.init();
runApp(MyApp());
}
4. 配置来电界面
你可以使用 FlutterCallkitIncoming.showCallkitIncoming()
方法来显示来电界面。以下是一个简单的示例:
void showIncomingCall(String uuid, String callerName, String callerNumber) async {
var params = <String, dynamic>{
'id': uuid,
'nameCaller': callerName,
'appName': 'MyApp',
'avatar': 'https://example.com/avatar.png', // 可选,来电者头像
'handle': callerNumber,
'type': 0, // 0 for voice call, 1 for video call
'duration': 30000, // 通话时长(毫秒)
'textAccept': 'Accept', // 接听按钮文本
'textDecline': 'Decline', // 拒绝按钮文本
'textMissedCall': 'Missed Call', // 未接来电文本
'textCallback': 'Callback', // 回拨按钮文本
'extra': <String, dynamic>{'userId': '1a2b3c4d'}, // 自定义数据
};
await FlutterCallkitIncoming.showCallkitIncoming(params);
}
5. 处理来电事件
你可以监听来电事件,例如用户接听、拒绝或未接来电。以下是一个示例:
void listenCallkitEvents() {
FlutterCallkitIncoming.onEvent.listen((event) async {
switch (event!.event) {
case Event.actionCallAccept:
// 用户接听来电
print('Call accepted');
break;
case Event.actionCallDecline:
// 用户拒绝来电
print('Call declined');
break;
case Event.actionCallEnded:
// 通话结束
print('Call ended');
break;
case Event.actionCallTimeout:
// 未接来电
print('Missed call');
break;
case Event.actionCallCallback:
// 用户点击回拨
print('Callback clicked');
break;
case Event.actionCallToggleHold:
// 用户切换保持状态
print('Call hold toggled');
break;
case Event.actionCallToggleMute:
// 用户切换静音状态
print('Call muted toggled');
break;
case Event.actionCallToggleDmtf:
// 用户发送双音多频信号
print('DTMF sent');
break;
case Event.actionCallToggleGroup:
// 用户切换群组通话
print('Call group toggled');
break;
case Event.actionCallToggleAudioSession:
// 用户切换音频会话
print('Audio session toggled');
break;
}
});
}
6. 结束通话
你可以使用 FlutterCallkitIncoming.endCall()
方法来结束通话:
void endCall(String uuid) async {
await FlutterCallkitIncoming.endCall(uuid);
}
7. 启动应用时恢复通话状态
如果应用在后台时收到来电,你可以在应用启动时恢复通话状态:
void restoreCallkitCalls() async {
var calls = await FlutterCallkitIncoming.activeCalls();
if (calls.isNotEmpty) {
// 处理恢复通话的逻辑
print('Active calls: $calls');
}
}
8. 后台模式(iOS)
在 iOS 上,你需要在 Info.plist
文件中添加以下配置来支持后台模式:
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
<string>voip</string>
</array>
9. 权限(Android)
在 Android 上,你需要在 AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
10. 启动应用时处理未接来电
你可以在应用启动时检查是否有未接来电,并显示通知或执行其他操作:
void checkMissedCalls() async {
var missedCalls = await FlutterCallkitIncoming.getMissedCalls();
if (missedCalls.isNotEmpty) {
// 处理未接来电的逻辑
print('Missed calls: $missedCalls');
}
}