“我正在开发一款 Flutter 应用,其中我使用 Firebase Cloud Messaging (FCM) 来接收通知。当应用处于前台时,徽章计数会正确更新和重置,但当...
`我正在开发一款 Flutter 应用,使用 Firebase Cloud Messaging (FCM) 接收通知。当应用处于前台时,徽章计数会正确更新和重置,但当应用处于后台或关闭时,徽章计数会按预期增加但不会重置。
我使用 SharedPreferences 实现了徽章计数功能以保留计数,并使用了在必要时重置计数的方法。我预计徽章计数会在应用在后台或关闭后重新打开时重置。当应用处于活动状态时,计数会按预期更新,但在应用进入后台或关闭然后重新打开后,计数无法重置并从之前的值继续。`
这是我的实现:
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
if (message.notification != null) {
NotificationApi().showNotification(message);
BadgeCounter.incrementBadgeCount();
}
}
class NotificationApi {
Future initNotifications() async {
// Other initialization code
await initPushNotifications();
}
Future<void> initPushNotifications() async {
FirebaseMessaging.instance.getInitialMessage().then(_handleMessage);
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
FirebaseMessaging.onBackgroundMessage(_handleBackgroundMessage);
FirebaseMessaging.onMessage.listen((message) {
debugPrint('onMessage: ${BadgeCounter.badgeNotifier.value}');
BadgeCounter.incrementBadgeCount();
showNotification(message);
});
}
}
class BadgeCounter {
static ValueNotifier<int> badgeNotifier = ValueNotifier<int>(0);
static const String keyBadgeCount = 'keyBadgeCount';
static Future<void> loadBadgeCount() async {
final prefs = await SharedPreferences.getInstance();
prefs.reload();
badgeNotifier.value = prefs.getInt(keyBadgeCount) ?? 0;
}
static Future<void> incrementBadgeCount() async {
final prefs = await SharedPreferences.getInstance();
prefs.reload();
badgeNotifier.value++;
await prefs.setInt(keyBadgeCount, badgeNotifier.value);
}
static Future<void> resetBadgeCount() async {
final prefs = await SharedPreferences.getInstance();
badgeNotifier.value = 0;
await prefs.setInt(keyBadgeCount, badgeNotifier.value);
}
}
class _HomeViewState extends ConsumerState<HomeView> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
NotificationApi().initNotifications();
BadgeCounter.loadBadgeCount();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.resumed) {
debugPrint('AppLifecycleState.resumed');
SharedPreferences.getInstance().then((prefs) => {
prefs.reload().then((_) {
BadgeCounter.loadBadgeCount();
})
});
}
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
}
class _NotificationViewState extends ConsumerState<NotificationView> {
@override
void initState() {
super.initState();
BadgeCounter.resetBadgeCount();
}
}
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
if (message.notification != null) {
BadgeCounter.incrementBadgeCount();
NotificationApi().showNotification(message);
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Badge Notification',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomeView(),
);
}
}
class BadgeCounter {
static ValueNotifier<int> badgeNotifier = ValueNotifier<int>(0);
static const String keyBadgeCount = 'keyBadgeCount';
static Future<void> loadBadgeCount() async {
final prefs = await SharedPreferences.getInstance();
badgeNotifier.value = prefs.getInt(keyBadgeCount) ?? 0;
}
static Future<void> incrementBadgeCount() async {
final prefs = await SharedPreferences.getInstance();
int currentCount = prefs.getInt(keyBadgeCount) ?? 0;
currentCount++;
await prefs.setInt(keyBadgeCount, currentCount);
badgeNotifier.value = currentCount;
}
static Future<void> resetBadgeCount() async {
final prefs = await SharedPreferences.getInstance();
badgeNotifier.value = 0;
await prefs.setInt(keyBadgeCount, badgeNotifier.value);
}
}
class NotificationApi {
Future<void> initNotifications() async {
await initPushNotifications();
}
Future<void> initPushNotifications() async {
FirebaseMessaging.instance.getInitialMessage().then(_handleMessage);
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
FirebaseMessaging.onMessage.listen((message) {
BadgeCounter.incrementBadgeCount();
showNotification(message);
});
}
void _handleMessage(RemoteMessage? message) {
if (message != null) {
showNotification(message);
}
}
void showNotification(RemoteMessage message) {
debugPrint('Notification: ${message.notification?.title ?? 'No Title'}');
}
}
class HomeView extends ConsumerStatefulWidget {
@override
_HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends ConsumerState<HomeView> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
NotificationApi().initNotifications();
BadgeCounter.loadBadgeCount();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.resumed) {
BadgeCounter.loadBadgeCount();
}
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home View'),
),
body: Center(
child: ValueListenableBuilder<int>(
valueListenable: BadgeCounter.badgeNotifier,
builder: (context, badgeCount, _) {
return Text('Badge Count: $badgeCount');
},
),
),
);
}
}
class NotificationView extends ConsumerStatefulWidget {
@override
_NotificationViewState createState() => _NotificationViewState();
}
class _NotificationViewState extends ConsumerState<NotificationView> {
@override
void initState() {
super.initState();
BadgeCounter.resetBadgeCount();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Notification View'),
),
body: Center(
child: Text('Notifications'),
),
);
}
}