Allow background sound notification

This commit is contained in:
2026-02-26 21:43:05 +08:00
parent 6ccf820438
commit 9cc99e612a
7 changed files with 265 additions and 142 deletions
+55 -8
View File
@@ -11,23 +11,50 @@ import 'package:firebase_messaging/firebase_messaging.dart';
import 'firebase_options.dart';
import 'providers/profile_provider.dart';
import 'models/profile.dart';
import 'app.dart';
import 'providers/notifications_provider.dart';
import 'utils/app_time.dart';
import 'utils/notification_permission.dart';
import 'services/notification_service.dart';
import 'services/notification_bridge.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
// Initialize the plugin
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
/// Handle messages received while the app is terminated or in background.
@pragma('vm:entry-point') // Required for background execution
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// Do minimal work in background isolate. Avoid initializing Flutter
// plugins here (e.g. flutter_local_notifications) as that can hang
// the background isolate and interfere with subsequent launches.
// If you need to persist data from a background message, perform a
// lightweight HTTP call or write to a background-capable DB.
return;
// 1. Initialize the plugin inside the background isolate
final FlutterLocalNotificationsPlugin localNotifPlugin =
FlutterLocalNotificationsPlugin();
// 2. Extract title and body from the DATA payload (not message.notification)
final String title = message.data['title'] ?? 'New Notification';
final String body = message.data['body'] ?? 'You have a new update in TasQ.';
// Create a unique ID
final int id = DateTime.now().millisecondsSinceEpoch ~/ 1000;
// 3. Define the exact same channel specifics
const androidDetails = AndroidNotificationDetails(
'tasq_custom_sound_channel_2',
'High Importance Notifications',
importance: Importance.max,
priority: Priority.high,
playSound: true,
sound: RawResourceAndroidNotificationSound('tasq_notification'),
);
// 4. Show the notification manually
await localNotifPlugin.show(
id: id,
title: title,
body: body,
notificationDetails: const NotificationDetails(android: androidDetails),
payload: message.data['type'], // Or whatever payload you need for routing
);
}
Future<void> main() async {
@@ -97,6 +124,7 @@ Future<void> main() async {
// request FCM permission (iOS/Android13+) and handle foreground messages
await FirebaseMessaging.instance.requestPermission();
}
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
final notification = message.notification;
if (notification != null) {
@@ -122,6 +150,25 @@ Future<void> main() async {
},
);
// 1. Define the High Importance Channel (This MUST match your manifest exactly)
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'tasq_custom_sound_channel', // id
'High Importance Notifications', // title visible to user in phone settings
description: 'This channel is used for important TasQ notifications.',
importance:
Importance.max, // THIS is what forces the sound and heads-up banner
playSound: true,
// 👇 Tell Android to use your specific file in the raw folder
sound: RawResourceAndroidNotificationSound('tasq_notification'),
);
// 2. Create the channel on the device
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin
>()
?.createNotificationChannel(channel);
// global navigator key used for snackbars/navigation from notification
final navigatorKey = GlobalKey<NavigatorState>();