diff options
Diffstat (limited to 'app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt')
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt | 97 |
1 files changed, 36 insertions, 61 deletions
diff --git a/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt b/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt index 9d731a5..29f72de 100644 --- a/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt +++ b/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon | 2 | * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon |
3 | * Copyright (C) 2017-2020 Pacien TRAN-GIRARD | 3 | * Copyright (C) 2017-2023 Pacien TRAN-GIRARD |
4 | * | 4 | * |
5 | * This program is free software: you can redistribute it and/or modify | 5 | * This program is free software: you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -18,84 +18,59 @@ | |||
18 | 18 | ||
19 | package org.pacien.tincapp.context | 19 | package org.pacien.tincapp.context |
20 | 20 | ||
21 | import android.app.Notification | ||
22 | import android.app.NotificationChannel | ||
23 | import android.app.NotificationManager | ||
24 | import android.app.PendingIntent | ||
25 | import android.content.Context | 21 | import android.content.Context |
26 | import android.content.Intent | 22 | import android.content.SharedPreferences.OnSharedPreferenceChangeListener |
27 | import android.net.Uri | ||
28 | import android.os.Build | ||
29 | import androidx.annotation.RequiresApi | ||
30 | import androidx.core.app.NotificationCompat | ||
31 | import androidx.core.app.NotificationManagerCompat | ||
32 | import org.pacien.tincapp.R | ||
33 | 23 | ||
34 | /** | 24 | /** |
35 | * @author pacien | 25 | * @author pacien |
36 | */ | 26 | */ |
37 | class AppNotificationManager(private val context: Context) { | 27 | class AppNotificationManager(private val context: Context) { |
38 | companion object { | 28 | data class ErrorNotification( |
39 | private const val ERROR_CHANNEL_ID = "org.pacien.tincapp.notification.channels.error" | 29 | val title: String, |
40 | private const val CONFIG_ACCESS_CHANNEL_ID = "org.pacien.tincapp.notification.channels.configuration" | 30 | val message: String, |
31 | val manualLink: String? | ||
32 | ) | ||
41 | 33 | ||
42 | const val ERROR_NOTIFICATION_ID = 0 | 34 | companion object { |
43 | const val CONFIG_ACCESS_NOTIFICATION_ID = 1 | 35 | private val STORE_NAME = this::class.java.`package`!!.name |
36 | private const val STORE_KEY_TITLE = "title" | ||
37 | private const val STORE_KEY_MESSAGE = "message" | ||
38 | private const val STORE_KEY_MANUAL_LINK = "manual_link" | ||
44 | } | 39 | } |
45 | 40 | ||
46 | init { | 41 | private val store by lazy { context.getSharedPreferences(STORE_NAME, Context.MODE_PRIVATE)!! } |
47 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) registerChannels() | ||
48 | } | ||
49 | 42 | ||
50 | fun notifyError(title: String, message: String, manualLink: String? = null) { | 43 | fun getError(): ErrorNotification? { |
51 | val notification = NotificationCompat.Builder(context, ERROR_CHANNEL_ID) | 44 | if (!store.contains(STORE_KEY_TITLE)) return null; |
52 | .setSmallIcon(R.drawable.ic_warning_primary_24dp) | ||
53 | .setContentTitle(title) | ||
54 | .setContentText(message) | ||
55 | .setStyle(NotificationCompat.BigTextStyle().bigText(message)) | ||
56 | .setHighPriority() | ||
57 | .setAutoCancel(true) | ||
58 | .apply { if (manualLink != null) setManualLink(manualLink) } | ||
59 | .build() | ||
60 | 45 | ||
61 | NotificationManagerCompat.from(context) | 46 | return ErrorNotification( |
62 | .notify(ERROR_NOTIFICATION_ID, notification) | 47 | store.getString(STORE_KEY_TITLE, null)!!, |
48 | store.getString(STORE_KEY_MESSAGE, null)!!, | ||
49 | store.getString(STORE_KEY_MANUAL_LINK, null) | ||
50 | ) | ||
63 | } | 51 | } |
64 | 52 | ||
65 | fun dismissAll() { | 53 | fun notifyError(title: String, message: String, manualLink: String? = null) { |
66 | NotificationManagerCompat.from(context).cancelAll() | 54 | store |
55 | .edit() | ||
56 | .putString(STORE_KEY_TITLE, title) | ||
57 | .putString(STORE_KEY_MESSAGE, message) | ||
58 | .putString(STORE_KEY_MANUAL_LINK, manualLink) | ||
59 | .apply() | ||
67 | } | 60 | } |
68 | 61 | ||
69 | fun newConfigurationAccessNotificationBuilder() = | 62 | fun dismissAll() { |
70 | NotificationCompat.Builder(context, CONFIG_ACCESS_CHANNEL_ID) | 63 | store |
71 | 64 | .edit() | |
72 | @RequiresApi(Build.VERSION_CODES.O) | 65 | .clear() |
73 | private fun registerChannels() { | 66 | .apply() |
74 | context.getSystemService(NotificationManager::class.java) | ||
75 | .apply { | ||
76 | createNotificationChannel(NotificationChannel( | ||
77 | ERROR_CHANNEL_ID, | ||
78 | context.getString(R.string.notification_error_channel_name), | ||
79 | NotificationManager.IMPORTANCE_HIGH | ||
80 | )) | ||
81 | } | ||
82 | .apply { | ||
83 | createNotificationChannel(NotificationChannel( | ||
84 | CONFIG_ACCESS_CHANNEL_ID, | ||
85 | context.getString(R.string.notification_config_access_channel_name), | ||
86 | NotificationManager.IMPORTANCE_MIN | ||
87 | )) | ||
88 | } | ||
89 | } | 67 | } |
90 | 68 | ||
91 | private fun NotificationCompat.Builder.setHighPriority() = apply { | 69 | fun registerListener(listener: OnSharedPreferenceChangeListener) { |
92 | priority = NotificationCompat.PRIORITY_MAX | 70 | store.registerOnSharedPreferenceChangeListener(listener) |
93 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) setDefaults(NotificationCompat.DEFAULT_SOUND) // force heads-up notification | ||
94 | } | 71 | } |
95 | 72 | ||
96 | private fun NotificationCompat.Builder.setManualLink(manualLink: String) = apply { | 73 | fun unregisterListener(listener: OnSharedPreferenceChangeListener) { |
97 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse(manualLink)) | 74 | store.unregisterOnSharedPreferenceChangeListener(listener) |
98 | val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0) | ||
99 | addAction(R.drawable.ic_help_primary_24dp, context.getString(R.string.notification_error_action_open_manual), pendingIntent) | ||
100 | } | 75 | } |
101 | } | 76 | } |