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

Android应用强制停止后无法接收FCM通知求助

问题描述

FCM消息推送在iOS和Web端正常,但Android平台应用被强制停止(终止)时无法接收通知,出现错误日志:

broadcast intent callback: result=CANCELLED forIntent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10000000 pkg= (has extras) }

应用处于前台/后台时接收正常,Google Play商店版本也存在此问题。

相关配置代码如下:

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="com.example.permission.C2D_MESSAGE"/>
    <permission android:name="com.example.permission.C2D_MESSAGE" android:protectionLevel="signature"/>

    <application
        android:label="Example"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <meta-data
                    android:name="com.google.firebase.messaging.default_notification_channel_id"
                    android:value="example_notification" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

main.dart关键代码

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  debugPrint("Handling a background message: ${message.messageId}");
  DartPluginRegistrant.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  await setupFlutterNotifications();
  showFlutterNotification(message);
  print('Handling a background message ${message.messageId}');
}

// 其余setupFlutterNotifications、showFlutterNotification等代码略

解决方案

1. 完善AndroidManifest的FCM组件配置

你的Manifest缺少FCM核心服务和系统级广播接收器的声明,这是应用被强制停止后能被唤醒接收推送的关键。在<application>标签内添加以下内容:

<!-- FCM消息处理服务 -->
<service
    android:name="com.google.firebase.messaging.FirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

<!-- 令牌刷新服务 -->
<service
    android:name="com.google.firebase.iid.FirebaseInstanceIdService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>

<!-- 系统级C2DM广播接收器,用于应用停止时接收推送唤醒信号 -->
<receiver
    android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
    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>

${applicationId}会自动替换为你的应用包名,无需手动修改。

2. 优化后台消息处理逻辑

  • 移除_firebaseMessagingBackgroundHandler中重复的Firebase.initializeApp调用,FirebaseMessaging.onBackgroundMessage已经自动初始化Firebase核心服务,重复调用可能导致冲突。
  • 确保setupFlutterNotifications的初始化逻辑不会重复执行,避免后台唤醒时出现异常。

修改后的_firebaseMessagingBackgroundHandler:

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  debugPrint("Handling a background message: ${message.messageId}");
  DartPluginRegistrant.ensureInitialized();
  await setupFlutterNotifications();
  showFlutterNotification(message);
  print('Handling a background message ${message.messageId}');
}

3. 处理厂商后台限制

部分国产Android厂商(小米、华为、OPPO等)有严格的后台唤醒限制,即使配置正确,应用被强制停止后也可能无法接收推送。需要引导用户:

  • 给应用开启「自启动权限」
  • 在电池优化中设置为「不优化」
  • 将应用锁定到后台多任务列表

4. 确认推送消息类型

FCM分为通知消息和数据消息:

  • 通知消息:应用后台时由系统直接展示,强制停止后系统仍会接收并展示;若用自定义组件展示,需确保消息格式包含notification字段。
  • 数据消息:必须由应用后台处理器处理,依赖正确的Manifest配置和厂商权限才能在应用停止时唤醒应用。

确保服务器端推送的消息包含notification字段,或同时包含data字段,且格式符合FCM规范。

5. 验证签名与包名一致性

Google Play商店版本需确保签名证书与Firebase控制台配置一致,包名也必须完全匹配,否则FCM服务会拒绝推送请求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:19:52