You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

193 lines
7.1 KiB

package com.timesafari.dailynotification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;
/**
* Manages notification channels and ensures they are properly configured
* for reliable notification delivery.
*
* Handles channel creation, importance checking, and provides deep links
* to channel settings when notifications are blocked.
*
* @author Matthew Raymer
* @version 1.0
*/
public class ChannelManager {
private static final String TAG = "ChannelManager";
private static final String DEFAULT_CHANNEL_ID = "timesafari.daily";
private static final String DEFAULT_CHANNEL_NAME = "Daily Notifications";
private static final String DEFAULT_CHANNEL_DESCRIPTION = "Daily notifications from TimeSafari";
private final Context context;
private final NotificationManager notificationManager;
public ChannelManager(Context context) {
this.context = context;
this.notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
/**
* Ensures the default notification channel exists and is properly configured.
* Creates the channel if it doesn't exist.
*
* @return true if channel is ready for notifications, false if blocked
*/
public boolean ensureChannelExists() {
try {
Log.d(TAG, "Ensuring notification channel exists");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = notificationManager.getNotificationChannel(DEFAULT_CHANNEL_ID);
if (channel == null) {
Log.d(TAG, "Creating notification channel");
createDefaultChannel();
return true;
} else {
Log.d(TAG, "Channel exists with importance: " + channel.getImportance());
return channel.getImportance() != NotificationManager.IMPORTANCE_NONE;
}
} else {
// Pre-Oreo: channels don't exist, always ready
Log.d(TAG, "Pre-Oreo device, channels not applicable");
return true;
}
} catch (Exception e) {
Log.e(TAG, "Error ensuring channel exists", e);
return false;
}
}
/**
* Checks if the notification channel is enabled and can deliver notifications.
*
* @return true if channel is enabled, false if blocked
*/
public boolean isChannelEnabled() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = notificationManager.getNotificationChannel(DEFAULT_CHANNEL_ID);
if (channel == null) {
Log.w(TAG, "Channel does not exist");
return false;
}
int importance = channel.getImportance();
Log.d(TAG, "Channel importance: " + importance);
return importance != NotificationManager.IMPORTANCE_NONE;
} else {
// Pre-Oreo: always enabled
return true;
}
} catch (Exception e) {
Log.e(TAG, "Error checking channel status", e);
return false;
}
}
/**
* Gets the current channel importance level.
*
* @return importance level, or -1 if channel doesn't exist
*/
public int getChannelImportance() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = notificationManager.getNotificationChannel(DEFAULT_CHANNEL_ID);
if (channel != null) {
return channel.getImportance();
}
}
return -1;
} catch (Exception e) {
Log.e(TAG, "Error getting channel importance", e);
return -1;
}
}
/**
* Opens the notification channel settings for the user to enable notifications.
*
* @return true if settings intent was launched, false otherwise
*/
public boolean openChannelSettings() {
try {
Log.d(TAG, "Opening channel settings");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName())
.putExtra(Settings.EXTRA_CHANNEL_ID, DEFAULT_CHANNEL_ID)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
Log.d(TAG, "Channel settings opened");
return true;
} else {
Log.d(TAG, "Channel settings not available on pre-Oreo");
return false;
}
} catch (Exception e) {
Log.e(TAG, "Error opening channel settings", e);
return false;
}
}
/**
* Creates the default notification channel with high importance.
*/
private void createDefaultChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
DEFAULT_CHANNEL_ID,
DEFAULT_CHANNEL_NAME,
NotificationManager.IMPORTANCE_HIGH
);
channel.setDescription(DEFAULT_CHANNEL_DESCRIPTION);
channel.enableLights(true);
channel.enableVibration(true);
channel.setShowBadge(true);
notificationManager.createNotificationChannel(channel);
Log.d(TAG, "Default channel created with HIGH importance");
}
}
/**
* Gets the default channel ID for use in notifications.
*
* @return the default channel ID
*/
public String getDefaultChannelId() {
return DEFAULT_CHANNEL_ID;
}
/**
* Logs the current channel status for debugging.
*/
public void logChannelStatus() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = notificationManager.getNotificationChannel(DEFAULT_CHANNEL_ID);
if (channel != null) {
Log.i(TAG, "Channel Status - ID: " + channel.getId() +
", Importance: " + channel.getImportance() +
", Enabled: " + (channel.getImportance() != NotificationManager.IMPORTANCE_NONE));
} else {
Log.w(TAG, "Channel does not exist");
}
} else {
Log.i(TAG, "Pre-Oreo device, channels not applicable");
}
} catch (Exception e) {
Log.e(TAG, "Error logging channel status", e);
}
}
}