我已经为我的 flutter 应用程序实现了 Firebase Messaging,可以发送呼叫通知。每当收到呼叫通知时,此包flutter_callkit_incoming将显示呼叫通知,允许用户接受/拒绝呼叫。当用户接听电话时,应用程序会将用户重定向到通话屏幕。
一切正常,但当应用程序处于终止状态时,它只会打开应用程序,不会将用户重定向到呼叫屏幕。
谁能帮我解决这个问题吗?
PS:我对这个堆栈溢出还很陌生
Soo 这是我处理来电通知的相关代码(如果代码不足,请告诉我):
创建一个名为displayIncomingCall的函数,为其配置一些参数,并使用包来显示来电通知
await FlutterCallkitIncoming.showCallkitIncoming(params);
添加了识别通知类型的功能
enum NotiActionType { incoming_calls, others }
NotiActionType? getNotiActionType(Map<String, dynamic>? data) {
if (data == null || data["action"] == null) return null;
switch (data["action"]) {
case "incoming_call":
return NotiActionType.incoming_calls;
default:
return NotiActionType.others;
}
}
在 firebase 类下,创建函数来调用 displayIncomingCall
static Future<void> handleIncomingCallNoti(RemoteMessage? message) async {
if (message == null) return;
var isInsertCallLog = await Notification.insertDatabase(
title: message.notification!.title!,
message: message.notification!.body!,
data: message.data,
receiveDatetime: DateTime.now(),
);
if (isInsertCallLog) {
var latestNoti = await Notification.getLatestNotification(
dataColumnKey: Notification.actionKey,
dataColumnValue: Notification.actionValueIncomingCall,
);
var props = await CallNotificationProps.fromDatabase(latestNoti);
await CallNotification.displayIncomingCall(props);
//set to true to alert notificationScreen fetch new data
GlobalValue().setIsNewNotification(true);
}
}
创建要在 FirebaseMessaging.onBackgroundMessage 中使用的函数
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
if (message.notification != null) {
var apiActionType = getNotiActionType(message.data);
if (apiActionType == NotiActionType.incoming_calls) {
await FirebaseApi.handleIncomingCallNoti(message);
} else {
await Notification.insertDatabase(
title: message.notification!.title!,
message: message.notification!.body!,
data: message.data,
receiveDatetime: DateTime.now(),
);
}
}
}
为 callkit 包初始化事件监听器并在应用程序启动时调用它
FlutterCallkitIncoming.onEvent.listen((CallEvent? callEvent) async {
var callNoti = CallNotification(
callNotification: CallNotificationProps.getEmptyProps,
deviceToken: "",
);
switch (callEvent?.event) {
case Event.actionCallIncoming:
var latestNoti = await noti.Notification.getLatestNotification(
dataColumnKey: noti.Notification.actionKey,
dataColumnValue: noti.Notification.actionValueIncomingCall,
);
var actionType = getNotiActionType(latestNoti?.data);
if (actionType == NotiActionType.incoming_calls) {
callNoti.callNotification =
await CallNotificationProps.fromDatabase(latestNoti);
}
break;
case Event.actionCallAccept:
await Navigator.pushNamed(
context, callScreenRoute,
arguments: {
"call_props": callNoti,
});
break;
}
});
List calls = [];
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
FirebaseMessaging.onBackgroundMessage(backgroundNotificationHandler);
FirebaseMessaging.onMessage.listen(foregroundNotificationHandler);
calls = await FlutterCallkitIncoming.activeCalls() as List;
await GetStorage.init();
log('calls: $calls');
if (calls.isNotEmpty) {
runApp(CallApp(calls: calls));
} else {
await initializeApp();
runApp(const MainApp());
}
}
class CallApp extends StatelessWidget {
const CallApp({super.key, required this.calls});
final List calls;
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(411.43, 867.5),
minTextAdapt: true,
splitScreenMode: true,
builder: (_, child) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
theme: getTheme(),
home: const BackgroundLiveScreen(),
initialBinding: CustomBinding(),
);
},
);
}
}