From 6aaeaf780849af12d9a294a07ec6b262104d4d0d Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Thu, 23 Oct 2025 11:47:55 +0000 Subject: [PATCH] fix(android): resolve permission request and status display issues - Add requestPermissions method alias to fix Vue app compatibility - Fix permission response format to include both string and boolean values - Add comprehensive debugging for permission request flow - Implement permission request throttling to prevent app crashes - Fix capacitor.settings.gradle plugin path configuration - Enhance Vue app logging for permission status debugging Resolves permission dialog not appearing and UI showing incorrect status. All permission functionality now works end-to-end with proper status updates. --- .../DailyNotificationPlugin.java | 60 +++++++++++++++++-- .../android/capacitor.settings.gradle | 2 +- .../src/views/HomeView.vue | 45 ++++++++++++-- 3 files changed, 96 insertions(+), 11 deletions(-) diff --git a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java index fc83e18..9e28a8f 100644 --- a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java +++ b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java @@ -1118,6 +1118,26 @@ public class DailyNotificationPlugin extends Plugin { } } + /** + * Request notification permissions (alias for requestNotificationPermissions) + * + * @param call Plugin call + */ + @PluginMethod + public void requestPermissions(PluginCall call) { + Log.d(TAG, "DEBUG: requestPermissions method called"); + Log.d(TAG, "DEBUG: Method call received from JavaScript"); + Log.d(TAG, "DEBUG: Delegating to requestNotificationPermissions"); + + try { + // Delegate to the main permission request method + requestNotificationPermissions(call); + } catch (Exception e) { + Log.e(TAG, "DEBUG: Error in requestPermissions delegation", e); + call.reject("Error in requestPermissions: " + e.getMessage()); + } + } + /** * Request notification permissions * @@ -1126,18 +1146,25 @@ public class DailyNotificationPlugin extends Plugin { @PluginMethod public void requestNotificationPermissions(PluginCall call) { try { + Log.d(TAG, "DEBUG: requestNotificationPermissions method called"); + Log.d(TAG, "DEBUG: Android SDK version: " + Build.VERSION.SDK_INT); + Log.d(TAG, "DEBUG: TIRAMISU version: " + Build.VERSION_CODES.TIRAMISU); Log.d(TAG, "Requesting notification permissions"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + Log.d(TAG, "DEBUG: Android 13+ detected, requesting POST_NOTIFICATIONS permission"); // Request POST_NOTIFICATIONS permission for Android 13+ - requestPermissionForAlias("notifications", call, "notificationPermissions"); + requestPermissionForAlias("notifications", call, "onPermissionResult"); } else { + Log.d(TAG, "DEBUG: Pre-Android 13, checking notification manager"); // For older versions, check if notifications are enabled boolean enabled = NotificationManagerCompat.from(getContext()).areNotificationsEnabled(); + Log.d(TAG, "DEBUG: Notifications enabled: " + enabled); if (enabled) { Log.i(TAG, "Notifications already enabled"); call.resolve(); } else { + Log.d(TAG, "DEBUG: Opening notification settings"); // Open notification settings openNotificationSettings(); call.resolve(); @@ -1145,6 +1172,7 @@ public class DailyNotificationPlugin extends Plugin { } } catch (Exception e) { + Log.e(TAG, "DEBUG: Exception in requestNotificationPermissions", e); Log.e(TAG, "Error requesting notification permissions", e); call.reject("Error requesting permissions: " + e.getMessage()); } @@ -1156,14 +1184,17 @@ public class DailyNotificationPlugin extends Plugin { * @param call Plugin call containing permission result */ @PermissionCallback - private void notificationPermissions(PluginCall call) { + private void onPermissionResult(PluginCall call) { try { - Log.d(TAG, "Notification permission callback received"); + Log.d(TAG, "DEBUG: onPermissionResult callback received"); + Log.d(TAG, "Permission callback received"); // Check if POST_NOTIFICATIONS permission was granted boolean permissionGranted = getContext().checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED; + Log.d(TAG, "DEBUG: Permission granted: " + permissionGranted); + if (permissionGranted) { Log.i(TAG, "Notification permission granted"); call.resolve(); @@ -1173,11 +1204,31 @@ public class DailyNotificationPlugin extends Plugin { } } catch (Exception e) { - Log.e(TAG, "Error in notification permission callback", e); + Log.e(TAG, "DEBUG: Exception in onPermissionResult callback", e); + Log.e(TAG, "Error in permission callback", e); call.reject("Error processing permission result: " + e.getMessage()); } } + /** + * Check current permission status (alias for checkPermissionStatus) + * + * @param call Plugin call + */ + @PluginMethod + public void checkPermissions(PluginCall call) { + Log.d(TAG, "DEBUG: checkPermissions method called (alias)"); + Log.d(TAG, "DEBUG: Delegating to checkPermissionStatus"); + + try { + // Delegate to the main permission check method + checkPermissionStatus(call); + } catch (Exception e) { + Log.e(TAG, "DEBUG: Error in checkPermissions delegation", e); + call.reject("Error in checkPermissions: " + e.getMessage()); + } + } + /** * Check current permission status * @@ -1193,6 +1244,7 @@ public class DailyNotificationPlugin extends Plugin { // Check notification permissions boolean notificationsEnabled = areNotificationsEnabled(); result.put("notificationsEnabled", notificationsEnabled); + result.put("notifications", notificationsEnabled ? "granted" : "denied"); // Check exact alarm permissions (Android 12+) boolean exactAlarmEnabled = true; diff --git a/test-apps/daily-notification-test/android/capacitor.settings.gradle b/test-apps/daily-notification-test/android/capacitor.settings.gradle index a5695c6..9fe3cec 100644 --- a/test-apps/daily-notification-test/android/capacitor.settings.gradle +++ b/test-apps/daily-notification-test/android/capacitor.settings.gradle @@ -3,4 +3,4 @@ include ':capacitor-android' project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') include ':timesafari-daily-notification-plugin' -project(':timesafari-daily-notification-plugin').projectDir = new File('../../../android/plugin') +project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android/plugin') diff --git a/test-apps/daily-notification-test/src/views/HomeView.vue b/test-apps/daily-notification-test/src/views/HomeView.vue index ec45479..2025a37 100644 --- a/test-apps/daily-notification-test/src/views/HomeView.vue +++ b/test-apps/daily-notification-test/src/views/HomeView.vue @@ -111,6 +111,7 @@ const appStore = useAppStore() const isScheduling = ref(false) const isCheckingStatus = ref(false) +const isRequestingPermissions = ref(false) const platformName = computed(() => { const platform = appStore.platform @@ -215,6 +216,12 @@ const checkSystemStatus = async (): Promise => { console.log(' - error:', status.error) console.log('📊 Plugin permissions:', permissions) + console.log('📊 Permissions details:') + console.log(' - notifications:', permissions.notifications) + console.log(' - notificationsEnabled:', (permissions as any).notificationsEnabled) + console.log(' - exactAlarmEnabled:', (permissions as any).exactAlarmEnabled) + console.log(' - wakeLockEnabled:', (permissions as any).wakeLockEnabled) + console.log(' - allPermissionsGranted:', (permissions as any).allPermissionsGranted) console.log('📊 Exact alarm status:', exactAlarmStatus) // Map plugin response to app store format @@ -239,12 +246,38 @@ const checkSystemStatus = async (): Promise => { // Log permission status for debugging if (!mappedStatus.postNotificationsGranted) { console.warn('⚠️ Notification permissions not granted - user needs to enable in settings') - console.log('🔧 Testing permission request...') - try { - await plugin.requestPermissions() - console.log('✅ Permission request completed') - } catch (permError) { - console.error('❌ Permission request failed:', permError) + + // Only request permissions if not already requesting + if (!isRequestingPermissions.value) { + console.log('🔧 Testing permission request...') + isRequestingPermissions.value = true + + // Enhanced debugging for permission request + console.log('🔍 DEBUG: Plugin object:', plugin) + console.log('🔍 DEBUG: Plugin type:', typeof plugin) + console.log('🔍 DEBUG: requestPermissions method:', typeof plugin.requestPermissions) + console.log('🔍 DEBUG: Available methods:', Object.getOwnPropertyNames(plugin)) + + try { + console.log('🔍 DEBUG: About to call plugin.requestPermissions()') + const result = await plugin.requestPermissions() + console.log('✅ Permission request completed, result:', result) + + // After permission request, refresh the status + console.log('🔄 Refreshing status after permission request...') + await checkSystemStatus() + } catch (permError) { + console.error('❌ Permission request failed:', permError) + console.error('❌ Error details:', { + name: permError.name, + message: permError.message, + stack: permError.stack + }) + } finally { + isRequestingPermissions.value = false + } + } else { + console.log('⏳ Permission request already in progress, skipping...') } } } catch (error) {