From 4d7dfcb8426514036c1f6f102c18679cbdaf2c7c Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Thu, 30 Oct 2025 07:04:29 +0000 Subject: [PATCH] feat(dev-app): register native fetcher SPI implementation Add host app implementation of NativeNotificationContentFetcher for development app: - Create PluginApplication extends Application to register fetcher on app startup - Create DemoNativeFetcher implementing NativeNotificationContentFetcher interface - Register PluginApplication in AndroidManifest.xml - DemoNativeFetcher returns mock notification content for testing This demonstrates the SPI pattern where host apps provide their own content fetching implementation to the plugin for background workers. --- android/app/src/main/AndroidManifest.xml | 1 + .../dailynotification/DemoNativeFetcher.java | 85 +++++++++++++++++++ .../dailynotification/PluginApplication.java | 38 +++++++++ 3 files changed, 124 insertions(+) create mode 100644 android/app/src/main/java/com/timesafari/dailynotification/DemoNativeFetcher.java create mode 100644 android/app/src/main/java/com/timesafari/dailynotification/PluginApplication.java diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a1a4759..0cd446e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ > fetchContent( + @NonNull FetchContext context) { + + Log.d(TAG, "DemoNativeFetcher: Fetch triggered - trigger=" + context.trigger + + ", scheduledTime=" + context.scheduledTime + ", fetchTime=" + context.fetchTime); + + return CompletableFuture.supplyAsync(() -> { + try { + // Simulate network delay + Thread.sleep(100); + + List contents = new ArrayList<>(); + + // Create a demo notification + NotificationContent demoContent = new NotificationContent(); + demoContent.setId("demo_notification_" + System.currentTimeMillis()); + demoContent.setTitle("Demo Notification from Native Fetcher"); + demoContent.setBody("This is a demo notification from the native fetcher SPI. " + + "Trigger: " + context.trigger + + (context.scheduledTime != null ? + ", Scheduled: " + new java.util.Date(context.scheduledTime) : "")); + + // Use scheduled time from context, or default to 1 hour from now + long scheduledTimeMs = context.scheduledTime != null ? + context.scheduledTime : (System.currentTimeMillis() + 3600000); + demoContent.setScheduledTime(scheduledTimeMs); + + // fetchTime is set automatically by NotificationContent constructor (as fetchedAt) + demoContent.setPriority("default"); + demoContent.setSound(true); + + contents.add(demoContent); + + Log.i(TAG, "DemoNativeFetcher: Returning " + contents.size() + + " notification(s)"); + + return contents; + + } catch (InterruptedException e) { + Log.e(TAG, "DemoNativeFetcher: Interrupted during fetch", e); + Thread.currentThread().interrupt(); + return Collections.emptyList(); + + } catch (Exception e) { + Log.e(TAG, "DemoNativeFetcher: Error during fetch", e); + return Collections.emptyList(); + } + }); + } +} + diff --git a/android/app/src/main/java/com/timesafari/dailynotification/PluginApplication.java b/android/app/src/main/java/com/timesafari/dailynotification/PluginApplication.java new file mode 100644 index 0000000..42e7657 --- /dev/null +++ b/android/app/src/main/java/com/timesafari/dailynotification/PluginApplication.java @@ -0,0 +1,38 @@ +/** + * PluginApplication.java + * + * Application class for the Daily Notification Plugin demo app. + * Registers the native content fetcher SPI implementation. + * + * @author Matthew Raymer + * @version 1.0.0 + */ + +package com.timesafari.dailynotification; + +import android.app.Application; +import android.util.Log; +import com.timesafari.dailynotification.DailyNotificationPlugin; +import com.timesafari.dailynotification.NativeNotificationContentFetcher; + +/** + * Application class that registers native fetcher for plugin demo app + */ +public class PluginApplication extends Application { + + private static final String TAG = "PluginApplication"; + + @Override + public void onCreate() { + super.onCreate(); + + Log.i(TAG, "Initializing Daily Notification Plugin demo app"); + + // Register demo native fetcher + NativeNotificationContentFetcher demoFetcher = new DemoNativeFetcher(); + DailyNotificationPlugin.setNativeFetcher(demoFetcher); + + Log.i(TAG, "Demo native fetcher registered: " + demoFetcher.getClass().getName()); + } +} +