diff --git a/app/src/debug/res/values/strings.xml b/app/src/debug/res/values/strings.xml
index 7bb3f6147ea4c7acac00231cd512d15caf1a6cde..9410ec8e70f3b38f0bea1d6d739dc42fa85e1afe 100644
--- a/app/src/debug/res/values/strings.xml
+++ b/app/src/debug/res/values/strings.xml
@@ -19,4 +19,6 @@
 
 <resources>
   <string name="app_name">QuasselTest</string>
+
+  <string name="package_name">com.iskrembilen.quasseldroid.debug</string>
 </resources>
diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasseldroidNotificationManager.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasseldroidNotificationManager.kt
index 0d7e52239cb6aca12ad33495415faf5e7eafd7ad..d1711f565b73a05053b52292421664c70b626932 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasseldroidNotificationManager.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasseldroidNotificationManager.kt
@@ -149,7 +149,7 @@ class QuasseldroidNotificationManager @Inject constructor(private val context: C
       .apply {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
           var defaults = 0
-          if (!notificationSettings.sound.isNullOrEmpty()) {
+          if (!notificationSettings.sound.isEmpty()) {
             setSound(Uri.parse(notificationSettings.sound))
           }
           if (notificationSettings.vibrate) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/NotificationSettings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/NotificationSettings.kt
index 71cc7334718c7a3bea76471cf1d453d3c9395976..af07daba16fa13ccd0986da2142f2712034aa7dc 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/settings/NotificationSettings.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/NotificationSettings.kt
@@ -23,8 +23,9 @@ data class NotificationSettings(
   val query: Level = Level.ALL,
   val channel: Level = Level.HIGHLIGHT,
   val other: Level = Level.NONE,
-  val sound: String? = null,
-  val vibrate: Boolean = true
+  val sound: String = "content://settings/system/notification_sound",
+  val vibrate: Boolean = true,
+  val light: Boolean = true
 ) {
   enum class Level {
     ALL,
diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt
index b690bb6a8df4524b391db0a41f140598dd2b2e71..bb91e49b0e2e6947f68f72b954ae53991412b4ea 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt
@@ -143,7 +143,19 @@ object Settings {
           context.getString(R.string.preference_notification_other_key),
           ""
         )
-      ) ?: NotificationSettings.DEFAULT.other
+      ) ?: NotificationSettings.DEFAULT.other,
+      sound = getString(
+        context.getString(R.string.preference_notification_sound_key),
+        NotificationSettings.DEFAULT.sound
+      ),
+      vibrate = getBoolean(
+        context.getString(R.string.preference_notification_sound_key),
+        NotificationSettings.DEFAULT.vibrate
+      ),
+      light = getBoolean(
+        context.getString(R.string.preference_notification_light_key),
+        NotificationSettings.DEFAULT.light
+      )
     )
   }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt
index f887d5576ef982f780f49f8dc1fff756dec1e014..3464146a144531b009b9dbf6fc148b0f148751e6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.chat.info.channel
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class ChannelInfoActivity : ServiceBoundSettingsActivity(ChannelInfoFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt
index 67f9608bc6c322ac385e235ecc08b83a865c756f..e7f23d3588972150a74f53a53ae99afb92c5c120 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt
@@ -23,7 +23,7 @@ import android.content.Context
 import android.content.Intent
 import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.protocol.NetworkId
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class UserInfoActivity : ServiceBoundSettingsActivity(UserInfoFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicActivity.kt
index b7862e0738e60260449ecb24a5353080fab355bd..af7be969e77af38b007ac6eced92a5c81888492d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.chat.topic
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class TopicActivity : ServiceBoundSettingsActivity(TopicFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutActivity.kt
index 36789b40a9287175556939bcc8e918ace0c2186b..3e09e26fc6fc2a487bd871b24adc4e784a1b945c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.clientsettings.about
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.SettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.SettingsActivity
 
 class AboutActivity : SettingsActivity(AboutFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsActivity.kt
index be8e7d46c5dc0f2f978374d60f757f6740db6cc1..0c4b8ba57d564c00068b59af74ae183a8e81dc92 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.clientsettings.client
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.SettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.SettingsActivity
 
 class ClientSettingsActivity : SettingsActivity(ClientSettingsFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
index c330f0d0baa2779a7a5184b754c7d21925ff8e89..a92c5be98c5efe51ed43d9f32a0ee27d449e6124 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
@@ -20,6 +20,7 @@
 package de.kuschku.quasseldroid.ui.clientsettings.client
 
 import android.content.SharedPreferences
+import android.os.Build
 import android.os.Bundle
 import android.support.v7.preference.ListPreference
 import android.support.v7.preference.Preference
@@ -33,11 +34,12 @@ import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.ui.clientsettings.about.AboutActivity
 import de.kuschku.quasseldroid.ui.clientsettings.crash.CrashActivity
 import de.kuschku.quasseldroid.ui.clientsettings.whitelist.WhitelistActivity
-import de.kuschku.quasseldroid.util.backport.DaggerPreferenceFragmentCompat
+import de.kuschku.quasseldroid.util.ui.settings.DaggerPreferenceFragmentCompat
 import javax.inject.Inject
 
 class ClientSettingsFragment : DaggerPreferenceFragmentCompat(),
                                SharedPreferences.OnSharedPreferenceChangeListener {
+
   @Inject
   lateinit var appearanceSettings: AppearanceSettings
 
@@ -48,6 +50,13 @@ class ClientSettingsFragment : DaggerPreferenceFragmentCompat(),
 
   override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
     setPreferencesFromResource(R.xml.preferences, rootKey)
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+      findPreference(getString(R.string.preference_notification_sound_key)).isVisible = false
+      findPreference(getString(R.string.preference_notification_vibration_key)).isVisible = false
+      findPreference(getString(R.string.preference_notification_light_key)).isVisible = false
+    } else {
+      findPreference(getString(R.string.preference_notification_configure_key)).isVisible = true
+    }
   }
 
   override fun onStart() {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashActivity.kt
index 3b2a8c091f70085ad39126a7dc0d79b681abff3f..bdf688447a50ae9ae556b5e0168391009b9853de 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.clientsettings.crash
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.SettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.SettingsActivity
 
 class CrashActivity : SettingsActivity(CrashFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseActivity.kt
index 92c824397139fa8b33757db5bd621af80cc2a843..d5abe2bf18f70d83ac4c669058eaab38a5faa69e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseActivity.kt
@@ -22,7 +22,7 @@ package de.kuschku.quasseldroid.ui.clientsettings.license
 import android.content.Context
 import android.content.Intent
 import android.support.annotation.StringRes
-import de.kuschku.quasseldroid.util.ui.SettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.SettingsActivity
 
 class LicenseActivity : SettingsActivity(LicenseFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistActivity.kt
index 72b518c734bf12910de792a438554e2a4a625406..ef04ba854f84900272091963f91116b09d3ba4e1 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.clientsettings.whitelist
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.SettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.SettingsActivity
 
 class WhitelistActivity : SettingsActivity(WhitelistFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsActivity.kt
index 72ae138eb09151d246297f766c6700b7361db525..ea7b38c96e24570554ef601069951a9fe4299405 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class CoreSettingsActivity : ServiceBoundSettingsActivity(CoreSettingsFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemActivity.kt
index ee3c1266677d8dccc96217400fdf850a6b790498..f80f3e8179a52a8052d597511124bf6a04a9c9ed 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemActivity.kt
@@ -22,7 +22,7 @@ package de.kuschku.quasseldroid.ui.coresettings.aliasitem
 import android.content.Context
 import android.content.Intent
 import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class AliasItemActivity : ServiceBoundSettingsActivity(AliasItemFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListActivity.kt
index 8f4b3e189080c7e3b5574b16a4f7771bbfabd7ab..45ed0299bcd05d2aedc2df7c58544e42813a8803 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings.aliaslist
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class AliasListActivity : ServiceBoundSettingsActivity(AliasListFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateActivity.kt
index 7abe8b46581d9df26a8b535723929b142735f2dd..314cd5a27fbdbfe67e276ab8ca6a11cb43646c7d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings.chatlist
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class ChatlistCreateActivity : ServiceBoundSettingsActivity(ChatListCreateFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditActivity.kt
index 36f2235b06615733ae1d930d7d1cc772b9048020..7a7039a8e3870288f83b4660399e6a8a86f8b12a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings.chatlist
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class ChatlistEditActivity : ServiceBoundSettingsActivity(ChatListEditFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListActivity.kt
index 94f6766b62e310e55d3115a044a7e2ae6d591e59..50c19866e8ca69b351263571c327020f2719f38b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings.highlightlist
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class HighlightListActivity : ServiceBoundSettingsActivity(HighlightListFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleActivity.kt
index f0d0bcd4ca363670af631531f0c3ab463bfea5d4..685695801cba3273f2f4fb7dcb48cbcdfdf349dd 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleActivity.kt
@@ -22,7 +22,7 @@ package de.kuschku.quasseldroid.ui.coresettings.highlightrule
 import android.content.Context
 import android.content.Intent
 import de.kuschku.libquassel.quassel.syncables.HighlightRuleManager
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class HighlightRuleActivity : ServiceBoundSettingsActivity(HighlightRuleFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateActivity.kt
index b27b7b8a1d68a2a807358a753373ce120d184e73..91c3210b635b5245eb86970001fdac271c0eb325 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings.identity
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class IdentityCreateActivity : ServiceBoundSettingsActivity(IdentityCreateFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditActivity.kt
index 5e04202967dcb78de152f23f13e1c51374265de2..e89980db1a55866fb9af16bbf2d9a6e65235144d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditActivity.kt
@@ -22,7 +22,7 @@ package de.kuschku.quasseldroid.ui.coresettings.identity
 import android.content.Context
 import android.content.Intent
 import de.kuschku.libquassel.protocol.IdentityId
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class IdentityEditActivity : ServiceBoundSettingsActivity(IdentityEditFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemActivity.kt
index d41612372e7f149ab979cf3c803172c8cd0480f0..e01e29df36ed435402e25d40dcb8b793da087497 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemActivity.kt
@@ -22,7 +22,7 @@ package de.kuschku.quasseldroid.ui.coresettings.ignoreitem
 import android.content.Context
 import android.content.Intent
 import de.kuschku.libquassel.quassel.syncables.IgnoreListManager
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class IgnoreItemActivity : ServiceBoundSettingsActivity(IgnoreItemFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListActivity.kt
index fb0a6b1579c58821d88e308a3486cc73793391f0..0ed928a8d871993aa38db00b9a17201cf7a80ec9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings.ignorelist
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class IgnoreListActivity : ServiceBoundSettingsActivity(IgnoreListFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkCreateActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkCreateActivity.kt
index 6e067129ae041c8b8926b0f9a800121109b0054a..790fddc7cd769f2fcc0ff4d26a14c23643fb03bf 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkCreateActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkCreateActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings.network
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class NetworkCreateActivity : ServiceBoundSettingsActivity(NetworkCreateFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkEditActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkEditActivity.kt
index 6820637a53d4ef93c8becacdf5e8dbadee683fbc..7c7e7674a796672bf967478b1a933515abc6104c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkEditActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkEditActivity.kt
@@ -22,7 +22,7 @@ package de.kuschku.quasseldroid.ui.coresettings.network
 import android.content.Context
 import android.content.Intent
 import de.kuschku.libquassel.protocol.NetworkId
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class NetworkEditActivity : ServiceBoundSettingsActivity(NetworkEditFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigActivity.kt
index 841e714bdb838b7c53038127ffc78c9dcabcf25f..78b116ec2d41711200eb6bdc44191efd7cda2c33 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigActivity.kt
@@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.coresettings.networkconfig
 
 import android.content.Context
 import android.content.Intent
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class NetworkConfigActivity : ServiceBoundSettingsActivity(NetworkConfigFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/NetworkServerActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/NetworkServerActivity.kt
index ba017085f7f5d8cb047cb8b070a4b7bee6f36b8c..b1baf1f671ab3e5ef852cbb6513e5a063b21bb09 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/NetworkServerActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/NetworkServerActivity.kt
@@ -22,7 +22,7 @@ package de.kuschku.quasseldroid.ui.coresettings.networkserver
 import android.content.Context
 import android.content.Intent
 import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork
-import de.kuschku.quasseldroid.util.ui.ServiceBoundSettingsActivity
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class NetworkServerActivity : ServiceBoundSettingsActivity(NetworkServerFragment()) {
   companion object {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/helper/PreferenceHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/helper/PreferenceHelper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..47a10d6dc5e019cd4bbfff68668b67326d59fe1d
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/helper/PreferenceHelper.kt
@@ -0,0 +1,26 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2018 Janne Koschinski
+ * Copyright (c) 2018 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.helper
+
+import android.support.v7.preference.PreferenceCategory
+import android.support.v7.preference.PreferenceScreen
+
+fun PreferenceCategory.preferences() = (0 until preferenceCount).map(this::getPreference)
+fun PreferenceScreen.preferences() = (0 until preferenceCount).map(this::getPreference)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ActivityLauncher.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ActivityLauncher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b3f5bdf99c0496c4cdb725bffc02b8793187ced8
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ActivityLauncher.kt
@@ -0,0 +1,29 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2018 Janne Koschinski
+ * Copyright (c) 2018 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.ui.settings
+
+import android.content.Intent
+
+interface ActivityLauncher {
+  fun startActivityForResult(intent: Intent, requestCode: Int)
+  fun registerOnActivityResultListener(listener: OnActivityResultListener)
+  fun unregisterOnActivityResultListener(listener: OnActivityResultListener)
+  fun getNextRequestCode(): Int
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/AttachingPreferenceFragmentCompat.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/AttachingPreferenceFragmentCompat.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b89e220da433d71b1c0b80b48dbb95d10137834b
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/AttachingPreferenceFragmentCompat.kt
@@ -0,0 +1,64 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2018 Janne Koschinski
+ * Copyright (c) 2018 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.ui.settings
+
+import android.content.Intent
+import android.os.Bundle
+import android.support.v7.preference.Preference
+import android.support.v7.preference.PreferenceCategory
+import android.support.v7.preference.PreferenceFragmentCompat
+import android.support.v7.preference.PreferenceScreen
+import de.kuschku.quasseldroid.util.helper.preferences
+import java.util.concurrent.atomic.AtomicInteger
+
+abstract class AttachingPreferenceFragmentCompat : PreferenceFragmentCompat(), ActivityLauncher {
+  private val nextRequestCode = AtomicInteger(0)
+
+  private var activityResultListeners = emptySet<OnActivityResultListener>()
+
+  override fun registerOnActivityResultListener(listener: OnActivityResultListener) {
+    activityResultListeners += listener
+  }
+
+  override fun unregisterOnActivityResultListener(listener: OnActivityResultListener) {
+    activityResultListeners -= listener
+  }
+
+  override fun getNextRequestCode() = nextRequestCode.getAndIncrement()
+
+  override fun onCreate(savedInstanceState: Bundle?) {
+    super.onCreate(savedInstanceState)
+    attachPreference(preferenceScreen)
+  }
+
+  private fun attachPreference(preference: Preference) {
+    when (preference) {
+      is PreferenceScreen         -> preference.preferences().forEach(::attachPreference)
+      is PreferenceCategory       -> preference.preferences().forEach(::attachPreference)
+      is RequiresActivityLauncher -> preference.activityLauncher = this
+    }
+  }
+
+  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+    for (it in activityResultListeners) {
+      it.onActivityResult(requestCode, resultCode, data)
+    }
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerPreferenceFragmentCompat.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/DaggerPreferenceFragmentCompat.kt
similarity index 88%
rename from app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerPreferenceFragmentCompat.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/DaggerPreferenceFragmentCompat.kt
index 49e81c0eabadd00769bbcfd30ea4089448ade8bd..aa7cb669867bcec6a4192177fe0312a1e7105325 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerPreferenceFragmentCompat.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/DaggerPreferenceFragmentCompat.kt
@@ -17,18 +17,17 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.backport
+package de.kuschku.quasseldroid.util.ui.settings
 
 import android.content.Context
 import android.support.v4.app.Fragment
-import android.support.v7.preference.PreferenceFragmentCompat
 import dagger.android.AndroidInjector
 import dagger.android.DispatchingAndroidInjector
 import dagger.android.support.AndroidSupportInjection
 import dagger.android.support.HasSupportFragmentInjector
 import javax.inject.Inject
 
-abstract class DaggerPreferenceFragmentCompat : PreferenceFragmentCompat(),
+abstract class DaggerPreferenceFragmentCompat : AttachingPreferenceFragmentCompat(),
                                                 HasSupportFragmentInjector {
   @Inject
   lateinit var childFragmentInjector: DispatchingAndroidInjector<Fragment>
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/OnActivityResultListener.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/OnActivityResultListener.kt
new file mode 100644
index 0000000000000000000000000000000000000000..160631e7e458f519fc82fd3da975258b85dcbd88
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/OnActivityResultListener.kt
@@ -0,0 +1,32 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2018 Janne Koschinski
+ * Copyright (c) 2018 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.ui.settings
+
+import android.content.Intent
+
+interface OnActivityResultListener {
+  /**
+   * See Activity's onActivityResult.
+   *
+   * @return Whether the request code was handled (in which case
+   * subsequent listeners will not be called.
+   */
+  fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RequiresActivityLauncher.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RequiresActivityLauncher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..13c33568ecea3961c1654cbe4301e02539f2101e
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RequiresActivityLauncher.kt
@@ -0,0 +1,24 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2018 Janne Koschinski
+ * Copyright (c) 2018 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.ui.settings
+
+interface RequiresActivityLauncher {
+  var activityLauncher: ActivityLauncher?
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RingtonePreference.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RingtonePreference.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e87f33555ff0cbfbc00b3a208f7a22a5714da03f
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RingtonePreference.kt
@@ -0,0 +1,226 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2018 Janne Koschinski
+ * Copyright (c) 2018 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.ui.settings
+
+import android.content.Context
+import android.content.Intent
+import android.content.res.TypedArray
+import android.media.RingtoneManager
+import android.net.Uri
+import android.support.v7.preference.DialogPreference
+import android.text.TextUtils
+import android.util.AttributeSet
+import de.kuschku.quasseldroid.R
+
+class RingtonePreference : DialogPreference,
+                           RequiresActivityLauncher,
+                           OnActivityResultListener {
+  private val TAG = "RingtonePreference"
+
+  private var mRingtoneType: Int = 0
+  private var mShowDefault: Boolean = false
+  private var mShowSilent: Boolean = false
+
+  private var mRequestCode: Int? = null
+
+  override var activityLauncher: ActivityLauncher? = null
+    set(value) {
+      field?.unregisterOnActivityResultListener(this)
+
+      field = value
+
+      value?.registerOnActivityResultListener(this)
+      mRequestCode = value?.getNextRequestCode()
+    }
+
+  constructor(context: Context) :
+    this(context, null)
+
+  constructor(context: Context, attrs: AttributeSet?) :
+    this(context, attrs, R.attr.ringtonePreferenceStyle)
+
+  constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
+    this(context, attrs, defStyleAttr, 0)
+
+  constructor(context: Context, attrs: AttributeSet?, styleAttr: Int, styleRes: Int) :
+    super(context, attrs, styleAttr, styleRes) {
+    val a = context.obtainStyledAttributes(
+      attrs, R.styleable.RingtonePreference, styleAttr, styleRes)
+    mRingtoneType = a.getInt(R.styleable.RingtonePreference_ringtoneType,
+                             RingtoneManager.TYPE_RINGTONE)
+    mShowDefault = a.getBoolean(R.styleable.RingtonePreference_showDefault, true)
+    mShowSilent = a.getBoolean(R.styleable.RingtonePreference_showSilent, true)
+    a.recycle()
+  }
+
+  /**
+   * Returns the sound type(s) that are shown in the picker.
+   *
+   * @return The sound type(s) that are shown in the picker.
+   * @see .setRingtoneType
+   */
+  fun getRingtoneType(): Int {
+    return mRingtoneType
+  }
+
+  /**
+   * Sets the sound type(s) that are shown in the picker.
+   *
+   * @param type The sound type(s) that are shown in the picker.
+   * @see RingtoneManager.EXTRA_RINGTONE_TYPE
+   */
+  fun setRingtoneType(type: Int) {
+    mRingtoneType = type
+  }
+
+  /**
+   * Returns whether to a show an item for the default sound/ringtone.
+   *
+   * @return Whether to show an item for the default sound/ringtone.
+   */
+  fun getShowDefault(): Boolean {
+    return mShowDefault
+  }
+
+  /**
+   * Sets whether to show an item for the default sound/ringtone. The default
+   * to use will be deduced from the sound type(s) being shown.
+   *
+   * @param showDefault Whether to show the default or not.
+   * @see RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT
+   */
+  fun setShowDefault(showDefault: Boolean) {
+    mShowDefault = showDefault
+  }
+
+  /**
+   * Returns whether to a show an item for 'Silent'.
+   *
+   * @return Whether to show an item for 'Silent'.
+   */
+  fun getShowSilent(): Boolean {
+    return mShowSilent
+  }
+
+  /**
+   * Sets whether to show an item for 'Silent'.
+   *
+   * @param showSilent Whether to show 'Silent'.
+   * @see RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT
+   */
+  fun setShowSilent(showSilent: Boolean) {
+    mShowSilent = showSilent
+  }
+
+  override fun onClick() {
+    // Launch the ringtone picker
+    val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
+    onPrepareRingtonePickerIntent(intent)
+    mRequestCode?.let {
+      activityLauncher?.startActivityForResult(intent, it)
+    }
+  }
+
+  /**
+   * Prepares the intent to launch the ringtone picker. This can be modified
+   * to adjust the parameters of the ringtone picker.
+   *
+   * @param ringtonePickerIntent The ringtone picker intent that can be
+   * modified by putting extras.
+   */
+  protected fun onPrepareRingtonePickerIntent(ringtonePickerIntent: Intent) {
+
+    ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, mShowDefault)
+    ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, mShowSilent)
+    ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, mRingtoneType)
+    ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, title)
+    if (mShowDefault) {
+      ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI,
+                                    RingtoneManager.getDefaultUri(getRingtoneType()))
+    }
+    ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, onRestoreRingtone())
+  }
+
+  /**
+   * Called when a ringtone is chosen.
+   *
+   *
+   * By default, this saves the ringtone URI to the persistent storage as a
+   * string.
+   *
+   * @param ringtoneUri The chosen ringtone's [Uri]. Can be null.
+   */
+  protected fun onSaveRingtone(ringtoneUri: Uri?) {
+    persistString(ringtoneUri?.toString() ?: "")
+    updateSummary(ringtoneUri)
+  }
+
+  /**
+   * Called when the chooser is about to be shown and the current ringtone
+   * should be marked. Can return null to not mark any ringtone.
+   *
+   *
+   * By default, this restores the previous ringtone URI from the persistent
+   * storage.
+   *
+   * @return The ringtone to be marked as the current ringtone.
+   */
+  protected fun onRestoreRingtone(): Uri? {
+    val uriString = getPersistedString(null)
+    return if (!TextUtils.isEmpty(uriString)) Uri.parse(uriString) else null
+  }
+
+  private fun updateSummary(ringtoneUri: Uri?) {
+    summary = ringtoneUri?.let {
+      RingtoneManager.getRingtone(context, ringtoneUri).getTitle(context)
+    } ?: context.getString(R.string.label_no_sound)
+  }
+
+  override fun onGetDefaultValue(a: TypedArray, index: Int): Any? {
+    return a.getString(index)
+  }
+
+  override fun onSetInitialValue(restorePersistedValue: Boolean, defaultValueObj: Any?) {
+    val defaultValue = defaultValueObj as? String ?: ""
+
+    if (restorePersistedValue) {
+      updateSummary(onRestoreRingtone())
+      return
+    }
+
+    // If we are setting to the default value, we should persist it.
+    if (!TextUtils.isEmpty(defaultValue)) {
+      onSaveRingtone(Uri.parse(defaultValue))
+    }
+  }
+
+  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
+    if (requestCode == mRequestCode) {
+      if (data != null) {
+        val uri = data.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
+        if (callChangeListener(uri?.toString() ?: "")) {
+          onSaveRingtone(uri)
+        }
+      }
+      return true
+    }
+    return false
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/SeekBarPreference.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
similarity index 99%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/SeekBarPreference.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
index 35bc50d535e0485c2f38190c5c5c0153cdd709a0..fa862ca4bcaf7e7a5f5a80ab6e5717c0fc851023 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/SeekBarPreference.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.settings
 
 import android.content.Context
 import android.content.res.TypedArray
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ServiceBoundSettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ServiceBoundSettingsActivity.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/ServiceBoundSettingsActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ServiceBoundSettingsActivity.kt
index f9e369950522878cbb86f9352a8b0f5aa4588a3f..27dbb9cd8f6564f274111d9b982c52e0909582ed 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ServiceBoundSettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ServiceBoundSettingsActivity.kt
@@ -17,7 +17,7 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.settings
 
 import android.os.Bundle
 import android.support.v4.app.Fragment
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SettingsActivity.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SettingsActivity.kt
index ea6df6328ed24286933c7329f1e3f593bcaa9479..750f21d23633cb102e894b424137f67b0566f693 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SettingsActivity.kt
@@ -17,7 +17,7 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.settings
 
 import android.os.Bundle
 import android.support.v4.app.Fragment
@@ -28,6 +28,7 @@ import butterknife.ButterKnife
 import com.afollestad.materialdialogs.MaterialDialog
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
+import de.kuschku.quasseldroid.util.ui.ThemedActivity
 
 abstract class SettingsActivity(private val fragment: Fragment? = null) : ThemedActivity() {
   protected open fun fragment(): Fragment? = null
diff --git a/app/src/main/res/layout/widget_preference_divider.xml b/app/src/main/res/layout/widget_preference_divider.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6845448044d27896588a2a78c375162240bfcd92
--- /dev/null
+++ b/app/src/main/res/layout/widget_preference_divider.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Quasseldroid - Quassel client for Android
+
+  Copyright (c) 2018 Janne Koschinski
+  Copyright (c) 2018 The Quassel Project
+
+  This program is free software: you can redistribute it and/or modify it
+  under the terms of the GNU General Public License version 3 as published
+  by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program.  If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+  android:layout_width="match_parent"
+  android:layout_height="1dp"
+  android:background="?colorDivider" />
diff --git a/app/src/main/res/layout/widget_spinner_item_inline.xml b/app/src/main/res/layout/widget_spinner_item_inline.xml
index e3102b3fd59796b5768f233e84553e6420c9d606..d109243dc90a70385ae87bdca6f8b975dba1ba35 100644
--- a/app/src/main/res/layout/widget_spinner_item_inline.xml
+++ b/app/src/main/res/layout/widget_spinner_item_inline.xml
@@ -25,7 +25,6 @@
   android:layout_height="wrap_content"
   android:gravity="center_vertical"
   android:minHeight="?listPreferredItemHeightSmall"
-  android:background="?background"
   android:paddingLeft="16dp"
   android:paddingRight="16dp"
   android:textAppearance="?android:attr/textAppearanceListItemSmall"
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 9da3b2a0aab3190a0e09754b2779b2bd6425d91a..db5a7effe65f9f40638804c282e5f9b6343e1e11 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -73,6 +73,7 @@
   <string name="label_nicklist">Benutzerliste</string>
   <string name="label_no">Nein</string>
   <string name="label_no_away_message">Kein Abwesenheitsgrund verfügbar</string>
+  <string name="label_no_sound">Ohne</string>
   <string name="label_reply">Antworten</string>
   <string name="label_reset">Zurücksetzen</string>
   <string name="label_open">Öffnen</string>
diff --git a/app/src/main/res/values-de/strings_preferences.xml b/app/src/main/res/values-de/strings_preferences.xml
index 1e3e0f078d7653f749ac10b43ffee54e1e9d5c60..695a0055193f62a576b278f5c16468fef4bc8819 100644
--- a/app/src/main/res/values-de/strings_preferences.xml
+++ b/app/src/main/res/values-de/strings_preferences.xml
@@ -46,8 +46,19 @@
   <string name="preference_notifications_title">Benachrichtigungen</string>
 
   <string name="preference_notification_query_title">Direktnachrichten</string>
+
   <string name="preference_notification_channel_title">Räume</string>
+
   <string name="preference_notification_other_title">Andere Nachrichten</string>
+
+  <string name="preference_notification_sound_title">Benachrichtigungston</string>
+
+  <string name="preference_notification_vibration_title">Vibration</string>
+
+  <string name="preference_notification_light_title">LED</string>
+
+  <string name="preference_notification_configure_title">Benachrichtigungen konfigurieren</string>
+
   <string name="preference_notifications_level_all">Alle Nachrichten</string>
   <string name="preference_notifications_level_highlight">Erwähnungen</string>
   <string name="preference_notifications_level_none">Niemals</string>
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index 84c05075ce3ef05fd71544a086597ad3ff06eed0..fe41efcb53e3c7d3e1318619a6efadce8bf50aa0 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -73,6 +73,7 @@
   <string name="label_nicklist">Slapyvardžių Sąrašas</string>
   <string name="label_no">Ne</string>
   <string name="label_no_away_message">Nėra pasišalinimo žinutės</string>
+  <string name="label_no_sound">Nėra</string>
   <string name="label_reply">Atsakyti</string>
   <string name="label_reset">Atstatyti</string>
   <string name="label_open">Atverti</string>
diff --git a/app/src/main/res/values-lt/strings_preferences.xml b/app/src/main/res/values-lt/strings_preferences.xml
index bd176ba2c6f8202ef490cfdcfb885336c7111a13..3e6e05abe116d0d7589f77d74635f82f979ff324 100644
--- a/app/src/main/res/values-lt/strings_preferences.xml
+++ b/app/src/main/res/values-lt/strings_preferences.xml
@@ -51,6 +51,12 @@
 
   <string name="preference_notification_other_title">Kitos žinutės</string>
 
+  <string name="preference_notification_sound_title">Pranešimo garsas</string>
+  <string name="preference_notification_vibration_title">Vibracija</string>
+  <string name="preference_notification_light_title">LED Lemputė</string>
+
+  <string name="preference_notification_configure_title">Pranešimų nustatymai</string>
+
   <string name="preference_notifications_level_all">Visos žinutės</string>
   <string name="preference_notifications_level_highlight">Paminėjimai</string>
   <string name="preference_notifications_level_none">Niekada</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c2734d5e607284d5f54dc0520aafa4a3ec3ccaf8..cc111438fb1403bea85a1f315a8c423e290c2f54 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -22,6 +22,8 @@
   <string name="app_description">An Android-based client for the decentralized Quassel IRC client.</string>
   <string name="app_description_long">Quassel is a distributed, decentralized IRC client, written using C++ and Qt. Quasseldroid is a pure-kotlin client for the Quassel core, allowing you to connect to your Quassel core using your Android™ phone.</string>
 
+  <string name="package_name">com.iskrembilen.quasseldroid</string>
+
   <string name="connection_service_title">Connection Service</string>
   <string name="connection_service_description">Keeps a connection to your core to allow for notifications, and to transmit messages.</string>
 
@@ -73,6 +75,7 @@
   <string name="label_nicklist">Nick List</string>
   <string name="label_no">No</string>
   <string name="label_no_away_message">No away message available</string>
+  <string name="label_no_sound">None</string>
   <string name="label_reply">Reply</string>
   <string name="label_reset">Reset</string>
   <string name="label_open">Open</string>
diff --git a/app/src/main/res/values/strings_preferences.xml b/app/src/main/res/values/strings_preferences.xml
index 896a78e8c97a359fba3d04286ee52429f4965aed..781f1b2be86acb6b630af66334e9c1edcf7bc6fe 100644
--- a/app/src/main/res/values/strings_preferences.xml
+++ b/app/src/main/res/values/strings_preferences.xml
@@ -105,6 +105,18 @@
   <string name="preference_notification_other_key" translatable="false">notification_other</string>
   <string name="preference_notification_other_title">Other Messages</string>
 
+  <string name="preference_notification_sound_key" translatable="false">notification_sound</string>
+  <string name="preference_notification_sound_title">Notification Sound</string>
+
+  <string name="preference_notification_vibration_key" translatable="false">notification_vibration</string>
+  <string name="preference_notification_vibration_title">Vibration</string>
+
+  <string name="preference_notification_light_key" translatable="false">notification_light</string>
+  <string name="preference_notification_light_title">LED</string>
+
+  <string name="preference_notification_configure_key" translatable="false">notification_configure</string>
+  <string name="preference_notification_configure_title">Configure Notifications</string>
+
   <string name="preference_notifications_level_all">All Messages</string>
   <string name="preference_notifications_level_highlight">Mentions</string>
   <string name="preference_notifications_level_none">Never</string>
diff --git a/app/src/main/res/values/styles_widgets.xml b/app/src/main/res/values/styles_widgets.xml
index 202296289048a85b49652435c4cb6f1c1ae0cd0b..10bbddc83828f5366c317ae9852ee93c1aa22bc5 100644
--- a/app/src/main/res/values/styles_widgets.xml
+++ b/app/src/main/res/values/styles_widgets.xml
@@ -104,6 +104,7 @@
     <item name="android:layout_height">wrap_content</item>
     <item name="android:paddingLeft">0dip</item>
     <item name="android:paddingRight">0dip</item>
+    <item name="android:popupBackground">?colorBackground</item>
   </style>
 
   <style name="Widget.CoreSettings.Wrapper" parent="">
@@ -263,6 +264,14 @@
     <item name="android:textColor">?colorTextSecondary</item>
   </style>
 
+  <style name="Widget.RingtonePreference" parent="">
+    <item name="android:layout">@layout/preference_vertical</item>
+
+    <item name="ringtoneType">ringtone</item>
+    <item name="showSilent">true</item>
+    <item name="showDefault">true</item>
+  </style>
+
   <style name="Widget.Subhead" parent="Widget.RtlConformTextView">
     <item name="android:layout_width">wrap_content</item>
     <item name="android:layout_height">wrap_content</item>
@@ -297,4 +306,23 @@
   <declare-styleable name="ShadowView">
     <attr name="android:gravity" />
   </declare-styleable>
+
+  <!-- RingtonePreference -->
+  <declare-styleable name="RingtonePreference">
+    <!-- Which ringtone type(s) to show in the picker. -->
+    <attr name="ringtoneType">
+      <!-- Ringtones. -->
+      <flag name="ringtone" value="1" />
+      <!-- Notification sounds. -->
+      <flag name="notification" value="2" />
+      <!-- Alarm sounds. -->
+      <flag name="alarm" value="4" />
+      <!-- All available ringtone sounds. -->
+      <flag name="all" value="7" />
+    </attr>
+    <!-- Whether to show an item for a default sound. -->
+    <attr name="showDefault" format="boolean" />
+    <!-- Whether to show an item for 'Silent'. -->
+    <attr name="showSilent" format="boolean" />
+  </declare-styleable>
 </resources>
diff --git a/app/src/main/res/values/themes_base.xml b/app/src/main/res/values/themes_base.xml
index 6ffe915e9641fbe7599e9be838e14a9a39e535bd..90022aeff8eae64bebb6afde73b46dd03c80fa10 100644
--- a/app/src/main/res/values/themes_base.xml
+++ b/app/src/main/res/values/themes_base.xml
@@ -72,6 +72,8 @@
     <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
     <item name="actionBarPopupTheme">@style/Widget.PopupOverlay</item>
 
+    <item name="ringtonePreferenceStyle">@style/Widget.RingtonePreference</item>
+
     <item name="backgroundMenuItem">@drawable/bg_menuitem_dark</item>
     <item name="backgroundMenuItemRounded">@drawable/bg_menuitem_rounded_dark</item>
 
@@ -106,6 +108,8 @@
     <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
     <item name="actionBarPopupTheme">@style/Widget.PopupOverlay.Light</item>
 
+    <item name="ringtonePreferenceStyle">@style/Widget.RingtonePreference</item>
+
     <item name="backgroundMenuItem">@drawable/bg_menuitem_light</item>
     <item name="backgroundMenuItemRounded">@drawable/bg_menuitem_rounded_light</item>
 
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 08bcb2591c2d59340214fd54ee2115ee598f17ea..ae83ca1528c9d495902f24dd66d47a2b52bc4981 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -18,6 +18,7 @@
   -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:robobunny="http://robobunny.com">
   <PreferenceCategory android:title="@string/preference_appearance_title">
     <ListPreference
@@ -48,6 +49,8 @@
       android:title="@string/preference_language_title" />
   </PreferenceCategory>
 
+  <PreferenceCategory android:layout="@layout/widget_preference_divider" />
+
   <PreferenceCategory android:title="@string/preference_notifications_title">
     <DropDownPreference
       android:defaultValue="ALL"
@@ -67,9 +70,41 @@
       android:entryValues="@array/preference_notifications_level_entryvalues"
       android:key="@string/preference_notification_other_key"
       android:title="@string/preference_notification_other_title" />
-    <!-- TODO: Add Notification ringtone/etc setting links -->
+
+    <de.kuschku.quasseldroid.util.ui.settings.RingtonePreference
+      android:defaultValue="content://settings/system/notification_sound"
+      android:key="@string/preference_notification_sound_key"
+      android:title="@string/preference_notification_sound_title"
+      app:ringtoneType="notification"
+      app:showDefault="true"
+      app:showSilent="true" />
+
+    <SwitchPreference
+      android:defaultValue="true"
+      android:key="@string/preference_notification_vibration_key"
+      android:title="@string/preference_notification_vibration_title" />
+
+    <SwitchPreference
+      android:defaultValue="true"
+      android:key="@string/preference_notification_light_key"
+      android:title="@string/preference_notification_light_title" />
+
+    <PreferenceScreen
+      android:key="@string/preference_notification_configure_key"
+      android:title="@string/preference_notification_configure_title">
+      <intent android:action="android.settings.CHANNEL_NOTIFICATION_SETTINGS">
+        <extra
+          android:name="android.provider.extra.APP_PACKAGE"
+          android:value="@string/package_name" />
+        <extra
+          android:name="android.provider.extra.CHANNEL_ID"
+          android:value="@string/notification_channel_highlight" />
+      </intent>
+    </PreferenceScreen>
   </PreferenceCategory>
 
+  <PreferenceCategory android:layout="@layout/widget_preference_divider" />
+
   <PreferenceCategory android:title="@string/preference_messages_title">
 
     <SwitchPreference
@@ -77,7 +112,7 @@
       android:key="@string/preference_monospace_key"
       android:title="@string/preference_monospace_title" />
 
-    <de.kuschku.quasseldroid.util.ui.SeekBarPreference
+    <de.kuschku.quasseldroid.util.ui.settings.SeekBarPreference
       android:defaultValue="14"
       android:key="@string/preference_textsize_key"
       android:max="24"
@@ -171,6 +206,8 @@
     -->
   </PreferenceCategory>
 
+  <PreferenceCategory android:layout="@layout/widget_preference_divider" />
+
   <PreferenceCategory android:title="@string/preference_autocomplete_title">
 
     <SwitchPreference
@@ -204,6 +241,8 @@
       android:title="@string/preference_autocomplete_prefix_title" />
   </PreferenceCategory>
 
+  <PreferenceCategory android:layout="@layout/widget_preference_divider" />
+
   <PreferenceCategory android:title="@string/preference_backlog_title">
     <EditTextPreference
       android:defaultValue="150"
@@ -219,6 +258,8 @@
       android:title="@string/preference_initial_amount_title" />
   </PreferenceCategory>
 
+  <PreferenceCategory android:layout="@layout/widget_preference_divider" />
+
   <PreferenceCategory android:title="@string/preference_connection_title">
     <SwitchPreference
       android:defaultValue="true"