fix AlarmSoundService crashing
This commit is contained in:
parent
3f77496c88
commit
7bc7388f06
|
@ -22,7 +22,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
|
|||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
||||
import info.nightscout.androidaps.services.AlarmSoundService
|
||||
import info.nightscout.androidaps.services.AlarmSoundServiceHelper
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.resources.IconsProvider
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
|
@ -39,6 +39,7 @@ class NotificationStore @Inject constructor(
|
|||
private val resourceHelper: ResourceHelper,
|
||||
private val context: Context,
|
||||
private val iconsProvider: IconsProvider,
|
||||
private val alarmSoundServiceHelper: AlarmSoundServiceHelper,
|
||||
private val dateUtil: DateUtil
|
||||
) {
|
||||
|
||||
|
@ -46,10 +47,12 @@ class NotificationStore @Inject constructor(
|
|||
private var usesChannels = false
|
||||
|
||||
companion object {
|
||||
|
||||
private const val CHANNEL_ID = "AndroidAPS-Overview"
|
||||
}
|
||||
|
||||
inner class NotificationComparator : Comparator<Notification> {
|
||||
|
||||
override fun compare(o1: Notification, o2: Notification): Int {
|
||||
return o1.level - o2.level
|
||||
}
|
||||
|
@ -68,17 +71,9 @@ class NotificationStore @Inject constructor(
|
|||
store.add(n)
|
||||
if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, false) && n !is NotificationWithAction) {
|
||||
raiseSystemNotification(n)
|
||||
if (usesChannels && n.soundId != null && n.soundId != 0) {
|
||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||
alarm.putExtra("soundid", n.soundId)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
|
||||
}
|
||||
if (usesChannels && n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId)
|
||||
} else {
|
||||
if (n.soundId != null && n.soundId != 0) {
|
||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||
alarm.putExtra("soundid", n.soundId)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
|
||||
}
|
||||
if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId)
|
||||
}
|
||||
Collections.sort(store, NotificationComparator())
|
||||
return true
|
||||
|
@ -87,10 +82,7 @@ class NotificationStore @Inject constructor(
|
|||
@Synchronized fun remove(id: Int): Boolean {
|
||||
for (i in store.indices) {
|
||||
if (store[i].id == id) {
|
||||
if (store[i].soundId != null) {
|
||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||
context.stopService(alarm)
|
||||
}
|
||||
if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context)
|
||||
store.removeAt(i)
|
||||
return true
|
||||
}
|
||||
|
@ -208,6 +200,7 @@ class NotificationStore @Inject constructor(
|
|||
}
|
||||
|
||||
inner class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
var cv: CardView = itemView.findViewById(R.id.notification_cardview)
|
||||
var text: TextView = itemView.findViewById(R.id.notification_text)
|
||||
var dismiss: Button = itemView.findViewById(R.id.notification_dismiss)
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -13,11 +10,13 @@ import dagger.android.support.DaggerDialogFragment
|
|||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.services.AlarmSoundService
|
||||
import info.nightscout.androidaps.services.AlarmSoundServiceHelper
|
||||
import kotlinx.android.synthetic.main.dialog_error.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class ErrorDialog : DaggerDialogFragment() {
|
||||
|
||||
@Inject lateinit var alarmSoundServiceHelper: AlarmSoundServiceHelper
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
|
||||
var helperActivity: ErrorHelperActivity? = null
|
||||
|
@ -80,17 +79,10 @@ class ErrorDialog : DaggerDialogFragment() {
|
|||
}
|
||||
|
||||
private fun startAlarm() {
|
||||
if (sound != 0) {
|
||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||
alarm.putExtra("soundid", sound)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context?.startForegroundService(alarm)
|
||||
} else {
|
||||
context?.startService(alarm)
|
||||
}
|
||||
}
|
||||
if (sound != 0)
|
||||
context?.let { context -> alarmSoundServiceHelper.startAlarm(context, sound) }
|
||||
}
|
||||
|
||||
private fun stopAlarm() =
|
||||
context?.stopService(Intent(context, AlarmSoundService::class.java))
|
||||
context?.let { context -> alarmSoundServiceHelper.stopService(context) }
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.media.AudioManager
|
||||
import android.media.MediaPlayer
|
||||
import android.os.Binder
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import dagger.android.DaggerService
|
||||
|
@ -43,11 +44,17 @@ class AlarmSoundService : DaggerService() {
|
|||
|
||||
}
|
||||
|
||||
inner class LocalBinder : Binder() {
|
||||
|
||||
fun getService(): AlarmSoundService = this@AlarmSoundService
|
||||
}
|
||||
|
||||
private val binder = LocalBinder()
|
||||
override fun onBind(intent: Intent): IBinder = binder
|
||||
|
||||
private val increaseVolumeHandler = Handler()
|
||||
private var currentVolumeLevel = 0
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
aapsLogger.debug(LTag.CORE, "onCreate parent called")
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package info.nightscout.androidaps.services
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import info.nightscout.androidaps.interfaces.NotificationHolderInterface
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/*
|
||||
This code replaces following
|
||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||
alarm.putExtra("soundid", n.soundId)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
|
||||
|
||||
it fails randomly with error
|
||||
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.AlarmSoundService}
|
||||
|
||||
*/
|
||||
@Singleton
|
||||
class AlarmSoundServiceHelper @Inject constructor(
|
||||
private val notificationHolder: NotificationHolderInterface
|
||||
) {
|
||||
|
||||
fun startAlarm(context: Context, sound: Int) {
|
||||
val connection = object : ServiceConnection {
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
// The binder of the service that returns the instance that is created.
|
||||
val binder: AlarmSoundService.LocalBinder = service as AlarmSoundService.LocalBinder
|
||||
|
||||
val alarmSoundService: AlarmSoundService = binder.getService()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
context.startForegroundService(getServiceIntent(context, sound))
|
||||
else
|
||||
context.startService(getServiceIntent(context, sound))
|
||||
|
||||
// This is the key: Without waiting Android Framework to call this method
|
||||
// inside Service.onCreate(), immediately call here to post the notification.
|
||||
alarmSoundService.startForeground(notificationHolder.notificationID, notificationHolder.notification)
|
||||
|
||||
// Release the connection to prevent leaks.
|
||||
context.unbindService(this)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
context.bindService(getServiceIntent(context, sound), connection, Context.BIND_AUTO_CREATE)
|
||||
} catch (ignored: RuntimeException) {
|
||||
// This is probably a broadcast receiver context even though we are calling getApplicationContext().
|
||||
// Just call startForegroundService instead since we cannot bind a service to a
|
||||
// broadcast receiver context. The service also have to call startForeground in
|
||||
// this case.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
context.startForegroundService(getServiceIntent(context, sound))
|
||||
else
|
||||
context.startService(getServiceIntent(context, sound))
|
||||
}
|
||||
}
|
||||
|
||||
fun stopService(context: Context) {
|
||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||
context.stopService(alarm)
|
||||
}
|
||||
|
||||
private fun getServiceIntent(context: Context, sound: Int): Intent {
|
||||
val alarm = Intent(context, AlarmSoundService::class.java)
|
||||
alarm.putExtra("soundid", sound)
|
||||
return alarm
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue