diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt index 54d2547b34e68ba8e833bdf4d9cdfe9fb14c60b3..93b188ec0f2d12f6dbd05ce385a8702dfaf0d39a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt @@ -4,13 +4,17 @@ import android.annotation.SuppressLint import android.arch.lifecycle.LifecycleService import android.arch.lifecycle.Observer import android.content.Intent +import android.content.SharedPreferences import android.os.Binder +import android.support.v7.preference.PreferenceManager import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.session.* import de.kuschku.quasseldroid_ng.BuildConfig import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.persistence.QuasselBacklogStorage import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase +import de.kuschku.quasseldroid_ng.ui.settings.data.ConnectionSettings +import de.kuschku.quasseldroid_ng.ui.settings.data.Settings import de.kuschku.quasseldroid_ng.util.AndroidHandlerThread import de.kuschku.quasseldroid_ng.util.compatibility.AndroidHandlerService import de.kuschku.quasseldroid_ng.util.helper.toLiveData @@ -19,11 +23,33 @@ import java.security.cert.X509Certificate import java.util.concurrent.TimeUnit import javax.net.ssl.X509TrustManager -class QuasselService : LifecycleService() { +class QuasselService : LifecycleService(), SharedPreferences.OnSharedPreferenceChangeListener { + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + val connectionSettings = Settings.connection(this) + if (this.connectionSettings.showNotification != connectionSettings.showNotification) { + this.connectionSettings = connectionSettings + + updateNotification(connectionSettings.showNotification) + } + } + + private lateinit var notificationManager: de.kuschku.quasseldroid_ng.util.NotificationManager + + private fun updateNotification(showNotification: Boolean) { + if (showNotification) { + val (id, notification) = notificationManager.notificationBackground() + startForeground(id, notification) + } else { + stopForeground(true) + } + } + private lateinit var sessionManager: SessionManager private lateinit var clientData: ClientData + private lateinit var connectionSettings: ConnectionSettings + private val trustManager = object : X509TrustManager { @SuppressLint("TrustAllX509TrustManager") override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) = Unit @@ -126,6 +152,15 @@ class QuasselService : LifecycleService() { sessionManager.reconnect() } ) + + connectionSettings = Settings.connection(this) + + PreferenceManager.getDefaultSharedPreferences(this) + .registerOnSharedPreferenceChangeListener(this) + + notificationManager = de.kuschku.quasseldroid_ng.util.NotificationManager(this) + notificationManager.init() + updateNotification(connectionSettings.showNotification) } override fun onBind(intent: Intent?): QuasselBinder { diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/ConnectionSettings.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/ConnectionSettings.kt new file mode 100644 index 0000000000000000000000000000000000000000..a328d9a6c76c91f4ed7b98f2517bc045fbd89780 --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/ConnectionSettings.kt @@ -0,0 +1,9 @@ +package de.kuschku.quasseldroid_ng.ui.settings.data + +data class ConnectionSettings( + val showNotification: Boolean = true +) { + companion object { + val DEFAULT = ConnectionSettings() + } +} \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/Settings.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/Settings.kt index ea9f3ce1c3e6f465eb623d144e7da5c346c262d3..ca4f45c5d4615c865b4f71f6029fa3e65f79eb12 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/Settings.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/Settings.kt @@ -1,20 +1,12 @@ package de.kuschku.quasseldroid_ng.ui.settings.data import android.content.Context -import android.content.SharedPreferences -import android.preference.PreferenceManager import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.ui.settings.data.AppearanceSettings.* +import de.kuschku.quasseldroid_ng.util.helper.sharedPreferences object Settings { - private fun <T> settings(context: Context, - f: SharedPreferences.() -> T) = PreferenceManager.getDefaultSharedPreferences( - context - ).f() - - fun appearance(context: Context) = settings( - context - ) { + fun appearance(context: Context) = context.sharedPreferences { AppearanceSettings( theme = Theme.valueOf( getString( @@ -57,9 +49,7 @@ object Settings { ) } - fun backlog(context: Context) = settings( - context - ) { + fun backlog(context: Context) = context.sharedPreferences { BacklogSettings( dynamicAmount = getString( context.getString(R.string.preference_dynamic_fetch_key), @@ -67,4 +57,13 @@ object Settings { ).toIntOrNull() ?: BacklogSettings.DEFAULT.dynamicAmount ) } + + fun connection(context: Context) = context.sharedPreferences { + ConnectionSettings( + showNotification = getBoolean( + context.getString(R.string.preference_show_notification_key), + ConnectionSettings.DEFAULT.showNotification + ) + ) + } } \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/NotificationManager.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/NotificationManager.kt new file mode 100644 index 0000000000000000000000000000000000000000..6977a21982f2242eb0f16ee33811f76e778b4ef2 --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/NotificationManager.kt @@ -0,0 +1,74 @@ +package de.kuschku.quasseldroid_ng.util + +import android.annotation.TargetApi +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import android.support.v4.app.NotificationCompat +import de.kuschku.quasseldroid_ng.R +import de.kuschku.quasseldroid_ng.ui.setup.accounts.AccountSelectionActivity +import de.kuschku.quasseldroid_ng.util.helper.editApply +import de.kuschku.quasseldroid_ng.util.helper.sharedPreferences +import de.kuschku.quasseldroid_ng.util.helper.systemService + +class NotificationManager(private val context: Context) { + fun init() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + prepareChannels() + } + + @TargetApi(Build.VERSION_CODES.O) + private fun prepareChannels() { + val notificationManager = context.systemService<NotificationManager>() + notificationManager.createNotificationChannels( + listOf( + NotificationChannel( + context.getString(R.string.notification_channel_background), + context.getString(R.string.notification_channel_background_title), + NotificationManager.IMPORTANCE_MIN + ), + NotificationChannel( + context.getString(R.string.notification_channel_highlight), + context.getString(R.string.notification_channel_highlight_title), + NotificationManager.IMPORTANCE_HIGH + ) + ) + ) + } + + private fun id(): Int = context.sharedPreferences { + val key = context.getString(R.string.preference_notification_id_key) + val id = getInt(key, 1) + 1 + editApply { + putInt(key, id) + } + id + } + + fun notificationBackground(): Pair<Int, Notification> { + val notification = NotificationCompat.Builder( + context.applicationContext, + context.getString(R.string.notification_channel_background) + ) + .setContentIntent( + PendingIntent.getActivity( + context.applicationContext, 0, + Intent(context.applicationContext, AccountSelectionActivity::class.java), 0 + ) + ) + .setContentText(context.getString(R.string.label_running_in_background)) + .setSmallIcon(R.mipmap.ic_launcher_recents) + .setPriority(NotificationCompat.PRIORITY_MIN) + .build() + + return BACKGROUND_NOTIFICATION_ID to notification + } + + companion object { + val BACKGROUND_NOTIFICATION_ID = Int.MAX_VALUE + } +} \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ContextHelper.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ContextHelper.kt index 1fe35d03f3a881b014c06ae01c6dc9e4483a6ecb..c1dd7d784a2d017ed4818af6363744cf382ebcbf 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ContextHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ContextHelper.kt @@ -1,8 +1,10 @@ package de.kuschku.quasseldroid_ng.util.helper import android.content.Context +import android.content.SharedPreferences import android.graphics.drawable.Drawable import android.os.Build +import android.preference.PreferenceManager import android.support.annotation.ColorInt import android.support.annotation.ColorRes import android.support.annotation.DrawableRes @@ -38,3 +40,7 @@ fun Context.getCompatColor(@ColorRes id: Int): Int { this.resources.getColor(id) } } + + +fun <T> Context.sharedPreferences(f: SharedPreferences.() -> T) = + PreferenceManager.getDefaultSharedPreferences(this).f() \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundActivity.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundActivity.kt index 7058ffaaf1612dd2b739f96c4a93f3922e902bf6..66ba271fe6246df7c5ca034b2ccc1fa5eb3e8e88 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundActivity.kt @@ -10,6 +10,7 @@ import de.kuschku.libquassel.session.Backend import de.kuschku.quasseldroid_ng.Keys import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.ui.settings.data.AppearanceSettings +import de.kuschku.quasseldroid_ng.ui.settings.data.ConnectionSettings import de.kuschku.quasseldroid_ng.ui.settings.data.Settings import de.kuschku.quasseldroid_ng.util.helper.updateRecentsHeaderIfExisting @@ -24,12 +25,14 @@ abstract class ServiceBoundActivity : AppCompatActivity() { get() = connection.backend protected lateinit var appearanceSettings: AppearanceSettings + protected lateinit var connectionSettings: ConnectionSettings protected var accountId: Long = -1 override fun onCreate(savedInstanceState: Bundle?) { connection.context = this appearanceSettings = Settings.appearance(this) + connectionSettings = Settings.connection(this) accountId = getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) ?.getLong(Keys.Status.selectedAccount, -1) ?: -1 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 65e50732aa89dfd041000b04dfd9349696d08510..34fc3bcec6315076ff1e79ee64403e1982f3e213 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -13,7 +13,13 @@ <string name="label_filter_messages">Filter Messages</string> <string name="label_input_history">Input History</string> <string name="label_placeholder">Write a messageā¦</string> + <string name="label_running_in_background">Running in background</string> <string name="label_save">Save</string> <string name="label_select_multiple">Select</string> <string name="label_settings">Settings</string> + + <string name="notification_channel_background" translatable="false">background</string> + <string name="notification_channel_background_title">Background</string> + <string name="notification_channel_highlight" translatable="false">highlight</string> + <string name="notification_channel_highlight_title">Highlight</string> </resources> diff --git a/app/src/main/res/values/strings_preferences.xml b/app/src/main/res/values/strings_preferences.xml index ff091e394736aa75eb2f7b534dab6bb7895fbadc..e6ef17ff599811d53159e7e6195faaadafd8bf77 100644 --- a/app/src/main/res/values/strings_preferences.xml +++ b/app/src/main/res/values/strings_preferences.xml @@ -86,4 +86,13 @@ <string name="preference_dynamic_fetch_key" translatable="false">dynamic_fetch</string> <string name="preference_dynamic_fetch_title">Dynamic Fetch Amount</string> <string name="preference_dynamic_fetch_summary">The number of backlog messages to fetch each time</string> + + + <string name="preference_connection_title">Connection</string> + + <string name="preference_show_notification_key" translatable="false">show_notification</string> + <string name="preference_show_notification_title">Show notification</string> + <string name="preference_show_notification_summary">Keeps QuasselDroid always connected by showing a persistent notification</string> + + <string name="preference_notification_id_key" translatable="false">notification_id</string> </resources> \ No newline at end of file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 03a1afc7772638d92f2a24d377cbe0b388974872..2e1c9c5eb267bdc0887bf23b6b361d0c1ed53ae8 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -59,4 +59,12 @@ android:summary="@string/preference_dynamic_fetch_summary" android:title="@string/preference_dynamic_fetch_title" /> </PreferenceCategory> + + <PreferenceCategory android:title="@string/preference_connection_title"> + <SwitchPreference + android:defaultValue="true" + android:key="@string/preference_show_notification_key" + android:summary="@string/preference_show_notification_summary" + android:title="@string/preference_show_notification_title" /> + </PreferenceCategory> </PreferenceScreen> \ No newline at end of file