fix: initialize reminder channel and clarify notification permission diagnostics

This commit is contained in:
Codex
2026-10-27 17:37:03 +08:00
parent db953b8b3d
commit fbcb7fb637
9 changed files with 165 additions and 10 deletions
@@ -8,6 +8,7 @@ import 'package:flutter/services.dart';
import '../domain/course.dart';
import '../domain/app_settings.dart';
import '../domain/course_occurrence.dart';
import 'diagnostic_log.dart';
import 'notification_service.dart';
class ReminderPermissions {
@@ -72,7 +73,8 @@ class LocalNotificationService extends NotificationService {
await cancelOwned();
return const ReminderResult(
ReminderStatus.permissionDenied,
message: '请允许通知,并检查系统中的“课前提醒”通知类别。',
message:
'通知未获允许,当前没有安排课前提醒。请在“通知设置”开启TPSchedule的通知总开关和“课前提醒”类别,再点“检查提醒”。',
);
}
final upcoming =
@@ -144,7 +146,7 @@ class LocalNotificationService extends NotificationService {
if (!saved.containsAll(desired.keys)) {
throw const ReminderSetupException(
'schedule_not_saved',
'系统未保存全部提醒,请点击“检查提醒”后重试。',
'部分提醒尚未完成登记,请点击“检查提醒”后重试。',
);
}
final message = [
@@ -191,6 +193,12 @@ class PluginReminderGateway extends ReminderGateway {
final void Function(String key)? onTap;
final _plugin = FlutterLocalNotificationsPlugin();
static const _system = MethodChannel('com.tpschedule.app/reminders');
static const _courseChannel = AndroidNotificationChannel(
'hepan_lessons',
'课前提醒',
description: '课程开始前的提醒',
importance: Importance.high,
);
String? _activeQueryWarning;
Future<void>? _initializing;
Future<void> initialize() => _initializing ??= Future<void>(() async {
@@ -205,6 +213,9 @@ class PluginReminderGateway extends ReminderGateway {
if (ready != true) {
throw StateError('通知服务初始化失败');
}
// Make the category visible before checking access or scheduling.
// Reusing its ID preserves the user's existing Android channel choices.
await _android?.createNotificationChannel(_courseChannel);
final launch = await _plugin.getNotificationAppLaunchDetails();
if (launch?.didNotificationLaunchApp == true) {
_select(launch?.notificationResponse?.payload);
@@ -239,9 +250,20 @@ class PluginReminderGateway extends ReminderGateway {
channel.id == 'hepan_lessons' &&
channel.importance == Importance.none,
);
final appEnabled = await _android?.areNotificationsEnabled() ?? false;
DiagnosticLog.instance.add(
'reminder_access_checked',
fields: {
'result': appEnabled && courseChannelEnabled,
'code': !appEnabled
? 'app_notifications_disabled'
: !courseChannelEnabled
? 'course_channel_disabled'
: 'allowed',
},
);
return ReminderPermissions(
(await _android?.areNotificationsEnabled() ?? false) &&
courseChannelEnabled,
appEnabled && courseChannelEnabled,
await _android?.canScheduleExactNotifications() ?? false,
);
}
@@ -305,7 +327,7 @@ class PluginReminderGateway extends ReminderGateway {
);
final saved = await _plugin.pendingNotificationRequests();
if (!saved.any((item) => item.id == -1002)) {
throw const ReminderSetupException('test_not_saved', '系统未保存测试提醒。');
throw const ReminderSetupException('test_not_saved', '测试提醒登记未完成。');
}
return '已安排测试,请按手机 Home 键回到桌面,10 秒后查看通知栏。';
}
@@ -327,6 +349,7 @@ class PluginReminderGateway extends ReminderGateway {
final channel = channels
?.where((item) => item.id == 'hepan_lessons')
.firstOrNull;
final appEnabled = await _android?.areNotificationsEnabled();
Map<Object?, Object?>? system;
String? systemError;
try {
@@ -338,6 +361,11 @@ class PluginReminderGateway extends ReminderGateway {
}
return {
'notifications': access.notifications,
'appNotificationsEnabled': appEnabled,
'channelExists': channels == null ? null : channel != null,
'courseChannelEnabled': channel == null
? null
: channel.importance != Importance.none,
'exactAlarm': access.exactAlarm,
'pendingCount': pending.length,
'channelImportance': channel?.importance.value,