@ -30,6 +30,7 @@ The `/android/app` directory contains a **Capacitor-based Android test applicati
4. **Documentation** : Live demonstration of plugin capabilities
### Architecture Pattern
```
┌─────────────────────────────────────────────────────────────┐
│ Android App Container │
@ -55,6 +56,7 @@ The `/android/app` directory contains a **Capacitor-based Android test applicati
## Directory Structure
### Root Android App Structure
```
android/app/
├── build.gradle # App build configuration
@ -68,8 +70,8 @@ android/app/
│ │ ├── capacitor.plugins.json
│ │ └── public/ # Web application files
│ │ ├── index.html # Main test interface
│ │ ├── cordova .js # Capacitor runtime
│ │ ├── cordova _plugins.js
│ │ ├── capacit or.js # Capacitor runtime
│ │ ├── capacit or_plugins.js
│ │ └── plugins/ # Plugin JavaScript files
│ ├── java/
│ │ └── com/timesafari/dailynotification/
@ -87,6 +89,7 @@ android/app/
## Key Components
### 1. MainActivity.java
**Purpose**: Entry point extending Capacitor's BridgeActivity
**Location**: `src/main/java/com/timesafari/dailynotification/MainActivity.java`
@ -100,16 +103,19 @@ public class MainActivity extends BridgeActivity {
```
**Key Features**:
- Minimal implementation - Capacitor handles most functionality
- Extends `BridgeActivity` for automatic plugin discovery
- Provides WebView container for web assets
- Handles plugin registration and JavaScript bridge
### 2. AndroidManifest.xml
**Purpose**: App configuration, permissions, and component declarations
**Location**: `src/main/AndroidManifest.xml`
**Key Declarations**:
```xml
<!-- App Configuration -->
< application android:name = "com.timesafari.dailynotification" >
@ -121,8 +127,23 @@ public class MainActivity extends BridgeActivity {
< / activity >
<!-- Plugin Components -->
< receiver android:name = "com.timesafari.dailynotification.DailyNotificationReceiver" / >
< receiver android:name = "com.timesafari.dailynotification.BootReceiver" / >
< receiver
android:name="com.timesafari.dailynotification.DailyNotificationReceiver"
android:enabled="true"
android:exported="false">
< intent-filter >
< action android:name = "com.timesafari.daily.NOTIFICATION" / >
< / intent-filter >
< / receiver >
< receiver
android:name="com.timesafari.dailynotification.BootReceiver"
android:enabled="true"
android:exported="true">
< intent-filter android:priority = "1000" >
< action android:name = "android.intent.action.BOOT_COMPLETED" / >
< / intent-filter >
< / receiver >
< / application >
<!-- Required Permissions -->
@ -134,6 +155,7 @@ public class MainActivity extends BridgeActivity {
```
**Critical Permissions**:
- `POST_NOTIFICATIONS` : Required for Android 13+ notification posting
- `SCHEDULE_EXACT_ALARM` : Required for precise notification timing
- `WAKE_LOCK` : Required for background processing
@ -143,7 +165,9 @@ public class MainActivity extends BridgeActivity {
### 3. Capacitor Configuration Files
#### capacitor.config.json
**Purpose**: Capacitor runtime configuration
```json
{
"appId": "com.timesafari.dailynotification",
@ -164,19 +188,23 @@ public class MainActivity extends BridgeActivity {
```
#### capacitor.plugins.json
**Purpose**: Plugin discovery and registration
**Note**: Auto-generated on `npx cap sync` - should not be manually edited
```json
[
{
"name": "DailyNotification",
"classpath": "com.timesafari.dailynotification.DailyNotificationPlugin"
}
{
"name": "DailyNotification",
"classpath": "com.timesafari.dailynotification.DailyNotificationPlugin"
}
]
```
## Web Asset Integration
### /www Directory Structure
The `/www` directory (mapped to `assets/public/` ) contains the web application that runs inside the Capacitor WebView:
```
@ -196,12 +224,14 @@ assets/public/
**Features**:
#### 1. User Interface
- **Modern Design** : Gradient background, responsive layout
- **Interactive Buttons** : 12 test functions with visual feedback
- **Status Display** : Real-time feedback with color-coded results
- **Mobile-Optimized** : Touch-friendly interface
#### 2. Test Categories
```javascript
// Plugin Testing
- testPlugin() // Basic plugin availability
@ -225,6 +255,7 @@ assets/public/
```
#### 3. Plugin Integration
```javascript
// Plugin Access Pattern
window.DailyNotification = window.Capacitor.Plugins.DailyNotification;
@ -240,6 +271,7 @@ window.DailyNotification.scheduleDailyNotification({
```
#### 4. Error Handling
- **Visual Feedback** : Color-coded status indicators
- **Error Messages** : Detailed error reporting
- **Graceful Degradation** : Fallback behavior for missing features
@ -247,15 +279,18 @@ window.DailyNotification.scheduleDailyNotification({
## Plugin Integration
### Plugin Discovery Process
1. **Capacitor Startup** : Loads `capacitor.plugins.json`
2. **Plugin Registration** : Discovers `DailyNotificationPlugin` class
3. **JavaScript Bridge** : Creates `window.Capacitor.Plugins.DailyNotification`
4. **Method Exposure** : Exposes `@PluginMethod` annotated methods
### Plugin Class Structure
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java`
**Key Methods** (from `@PluginMethod` annotations):
```java
@PluginMethod
public void configure(PluginCall call) { ... }
@ -289,15 +324,18 @@ public void openExactAlarmSettings(PluginCall call) { ... }
```
### Supporting Classes (34 files)
The plugin includes a comprehensive set of supporting classes:
**Core Components**:
- `BootReceiver.java` - Handles system boot events
- `DailyNotificationReceiver.java` - Handles notification events
- `DailyNotificationScheduler.java` - Manages notification scheduling
- `DailyNotificationFetcher.java` - Handles content fetching
**Storage & Database**:
- `DailyNotificationStorage.java` - Storage abstraction
- `DailyNotificationStorageRoom.java` - Room database implementation
- `DailyNotificationDatabase.java` - Database definition
@ -305,6 +343,7 @@ The plugin includes a comprehensive set of supporting classes:
- `entities/` - Database entities (3 files)
**Management & Utilities**:
- `PermissionManager.java` - Permission handling
- `ChannelManager.java` - Notification channel management
- `DailyNotificationExactAlarmManager.java` - Exact alarm management
@ -312,6 +351,7 @@ The plugin includes a comprehensive set of supporting classes:
- `DailyNotificationPerformanceOptimizer.java` - Performance optimization
**Workers & Background Tasks**:
- `DailyNotificationWorker.java` - Main background worker
- `DailyNotificationFetchWorker.java` - Content fetching worker
- `DailyNotificationMaintenanceWorker.java` - Maintenance tasks
@ -321,9 +361,11 @@ The plugin includes a comprehensive set of supporting classes:
## Build Configuration
### app/build.gradle
**Purpose**: App-level build configuration and dependencies
**Key Dependencies**:
```gradle
dependencies {
// Capacitor Core
@ -340,12 +382,13 @@ dependencies {
implementation "androidx.work:work-runtime-ktx:2.9.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
// Cordova Compatibility
// Cordova Compatibility (only if shipping Cordova shims)
implementation project(':capacitor-cordova-android-plugins')
}
```
**Build Configuration**:
```gradle
android {
namespace "com.timesafari.dailynotification"
@ -362,10 +405,12 @@ android {
```
### capacitor.build.gradle
**Purpose**: Auto-generated Capacitor configuration
**Note**: Regenerated on each `npx cap sync` - should not be manually edited
**Manifest Hygiene (Quick Scan)**
- [ ] `<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>`
- [ ] `<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>` (if you truly need exact)
- [ ] `<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>`
@ -376,6 +421,7 @@ android {
## Runtime Behavior
### App Startup Sequence
1. **Android System** : Launches `MainActivity`
2. **Capacitor Initialization** : Loads Capacitor runtime
3. **Plugin Discovery** : Scans `capacitor.plugins.json` for plugins
@ -385,6 +431,7 @@ android {
7. **Plugin Availability** : `window.Capacitor.Plugins.DailyNotification` becomes available
### Plugin Method Execution Flow
```
JavaScript Call
↓
@ -400,6 +447,7 @@ JavaScript Promise Resolution
```
### Background Processing
- **WorkManager** : Handles background content fetching
- **AlarmManager** : Manages notification scheduling
- **BootReceiver** : Reschedules notifications after reboot
@ -408,14 +456,17 @@ JavaScript Promise Resolution
## Testing Capabilities
### Interactive Testing Features
The test app provides comprehensive testing capabilities:
#### 1. Plugin Availability Testing
- **Basic Detection** : Verify plugin is loaded and accessible
- **Method Availability** : Check if specific methods are callable
- **Error Handling** : Test error conditions and edge cases
#### 2. Notification Testing
- **Immediate Notifications** : Test instant notification display
- **Scheduled Notifications** : Test time-based notification scheduling
- **Reminder Testing** : Test daily reminder functionality
@ -545,6 +596,10 @@ This architecture serves as both a practical testing tool and a reference implem
**Status Matrix MUST include:** `postNotificationsGranted` , `exactAlarmGranted` , `channelEnabled` , `batteryOptimizationsIgnored` , `canScheduleNow` .
### Exact-Alarm Decision Rule (User-Visible)
If `SCHEDULE_EXACT_ALARM` is **granted** → schedule with `setExactAndAllowWhileIdle` .
If **denied or quota-limited** → schedule via WorkManager (exp backoff + jitter) and surface `E_EXACT_ALARM_DENIED` (with "Degraded timing — Doze may delay" hint).
## Permission & Settings Truth Table
| Symptom | Likely Cause | Action |
@ -569,6 +624,11 @@ graph TD
G --> H
H --> I[NotificationReceiver]
I --> J[UI Update]
%% Error paths
C -->|Validation Error| K[Canonical Error]
D -->|Use-case Error| K
K --> L[JavaScript Promise Rejection]
```
## Cordova vs Capacitor Assets – Accuracy Note