You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:FirebaseMessaging通知到达时自动打开App(无需用户操作)

解决通讯App来电通知自动打开指定页面的问题

核心问题分析

external_app_launcher无法在后台消息回调中生效,因为后台运行环境限制了插件的启动能力。实际上你代码里用到的AndroidfullScreenIntent就是专门处理来电这类需自动唤起App的场景,只需完善配置就能实现无需用户点击、直接打开通话页面的效果。

解决方案步骤

1. 完善Android端通知的FullScreenIntent配置

你当前代码已设置fullScreenIntent: true,但需要给这个Intent指定跳转的目标通话页面,而非默认启动页。修改通知展示代码,添加自定义PendingIntent:

// 创建指向通话页Activity的Intent(替换成你实际的Activity路径)
final intent = Intent()
  ..setClassName("com.example.chat_app", "com.example.chat_app.CallActivity")
  ..putExtra("call_data", json.encode(message.data)); // 传递通话相关数据

// 生成PendingIntent,确保能唤起指定页面
final pendingIntent = PendingIntent.getActivity(
  context,
  Random().nextInt(1000000),
  intent,
  PendingIntentFlags.updateCurrent | PendingIntentFlags.immutable,
);

// 更新通知配置,关联fullScreenIntent的PendingIntent
flutterLocalNotificationsPlugin.show(
    Random().nextInt(1000000000),
    message.data['title'],
    message.data["body"],
    NotificationDetails(
      android: AndroidNotificationDetails(
        channel.id, 
        channel.name,
        channelDescription: channel.description,
        importance: Importance.max,
        priority: Priority.high,
        playSound: true,
        sound: const RawResourceAndroidNotificationSound("ringtone1"),
        fullScreenIntent: true,
        fullScreenIntentPendingIntent: pendingIntent, // 新增该行配置
      ),
    ),
    payload: json.encode(message.data));

2. 配置AndroidManifest.xml

确保通话页Activity能被外部Intent唤起,且支持锁屏状态下启动:

<activity
    android:name=".CallActivity"
    android:launchMode="singleTop"
    android:showOnLockScreen="true"
    android:turnScreenOn="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
  • showOnLockScreen+turnScreenOn:实现锁屏状态下自动点亮屏幕并展示通话页
  • singleTop:避免重复创建Activity实例

3. Flutter端处理全场景页面跳转

覆盖App前台、后台、被杀死三种状态的跳转逻辑:

  • 前台/后台状态:在onSelectNotification或firebaseMessaging.onMessageOpenedApp中直接调用goToNextScreen跳转
  • 被杀死状态:通过MethodChannel从Android原生层传递数据给Flutter,触发跳转:
// MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    intent?.extras?.let { extras ->
        val callData = extras.getString("call_data")
        callData?.let {
            val channel = MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, "call_channel")
            channel.invokeMethod("openCallPage", it)
        }
    }
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    intent?.extras?.let { extras ->
        val callData = extras.getString("call_data")
        callData?.let {
            val channel = MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, "call_channel")
            channel.invokeMethod("openCallPage", it)
        }
    }
}

Flutter侧监听MethodChannel:

final MethodChannel _callChannel = MethodChannel('call_channel');

@override
void initState() {
    super.initState();
    _callChannel.setMethodCallHandler((call) async {
        if (call.method == 'openCallPage') {
            String data = call.arguments as String;
            Map<String, dynamic> callData = json.decode(data);
            goToNextScreen(callData, true);
        }
    });
}

4. iOS端适配

在AppDelegate中处理通知唤起逻辑:

// AppDelegate.swift
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo
    if let callData = userInfo["call_data"] as? String {
        let channel = FlutterMethodChannel(name: "call_channel", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger)
        channel.invokeMethod("openCallPage", arguments: callData)
    }
    completionHandler()
}

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.sound, .alert])
}

关键注意事项

  • 确保Firebase后台发送的是数据消息,而非纯通知消息,这样后台消息回调才能稳定触发
  • Android 12及以上需添加权限:
    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
    

内容的提问来源于stack exchange,提问作者Mohamed Ayman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 12:27:13