Skip to main content

badge_kit 0.1.0 copy "badge_kit: ^0.1.0" to clipboard
badge_kit: ^0.1.0 copied to clipboard

A Flutter plugin to update the app icon badge and clear notifications through a single API. Swift Package Manager only on iOS.

example/lib/main.dart

import 'package:flutter/material.dart';

import 'package:badge_kit/badge_kit.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

final _notifications = FlutterLocalNotificationsPlugin();

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await _notifications.initialize(
    settings: const InitializationSettings(
      android: AndroidInitializationSettings('@mipmap/ic_launcher'),
      iOS: DarwinInitializationSettings(),
    ),
  );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: BadgeDemoPage());
  }
}

class BadgeDemoPage extends StatefulWidget {
  const BadgeDemoPage({super.key});

  @override
  State<BadgeDemoPage> createState() => _BadgeDemoPageState();
}

class _BadgeDemoPageState extends State<BadgeDemoPage> {
  int _count = 0;
  int _notificationId = 0;
  String _status = '';

  @override
  void initState() {
    super.initState();
    // Android 13+ requires a runtime permission to post notifications.
    _notifications
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.requestNotificationsPermission();
  }

  /// Runs [action] and shows its result in the status line. When [action]
  /// returns a message it is displayed as-is; otherwise '<label>: OK'.
  Future<void> _run(String label, Future<String?> Function() action) async {
    try {
      final message = await action();
      setState(() => _status = message ?? '$label: OK');
    } catch (e) {
      setState(() => _status = '$label: $e');
    }
  }

  Future<void> _sendNotification(String tag) async {
    // Let the notification itself set the app icon badge, the same way an
    // FCM push does with `aps.badge` / `notification_count`.
    setState(() => _count++);
    await _notifications.show(
      id: _notificationId++,
      title: 'badge_kit demo',
      body: "Notification tagged '$tag'",
      notificationDetails: NotificationDetails(
        android: AndroidNotificationDetails(
          'badge_kit_demo',
          'badge_kit demo',
          tag: tag,
          number: _count,
        ),
        // badge_kit matches iOS notifications by thread identifier
        // (or a "tag" key in the payload).
        iOS: DarwinNotificationDetails(
          threadIdentifier: tag,
          badgeNumber: _count,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('badge_kit example')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          Text('Badge count: $_count',
              style: Theme.of(context).textTheme.headlineSmall),
          const SizedBox(height: 16),
          Text('Send', style: Theme.of(context).textTheme.titleMedium),
          const SizedBox(height: 8),
          FilledButton(
            onPressed: () => _run('send chat', () async {
              await _sendNotification('chat');
              return null;
            }),
            child: const Text("Send notification tagged 'chat'"),
          ),
          const SizedBox(height: 8),
          FilledButton(
            onPressed: () => _run('send news', () async {
              await _sendNotification('news');
              return null;
            }),
            child: const Text("Send notification tagged 'news'"),
          ),
          const SizedBox(height: 16),
          Text('Badge', style: Theme.of(context).textTheme.titleMedium),
          const SizedBox(height: 8),
          FilledButton.tonal(
            onPressed: () => _run('setBadge', () async {
              setState(() => _count++);
              await BadgeKit.setBadge(_count);
              return null;
            }),
            child: const Text('Increment badge'),
          ),
          const SizedBox(height: 8),
          FilledButton.tonal(
            onPressed: () => _run('clearBadge', () async {
              setState(() => _count = 0);
              await BadgeKit.clearBadge();
              return null;
            }),
            child: const Text('Clear badge (keep notifications)'),
          ),
          const SizedBox(height: 8),
          FilledButton.tonal(
            onPressed: () => _run('clearBadge+notifications', () async {
              setState(() => _count = 0);
              await BadgeKit.clearBadge(removeNotifications: true);
              return null;
            }),
            child: const Text('Clear badge and notifications'),
          ),
          const SizedBox(height: 16),
          Text('Erase', style: Theme.of(context).textTheme.titleMedium),
          const SizedBox(height: 8),
          OutlinedButton(
            onPressed: () => _run('clearAllNotifications', () async {
              await BadgeKit.clearAllNotifications();
              return null;
            }),
            child: const Text('Clear all notifications'),
          ),
          const SizedBox(height: 8),
          OutlinedButton(
            onPressed: () => _run('clearNotificationsByTag', () async {
              await BadgeKit.clearNotificationsByTag('chat');
              return null;
            }),
            child: const Text("Clear notifications tagged 'chat'"),
          ),
          const SizedBox(height: 8),
          OutlinedButton(
            onPressed: () => _run('clearNotificationsByTags', () async {
              await BadgeKit.clearNotificationsByTags(['chat', 'news']);
              return null;
            }),
            child: const Text("Clear notifications tagged 'chat' or 'news'"),
          ),
          const SizedBox(height: 8),
          OutlinedButton(
            onPressed: () => _run('isBadgeSupported', () async {
              final supported = await BadgeKit.isBadgeSupported();
              return 'isBadgeSupported: $supported';
            }),
            child: const Text('Is badge supported?'),
          ),
          const SizedBox(height: 8),
          OutlinedButton(
            onPressed: () => _run('activeNotifications', () async {
              final active = await _notifications.getActiveNotifications();
              return 'active: ${active.length} ids=${active.map((n) => n.id).toList()}';
            }),
            child: const Text('List active notifications'),
          ),
          const SizedBox(height: 16),
          Text(_status),
        ],
      ),
    );
  }
}
0
likes
160
points
159
downloads

Documentation

API reference

Publisher

verified publishertukuyo.net

Weekly Downloads

A Flutter plugin to update the app icon badge and clear notifications through a single API. Swift Package Manager only on iOS.

Repository (GitHub)
View/report issues

Topics

#badge #notifications #app-icon-badge #swift-package-manager

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on badge_kit

Packages that implement badge_kit