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

Show actions in notification and allow disconnecting from notification

parent 00f740a3
No related branches found
No related tags found
No related merge requests found
......@@ -16,6 +16,7 @@
android:name=".ui.chat.ChatActivity"
android:exported="false"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.setup.accounts.AccountSetupActivity"
......@@ -33,7 +34,7 @@
android:name=".ui.settings.SettingsActivity"
android:exported="false"
android:label="@string/label_settings"
android:parentActivityName=".ui.chat.ChatActivity"
android:parentActivityName=".ui.setup.accounts.AccountSelectionActivity"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.setup.accounts.AccountSelectionActivity"
......
......@@ -17,8 +17,9 @@ 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.NotificationManager
import de.kuschku.quasseldroid_ng.util.QuasseldroidNotificationManager
import de.kuschku.quasseldroid_ng.util.compatibility.AndroidHandlerService
import de.kuschku.quasseldroid_ng.util.helper.editApply
import de.kuschku.quasseldroid_ng.util.helper.sharedPreferences
import de.kuschku.quasseldroid_ng.util.helper.toLiveData
import io.reactivex.Observable
......@@ -60,8 +61,8 @@ class QuasselService : LifecycleService(),
private var accountId: Long = -1
private var reconnect: Boolean = false
private lateinit var notificationManager: NotificationManager
private var notificationHandle: NotificationManager.Handle? = null
private lateinit var notificationManager: QuasseldroidNotificationManager
private var notificationHandle: QuasseldroidNotificationManager.Handle? = null
private var progress = Triple(ConnectionState.DISCONNECTED, 0, 0)
private fun updateNotificationStatus() {
......@@ -75,7 +76,23 @@ class QuasselService : LifecycleService(),
}
}
private fun updateNotification(handle: NotificationManager.Handle) {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val result = super.onStartCommand(intent, flags, startId)
handleIntent(intent)
return result
}
private fun handleIntent(intent: Intent?) {
if (intent?.getBooleanExtra("disconnect", false) == true) {
sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) {
editApply {
putBoolean(Keys.Status.reconnect, false)
}
}
}
}
private fun updateNotification(handle: QuasseldroidNotificationManager.Handle) {
val (state, progress, max) = this.progress
when (state) {
ConnectionState.DISCONNECTED -> {
......@@ -103,10 +120,10 @@ class QuasselService : LifecycleService(),
private fun updateConnection(accountId: Long, reconnect: Boolean) {
handler.post {
val account = if (accountId == -1L || !reconnect) {
null
} else {
val account = if (accountId != -1L && reconnect) {
AccountDatabase.Creator.init(this).accounts().findById(accountId)
} else {
null
}
if (account == null) {
......@@ -192,17 +209,13 @@ class QuasselService : LifecycleService(),
override fun disconnect(forever: Boolean) {
handler.post {
backendImplementation.disconnect(forever)
if (forever)
if (forever) {
stopSelf()
}
}
override fun sessionManager() = backendImplementation.sessionManager()
}
override fun onDestroy() {
handler.onDestroy()
super.onDestroy()
override fun sessionManager() = backendImplementation.sessionManager()
}
private lateinit var database: QuasselDatabase
......@@ -263,12 +276,28 @@ class QuasselService : LifecycleService(),
registerReceiver(receiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
notificationManager = NotificationManager(this)
notificationManager = QuasseldroidNotificationManager(this)
notificationManager.init()
update()
}
override fun onDestroy() {
sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) {
unregisterOnSharedPreferenceChangeListener(this@QuasselService)
}
sharedPreferences {
unregisterOnSharedPreferenceChangeListener(this@QuasselService)
}
unregisterReceiver(receiver)
notificationHandle?.let { notificationManager.remove(it) }
handler.onDestroy()
super.onDestroy()
}
override fun onBind(intent: Intent?): QuasselBinder {
super.onBind(intent)
return QuasselBinder(asyncBackend)
......
......@@ -5,7 +5,10 @@ import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.os.PersistableBundle
import android.support.design.widget.Snackbar
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.ActionBarDrawerToggle
......@@ -38,7 +41,7 @@ import de.kuschku.quasseldroid_ng.util.helper.sharedPreferences
import de.kuschku.quasseldroid_ng.util.service.ServiceBoundActivity
import de.kuschku.quasseldroid_ng.util.ui.MaterialContentLoadingProgressBar
class ChatActivity : ServiceBoundActivity() {
class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
@BindView(R.id.drawerLayout)
lateinit var drawerLayout: DrawerLayout
......@@ -129,8 +132,8 @@ class ChatActivity : ServiceBoundActivity() {
drawerToggle = ActionBarDrawerToggle(
this,
drawerLayout,
R.string.label_drawer_open,
R.string.label_drawer_close
R.string.label_open,
R.string.label_close
)
drawerToggle.syncState()
......@@ -171,11 +174,27 @@ class ChatActivity : ServiceBoundActivity() {
outState?.putInt("OPEN_BUFFER", viewModel.getBuffer().value ?: -1)
}
override fun onSaveInstanceState(outState: Bundle?, outPersistentState: PersistableBundle?) {
super.onSaveInstanceState(outState, outPersistentState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
outPersistentState?.putInt("OPEN_BUFFER", viewModel.getBuffer().value ?: -1)
}
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
super.onRestoreInstanceState(savedInstanceState)
viewModel.setBuffer(savedInstanceState?.getInt("OPEN_BUFFER", -1) ?: -1)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?,
persistentState: PersistableBundle?) {
super.onRestoreInstanceState(savedInstanceState, persistentState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val fallback = persistentState?.getInt("OPEN_BUFFER", -1) ?: -1
viewModel.setBuffer(savedInstanceState?.getInt("OPEN_BUFFER", fallback) ?: fallback)
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.activity_main, menu)
return super.onCreateOptionsMenu(menu)
......
......@@ -10,12 +10,13 @@ import android.os.Build
import android.support.v4.app.NotificationCompat
import android.support.v4.app.NotificationManagerCompat
import de.kuschku.quasseldroid_ng.R
import de.kuschku.quasseldroid_ng.ui.setup.accounts.AccountSelectionActivity
import de.kuschku.quasseldroid_ng.service.QuasselService
import de.kuschku.quasseldroid_ng.ui.chat.ChatActivity
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) {
class QuasseldroidNotificationManager(private val context: Context) {
fun init() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
prepareChannels()
......@@ -50,16 +51,23 @@ class NotificationManager(private val context: Context) {
}
fun notificationBackground(): Handle {
val intentOpen = Intent(context.applicationContext, ChatActivity::class.java)
intentOpen.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
val pendingIntentOpen = PendingIntent.getActivity(context.applicationContext, 0, intentOpen, 0)
val intentDisconnect = Intent(context, QuasselService::class.java)
intentDisconnect.putExtra("disconnect", true)
val pendingIntentDisconnect = PendingIntent.getService(
context, 0, intentDisconnect, PendingIntent.FLAG_UPDATE_CURRENT
)
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
)
)
.setContentIntent(pendingIntentOpen)
.addAction(0, context.getString(R.string.label_open), pendingIntentOpen)
.addAction(0, context.getString(R.string.label_disconnect), pendingIntentDisconnect)
.setSmallIcon(R.mipmap.ic_launcher_recents)
.setPriority(NotificationCompat.PRIORITY_MIN)
return Handle(BACKGROUND_NOTIFICATION_ID, notification)
......@@ -69,6 +77,10 @@ class NotificationManager(private val context: Context) {
NotificationManagerCompat.from(context).notify(handle.id, handle.builder.build())
}
fun remove(handle: Handle) {
NotificationManagerCompat.from(context).cancel(handle.id)
}
companion object {
val BACKGROUND_NOTIFICATION_ID = Int.MAX_VALUE
}
......
package de.kuschku.quasseldroid_ng.util.service
import android.app.Activity
import android.arch.lifecycle.LiveData
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.support.annotation.ColorRes
import android.support.annotation.DrawableRes
......@@ -12,9 +14,11 @@ 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.sharedPreferences
import de.kuschku.quasseldroid_ng.util.helper.updateRecentsHeaderIfExisting
abstract class ServiceBoundActivity : AppCompatActivity() {
abstract class ServiceBoundActivity : AppCompatActivity(),
SharedPreferences.OnSharedPreferenceChangeListener {
@DrawableRes
protected val icon: Int = R.mipmap.ic_launcher_recents
@ColorRes
......@@ -54,13 +58,33 @@ abstract class ServiceBoundActivity : AppCompatActivity() {
if (Settings.appearance(this) != appearanceSettings) {
recreate()
}
sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) {
registerOnSharedPreferenceChangeListener(this@ServiceBoundActivity)
}
connection.bind()
checkConnection()
super.onStart()
}
override fun onStop() {
super.onStop()
connection.unbind()
sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) {
unregisterOnSharedPreferenceChangeListener(this@ServiceBoundActivity)
}
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
checkConnection()
}
private fun checkConnection() {
if (!sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) {
getBoolean(Keys.Status.reconnect, false)
}) {
setResult(Activity.RESULT_OK)
finish()
}
}
protected fun stopService() {
......
......@@ -8,8 +8,8 @@
<string name="label_clear_backlog">Clear Backlog</string>
<string name="label_delete">Delete</string>
<string name="label_disconnect">Disconnect</string>
<string name="label_drawer_close">Close</string>
<string name="label_drawer_open">Open</string>
<string name="label_close">Close</string>
<string name="label_open">Open</string>
<string name="label_filter_messages">Filter Messages</string>
<string name="label_input_history">Input History</string>
<string name="label_placeholder">Write a message…</string>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment