Skip to content
Snippets Groups Projects
Commit 12b0dc56 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Implement background notifications

parent 97fc3cec
Branches
Tags
No related merge requests found
...@@ -4,13 +4,17 @@ import android.annotation.SuppressLint ...@@ -4,13 +4,17 @@ import android.annotation.SuppressLint
import android.arch.lifecycle.LifecycleService import android.arch.lifecycle.LifecycleService
import android.arch.lifecycle.Observer import android.arch.lifecycle.Observer
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.os.Binder import android.os.Binder
import android.support.v7.preference.PreferenceManager
import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.protocol.*
import de.kuschku.libquassel.session.* import de.kuschku.libquassel.session.*
import de.kuschku.quasseldroid_ng.BuildConfig import de.kuschku.quasseldroid_ng.BuildConfig
import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.R
import de.kuschku.quasseldroid_ng.persistence.QuasselBacklogStorage import de.kuschku.quasseldroid_ng.persistence.QuasselBacklogStorage
import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase 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.AndroidHandlerThread
import de.kuschku.quasseldroid_ng.util.compatibility.AndroidHandlerService import de.kuschku.quasseldroid_ng.util.compatibility.AndroidHandlerService
import de.kuschku.quasseldroid_ng.util.helper.toLiveData import de.kuschku.quasseldroid_ng.util.helper.toLiveData
...@@ -19,11 +23,33 @@ import java.security.cert.X509Certificate ...@@ -19,11 +23,33 @@ import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.net.ssl.X509TrustManager 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 sessionManager: SessionManager
private lateinit var clientData: ClientData private lateinit var clientData: ClientData
private lateinit var connectionSettings: ConnectionSettings
private val trustManager = object : X509TrustManager { private val trustManager = object : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager") @SuppressLint("TrustAllX509TrustManager")
override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) = Unit override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) = Unit
...@@ -126,6 +152,15 @@ class QuasselService : LifecycleService() { ...@@ -126,6 +152,15 @@ class QuasselService : LifecycleService() {
sessionManager.reconnect() 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 { override fun onBind(intent: Intent?): QuasselBinder {
......
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
package de.kuschku.quasseldroid_ng.ui.settings.data package de.kuschku.quasseldroid_ng.ui.settings.data
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.preference.PreferenceManager
import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.R
import de.kuschku.quasseldroid_ng.ui.settings.data.AppearanceSettings.* import de.kuschku.quasseldroid_ng.ui.settings.data.AppearanceSettings.*
import de.kuschku.quasseldroid_ng.util.helper.sharedPreferences
object Settings { object Settings {
private fun <T> settings(context: Context, fun appearance(context: Context) = context.sharedPreferences {
f: SharedPreferences.() -> T) = PreferenceManager.getDefaultSharedPreferences(
context
).f()
fun appearance(context: Context) = settings(
context
) {
AppearanceSettings( AppearanceSettings(
theme = Theme.valueOf( theme = Theme.valueOf(
getString( getString(
...@@ -57,9 +49,7 @@ object Settings { ...@@ -57,9 +49,7 @@ object Settings {
) )
} }
fun backlog(context: Context) = settings( fun backlog(context: Context) = context.sharedPreferences {
context
) {
BacklogSettings( BacklogSettings(
dynamicAmount = getString( dynamicAmount = getString(
context.getString(R.string.preference_dynamic_fetch_key), context.getString(R.string.preference_dynamic_fetch_key),
...@@ -67,4 +57,13 @@ object Settings { ...@@ -67,4 +57,13 @@ object Settings {
).toIntOrNull() ?: BacklogSettings.DEFAULT.dynamicAmount ).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
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
package de.kuschku.quasseldroid_ng.util.helper package de.kuschku.quasseldroid_ng.util.helper
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.preference.PreferenceManager
import android.support.annotation.ColorInt import android.support.annotation.ColorInt
import android.support.annotation.ColorRes import android.support.annotation.ColorRes
import android.support.annotation.DrawableRes import android.support.annotation.DrawableRes
...@@ -38,3 +40,7 @@ fun Context.getCompatColor(@ColorRes id: Int): Int { ...@@ -38,3 +40,7 @@ fun Context.getCompatColor(@ColorRes id: Int): Int {
this.resources.getColor(id) this.resources.getColor(id)
} }
} }
fun <T> Context.sharedPreferences(f: SharedPreferences.() -> T) =
PreferenceManager.getDefaultSharedPreferences(this).f()
\ No newline at end of file
...@@ -10,6 +10,7 @@ import de.kuschku.libquassel.session.Backend ...@@ -10,6 +10,7 @@ import de.kuschku.libquassel.session.Backend
import de.kuschku.quasseldroid_ng.Keys import de.kuschku.quasseldroid_ng.Keys
import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.R
import de.kuschku.quasseldroid_ng.ui.settings.data.AppearanceSettings 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.ui.settings.data.Settings
import de.kuschku.quasseldroid_ng.util.helper.updateRecentsHeaderIfExisting import de.kuschku.quasseldroid_ng.util.helper.updateRecentsHeaderIfExisting
...@@ -24,12 +25,14 @@ abstract class ServiceBoundActivity : AppCompatActivity() { ...@@ -24,12 +25,14 @@ abstract class ServiceBoundActivity : AppCompatActivity() {
get() = connection.backend get() = connection.backend
protected lateinit var appearanceSettings: AppearanceSettings protected lateinit var appearanceSettings: AppearanceSettings
protected lateinit var connectionSettings: ConnectionSettings
protected var accountId: Long = -1 protected var accountId: Long = -1
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
connection.context = this connection.context = this
appearanceSettings = Settings.appearance(this) appearanceSettings = Settings.appearance(this)
connectionSettings = Settings.connection(this)
accountId = getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) accountId = getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE)
?.getLong(Keys.Status.selectedAccount, -1) ?: -1 ?.getLong(Keys.Status.selectedAccount, -1) ?: -1
......
...@@ -13,7 +13,13 @@ ...@@ -13,7 +13,13 @@
<string name="label_filter_messages">Filter Messages</string> <string name="label_filter_messages">Filter Messages</string>
<string name="label_input_history">Input History</string> <string name="label_input_history">Input History</string>
<string name="label_placeholder">Write a message…</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_save">Save</string>
<string name="label_select_multiple">Select</string> <string name="label_select_multiple">Select</string>
<string name="label_settings">Settings</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> </resources>
...@@ -86,4 +86,13 @@ ...@@ -86,4 +86,13 @@
<string name="preference_dynamic_fetch_key" translatable="false">dynamic_fetch</string> <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_title">Dynamic Fetch Amount</string>
<string name="preference_dynamic_fetch_summary">The number of backlog messages to fetch each time</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> </resources>
\ No newline at end of file
...@@ -59,4 +59,12 @@ ...@@ -59,4 +59,12 @@
android:summary="@string/preference_dynamic_fetch_summary" android:summary="@string/preference_dynamic_fetch_summary"
android:title="@string/preference_dynamic_fetch_title" /> android:title="@string/preference_dynamic_fetch_title" />
</PreferenceCategory> </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> </PreferenceScreen>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment