204 lines
5.8 KiB
Dart
204 lines
5.8 KiB
Dart
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
/// Service for managing local notifications
|
|
/// Handles batch evaluation progress notifications and completion alerts
|
|
///
|
|
/// Usage example:
|
|
/// ```dart
|
|
/// final notificationService = NotificationService();
|
|
/// await notificationService.initialize();
|
|
///
|
|
/// // Set up tap callback
|
|
/// notificationService.onNotificationTapped = (payload) {
|
|
/// // Handle navigation based on payload
|
|
/// if (payload == 'batch_complete') {
|
|
/// // Navigate to results screen
|
|
/// }
|
|
/// };
|
|
///
|
|
/// // Show batch start notification
|
|
/// await notificationService.showBatchStartNotification(10);
|
|
///
|
|
/// // Update progress
|
|
/// await notificationService.updateProgressNotification(
|
|
/// current: 5,
|
|
/// total: 10,
|
|
/// courseName: '高等数学',
|
|
/// );
|
|
///
|
|
/// // Show completion
|
|
/// await notificationService.showCompletionNotification(
|
|
/// success: 9,
|
|
/// failed: 1,
|
|
/// total: 10,
|
|
/// );
|
|
/// ```
|
|
class NotificationService {
|
|
static const String _channelId = 'evaluation_progress';
|
|
static const String _channelName = '评教进度';
|
|
static const String _channelDescription = '显示批量评教的实时进度';
|
|
|
|
static const int _batchNotificationId = 1000;
|
|
static const int _progressNotificationId = 1001;
|
|
static const int _completionNotificationId = 1002;
|
|
static const int _errorNotificationId = 1003;
|
|
|
|
final FlutterLocalNotificationsPlugin _notifications;
|
|
bool _isInitialized = false;
|
|
|
|
// Callback for when notification is tapped
|
|
Function(String?)? onNotificationTapped;
|
|
|
|
NotificationService() : _notifications = FlutterLocalNotificationsPlugin();
|
|
|
|
/// Initialize the notification service
|
|
///
|
|
/// Configures notification channels for Android and iOS
|
|
/// Sets up notification icons and default settings
|
|
///
|
|
/// Returns true if initialization succeeds, false otherwise
|
|
Future<bool> initialize() async {
|
|
if (_isInitialized) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
// Android initialization settings
|
|
const androidSettings = AndroidInitializationSettings(
|
|
'@mipmap/ic_launcher',
|
|
);
|
|
|
|
// iOS initialization settings
|
|
const iosSettings = DarwinInitializationSettings(
|
|
requestAlertPermission: true,
|
|
requestBadgePermission: true,
|
|
requestSoundPermission: true,
|
|
);
|
|
|
|
// Combined initialization settings
|
|
const initSettings = InitializationSettings(
|
|
android: androidSettings,
|
|
iOS: iosSettings,
|
|
);
|
|
|
|
// Initialize the plugin
|
|
final initialized = await _notifications.initialize(
|
|
initSettings,
|
|
onDidReceiveNotificationResponse: _onNotificationTapped,
|
|
onDidReceiveBackgroundNotificationResponse: _onNotificationTapped,
|
|
);
|
|
|
|
if (initialized == true) {
|
|
// Create notification channel for Android
|
|
await _createNotificationChannel();
|
|
_isInitialized = true;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
} catch (e) {
|
|
debugPrint('Failed to initialize notification service: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// Create Android notification channel
|
|
///
|
|
/// Sets up a high-priority channel for evaluation progress notifications
|
|
Future<void> _createNotificationChannel() async {
|
|
const androidChannel = AndroidNotificationChannel(
|
|
_channelId,
|
|
_channelName,
|
|
description: _channelDescription,
|
|
importance: Importance.high,
|
|
enableVibration: true,
|
|
playSound: true,
|
|
);
|
|
|
|
await _notifications
|
|
.resolvePlatformSpecificImplementation<
|
|
AndroidFlutterLocalNotificationsPlugin
|
|
>()
|
|
?.createNotificationChannel(androidChannel);
|
|
}
|
|
|
|
/// Handle notification tap events
|
|
///
|
|
/// Called when user taps on a notification
|
|
/// Triggers the callback to allow navigation to specific screens
|
|
void _onNotificationTapped(NotificationResponse response) {
|
|
debugPrint('Notification tapped: ${response.payload}');
|
|
|
|
// Trigger the callback if set
|
|
if (onNotificationTapped != null) {
|
|
onNotificationTapped!(response.payload);
|
|
}
|
|
}
|
|
|
|
/// Check if the service is initialized
|
|
bool get isInitialized => _isInitialized;
|
|
|
|
/// Show notification when batch evaluation starts
|
|
///
|
|
/// [totalCourses] - Total number of courses to evaluate
|
|
Future<void> showBatchStartNotification(int totalCourses) async {
|
|
// Notification service disabled
|
|
return;
|
|
}
|
|
|
|
/// Update progress notification with current status
|
|
///
|
|
/// Shows a progress bar and current course being evaluated
|
|
///
|
|
/// [current] - Number of courses completed
|
|
/// [total] - Total number of courses
|
|
/// [courseName] - Name of the current course being evaluated
|
|
Future<void> updateProgressNotification({
|
|
required int current,
|
|
required int total,
|
|
required String courseName,
|
|
}) async {
|
|
// Notification service disabled
|
|
return;
|
|
}
|
|
|
|
/// Show completion notification with final statistics
|
|
///
|
|
/// [success] - Number of successfully evaluated courses
|
|
/// [failed] - Number of failed evaluations
|
|
/// [total] - Total number of courses
|
|
Future<void> showCompletionNotification({
|
|
required int success,
|
|
required int failed,
|
|
required int total,
|
|
}) async {
|
|
// Notification service disabled
|
|
return;
|
|
}
|
|
|
|
/// Show error notification
|
|
///
|
|
/// [message] - Error message to display
|
|
Future<void> showErrorNotification(String message) async {
|
|
// Notification service disabled
|
|
return;
|
|
}
|
|
|
|
/// Cancel all active notifications
|
|
///
|
|
/// Clears all notifications from the notification tray
|
|
Future<void> cancelAll() async {
|
|
if (!_isInitialized) {
|
|
debugPrint('Notification service not initialized');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await _notifications.cancelAll();
|
|
} catch (e) {
|
|
debugPrint('Failed to cancel notifications: $e');
|
|
}
|
|
}
|
|
}
|