Firebase Messaging Service在Android Nougat上崩溃求助
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
NotificationChannelcode is wrapped in a check forBuild.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.Builderfor 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_MAXconstant. - 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 theonMessageReceivedmethod—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

