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.
 
 
 
 
 
 

291 lines
11 KiB

/**
* PermissionManager.java
*
* Specialized manager for permission handling and notification settings
* Handles notification permissions, channel management, and exact alarm settings
*
* @author Matthew Raymer
* @version 2.0.0 - Modular Architecture
*/
package com.timesafari.dailynotification;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;
import androidx.core.app.NotificationManagerCompat;
import com.getcapacitor.JSObject;
import com.getcapacitor.PluginCall;
/**
* Manager class for permission and settings management
*
* Responsibilities:
* - Request notification permissions
* - Check permission status
* - Manage notification channels
* - Handle exact alarm settings
* - Provide comprehensive status checking
*/
public class PermissionManager {
private static final String TAG = "PermissionManager";
private final Context context;
private final ChannelManager channelManager;
/**
* Initialize the PermissionManager
*
* @param context Android context
* @param channelManager Channel manager for notification channels
*/
public PermissionManager(Context context, ChannelManager channelManager) {
this.context = context;
this.channelManager = channelManager;
Log.d(TAG, "PermissionManager initialized");
}
/**
* Request notification permissions from the user
*
* @param call Plugin call
*/
public void requestNotificationPermissions(PluginCall call) {
try {
Log.d(TAG, "Requesting notification permissions");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// For Android 13+, request POST_NOTIFICATIONS permission
requestPermission(Manifest.permission.POST_NOTIFICATIONS, call);
} else {
// For older versions, permissions are granted at install time
JSObject result = new JSObject();
result.put("success", true);
result.put("granted", true);
result.put("message", "Notifications enabled (pre-Android 13)");
call.resolve(result);
}
} catch (Exception e) {
Log.e(TAG, "Error requesting notification permissions", e);
call.reject("Failed to request permissions: " + e.getMessage());
}
}
/**
* Check the current status of notification permissions
*
* @param call Plugin call
*/
public void checkPermissionStatus(PluginCall call) {
try {
Log.d(TAG, "Checking permission status");
boolean postNotificationsGranted = false;
boolean exactAlarmsGranted = false;
// Check POST_NOTIFICATIONS permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
postNotificationsGranted = context.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED;
} else {
postNotificationsGranted = NotificationManagerCompat.from(context).areNotificationsEnabled();
}
// Check exact alarm permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
android.app.AlarmManager alarmManager = (android.app.AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
exactAlarmsGranted = alarmManager.canScheduleExactAlarms();
} else {
exactAlarmsGranted = true; // Pre-Android 12, exact alarms are always allowed
}
JSObject result = new JSObject();
result.put("success", true);
result.put("postNotificationsGranted", postNotificationsGranted);
result.put("exactAlarmsGranted", exactAlarmsGranted);
result.put("channelEnabled", channelManager.isChannelEnabled());
result.put("channelImportance", channelManager.getChannelImportance());
call.resolve(result);
} catch (Exception e) {
Log.e(TAG, "Error checking permission status", e);
call.reject("Failed to check permissions: " + e.getMessage());
}
}
/**
* Open exact alarm settings for the user
*
* @param call Plugin call
*/
public void openExactAlarmSettings(PluginCall call) {
try {
Log.d(TAG, "Opening exact alarm settings");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
Intent intent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
intent.setData(android.net.Uri.parse("package:" + context.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
JSObject result = new JSObject();
result.put("success", true);
result.put("message", "Exact alarm settings opened");
call.resolve(result);
} catch (Exception e) {
Log.e(TAG, "Failed to open exact alarm settings", e);
call.reject("Failed to open exact alarm settings: " + e.getMessage());
}
} else {
JSObject result = new JSObject();
result.put("success", true);
result.put("message", "Exact alarms not supported on this Android version");
call.resolve(result);
}
} catch (Exception e) {
Log.e(TAG, "Error opening exact alarm settings", e);
call.reject("Failed to open exact alarm settings: " + e.getMessage());
}
}
/**
* Check if the notification channel is enabled
*
* @param call Plugin call
*/
public void isChannelEnabled(PluginCall call) {
try {
Log.d(TAG, "Checking channel status");
boolean enabled = channelManager.isChannelEnabled();
int importance = channelManager.getChannelImportance();
JSObject result = new JSObject();
result.put("success", true);
result.put("enabled", enabled);
result.put("importance", importance);
result.put("channelId", channelManager.getDefaultChannelId());
call.resolve(result);
} catch (Exception e) {
Log.e(TAG, "Error checking channel status", e);
call.reject("Failed to check channel status: " + e.getMessage());
}
}
/**
* Open notification channel settings for the user
*
* @param call Plugin call
*/
public void openChannelSettings(PluginCall call) {
try {
Log.d(TAG, "Opening channel settings");
boolean opened = channelManager.openChannelSettings();
JSObject result = new JSObject();
result.put("success", true);
result.put("opened", opened);
result.put("message", opened ? "Channel settings opened" : "Failed to open channel settings");
call.resolve(result);
} catch (Exception e) {
Log.e(TAG, "Error opening channel settings", e);
call.reject("Failed to open channel settings: " + e.getMessage());
}
}
/**
* Get comprehensive status of the notification system
*
* @param call Plugin call
*/
public void checkStatus(PluginCall call) {
try {
Log.d(TAG, "Checking comprehensive status");
// Check permissions
boolean postNotificationsGranted = false;
boolean exactAlarmsGranted = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
postNotificationsGranted = context.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED;
} else {
postNotificationsGranted = NotificationManagerCompat.from(context).areNotificationsEnabled();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
android.app.AlarmManager alarmManager = (android.app.AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
exactAlarmsGranted = alarmManager.canScheduleExactAlarms();
} else {
exactAlarmsGranted = true;
}
// Check channel status
boolean channelEnabled = channelManager.isChannelEnabled();
int channelImportance = channelManager.getChannelImportance();
// Determine overall status
boolean canScheduleNow = postNotificationsGranted && channelEnabled && exactAlarmsGranted;
JSObject result = new JSObject();
result.put("success", true);
result.put("canScheduleNow", canScheduleNow);
result.put("postNotificationsGranted", postNotificationsGranted);
result.put("exactAlarmsGranted", exactAlarmsGranted);
result.put("channelEnabled", channelEnabled);
result.put("channelImportance", channelImportance);
result.put("channelId", channelManager.getDefaultChannelId());
result.put("androidVersion", Build.VERSION.SDK_INT);
call.resolve(result);
} catch (Exception e) {
Log.e(TAG, "Error checking comprehensive status", e);
call.reject("Failed to check status: " + e.getMessage());
}
}
/**
* Request a specific permission
*
* @param permission Permission to request
* @param call Plugin call
*/
private void requestPermission(String permission, PluginCall call) {
try {
// This would typically be handled by the Capacitor framework
// For now, we'll check if the permission is already granted
boolean granted = context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
JSObject result = new JSObject();
result.put("success", true);
result.put("granted", granted);
result.put("permission", permission);
result.put("message", granted ? "Permission already granted" : "Permission not granted");
call.resolve(result);
} catch (Exception e) {
Log.e(TAG, "Error requesting permission: " + permission, e);
call.reject("Failed to request permission: " + e.getMessage());
}
}
}