flutter_badge_manager

Pub

Plugin to set / clear application badge numbers on iOS, macOS and supported Android launchers (OEM / third‑party). Stock Android (Pixel / AOSP) only shows a notification dot; numeric badges depend on the launcher.

Platform Min Version Notes
Android API 21+ Numeric badge only on supported launchers; request POST_NOTIFICATIONS on API 33+.
iOS 13.0+ Updates the app badge directly and also syncs it through the notification center on iOS 16+ for better persistence.
macOS 10.15+ Uses dockTile.badgeLabel; needs notification authorization.

Features

  • Unified API with automatic federated implementation selection.
  • Preferred instance style (FlutterBadgeManager.instance.update(3)).
  • 0.2.0 exposes only the instance API and federated Pigeon-backed platform implementations.
  • Fails fast if no federated implementation is registered for the current platform.
  • Simple support check: isSupported().

Installation

Add to pubspec.yaml (only top-level plugin needed):

dependencies:
  flutter_badge_manager: ^<latest>

Federated platform packages (Android, iOS/macOS) are auto-included when you build your app.

iOS Setup

If your app also posts notifications, request notification authorization through your app's normal notification flow. On tested iOS versions below 26, request badge notification permission before relying on badge display or persistence. Badge visibility can still be affected by system notification settings.

Optional (for remote notification background handling) add to ios/Runner/Info.plist:

<key>UIBackgroundModes</key>
<array>
  <string>remote-notification</string>
</array>

macOS Setup

Optional banner style in macos/Runner/Info.plist:

<key>NSUserNotificationAlertStyle</key>
<string>banner</string>

Android Notes

No official numeric badge API. Supported via OEM/third‑party launchers (Samsung, Xiaomi, Huawei, Sony, etc.). Pixel shows only dots triggered by notifications.

Android 13+ (API 33): request runtime notification permission before updating badge number.

Optional launcher permissions (add only what you really need) in AndroidManifest.xml:

<!-- Samsung -->
<uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
<!-- Huawei -->
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
<uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/>
<!-- Sony -->
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
<uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE"/>
<!-- HTC / others -->
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>
<uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE"/>

Usage

Import:

import 'package:flutter_badge_manager/flutter_badge_manager.dart';

Instance style (recommended):

final badge = FlutterBadgeManager.instance;
if (await badge.isSupported()) {
  await badge.update(7);
  await badge.remove();
}

Basic helper:

Future<void> setUnread(int unread) async {
  final badge = FlutterBadgeManager.instance;
  if (!await badge.isSupported()) return;
  await badge.update(unread.clamp(0, 9999));
}

For migration details, see ../MIGRATION.md.

For tests, bind a specific platform implementation with FlutterBadgeManager.instanceFor(...) instead of relying on the shared singleton.

iOS/macOS:

  • Request notification authorization as part of your app's notification flow when needed. On tested iOS versions below 26, request badge permission before relying on badge display or persistence. Badge capability detection does not depend on that authorization state.

Android (API 33+):

import 'package:permission_handler/permission_handler.dart';

Future<void> ensureNotificationPermission() async {
  final status = await Permission.notification.status;
  if (!status.isGranted) {
    await Permission.notification.request();
  }
}

Constraints

  • count >= 0; negative values throw ArgumentError.
  • Unsupported launchers may ignore numeric changes.
  • Clearing badge = remove() (sets label to blank / 0 depending on platform).

Troubleshooting

  • Returns false on isSupported() on Pixel: expected (numeric not available).
  • Badge not visible on Android: launcher does not support numeric badges or permission not granted.
  • iOS badge not updating or not persisting: check app notification settings and badge allowance in iOS Settings. On tested iOS versions below 26, confirm the app has explicitly requested badge notification permission.

Documentation

Contributing

Issues / PRs welcome. Prefer evolving the instance API and federated platform implementations without reintroducing a legacy static wrapper.

License

MIT License (see LICENSE).