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

Flutter应用关闭/闲置时推送通知失效问题及实现方案咨询

Flutter 应用后台/关闭状态接收推送通知解决方案

你的问题核心是没有配置系统级推送通道和后台消息处理逻辑——社交APP之所以能在关闭后收推送,是因为它们依赖了Android的FCM/厂商推送、iOS的APNs这些原生系统服务,而非仅依赖应用自身的运行状态。下面是具体实现步骤和代码:

一、依赖集成(以Firebase Cloud Messaging为例,最通用的方案)

在pubspec.yaml中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^2.15.0
  firebase_messaging: ^14.6.5

执行flutter pub get完成依赖安装。

二、Android 端配置

1. 修改AndroidManifest.xml

在android/app/src/main/AndroidManifest.xml中添加权限和推送组件:

<!-- 必要权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<application ...>
  <!-- FCM消息接收器 -->
  <receiver
      android:name="com.google.firebase.messaging.FirebaseMessagingReceiver"
      android:exported="true"
      android:permission="com.google.android.c2dm.permission.SEND">
      <intent-filter>
          <action android:name="com.google.android.c2dm.intent.RECEIVE" />
          <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
          <category android:name="${applicationId}" />
      </intent-filter>
  </receiver>

  <!-- 后台消息处理服务 -->
  <service
      android:name=".MyFirebaseMessagingService"
      android:exported="false">
      <intent-filter>
          <action android:name="com.google.firebase.MESSAGING_EVENT" />
      </intent-filter>
  </service>
</application>

2. 创建后台消息服务类

在android/app/src/main/kotlin/[你的包名]/MyFirebaseMessagingService.kt中实现自定义服务,用于在后台/关闭状态下处理推送并显示通知:

package com.yourpackage.name

import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        // 应用后台/关闭时收到推送会触发此方法
        remoteMessage.notification?.let {
            showNotification(it.title, it.body)
        }
    }

    private fun showNotification(title: String?, body: String?) {
        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as android.app.NotificationManager
        val channelId = "app_push_channel"

        // Android 8.0+ 必须创建通知渠道
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            val channel = android.app.NotificationChannel(
                channelId,
                "应用推送",
                android.app.NotificationManager.IMPORTANCE_DEFAULT
            )
            notificationManager.createNotificationChannel(channel)
        }

        val notification = android.app.NotificationCompat.Builder(this, channelId)
            .setContentTitle(title)
            .setContentText(body)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setAutoCancel(true)
            .build()

        notificationManager.notify(System.currentTimeMillis().toInt(), notification)
    }
}

三、iOS 端配置

1. 开启后台推送模式

在Xcode中打开项目的Info.plist,添加如下配置:

<key>UIBackgroundModes</key>
<array>
    <string>remote-notification</string>
</array>

2. 配置APNs证书

在Apple Developer后台生成推送证书,将其上传到Firebase控制台,确保FCM与APNs关联(这一步是iOS关闭后收推送的核心)。

四、Flutter 核心代码实现

1. 初始化推送服务

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

// 后台消息处理器(应用关闭时,系统会唤醒应用执行此方法)
Future<void> _backgroundMessageHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  print("后台收到推送: ${message.messageId}");
  // 可在此处理数据,比如存储到本地数据库
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  // 注册后台消息处理器
  FirebaseMessaging.onBackgroundMessage(_backgroundMessageHandler);

  // 请求用户推送权限
  final settings = await FirebaseMessaging.instance.requestPermission(
    alert: true,
    badge: true,
    sound: true,
  );

  print("用户推送权限状态: ${settings.authorizationStatus}");

  // 获取设备推送令牌(用于后端发送推送)
  final token = await FirebaseMessaging.instance.getToken();
  print("FCM令牌: $token");

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Push Demo',
      home: Scaffold(
        appBar: AppBar(title: const Text('推送测试')),
        body: const Center(child: Text('查看通知栏接收推送')),
      ),
    );
  }
}

2. 前台消息处理(可选)

如果需要在应用前台显示通知,可添加如下代码(需先集成flutter_local_notifications库):

// 在StatefulWidget的initState中添加
@override
void initState() {
  super.initState();
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    final notification = message.notification;
    if (notification != null) {
      // 用flutter_local_notifications显示前台通知
      // 示例代码(需先初始化通知插件)
      // await flutterLocalNotificationsPlugin.show(
      //   0,
      //   notification.title,
      //   notification.body,
      //   NotificationDetails(
      //     android: AndroidNotificationDetails(
      //       'app_push_channel',
      //       '应用推送',
      //       importance: Importance.defaultImportance,
      //     ),
      //   ),
      // );
    }
  });
}

关键注意事项

  • 国内Android机型:小米、华为、OPPO等厂商有自己的推送通道,FCM可能被系统后台限制,需额外集成对应厂商的推送SDK才能保证关闭应用后稳定收推送。
  • iOS推送格式:发送推送时需确保apns-push-type为alert(普通通知),如果是数据推送需添加content-available: 1字段。
  • 推送消息结构:必须包含notification字段才能触发系统通知栏显示,纯数据消息需要后台服务自行处理并显示通知。

内容的提问来源于stack exchange,提问作者Cristiano Z

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:43:17