docs: Consolidate documentation structure (139 files, zero information loss)
Consolidate all markdown documentation into organized structure per CONSOLIDATION_DIRECTIVE. All files preserved (canonical, merged, or archived). - docs/integration/ - Integration documentation (7 files) - docs/platform/ios/ - iOS platform docs (12 files) - docs/platform/android/ - Android platform docs (9 files) - docs/testing/ - Testing documentation (15 files) - docs/design/ - Design & research (5 files) - docs/ai/ - AI/ChatGPT artifacts (7 files) - docs/archive/2025-legacy-doc/ - Historical docs (17 files) - Integration: Root INTEGRATION_GUIDE.md → docs/integration/ - Platform: Separated iOS and Android into platform/ subdirectories - Testing: Consolidated all testing docs to docs/testing/ - Legacy: Archived entire doc/ directory to archive/ - AI: Moved all ChatGPT artifacts to docs/ai/ - Added docs/00-INDEX.md - Central navigation hub - Added docs/CONSOLIDATION_SOURCE_MAP.md - Complete audit trail - Added docs/CONSOLIDATION_COMPLETE.md - Consolidation summary - Updated README.md with links to documentation index - All 139 files have destinations (see CONSOLIDATION_SOURCE_MAP.md) - Zero information loss (all files preserved) - Archive preserves original structure - Index provides clear navigation - 87 files moved/created/updated - Root-level docs consolidated - Legacy doc/ directory archived - Test app docs remain with test apps (indexed) Ref: CONSOLIDATION_DIRECTIVE Author: Matthew Raymer
This commit is contained in:
680
docs/platform/android/APP_ANALYSIS.md
Normal file
680
docs/platform/android/APP_ANALYSIS.md
Normal file
@@ -0,0 +1,680 @@
|
||||
# Android App Analysis: DailyNotification Plugin Test App
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-10-24
|
||||
**Version**: 1.0.0
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a comprehensive analysis of the `/android/app` portion of the DailyNotification plugin, examining its structure, purpose, and interaction with the `/www` web assets. This analysis is designed to help understand the plugin's test application architecture and provide context for ChatGPT analysis.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Architecture Overview](#architecture-overview)
|
||||
- [Directory Structure](#directory-structure)
|
||||
- [Key Components](#key-components)
|
||||
- [Web Asset Integration](#web-asset-integration)
|
||||
- [Plugin Integration](#plugin-integration)
|
||||
- [Build Configuration](#build-configuration)
|
||||
- [Runtime Behavior](#runtime-behavior)
|
||||
- [Testing Capabilities](#testing-capabilities)
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Purpose
|
||||
The `/android/app` directory contains a **Capacitor-based Android test application** specifically designed to test and demonstrate the DailyNotification plugin functionality. It serves as:
|
||||
|
||||
1. **Plugin Testing Environment**: Interactive testing interface for all plugin features
|
||||
2. **Development Tool**: Real-time debugging and validation of plugin behavior
|
||||
3. **Integration Example**: Reference implementation for plugin integration
|
||||
4. **Documentation**: Live demonstration of plugin capabilities
|
||||
|
||||
### Architecture Pattern
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Android App Container │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ MainActivity (BridgeActivity) │
|
||||
│ ├── Capacitor Bridge │
|
||||
│ ├── Plugin Discovery │
|
||||
│ └── WebView Container │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Web Assets (/www) │
|
||||
│ ├── index.html (Test Interface) │
|
||||
│ ├── capacitor.js (Capacitor Runtime) │
|
||||
│ └── plugins/ (Plugin JavaScript) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Native Plugin Integration │
|
||||
│ ├── DailyNotificationPlugin.java │
|
||||
│ ├── BootReceiver.java │
|
||||
│ ├── DailyNotificationReceiver.java │
|
||||
│ └── Supporting Classes (34 files) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Directory Structure
|
||||
|
||||
### Root Android App Structure
|
||||
|
||||
```
|
||||
android/app/
|
||||
├── build.gradle # App build configuration
|
||||
├── capacitor.build.gradle # Auto-generated Capacitor config
|
||||
├── proguard-rules.pro # Code obfuscation rules
|
||||
└── src/
|
||||
├── main/
|
||||
│ ├── AndroidManifest.xml # App permissions and components
|
||||
│ ├── assets/ # Web assets (Capacitor www)
|
||||
│ │ ├── capacitor.config.json
|
||||
│ │ ├── capacitor.plugins.json
|
||||
│ │ └── public/ # Web application files
|
||||
│ │ ├── index.html # Main test interface
|
||||
│ │ ├── capacitor.js # Capacitor runtime
|
||||
│ │ ├── capacitor_plugins.js
|
||||
│ │ └── plugins/ # Plugin JavaScript files
|
||||
│ ├── java/
|
||||
│ │ └── com/timesafari/dailynotification/
|
||||
│ │ └── MainActivity.java # Capacitor BridgeActivity
|
||||
│ └── res/ # Android resources
|
||||
│ ├── drawable/ # App icons and images
|
||||
│ ├── layout/ # Android layouts
|
||||
│ ├── mipmap/ # App launcher icons
|
||||
│ ├── values/ # Strings, styles, colors
|
||||
│ └── xml/ # Configuration files
|
||||
├── androidTest/ # Instrumented tests
|
||||
└── test/ # Unit tests
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### 1. MainActivity.java
|
||||
|
||||
**Purpose**: Entry point extending Capacitor's BridgeActivity
|
||||
**Location**: `src/main/java/com/timesafari/dailynotification/MainActivity.java`
|
||||
|
||||
```java
|
||||
public class MainActivity extends BridgeActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**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">
|
||||
<activity android:name=".MainActivity" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
> **Note:** Set `android:name` only if you provide a custom `Application` class; otherwise remove to avoid ClassNotFound at runtime.
|
||||
|
||||
**Safe default (no custom Application class):**
|
||||
```xml
|
||||
<application>
|
||||
<activity android:name=".MainActivity" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
```
|
||||
|
||||
<!-- Plugin Components -->
|
||||
<!-- Internal receiver: keep non-exported unless intentionally public -->
|
||||
<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>
|
||||
|
||||
> **Note:** `android:priority` has no practical effect for `BOOT_COMPLETED`; safe to omit.
|
||||
|
||||
**Minimal example (recommended):**
|
||||
```xml
|
||||
<receiver
|
||||
android:name="com.timesafari.dailynotification.BootReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
```
|
||||
</application>
|
||||
|
||||
<!-- Required Permissions -->
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
> **Tip:** `WAKE_LOCK` is typically unnecessary with AlarmManager/WorkManager; remove unless you explicitly acquire/release your own wakelocks.
|
||||
> **Note:** `POST_NOTIFICATIONS` is required **on Android 13+**; lower API levels ignore it gracefully.
|
||||
```
|
||||
|
||||
**Critical Permissions**:
|
||||
|
||||
- `POST_NOTIFICATIONS`: Required for Android 13+ notification posting
|
||||
- `SCHEDULE_EXACT_ALARM`: Required for precise notification timing
|
||||
- `WAKE_LOCK` **not required** unless you explicitly acquire/release your own wakelocks (AlarmManager & WorkManager handle theirs)
|
||||
- `INTERNET`: Required for content fetching
|
||||
- `RECEIVE_BOOT_COMPLETED`: Required for reboot recovery
|
||||
|
||||
> **Note:** If you later introduce foreground services, revisit WAKE_LOCK; otherwise keep it out.
|
||||
|
||||
### 3. Capacitor Configuration Files
|
||||
|
||||
#### capacitor.config.json
|
||||
|
||||
**Purpose**: Capacitor runtime configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"appId": "com.timesafari.dailynotification",
|
||||
"appName": "DailyNotification Test App",
|
||||
"webDir": "www",
|
||||
"server": {
|
||||
"androidScheme": "https"
|
||||
},
|
||||
"plugins": {
|
||||
"DailyNotification": {
|
||||
"fetchUrl": "https://api.example.com/daily-content",
|
||||
"scheduleTime": "09:00",
|
||||
"enableNotifications": true,
|
||||
"debugMode": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 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"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Web Asset Integration
|
||||
|
||||
### /www Directory Structure
|
||||
|
||||
The `/www` directory (mapped to `assets/public/`) contains the web application that runs inside the Capacitor WebView:
|
||||
|
||||
> Capacitor builds copy your `webDir` (e.g., `www/`) to `src/main/assets/public/` on Android; the WebView serves from that `public/` folder.
|
||||
|
||||
```
|
||||
assets/public/
|
||||
├── index.html # Main test interface (549 lines)
|
||||
├── capacitor.js # Capacitor runtime
|
||||
├── capacitor_plugins.js # Plugin JavaScript bridge
|
||||
|
||||
> **Note:** On pure Capacitor builds, the runtime is `capacitor.js`. Only include `cordova.js/cordova_plugins.js` if Cordova-compat is enabled; otherwise remove those references for accuracy.
|
||||
└── plugins/ # Plugin JavaScript files
|
||||
```
|
||||
|
||||
### index.html Analysis
|
||||
|
||||
**Purpose**: Interactive test interface for plugin functionality
|
||||
**Size**: 549 lines of HTML, CSS, and JavaScript
|
||||
**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
|
||||
- configurePlugin() // Plugin configuration
|
||||
- checkStatus() // Plugin status check
|
||||
|
||||
// Notification Testing
|
||||
- testNotification() // Immediate notification test
|
||||
- scheduleNotification() // Scheduled notification test
|
||||
- showReminder() // Daily reminder test
|
||||
|
||||
// Permission Management
|
||||
- checkPermissions() // Permission status check
|
||||
- requestPermissions() // Permission request
|
||||
- openExactAlarmSettings() // Settings navigation
|
||||
|
||||
// Channel Management
|
||||
- checkChannelStatus() // Notification channel status
|
||||
- openChannelSettings() // Channel settings navigation
|
||||
- checkComprehensiveStatus() // Complete status check
|
||||
```
|
||||
|
||||
#### 3. Plugin Integration
|
||||
|
||||
```javascript
|
||||
// Plugin Access Pattern
|
||||
window.DailyNotification = window.Capacitor.Plugins.DailyNotification;
|
||||
|
||||
// Example Usage
|
||||
window.DailyNotification.scheduleDailyNotification({
|
||||
time: "09:00",
|
||||
title: "Test Notification",
|
||||
body: "This is a test notification!",
|
||||
sound: true,
|
||||
priority: "high"
|
||||
});
|
||||
```
|
||||
|
||||
#### 4. Error Handling
|
||||
|
||||
- **Visual Feedback**: Color-coded status indicators
|
||||
- **Error Messages**: Detailed error reporting
|
||||
- **Graceful Degradation**: Fallback behavior for missing features
|
||||
|
||||
## 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) { ... }
|
||||
|
||||
@PluginMethod
|
||||
public void scheduleDailyNotification(PluginCall call) { ... }
|
||||
|
||||
@PluginMethod
|
||||
public void scheduleDailyReminder(PluginCall call) { ... }
|
||||
|
||||
@PluginMethod
|
||||
public void getNotificationStatus(PluginCall call) { ... }
|
||||
|
||||
@PluginMethod
|
||||
public void checkPermissionStatus(PluginCall call) { ... }
|
||||
|
||||
@PluginMethod
|
||||
public void requestNotificationPermissions(PluginCall call) { ... }
|
||||
|
||||
@PluginMethod
|
||||
public void checkStatus(PluginCall call) { ... }
|
||||
|
||||
@PluginMethod
|
||||
public void isChannelEnabled(PluginCall call) { ... }
|
||||
|
||||
@PluginMethod
|
||||
public void openChannelSettings(PluginCall call) { ... }
|
||||
|
||||
@PluginMethod
|
||||
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
|
||||
- `dao/` - Data Access Objects (3 files)
|
||||
- `entities/` - Database entities (3 files)
|
||||
|
||||
**Management & Utilities**:
|
||||
|
||||
- `PermissionManager.java` - Permission handling
|
||||
- `ChannelManager.java` - Notification channel management
|
||||
- `DailyNotificationExactAlarmManager.java` - Exact alarm management
|
||||
- `DailyNotificationErrorHandler.java` - Error handling
|
||||
- `DailyNotificationPerformanceOptimizer.java` - Performance optimization
|
||||
|
||||
**Workers & Background Tasks**:
|
||||
|
||||
- `DailyNotificationWorker.java` - Main background worker
|
||||
- `DailyNotificationFetchWorker.java` - Content fetching worker
|
||||
- `DailyNotificationMaintenanceWorker.java` - Maintenance tasks
|
||||
- `DozeFallbackWorker.java` - Doze mode handling
|
||||
- `SoftRefetchWorker.java` - Soft refresh handling
|
||||
|
||||
## Build Configuration
|
||||
|
||||
### app/build.gradle
|
||||
|
||||
**Purpose**: App-level build configuration and dependencies
|
||||
|
||||
**Key Dependencies**:
|
||||
|
||||
```gradle
|
||||
dependencies {
|
||||
// Capacitor Core
|
||||
implementation project(':capacitor-android')
|
||||
implementation project(':plugin') // DailyNotification plugin
|
||||
|
||||
// AndroidX Libraries
|
||||
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
|
||||
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
|
||||
|
||||
// Plugin-Specific Dependencies
|
||||
implementation "androidx.room:room-runtime:2.6.1"
|
||||
implementation "androidx.work:work-runtime-ktx:2.9.0"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
|
||||
|
||||
// Cordova compatibility (include ONLY if using Cordova plugins)
|
||||
debugImplementation(project(':capacitor-cordova-android-plugins')) { transitive = false }
|
||||
releaseImplementation(project(':capacitor-cordova-android-plugins')) { transitive = false }
|
||||
|
||||
> **Note:** Include `capacitor-cordova-android-plugins` **only** when using Cordova plugins.
|
||||
}
|
||||
```
|
||||
|
||||
**Build Configuration**:
|
||||
|
||||
```gradle
|
||||
android {
|
||||
namespace "com.timesafari.dailynotification"
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.timesafari.dailynotification"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 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"/>`
|
||||
- [ ] BootReceiver: `exported="true"` + BOOT_COMPLETED filter
|
||||
- [ ] Other receivers exported=false unless needed
|
||||
- [ ] No stray `android:permission=` on BootReceiver
|
||||
|
||||
## 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
|
||||
4. **Plugin Registration**: Instantiates `DailyNotificationPlugin`
|
||||
5. **WebView Loading**: Loads `index.html` from assets
|
||||
6. **JavaScript Bridge**: Establishes communication between web and native
|
||||
7. **Plugin Availability**: `window.Capacitor.Plugins.DailyNotification` becomes available
|
||||
|
||||
### Plugin Method Execution Flow
|
||||
|
||||
```
|
||||
JavaScript Call
|
||||
↓
|
||||
Capacitor Bridge
|
||||
↓
|
||||
Plugin Method (@PluginMethod)
|
||||
↓
|
||||
Native Implementation
|
||||
↓
|
||||
Response (JSObject)
|
||||
↓
|
||||
JavaScript Promise Resolution
|
||||
```
|
||||
|
||||
### Background Processing
|
||||
|
||||
- **WorkManager**: Handles background content fetching
|
||||
- **AlarmManager**: Manages notification scheduling
|
||||
- **BootReceiver**: Reschedules notifications after reboot
|
||||
- **Doze Mode**: Handles Android's battery optimization
|
||||
|
||||
> **Closed vs force-stopped:** Closing/swiping the app does not affect alarms or WorkManager. **Force-stopping** from Settings cancels alarms and suppresses receivers until the next launch, after which Boot/rehydration logic can restore future schedules.
|
||||
|
||||
## 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
|
||||
- **Content Testing**: Test with different notification content
|
||||
|
||||
#### 3. Permission Management
|
||||
- **Permission Status**: Check current permission state
|
||||
- **Permission Requests**: Test permission request flow
|
||||
- **Settings Navigation**: Test opening system settings
|
||||
- **Permission Validation**: Verify permission changes
|
||||
|
||||
#### 4. Channel Management
|
||||
- **Channel Status**: Check notification channel state
|
||||
- **Channel Settings**: Test channel configuration
|
||||
- **Importance Levels**: Test different importance settings
|
||||
- **Channel Creation**: Test channel creation and management
|
||||
|
||||
#### 5. Comprehensive Status Checking
|
||||
- **Overall Status**: Complete system status check
|
||||
- **Issue Detection**: Identify configuration problems
|
||||
- **Readiness Check**: Verify system is ready for notifications
|
||||
- **Troubleshooting**: Help identify and resolve issues
|
||||
|
||||
### Debugging Features
|
||||
- **Console Logging**: Detailed console output for debugging
|
||||
- **Visual Feedback**: Color-coded status indicators
|
||||
- **Error Reporting**: Detailed error messages and stack traces
|
||||
- **Real-time Updates**: Live status updates during testing
|
||||
|
||||
## Integration Patterns
|
||||
|
||||
### Plugin Integration Pattern
|
||||
```javascript
|
||||
// 1. Check Plugin Availability
|
||||
if (!window.DailyNotification) {
|
||||
console.error('Plugin not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Call Plugin Method
|
||||
window.DailyNotification.scheduleDailyNotification({
|
||||
time: "09:00",
|
||||
title: "Daily Notification",
|
||||
body: "Your daily content is ready!",
|
||||
sound: true,
|
||||
priority: "high"
|
||||
})
|
||||
.then(() => {
|
||||
console.log('Notification scheduled successfully');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Scheduling failed:', error);
|
||||
});
|
||||
```
|
||||
|
||||
### Error Handling Pattern
|
||||
```javascript
|
||||
try {
|
||||
const result = await window.DailyNotification.checkStatus();
|
||||
// Handle success
|
||||
} catch (error) {
|
||||
// Handle error
|
||||
console.error('Status check failed:', error.message);
|
||||
}
|
||||
```
|
||||
|
||||
### Permission Management Pattern
|
||||
```javascript
|
||||
// Check permissions first
|
||||
const permissions = await window.DailyNotification.checkPermissionStatus();
|
||||
if (!permissions.allPermissionsGranted) {
|
||||
// Request permissions
|
||||
await window.DailyNotification.requestNotificationPermissions();
|
||||
}
|
||||
```
|
||||
|
||||
## Key Insights
|
||||
|
||||
### Strengths
|
||||
1. **Comprehensive Testing**: Covers all plugin functionality
|
||||
2. **Interactive Interface**: Easy-to-use testing interface
|
||||
3. **Real-time Feedback**: Immediate visual feedback
|
||||
4. **Error Handling**: Robust error handling and reporting
|
||||
5. **Permission Management**: Complete permission testing
|
||||
6. **Documentation**: Self-documenting through interface
|
||||
|
||||
### Architecture Benefits
|
||||
1. **Separation of Concerns**: Clear separation between web and native
|
||||
2. **Plugin Isolation**: Plugin functionality is isolated and testable
|
||||
3. **Capacitor Integration**: Leverages Capacitor's plugin system
|
||||
4. **Cross-Platform**: Web interface works across platforms
|
||||
5. **Maintainable**: Easy to update and maintain
|
||||
|
||||
### Use Cases
|
||||
1. **Plugin Development**: Test new plugin features
|
||||
2. **Integration Testing**: Verify plugin integration
|
||||
3. **Debugging**: Debug plugin issues
|
||||
4. **Documentation**: Demonstrate plugin capabilities
|
||||
5. **Quality Assurance**: Validate plugin functionality
|
||||
|
||||
## Conclusion
|
||||
|
||||
The `/android/app` portion of the DailyNotification plugin represents a well-architected test application that provides comprehensive testing capabilities for the plugin. It demonstrates best practices for Capacitor plugin integration, including proper permission handling, error management, and user interface design.
|
||||
|
||||
The integration between the web assets (`/www`) and native Android code through Capacitor's bridge system creates a seamless testing environment that allows developers to validate plugin functionality in real-time while providing an intuitive interface for non-technical users to test and understand the plugin's capabilities.
|
||||
|
||||
This architecture serves as both a practical testing tool and a reference implementation for integrating the DailyNotification plugin into other applications.
|
||||
|
||||
## Assumptions & Versions
|
||||
|
||||
| Topic | Value | Notes |
|
||||
|---|---|---|
|
||||
| Android min/target SDK | 24 / 35 | Align with `compileSdkVersion`/`targetSdkVersion`. |
|
||||
| Capacitor | v5.x | Confirm web asset naming (`capacitor.js` vs Cordova shims). |
|
||||
| WorkManager | 2.9.0 | Matches Gradle deps listed. |
|
||||
| Room | 2.6.1 | Matches Gradle deps listed. |
|
||||
| Exact Alarms | Tiramisu+ | Requires user grant on many OEMs. |
|
||||
|
||||
## Bridge Surface (Summary)
|
||||
|
||||
- `scheduleDailyNotification(req: {time, title, body, sound, priority}) -> {success, scheduledAt?, error?}`
|
||||
- `checkPermissionStatus() -> {postNotificationsGranted, exactAlarmGranted, batteryOptIgnored, channelEnabled, ...}`
|
||||
- `openChannelSettings() -> {opened: boolean}`
|
||||
- `openExactAlarmSettings() -> {opened: boolean}`
|
||||
- `requestNotificationPermissions() -> {granted: boolean, permissions: {...}}`
|
||||
- `getNotificationStatus() -> {isEnabled, isScheduled, nextNotificationTime, ...}`
|
||||
|
||||
**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).
|
||||
|
||||
> **Exact Alarm note:** `SCHEDULE_EXACT_ALARM` is a **special app-op**, not a runtime permission prompt. Users grant it via Settings; your UI should deep-link there and reflect denial by degrading to WorkManager.
|
||||
|
||||
## Permission & Settings Truth Table
|
||||
|
||||
| Symptom | Likely Cause | Action |
|
||||
|---|---|---|
|
||||
| No notification posts | `POST_NOTIFICATIONS` denied | Call `requestNotificationPermissions()` |
|
||||
| Fires late/misses | No exact alarm grant / Doze | `openExactAlarmSettings()` or fallback to WorkManager |
|
||||
| Silent notifications | Channel disabled/low importance | `openChannelSettings()` then retest |
|
||||
| Battery optimization kills | App not whitelisted | Guide user to battery optimization settings |
|
||||
| Boot reschedule fails | `RECEIVE_BOOT_COMPLETED` denied | Check manifest receiver registration |
|
||||
|
||||
> **Test UI Integration:** Use "Open Channel Settings" and "Open Exact Alarm Settings" buttons in the test interface to resolve channel and exact alarm issues.
|
||||
|
||||
## Runtime Flow Diagram
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[JavaScript Call] --> B[Capacitor Bridge]
|
||||
B --> C[@PluginMethod → Canonical Error]
|
||||
C --> D[Use Case Handler → Canonical Error]
|
||||
D --> E{Alarm vs WorkManager}
|
||||
E -->|Exact Alarm| F[AlarmManager]
|
||||
E -->|Fallback| G[WorkManager]
|
||||
F --> H[BootReceiver]
|
||||
G --> H
|
||||
H --> I[NotificationReceiver]
|
||||
I --> J[UI Update]
|
||||
|
||||
%% Error paths
|
||||
C -->|Validation Error → Canonical Error| K[Canonical Error]
|
||||
D -->|Use-case Error → Canonical Error| K
|
||||
K --> L[JavaScript Promise Rejection]
|
||||
```
|
||||
|
||||
## Cordova vs Capacitor Assets – Accuracy Note
|
||||
|
||||
> **Note:** If using pure Capacitor v5, the web runtime is `capacitor.js`. If Cordova compatibility is enabled, `cordova.js/cordova_plugins.js` will appear; otherwise remove those references here for accuracy.
|
||||
Reference in New Issue
Block a user