fix(android): improve channel status detection and UI refresh
- Fix isChannelEnabled() to create channel if missing and re-fetch from system to get actual state (handles previously blocked channels) - Use correct channel ID 'timesafari.daily' instead of 'daily_notification_channel' - Add detailed logging for channel status checks - Fix UI to refresh channel status after notification permissions are granted - Channel status now correctly reflects both app-level and channel-level settings
This commit is contained in:
@@ -95,7 +95,7 @@ open class DailyNotificationPlugin : Plugin() {
|
||||
Log.e(TAG, "Context is null, cannot initialize database")
|
||||
return
|
||||
}
|
||||
db = DailyNotificationDatabase.getDatabase(context)
|
||||
db = DailyNotificationDatabase.getDatabase(context)
|
||||
Log.i(TAG, "Daily Notification Plugin loaded successfully")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to initialize Daily Notification Plugin", e)
|
||||
@@ -1048,21 +1048,73 @@ open class DailyNotificationPlugin : Plugin() {
|
||||
@PluginMethod
|
||||
fun isChannelEnabled(call: PluginCall) {
|
||||
try {
|
||||
val channelId = call.getString("channelId") ?: "daily_notification_channel"
|
||||
val enabled = NotificationManagerCompat.from(context).areNotificationsEnabled()
|
||||
if (context == null) {
|
||||
return call.reject("Context not available")
|
||||
}
|
||||
|
||||
// Use the actual channel ID that matches what's used in notifications
|
||||
val channelId = call.getString("channelId") ?: "timesafari.daily"
|
||||
|
||||
// Check app-level notifications first
|
||||
val appNotificationsEnabled = NotificationManagerCompat.from(context).areNotificationsEnabled()
|
||||
|
||||
// Get notification channel importance if available
|
||||
var importance = 0
|
||||
var channelEnabled = false
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val notificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager?
|
||||
val channel = notificationManager?.getNotificationChannel(channelId)
|
||||
importance = channel?.importance ?: android.app.NotificationManager.IMPORTANCE_DEFAULT
|
||||
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? android.app.NotificationManager
|
||||
var channel = notificationManager?.getNotificationChannel(channelId)
|
||||
|
||||
if (channel == null) {
|
||||
// Channel doesn't exist - create it first (same as ChannelManager does)
|
||||
Log.i(TAG, "Channel $channelId doesn't exist, creating it")
|
||||
val newChannel = android.app.NotificationChannel(
|
||||
channelId,
|
||||
"Daily Notifications",
|
||||
android.app.NotificationManager.IMPORTANCE_HIGH
|
||||
).apply {
|
||||
description = "Daily notifications from TimeSafari"
|
||||
enableLights(true)
|
||||
enableVibration(true)
|
||||
setShowBadge(true)
|
||||
}
|
||||
notificationManager?.createNotificationChannel(newChannel)
|
||||
Log.i(TAG, "Channel $channelId created with HIGH importance")
|
||||
|
||||
// Re-fetch the channel from the system to get actual state
|
||||
// (in case it was previously blocked by user)
|
||||
channel = notificationManager?.getNotificationChannel(channelId)
|
||||
}
|
||||
|
||||
// Now check the channel (re-fetched from system to get actual state)
|
||||
if (channel != null) {
|
||||
importance = channel.importance
|
||||
// Channel is enabled if importance is not IMPORTANCE_NONE
|
||||
// IMPORTANCE_NONE = 0 means blocked/disabled
|
||||
channelEnabled = importance != android.app.NotificationManager.IMPORTANCE_NONE
|
||||
Log.d(TAG, "Channel $channelId status: importance=$importance, enabled=$channelEnabled")
|
||||
} else {
|
||||
// Channel still doesn't exist after creation attempt - should not happen
|
||||
Log.w(TAG, "Channel $channelId still doesn't exist after creation attempt")
|
||||
importance = android.app.NotificationManager.IMPORTANCE_NONE
|
||||
channelEnabled = false
|
||||
}
|
||||
} else {
|
||||
// Pre-Oreo: channels don't exist, use app-level check
|
||||
channelEnabled = appNotificationsEnabled
|
||||
importance = android.app.NotificationManager.IMPORTANCE_DEFAULT
|
||||
}
|
||||
|
||||
val finalEnabled = appNotificationsEnabled && channelEnabled
|
||||
Log.i(TAG, "Channel status check complete: channelId=$channelId, appNotificationsEnabled=$appNotificationsEnabled, channelEnabled=$channelEnabled, importance=$importance, finalEnabled=$finalEnabled")
|
||||
|
||||
val result = JSObject().apply {
|
||||
put("enabled", enabled)
|
||||
// Channel is enabled if both app notifications are enabled AND channel importance is not NONE
|
||||
put("enabled", finalEnabled)
|
||||
put("channelId", channelId)
|
||||
put("importance", importance)
|
||||
put("appNotificationsEnabled", appNotificationsEnabled)
|
||||
put("channelBlocked", importance == android.app.NotificationManager.IMPORTANCE_NONE)
|
||||
}
|
||||
call.resolve(result)
|
||||
} catch (e: Exception) {
|
||||
@@ -1074,28 +1126,80 @@ open class DailyNotificationPlugin : Plugin() {
|
||||
@PluginMethod
|
||||
fun openChannelSettings(call: PluginCall) {
|
||||
try {
|
||||
val channelId = call.getString("channelId") ?: "daily_notification_channel"
|
||||
val intent = Intent(android.provider.Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
|
||||
putExtra(android.provider.Settings.EXTRA_APP_PACKAGE, context?.packageName)
|
||||
putExtra(android.provider.Settings.EXTRA_CHANNEL_ID, channelId)
|
||||
if (context == null) {
|
||||
return call.reject("Context not available")
|
||||
}
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
|
||||
// Use the actual channel ID that matches what's used in notifications
|
||||
val channelId = call.getString("channelId") ?: "timesafari.daily"
|
||||
|
||||
// Ensure channel exists before trying to open settings
|
||||
// This ensures the channel-specific settings page can be opened
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? android.app.NotificationManager
|
||||
val channel = notificationManager?.getNotificationChannel(channelId)
|
||||
|
||||
if (channel == null) {
|
||||
// Channel doesn't exist - create it first
|
||||
Log.i(TAG, "Channel $channelId doesn't exist, creating it")
|
||||
val newChannel = android.app.NotificationChannel(
|
||||
channelId,
|
||||
"Daily Notifications",
|
||||
android.app.NotificationManager.IMPORTANCE_HIGH
|
||||
).apply {
|
||||
description = "Daily notifications from TimeSafari"
|
||||
enableLights(true)
|
||||
enableVibration(true)
|
||||
setShowBadge(true)
|
||||
}
|
||||
notificationManager?.createNotificationChannel(newChannel)
|
||||
Log.i(TAG, "Channel $channelId created")
|
||||
}
|
||||
}
|
||||
|
||||
// Try to open channel-specific settings first
|
||||
try {
|
||||
activity?.startActivity(intent)
|
||||
val intent = Intent(android.provider.Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
|
||||
putExtra(android.provider.Settings.EXTRA_APP_PACKAGE, context.packageName)
|
||||
putExtra(android.provider.Settings.EXTRA_CHANNEL_ID, channelId)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
|
||||
activity?.startActivity(intent) ?: context.startActivity(intent)
|
||||
Log.i(TAG, "Channel settings opened for channel: $channelId")
|
||||
|
||||
val result = JSObject().apply {
|
||||
put("opened", true)
|
||||
put("channelId", channelId)
|
||||
}
|
||||
call.resolve(result)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to start activity", e)
|
||||
val result = JSObject().apply {
|
||||
put("opened", false)
|
||||
put("channelId", channelId)
|
||||
put("error", e.message)
|
||||
// Fallback to general app notification settings if channel-specific fails
|
||||
Log.w(TAG, "Failed to open channel-specific settings, trying app notification settings", e)
|
||||
try {
|
||||
val fallbackIntent = Intent(android.provider.Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
|
||||
putExtra(android.provider.Settings.EXTRA_APP_PACKAGE, context.packageName)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
activity?.startActivity(fallbackIntent) ?: context.startActivity(fallbackIntent)
|
||||
Log.i(TAG, "App notification settings opened (fallback)")
|
||||
|
||||
val result = JSObject().apply {
|
||||
put("opened", true)
|
||||
put("channelId", channelId)
|
||||
put("fallback", true)
|
||||
put("message", "Opened app notification settings (channel-specific unavailable)")
|
||||
}
|
||||
call.resolve(result)
|
||||
} catch (e2: Exception) {
|
||||
Log.e(TAG, "Failed to open notification settings", e2)
|
||||
val result = JSObject().apply {
|
||||
put("opened", false)
|
||||
put("channelId", channelId)
|
||||
put("error", e2.message)
|
||||
}
|
||||
call.resolve(result)
|
||||
}
|
||||
call.resolve(result)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to open channel settings", e)
|
||||
|
||||
Reference in New Issue
Block a user