Request notification permission for geofence alerts

This commit is contained in:
Artem Kokos
2026-05-15 10:43:21 +07:00
parent 8b9a25e746
commit 50748c6945
6 changed files with 124 additions and 14 deletions

View File

@@ -1,12 +1,14 @@
enum NotificationPermissionStatus {
enabled,
disabled,
requestable,
settingsRequired,
unsupported;
static NotificationPermissionStatus fromPlatformValue(String? value) {
return switch (value) {
'enabled' => NotificationPermissionStatus.enabled,
'disabled' => NotificationPermissionStatus.disabled,
'requestable' => NotificationPermissionStatus.requestable,
'settings_required' => NotificationPermissionStatus.settingsRequired,
_ => NotificationPermissionStatus.unsupported,
};
}

View File

@@ -93,6 +93,8 @@ final geofenceSystemStatusProvider = FutureProvider<GeofenceSystemState>((
abstract class NotificationPermissionStatusService {
Future<NotificationPermissionStatus> inspect();
Future<void> requestPermission();
Future<void> openSettings();
}
@@ -112,6 +114,15 @@ class DeviceNotificationPermissionStatusService
}
}
@override
Future<void> requestPermission() async {
try {
await _channel.invokeMethod<void>('requestNotificationPermission');
} on MissingPluginException {
return;
}
}
@override
Future<void> openSettings() async {
try {

View File

@@ -58,11 +58,12 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen>
final geofenceState = geofenceStatus.asData?.value;
final notificationStatus = ref.watch(notificationPermissionStatusProvider);
final notificationPermission = notificationStatus.asData?.value;
final bottomInset = MediaQuery.paddingOf(context).bottom;
return Scaffold(
appBar: AppBar(title: const Text('НАСТРОЙКИ')),
body: ListView(
padding: const EdgeInsets.all(16),
padding: EdgeInsets.fromLTRB(16, 16, 16, bottomInset + 24),
children: [
_SectionTitle(
title: 'Дом и подключение',
@@ -321,7 +322,21 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen>
],
};
if (notificationPermission == NotificationPermissionStatus.disabled) {
if (notificationPermission == NotificationPermissionStatus.requestable) {
actions.add(
FilledButton.tonalIcon(
onPressed: () async {
await notificationNotifier.requestPermission();
ref.invalidate(notificationPermissionStatusProvider);
},
icon: const Icon(Icons.notifications_active_outlined),
label: const Text('Разрешить уведомления'),
),
);
}
if (notificationPermission ==
NotificationPermissionStatus.settingsRequired) {
actions.add(
OutlinedButton.icon(
onPressed: () async {
@@ -631,7 +646,10 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen>
return switch (status) {
NotificationPermissionStatus.enabled =>
Icons.notifications_active_outlined,
NotificationPermissionStatus.disabled => Icons.notifications_off_outlined,
NotificationPermissionStatus.requestable =>
Icons.notifications_off_outlined,
NotificationPermissionStatus.settingsRequired =>
Icons.notifications_paused_outlined,
NotificationPermissionStatus.unsupported ||
null => Icons.notifications_none_outlined,
};
@@ -643,7 +661,8 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen>
) {
return switch (status) {
NotificationPermissionStatus.enabled => Colors.green,
NotificationPermissionStatus.disabled => Theme.of(
NotificationPermissionStatus.requestable ||
NotificationPermissionStatus.settingsRequired => Theme.of(
context,
).colorScheme.error,
NotificationPermissionStatus.unsupported || null => Colors.white70,
@@ -654,8 +673,10 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen>
return switch (status) {
NotificationPermissionStatus.enabled =>
'После срабатывания geofence приложение сможет прислать подтверждение.',
NotificationPermissionStatus.disabled =>
'Автовыключение сработает и без них, но подтверждение ты не увидишь.',
NotificationPermissionStatus.requestable =>
'Android ещё может показать системный запрос на уведомления.',
NotificationPermissionStatus.settingsRequired =>
'Автовыключение сработает и без них, но подтверждение нужно включить вручную.',
NotificationPermissionStatus.unsupported =>
'На этой платформе отдельный статус уведомлений не используется.',
null => 'Проверяем, доступны ли уведомления для подтверждения.',