Nitification store logging
This commit is contained in:
parent
a025fc8ece
commit
fe3c049999
5 changed files with 42 additions and 62 deletions
|
@ -1,6 +1,5 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.notifications
|
package info.nightscout.androidaps.plugins.general.overview.notifications
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
|
@ -11,14 +10,10 @@ import android.media.RingtoneManager
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.cardview.widget.CardView
|
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.TaskStackBuilder
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import info.nightscout.androidaps.MainActivity
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.databinding.OverviewNotificationItemBinding
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
|
@ -45,8 +40,7 @@ class NotificationStore @Inject constructor(
|
||||||
private val dateUtil: DateUtil
|
private val dateUtil: DateUtil
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var store: MutableList<Notification> = ArrayList()
|
private var store: MutableList<Notification> = ArrayList()
|
||||||
private var usesChannels = false
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@ -71,33 +65,35 @@ class NotificationStore @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
store.add(n)
|
store.add(n)
|
||||||
if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction) {
|
if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction)
|
||||||
raiseSystemNotification(n)
|
raiseSystemNotification(n)
|
||||||
if (usesChannels && n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId)
|
|
||||||
} else {
|
|
||||||
if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId)
|
if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId)
|
||||||
}
|
|
||||||
Collections.sort(store, NotificationComparator())
|
Collections.sort(store, NotificationComparator())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized fun remove(id: Int): Boolean {
|
@Synchronized
|
||||||
|
fun remove(id: Int): Boolean {
|
||||||
for (i in store.indices) {
|
for (i in store.indices) {
|
||||||
if (store[i].id == id) {
|
if (store[i].id == id) {
|
||||||
if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context)
|
if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context)
|
||||||
store.removeAt(i)
|
store.removeAt(i)
|
||||||
|
aapsLogger.debug(LTag.NOTIFICATION, "Notification removed: " + store[i].text)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized private fun removeExpired() {
|
@Synchronized
|
||||||
|
private fun removeExpired() {
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < store.size) {
|
while (i < store.size) {
|
||||||
val n = store[i]
|
val n = store[i]
|
||||||
if (n.validTo != 0L && n.validTo < System.currentTimeMillis()) {
|
if (n.validTo != 0L && n.validTo < System.currentTimeMillis()) {
|
||||||
|
if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context)
|
||||||
store.removeAt(i)
|
store.removeAt(i)
|
||||||
|
aapsLogger.debug(LTag.NOTIFICATION, "Notification expired: " + store[i].text)
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
|
@ -135,20 +131,17 @@ class NotificationStore @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createNotificationChannel() {
|
fun createNotificationChannel() {
|
||||||
usesChannels = true
|
|
||||||
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
@SuppressLint("WrongConstant") val channel = NotificationChannel(CHANNEL_ID,
|
val channel = NotificationChannel(CHANNEL_ID, CHANNEL_ID, NotificationManager.IMPORTANCE_HIGH)
|
||||||
CHANNEL_ID,
|
|
||||||
NotificationManager.IMPORTANCE_HIGH)
|
|
||||||
mNotificationManager.createNotificationChannel(channel)
|
mNotificationManager.createNotificationChannel(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun updateNotifications(notificationsView: RecyclerView) {
|
fun updateNotifications(notificationsView: RecyclerView) {
|
||||||
removeExpired()
|
removeExpired()
|
||||||
// unSnooze()
|
val clonedStore = ArrayList(store)
|
||||||
if (store.size > 0) {
|
if (clonedStore.isNotEmpty()) {
|
||||||
val adapter = NotificationRecyclerViewAdapter(cloneStore())
|
val adapter = NotificationRecyclerViewAdapter(clonedStore)
|
||||||
notificationsView.adapter = adapter
|
notificationsView.adapter = adapter
|
||||||
notificationsView.visibility = View.VISIBLE
|
notificationsView.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
|
@ -156,33 +149,24 @@ class NotificationStore @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
private fun cloneStore(): List<Notification> {
|
|
||||||
val clone: MutableList<Notification> = ArrayList(store.size)
|
|
||||||
clone.addAll(store)
|
|
||||||
return clone
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class NotificationRecyclerViewAdapter internal constructor(private val notificationsList: List<Notification>) : RecyclerView.Adapter<NotificationRecyclerViewAdapter.NotificationsViewHolder>() {
|
inner class NotificationRecyclerViewAdapter internal constructor(private val notificationsList: List<Notification>) : RecyclerView.Adapter<NotificationRecyclerViewAdapter.NotificationsViewHolder>() {
|
||||||
|
|
||||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NotificationsViewHolder {
|
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NotificationsViewHolder =
|
||||||
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.overview_notification_item, viewGroup, false)
|
NotificationsViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.overview_notification_item, viewGroup, false))
|
||||||
return NotificationsViewHolder(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: NotificationsViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: NotificationsViewHolder, position: Int) {
|
||||||
val notification = notificationsList[position]
|
val notification = notificationsList[position]
|
||||||
holder.dismiss.tag = notification
|
holder.binding.dismiss.tag = notification
|
||||||
if (notification.buttonText != 0) holder.dismiss.setText(notification.buttonText)
|
if (notification.buttonText != 0) holder.binding.dismiss.setText(notification.buttonText)
|
||||||
else holder.dismiss.setText(R.string.snooze)
|
else holder.binding.dismiss.setText(R.string.snooze)
|
||||||
@Suppress("SetTextI18n")
|
@Suppress("SetTextI18n")
|
||||||
holder.text.text = dateUtil.timeString(notification.date) + " " + notification.text
|
holder.binding.text.text = dateUtil.timeString(notification.date) + " " + notification.text
|
||||||
when (notification.level) {
|
when (notification.level) {
|
||||||
Notification.URGENT -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent))
|
Notification.URGENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent))
|
||||||
Notification.NORMAL -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal))
|
Notification.NORMAL -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal))
|
||||||
Notification.LOW -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow))
|
Notification.LOW -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow))
|
||||||
Notification.INFO -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo))
|
Notification.INFO -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo))
|
||||||
Notification.ANNOUNCEMENT -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationAnnouncement))
|
Notification.ANNOUNCEMENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationAnnouncement))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,12 +176,10 @@ class NotificationStore @Inject constructor(
|
||||||
|
|
||||||
inner class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
inner class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
|
||||||
var cv: CardView = itemView.findViewById(R.id.notification_cardview)
|
val binding = OverviewNotificationItemBinding.bind(itemView)
|
||||||
var text: TextView = itemView.findViewById(R.id.notification_text)
|
|
||||||
var dismiss: Button = itemView.findViewById(R.id.notification_dismiss)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
dismiss.setOnClickListener {
|
binding.dismiss.setOnClickListener {
|
||||||
val notification = it.tag as Notification
|
val notification = it.tag as Notification
|
||||||
rxBus.send(EventDismissNotification(notification.id))
|
rxBus.send(EventDismissNotification(notification.id))
|
||||||
notification.action?.run()
|
notification.action?.run()
|
||||||
|
|
|
@ -4,9 +4,7 @@ import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.os.Build
|
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import info.nightscout.androidaps.interfaces.NotificationHolderInterface
|
import info.nightscout.androidaps.interfaces.NotificationHolderInterface
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
@ -14,14 +12,13 @@ import javax.inject.Singleton
|
||||||
/*
|
/*
|
||||||
This code replaces following
|
This code replaces following
|
||||||
val alarm = Intent(context, DummyService::class.java)
|
val alarm = Intent(context, DummyService::class.java)
|
||||||
alarm.putExtra("soundid", n.soundId)
|
alarm.putExtra("soundId", n.soundId)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
|
||||||
|
|
||||||
it fails randomly with error
|
it fails randomly with error
|
||||||
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.DummyService}
|
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.DummyService}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class DummyServiceHelper @Inject constructor(
|
class DummyServiceHelper @Inject constructor(
|
||||||
private val notificationHolder: NotificationHolderInterface
|
private val notificationHolder: NotificationHolderInterface
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/notification_cardview"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/cv"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
@ -16,16 +17,17 @@
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/notification_text"
|
android:id="@+id/text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:maxLines="4"
|
android:maxLines="4"
|
||||||
android:text="Notification text. Notification text. Notification text. Notification text. Notification text. Notification text. " />
|
android:text="Notification text. Notification text. Notification text. Notification text. Notification text. Notification text. "
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/notification_dismiss"
|
android:id="@+id/dismiss"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:text="@string/dismiss" />
|
android:text="@string/dismiss" />
|
||||||
|
|
|
@ -4,31 +4,32 @@ import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.os.Build
|
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
import info.nightscout.androidaps.interfaces.NotificationHolderInterface
|
import info.nightscout.androidaps.interfaces.NotificationHolderInterface
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This code replaces following
|
This code replaces following
|
||||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||||
alarm.putExtra("soundid", n.soundId)
|
alarm.putExtra("soundId", n.soundId)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
|
||||||
|
|
||||||
it fails randomly with error
|
it fails randomly with error
|
||||||
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.AlarmSoundService}
|
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.AlarmSoundService}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class AlarmSoundServiceHelper @Inject constructor(
|
class AlarmSoundServiceHelper @Inject constructor(
|
||||||
|
private val aapsLogger: AAPSLogger,
|
||||||
private val notificationHolder: NotificationHolderInterface
|
private val notificationHolder: NotificationHolderInterface
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun startAlarm(context: Context, sound: Int) {
|
fun startAlarm(context: Context, sound: Int) {
|
||||||
|
aapsLogger.debug(LTag.CORE, "Starting alarm")
|
||||||
val connection = object : ServiceConnection {
|
val connection = object : ServiceConnection {
|
||||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||||
// The binder of the service that returns the instance that is created.
|
// The binder of the service that returns the instance that is created.
|
||||||
|
@ -62,6 +63,7 @@ class AlarmSoundServiceHelper @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopService(context: Context) {
|
fun stopService(context: Context) {
|
||||||
|
aapsLogger.debug(LTag.CORE, "Stopping alarm")
|
||||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||||
context.stopService(alarm)
|
context.stopService(alarm)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,10 @@ package info.nightscout.androidaps.utils.protection
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import info.nightscout.androidaps.core.R
|
import info.nightscout.androidaps.core.R
|
||||||
import info.nightscout.androidaps.utils.CryptoUtil
|
import info.nightscout.androidaps.utils.CryptoUtil
|
||||||
|
@ -20,7 +18,6 @@ import javax.inject.Singleton
|
||||||
// since androidx.autofill.HintConstants are not available
|
// since androidx.autofill.HintConstants are not available
|
||||||
const val AUTOFILL_HINT_NEW_PASSWORD = "newPassword"
|
const val AUTOFILL_HINT_NEW_PASSWORD = "newPassword"
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class PasswordCheck @Inject constructor(
|
class PasswordCheck @Inject constructor(
|
||||||
val sp: SP,
|
val sp: SP,
|
||||||
|
|
Loading…
Reference in a new issue