feat: compose Android app and verify native calendar and reminders

This commit is contained in:
Codex
2026-10-13 09:14:47 +08:00
parent 2c4256b880
commit 5ceab20b67
37 changed files with 695 additions and 229 deletions
@@ -51,6 +51,11 @@ class AndroidCalendarService extends CalendarService {
AndroidCalendarService(this.gateway);
final CalendarGateway gateway;
@override
Future<Map<String, String>> ownedEventIds(String calendarId) async => {
for (final event in await gateway.ownedEvents(calendarId))
if (event.owned && event.calendarId == calendarId) event.key: event.id,
};
@override
Future<bool> requestAccess() => gateway.requestAccess();
@override
Future<List<DeviceCalendar>> listWritableCalendars() => gateway.calendars();
@@ -14,4 +14,6 @@ abstract class CalendarService {
Map<String, String> knownEventIds,
);
Future<void> deleteOwned(Map<String, String> eventIds);
Future<Map<String, String>> ownedEventIds(String calendarId) async =>
const {};
}
@@ -147,18 +147,27 @@ class PluginReminderGateway extends ReminderGateway {
final void Function(String key)? onTap;
final _plugin = FlutterLocalNotificationsPlugin();
Future<void>? _initializing;
Future<void> initialize() => _initializing ??= () async {
await _plugin.initialize(
settings: const InitializationSettings(
android: AndroidInitializationSettings('ic_stat_calendar'),
),
onDidReceiveNotificationResponse: (response) => _select(response.payload),
);
final launch = await _plugin.getNotificationAppLaunchDetails();
if (launch?.didNotificationLaunchApp == true) {
_select(launch?.notificationResponse?.payload);
Future<void> initialize() => _initializing ??= Future<void>(() async {
try {
final ready = await _plugin.initialize(
settings: const InitializationSettings(
android: AndroidInitializationSettings('ic_stat_calendar'),
),
onDidReceiveNotificationResponse: (response) =>
_select(response.payload),
);
if (ready != true) {
throw StateError('通知服务初始化失败');
}
final launch = await _plugin.getNotificationAppLaunchDetails();
if (launch?.didNotificationLaunchApp == true) {
_select(launch?.notificationResponse?.payload);
}
} catch (_) {
_initializing = null;
rethrow;
}
}();
});
void _select(String? payload) {
if (payload?.startsWith('hepan:') == true) {
onTap?.call(payload!.substring(6));