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
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);
|
|
}
|
|
}
|
|
}
|
|
|