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

Firebase Messaging Service在Android Nougat上崩溃求助

Fixing FCM Notification Crash on Android Nougat (API 24/25)

Hey there! That crash you're hitting makes total sense—Notification Channels were only introduced in Android Oreo (API 26). Trying to use them on Nougat (API 24/25) will trigger a runtime error because those classes don't exist on older systems. Let's tweak your code to support both old and new Android versions smoothly.

The Root Cause

Your current code creates a NotificationChannel and uses the Oreo+ Notification.Builder constructor (with channel ID) unconditionally. On Nougat, the system can't find the NotificationChannel class at all, leading to an immediate crash.

Step-by-Step Fix

Here's the adjusted MessagingService code that handles all versions down to Jelly Bean (API 16) without crashing:

public class MessagingService extends FirebaseMessagingService {
    private static final String TAG = "FCM Message";
    private static final String CHANNEL_ID = "channel";
    private static final String CHANNEL_NAME = "App Notifications";

    public MessagingService() {
        super();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        String message = remoteMessage.getData().get("team");
        
        // Setup intent for notification tap action
        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                getApplicationContext(),
                1,
                intent,
                // Handle immutable flags for newer SDKs to avoid crashes
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT
        );
        
        Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // 1. Only create Notification Channel for API 26+ (Oreo and above)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel(
                    CHANNEL_ID,
                    CHANNEL_NAME,
                    NotificationManager.IMPORTANCE_HIGH
            );
            // Optional: Add extra channel config (vibration, lights, etc.)
            notificationChannel.setSound(defaultSound, null);
            notificationManager.createNotificationChannel(notificationChannel);
        }

        // 2. Build notification with version-specific logic
        Notification notification;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Oreo+ requires channel ID in the builder
            notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID)
                    .setContentText(message)
                    .setSound(defaultSound)
                    .setContentIntent(pendingIntent)
                    .setSmallIcon(android.R.drawable.sym_action_chat)
                    .setWhen(System.currentTimeMillis())
                    .setPriority(NotificationManager.IMPORTANCE_HIGH) // Use channel-based priority for Oreo+
                    .build();
        } else {
            // Pre-Oreo uses legacy builder and direct priority setting
            notification = new Notification.Builder(getApplicationContext())
                    .setContentText(message)
                    .setSound(defaultSound)
                    .setContentIntent(pendingIntent)
                    .setSmallIcon(android.R.drawable.sym_action_chat)
                    .setWhen(System.currentTimeMillis())
                    .setPriority(Notification.PRIORITY_MAX)
                    .build();
        }

        // Trigger the notification
        notificationManager.notify(1, notification);
    }
}

Key Changes Explained

  • Version Guard Clauses: All NotificationChannel code is wrapped in a check for Build.VERSION.SDK_INT >= Build.VERSION_CODES.O—this ensures the code never runs on systems that can't support it.
  • Dual Builder Logic: We use the correct Notification.Builder for each API level:
    • Oreo+ uses the constructor that requires a channel ID
    • Pre-Oreo uses the legacy constructor (no channel ID needed)
  • Priority Handling: On Oreo+, notification priority is controlled by the channel's importance instead of the old Notification.PRIORITY_MAX constant.
  • PendingIntent Flags: Added a check for immutable flags (required for target SDK 31+) to avoid another potential crash on newer Android versions.

Quick Cleanup Tips

  • Remove the @TargetApi(Build.VERSION_CODES.O) and @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) annotations from the onMessageReceived method—they're redundant now that we handle version checks internally.
  • Test on both Nougat (API 24/25) and Oreo+ devices to confirm notifications work without crashes on either.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:57:29