flutter_badge_manager
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.0exposes 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.
Permissions (recommended flow)
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 throwArgumentError.- 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
- Repository architecture: ../docs/architecture.md
- Feature details: ../docs/features.md
- Testing and CI: ../docs/tests.md
- Release workflow: ../docs/deployment.md
Contributing
Issues / PRs welcome. Prefer evolving the instance API and federated platform implementations without reintroducing a legacy static wrapper.
License
MIT License (see LICENSE).