Browse Source
Extracted daily reminder functionality from DailyNotificationPlugin into a dedicated DailyReminderManager class to reduce the plugin's size and effortsify responsibilities. Changes: - Created DailyReminderManager class (405 lines) for reminder CRUD - Created DailyReminderInfo data class (moved from inner class) - Delegated reminder methods to the manager - Removed duplicate helper methods from plugin - Added ensureReminderManagerInitialized() helper Impact: - Reduced DailyNotificationPlugin from 2639 to 2430 lines (209 lines) - Clear separation of concerns - Easier to test and maintain reminder functionality - Follows existing manager pattern (PermissionManager, ChannelManager, etc.) All public API methods remain unchanged - this is purely an internal refactoring.master
3 changed files with 486 additions and 260 deletions
@ -0,0 +1,31 @@ |
|||
/** |
|||
* DailyReminderInfo.java |
|||
* |
|||
* Data class representing a daily reminder configuration |
|||
* and its current state. |
|||
* |
|||
* @author Matthew Raymer |
|||
* @version 1.0.0 |
|||
*/ |
|||
|
|||
package com.timesafari.dailynotification; |
|||
|
|||
/** |
|||
* Information about a scheduled daily reminder |
|||
*/ |
|||
public class DailyReminderInfo { |
|||
public String id; |
|||
public String title; |
|||
public String body; |
|||
public String time; |
|||
public boolean sound; |
|||
public boolean vibration; |
|||
public String priority; |
|||
public boolean repeatDaily; |
|||
public String timezone; |
|||
public boolean isScheduled; |
|||
public long nextTriggerTime; |
|||
public long createdAt; |
|||
public long lastTriggered; |
|||
} |
|||
|
|||
@ -0,0 +1,403 @@ |
|||
/** |
|||
* DailyReminderManager.java |
|||
* |
|||
* Manages daily reminder functionality including creation, updates, |
|||
* cancellation, and retrieval. Handles persistent storage and |
|||
* notification scheduling. |
|||
* |
|||
* @author Matthew Raymer |
|||
* @version 1.0.0 |
|||
*/ |
|||
|
|||
package com.timesafari.dailynotification; |
|||
|
|||
import android.content.Context; |
|||
import android.content.SharedPreferences; |
|||
import android.util.Log; |
|||
|
|||
import com.getcapacitor.JSObject; |
|||
import com.getcapacitor.PluginCall; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Calendar; |
|||
import java.util.HashSet; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Set; |
|||
|
|||
/** |
|||
* Manager class for daily reminder operations |
|||
* |
|||
* Responsibilities: |
|||
* - Schedule daily reminders |
|||
* - Cancel scheduled reminders |
|||
* - Update existing reminders |
|||
* - Retrieve reminder list |
|||
* - Manage persistent storage |
|||
*/ |
|||
public class DailyReminderManager { |
|||
private static final String TAG = "DailyReminderManager"; |
|||
private static final String PREF_NAME = "daily_reminders"; |
|||
private static final String REMINDER_ID_PREFIX = "reminder_"; |
|||
|
|||
private final Context context; |
|||
private final DailyNotificationScheduler scheduler; |
|||
|
|||
/** |
|||
* Initialize the DailyReminderManager |
|||
* |
|||
* @param context Android context |
|||
* @param scheduler Notification scheduler instance |
|||
*/ |
|||
public DailyReminderManager(Context context, |
|||
DailyNotificationScheduler scheduler) { |
|||
this.context = context; |
|||
this.scheduler = scheduler; |
|||
Log.d(TAG, "DailyReminderManager initialized"); |
|||
} |
|||
|
|||
/** |
|||
* Schedule a new daily reminder |
|||
* |
|||
* @param id Unique identifier for the reminder |
|||
* @param title Reminder title |
|||
* @param body Reminder body text |
|||
* @param time Time in HH:mm format |
|||
* @param sound Whether to play sound |
|||
* @param vibration Whether to vibrate |
|||
* @param priority Notification priority |
|||
* @param repeatDaily Whether to repeat daily |
|||
* @param timezone Optional timezone string |
|||
* @return true if scheduled successfully |
|||
*/ |
|||
public boolean scheduleReminder(String id, String title, String body, |
|||
String time, boolean sound, |
|||
boolean vibration, String priority, |
|||
boolean repeatDaily, String timezone) { |
|||
try { |
|||
Log.d(TAG, "Scheduling daily reminder: " + id); |
|||
|
|||
// Validate time format
|
|||
String[] timeParts = time.split(":"); |
|||
if (timeParts.length != 2) { |
|||
Log.e(TAG, "Invalid time format: " + time); |
|||
return false; |
|||
} |
|||
|
|||
int hour = Integer.parseInt(timeParts[0]); |
|||
int minute = Integer.parseInt(timeParts[1]); |
|||
|
|||
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) { |
|||
Log.e(TAG, "Invalid time values"); |
|||
return false; |
|||
} |
|||
|
|||
// Create reminder content
|
|||
NotificationContent reminderContent = new NotificationContent(); |
|||
reminderContent.setId(REMINDER_ID_PREFIX + id); |
|||
reminderContent.setTitle(title); |
|||
reminderContent.setBody(body); |
|||
reminderContent.setSound(sound); |
|||
reminderContent.setPriority(priority); |
|||
|
|||
// Calculate next trigger time
|
|||
Calendar calendar = Calendar.getInstance(); |
|||
calendar.set(Calendar.HOUR_OF_DAY, hour); |
|||
calendar.set(Calendar.MINUTE, minute); |
|||
calendar.set(Calendar.SECOND, 0); |
|||
calendar.set(Calendar.MILLISECOND, 0); |
|||
|
|||
// If time has passed today, schedule for tomorrow
|
|||
if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { |
|||
calendar.add(Calendar.DAY_OF_MONTH, 1); |
|||
} |
|||
|
|||
reminderContent.setScheduledTime(calendar.getTimeInMillis()); |
|||
|
|||
// Store reminder in database
|
|||
storeReminderInDatabase(id, title, body, time, sound, |
|||
vibration, priority, repeatDaily, timezone); |
|||
|
|||
// Schedule the notification
|
|||
boolean scheduled = scheduler.scheduleNotification(reminderContent); |
|||
|
|||
if (scheduled) { |
|||
Log.i(TAG, "Daily reminder scheduled successfully: " + id); |
|||
} else { |
|||
Log.e(TAG, "Failed to schedule daily reminder: " + id); |
|||
} |
|||
|
|||
return scheduled; |
|||
|
|||
} catch (Exception e) { |
|||
Log.e(TAG, "Error scheduling daily reminder", e); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Cancel a scheduled reminder |
|||
* |
|||
* @param reminderId Reminder ID to cancel |
|||
* @return true if cancelled successfully |
|||
*/ |
|||
public boolean cancelReminder(String reminderId) { |
|||
try { |
|||
Log.d(TAG, "Cancelling daily reminder: " + reminderId); |
|||
|
|||
// Cancel the scheduled notification
|
|||
scheduler.cancelNotification(REMINDER_ID_PREFIX + reminderId); |
|||
|
|||
// Remove from database
|
|||
removeReminderFromDatabase(reminderId); |
|||
|
|||
Log.i(TAG, "Daily reminder cancelled: " + reminderId); |
|||
return true; |
|||
|
|||
} catch (Exception e) { |
|||
Log.e(TAG, "Error cancelling daily reminder", e); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Update an existing reminder |
|||
* |
|||
* @param reminderId Reminder ID to update |
|||
* @param title Optional new title |
|||
* @param body Optional new body |
|||
* @param time Optional new time in HH:mm format |
|||
* @param sound Optional new sound setting |
|||
* @param vibration Optional new vibration setting |
|||
* @param priority Optional new priority |
|||
* @param repeatDaily Optional new repeat setting |
|||
* @param timezone Optional new timezone |
|||
* @return true if updated successfully |
|||
*/ |
|||
public boolean updateReminder(String reminderId, String title, |
|||
String body, String time, Boolean sound, |
|||
Boolean vibration, String priority, |
|||
Boolean repeatDaily, String timezone) { |
|||
try { |
|||
Log.d(TAG, "Updating daily reminder: " + reminderId); |
|||
|
|||
// Cancel existing reminder
|
|||
scheduler.cancelNotification(REMINDER_ID_PREFIX + reminderId); |
|||
|
|||
// Update in database
|
|||
updateReminderInDatabase(reminderId, title, body, time, |
|||
sound, vibration, priority, |
|||
repeatDaily, timezone); |
|||
|
|||
// Reschedule with new settings
|
|||
if (title != null && body != null && time != null) { |
|||
// Parse time
|
|||
String[] timeParts = time.split(":"); |
|||
int hour = Integer.parseInt(timeParts[0]); |
|||
int minute = Integer.parseInt(timeParts[1]); |
|||
|
|||
// Create new reminder content
|
|||
NotificationContent reminderContent = new NotificationContent(); |
|||
reminderContent.setId(REMINDER_ID_PREFIX + reminderId); |
|||
reminderContent.setTitle(title); |
|||
reminderContent.setBody(body); |
|||
reminderContent.setSound(sound != null ? sound : true); |
|||
reminderContent.setPriority(priority != null ? priority : "normal"); |
|||
|
|||
// Calculate next trigger time
|
|||
Calendar calendar = Calendar.getInstance(); |
|||
calendar.set(Calendar.HOUR_OF_DAY, hour); |
|||
calendar.set(Calendar.MINUTE, minute); |
|||
calendar.set(Calendar.SECOND, 0); |
|||
calendar.set(Calendar.MILLISECOND, 0); |
|||
|
|||
if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { |
|||
calendar.add(Calendar.DAY_OF_MONTH, 1); |
|||
} |
|||
|
|||
reminderContent.setScheduledTime(calendar.getTimeInMillis()); |
|||
|
|||
// Schedule the updated notification
|
|||
boolean scheduled = scheduler.scheduleNotification(reminderContent); |
|||
|
|||
if (!scheduled) { |
|||
Log.e(TAG, "Failed to reschedule updated reminder"); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
Log.i(TAG, "Daily reminder updated: " + reminderId); |
|||
return true; |
|||
|
|||
} catch (Exception e) { |
|||
Log.e(TAG, "Error updating daily reminder", e); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Get all scheduled reminders |
|||
* |
|||
* @return List of DailyReminderInfo objects |
|||
*/ |
|||
public List<DailyReminderInfo> getReminders() { |
|||
try { |
|||
Log.d(TAG, "Getting scheduled reminders"); |
|||
return getRemindersFromDatabase(); |
|||
} catch (Exception e) { |
|||
Log.e(TAG, "Error getting reminders from database", e); |
|||
return new ArrayList<>(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Store reminder in SharedPreferences database |
|||
*/ |
|||
private void storeReminderInDatabase(String id, String title, String body, |
|||
String time, boolean sound, |
|||
boolean vibration, String priority, |
|||
boolean repeatDaily, String timezone) { |
|||
try { |
|||
SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, |
|||
Context.MODE_PRIVATE); |
|||
SharedPreferences.Editor editor = prefs.edit(); |
|||
|
|||
editor.putString(id + "_title", title); |
|||
editor.putString(id + "_body", body); |
|||
editor.putString(id + "_time", time); |
|||
editor.putBoolean(id + "_sound", sound); |
|||
editor.putBoolean(id + "_vibration", vibration); |
|||
editor.putString(id + "_priority", priority); |
|||
editor.putBoolean(id + "_repeatDaily", repeatDaily); |
|||
editor.putString(id + "_timezone", timezone); |
|||
editor.putLong(id + "_createdAt", System.currentTimeMillis()); |
|||
editor.putBoolean(id + "_isScheduled", true); |
|||
|
|||
editor.apply(); |
|||
Log.d(TAG, "Reminder stored in database: " + id); |
|||
|
|||
} catch (Exception e) { |
|||
Log.e(TAG, "Error storing reminder in database", e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Remove reminder from SharedPreferences database |
|||
*/ |
|||
private void removeReminderFromDatabase(String id) { |
|||
try { |
|||
SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, |
|||
Context.MODE_PRIVATE); |
|||
SharedPreferences.Editor editor = prefs.edit(); |
|||
|
|||
editor.remove(id + "_title"); |
|||
editor.remove(id + "_body"); |
|||
editor.remove(id + "_time"); |
|||
editor.remove(id + "_sound"); |
|||
editor.remove(id + "_vibration"); |
|||
editor.remove(id + "_priority"); |
|||
editor.remove(id + "_repeatDaily"); |
|||
editor.remove(id + "_timezone"); |
|||
editor.remove(id + "_createdAt"); |
|||
editor.remove(id + "_isScheduled"); |
|||
editor.remove(id + "_lastTriggered"); |
|||
|
|||
editor.apply(); |
|||
Log.d(TAG, "Reminder removed from database: " + id); |
|||
|
|||
} catch (Exception e) { |
|||
Log.e(TAG, "Error removing reminder from database", e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Get reminders from SharedPreferences database |
|||
*/ |
|||
private List<DailyReminderInfo> getRemindersFromDatabase() { |
|||
List<DailyReminderInfo> reminders = new ArrayList<>(); |
|||
|
|||
try { |
|||
SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, |
|||
Context.MODE_PRIVATE); |
|||
Map<String, ?> allEntries = prefs.getAll(); |
|||
|
|||
Set<String> reminderIds = new HashSet<>(); |
|||
for (String key : allEntries.keySet()) { |
|||
if (key.endsWith("_title")) { |
|||
String id = key.substring(0, key.length() - 6); // Remove "_title"
|
|||
reminderIds.add(id); |
|||
} |
|||
} |
|||
|
|||
for (String id : reminderIds) { |
|||
DailyReminderInfo reminder = new DailyReminderInfo(); |
|||
reminder.id = id; |
|||
reminder.title = prefs.getString(id + "_title", ""); |
|||
reminder.body = prefs.getString(id + "_body", ""); |
|||
reminder.time = prefs.getString(id + "_time", ""); |
|||
reminder.sound = prefs.getBoolean(id + "_sound", true); |
|||
reminder.vibration = prefs.getBoolean(id + "_vibration", true); |
|||
reminder.priority = prefs.getString(id + "_priority", "normal"); |
|||
reminder.repeatDaily = prefs.getBoolean(id + "_repeatDaily", true); |
|||
reminder.timezone = prefs.getString(id + "_timezone", null); |
|||
reminder.isScheduled = prefs.getBoolean(id + "_isScheduled", false); |
|||
reminder.createdAt = prefs.getLong(id + "_createdAt", 0); |
|||
reminder.lastTriggered = prefs.getLong(id + "_lastTriggered", 0); |
|||
|
|||
// Calculate next trigger time
|
|||
String[] timeParts = reminder.time.split(":"); |
|||
int hour = Integer.parseInt(timeParts[0]); |
|||
int minute = Integer.parseInt(timeParts[1]); |
|||
|
|||
Calendar calendar = Calendar.getInstance(); |
|||
calendar.set(Calendar.HOUR_OF_DAY, hour); |
|||
calendar.set(Calendar.MINUTE, minute); |
|||
calendar.set(Calendar.SECOND, 0); |
|||
calendar.set(Calendar.MILLISECOND, 0); |
|||
|
|||
if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { |
|||
calendar.add(Calendar.DAY_OF_MONTH, 1); |
|||
} |
|||
|
|||
reminder.nextTriggerTime = calendar.getTimeInMillis(); |
|||
|
|||
reminders.add(reminder); |
|||
} |
|||
|
|||
} catch (Exception e) { |
|||
Log.e(TAG, "Error getting reminders from database", e); |
|||
} |
|||
|
|||
return reminders; |
|||
} |
|||
|
|||
/** |
|||
* Update reminder in SharedPreferences database |
|||
*/ |
|||
private void updateReminderInDatabase(String id, String title, String body, |
|||
String time, Boolean sound, |
|||
Boolean vibration, String priority, |
|||
Boolean repeatDaily, String timezone) { |
|||
try { |
|||
SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, |
|||
Context.MODE_PRIVATE); |
|||
SharedPreferences.Editor editor = prefs.edit(); |
|||
|
|||
if (title != null) editor.putString(id + "_title", title); |
|||
if (body != null) editor.putString(id + "_body", body); |
|||
if (time != null) editor.putString(id + "_time", time); |
|||
if (sound != null) editor.putBoolean(id + "_sound", sound); |
|||
if (vibration != null) editor.putBoolean(id + "_vibration", vibration); |
|||
if (priority != null) editor.putString(id + "_priority", priority); |
|||
if (repeatDaily != null) editor.putBoolean(id + "_repeatDaily", repeatDaily); |
|||
if (timezone != null) editor.putString(id + "_timezone", timezone); |
|||
|
|||
editor.apply(); |
|||
Log.d(TAG, "Reminder updated in database: " + id); |
|||
|
|||
} catch (Exception e) { |
|||
Log.e(TAG, "Error updating reminder in database", e); |
|||
} |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue