DummyServiceHelper
This commit is contained in:
parent
8a683ee571
commit
68faba8951
4 changed files with 106 additions and 28 deletions
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.general.persistentNotification
|
|||
import android.app.Notification
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import dagger.android.DaggerService
|
||||
import info.nightscout.androidaps.events.EventAppExit
|
||||
|
@ -27,7 +28,13 @@ class DummyService : DaggerService() {
|
|||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? = null
|
||||
inner class LocalBinder : Binder() {
|
||||
|
||||
fun getService(): DummyService = this@DummyService
|
||||
}
|
||||
|
||||
private val binder = LocalBinder()
|
||||
override fun onBind(intent: Intent): IBinder = binder
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
@ -44,7 +51,7 @@ class DummyService : DaggerService() {
|
|||
.subscribe({
|
||||
aapsLogger.debug(LTag.CORE, "EventAppExit received")
|
||||
stopSelf()
|
||||
}, fabricPrivacy::logException )
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package info.nightscout.androidaps.plugins.general.persistentNotification
|
||||
|
||||
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 androidx.annotation.RequiresApi
|
||||
import info.nightscout.androidaps.interfaces.NotificationHolderInterface
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/*
|
||||
This code replaces following
|
||||
val alarm = Intent(context, DummyService::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.DummyService}
|
||||
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
@Singleton
|
||||
class DummyServiceHelper @Inject constructor(
|
||||
private val notificationHolder: NotificationHolderInterface
|
||||
) {
|
||||
|
||||
fun startService(context: Context) {
|
||||
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: DummyService.LocalBinder = service as DummyService.LocalBinder
|
||||
|
||||
val dummyService: DummyService = binder.getService()
|
||||
|
||||
context.startForegroundService(Intent(context, DummyService::class.java))
|
||||
|
||||
// This is the key: Without waiting Android Framework to call this method
|
||||
// inside Service.onCreate(), immediately call here to post the notification.
|
||||
dummyService.startForeground(notificationHolder.notificationID, notificationHolder.notification)
|
||||
|
||||
// Release the connection to prevent leaks.
|
||||
context.unbindService(this)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
context.bindService(Intent(context, DummyService::class.java), 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.
|
||||
context.startForegroundService(Intent(context, DummyService::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
fun stopService(context: Context) {
|
||||
context.stopService(Intent(context, DummyService::class.java))
|
||||
}
|
||||
}
|
|
@ -30,18 +30,20 @@ import io.reactivex.schedulers.Schedulers
|
|||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Suppress("PrivatePropertyName")
|
||||
@Singleton
|
||||
class PersistentNotificationPlugin @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
resourceHelper: ResourceHelper,
|
||||
private var profileFunction: ProfileFunction,
|
||||
private var fabricPrivacy: FabricPrivacy,
|
||||
private var activePlugins: ActivePluginProvider,
|
||||
private var iobCobCalculatorPlugin: IobCobCalculatorPlugin,
|
||||
private var rxBus: RxBusWrapper,
|
||||
private var context: Context,
|
||||
private var notificationHolder: NotificationHolder,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val activePlugins: ActivePluginProvider,
|
||||
private val iobCobCalculatorPlugin: IobCobCalculatorPlugin,
|
||||
private val rxBus: RxBusWrapper,
|
||||
private val context: Context,
|
||||
private val notificationHolder: NotificationHolder,
|
||||
private val dummyServiceHelper: DummyServiceHelper,
|
||||
private val iconsProvider: IconsProvider,
|
||||
private val databaseHelper: DatabaseHelperInterface
|
||||
) : PluginBase(PluginDescription()
|
||||
|
@ -112,13 +114,13 @@ class PersistentNotificationPlugin @Inject constructor(
|
|||
|
||||
override fun onStop() {
|
||||
disposable.clear()
|
||||
context.stopService(Intent(context, DummyService::class.java))
|
||||
dummyServiceHelper.stopService(context)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
private fun triggerNotificationUpdate() {
|
||||
updateNotification()
|
||||
context.startForegroundService(Intent(context, DummyService::class.java))
|
||||
dummyServiceHelper.startService(context)
|
||||
}
|
||||
|
||||
private fun updateNotification() {
|
||||
|
@ -128,31 +130,31 @@ class PersistentNotificationPlugin @Inject constructor(
|
|||
var line3: String? = null
|
||||
var unreadConversationBuilder: NotificationCompat.CarExtender.UnreadConversation.Builder? = null
|
||||
if (profileFunction.isProfileValid("Notification")) {
|
||||
var line1_aa: String
|
||||
var line1aa: String
|
||||
val units = profileFunction.getUnits()
|
||||
val lastBG = iobCobCalculatorPlugin.lastBg()
|
||||
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
|
||||
if (lastBG != null) {
|
||||
line1_aa = lastBG.valueToUnitsToString(units)
|
||||
line1 = line1_aa
|
||||
line1aa = lastBG.valueToUnitsToString(units)
|
||||
line1 = line1aa
|
||||
if (glucoseStatus != null) {
|
||||
line1 += (" Δ" + Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
|
||||
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units))
|
||||
line1_aa += " " + lastBG.directionToSymbol(databaseHelper)
|
||||
line1aa += " " + lastBG.directionToSymbol(databaseHelper)
|
||||
} else {
|
||||
line1 += " " +
|
||||
resourceHelper.gs(R.string.old_data) +
|
||||
" "
|
||||
line1_aa += "$line1."
|
||||
line1aa += "$line1."
|
||||
}
|
||||
} else {
|
||||
line1_aa = resourceHelper.gs(R.string.missed_bg_readings)
|
||||
line1 = line1_aa
|
||||
line1aa = resourceHelper.gs(R.string.missed_bg_readings)
|
||||
line1 = line1aa
|
||||
}
|
||||
val activeTemp = activePlugins.activeTreatments.getTempBasalFromHistory(System.currentTimeMillis())
|
||||
if (activeTemp != null) {
|
||||
line1 += " " + activeTemp.toStringShort()
|
||||
line1_aa += " " + activeTemp.toStringShort() + "."
|
||||
line1aa += " " + activeTemp.toStringShort() + "."
|
||||
}
|
||||
//IOB
|
||||
activePlugins.activeTreatments.updateTotalIOBTreatments()
|
||||
|
@ -160,11 +162,11 @@ class PersistentNotificationPlugin @Inject constructor(
|
|||
val bolusIob = activePlugins.activeTreatments.lastCalculationTreatments.round()
|
||||
val basalIob = activePlugins.activeTreatments.lastCalculationTempBasals.round()
|
||||
line2 = resourceHelper.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + resourceHelper.gs(R.string.cob) + ": " + iobCobCalculatorPlugin.getCobInfo(false, "PersistentNotificationPlugin").generateCOBString()
|
||||
val line2_aa = resourceHelper.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + resourceHelper.gs(R.string.cob) + ": " + iobCobCalculatorPlugin.getCobInfo(false, "PersistentNotificationPlugin").generateCOBString() + "."
|
||||
val line2aa = resourceHelper.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + resourceHelper.gs(R.string.cob) + ": " + iobCobCalculatorPlugin.getCobInfo(false, "PersistentNotificationPlugin").generateCOBString() + "."
|
||||
line3 = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h"
|
||||
var line3_aa = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h."
|
||||
var line3aa = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h."
|
||||
line3 += " - " + profileFunction.getProfileName()
|
||||
line3_aa += " - " + profileFunction.getProfileName() + "."
|
||||
line3aa += " - " + profileFunction.getProfileName() + "."
|
||||
/// For Android Auto
|
||||
val msgReadIntent = Intent()
|
||||
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
|
@ -188,12 +190,12 @@ class PersistentNotificationPlugin @Inject constructor(
|
|||
// Build a RemoteInput for receiving voice input from devices
|
||||
val remoteInput = RemoteInput.Builder(EXTRA_VOICE_REPLY).build()
|
||||
// Create the UnreadConversation
|
||||
unreadConversationBuilder = NotificationCompat.CarExtender.UnreadConversation.Builder(line1_aa + "\n" + line2_aa)
|
||||
unreadConversationBuilder = NotificationCompat.CarExtender.UnreadConversation.Builder(line1aa + "\n" + line2aa)
|
||||
.setLatestTimestamp(System.currentTimeMillis())
|
||||
.setReadPendingIntent(msgReadPendingIntent)
|
||||
.setReplyAction(msgReplyPendingIntent, remoteInput)
|
||||
/// Add dot to produce a "more natural sounding result"
|
||||
unreadConversationBuilder.addMessage(line3_aa)
|
||||
unreadConversationBuilder.addMessage(line3aa)
|
||||
/// End Android Auto
|
||||
} else {
|
||||
line1 = resourceHelper.gs(R.string.noprofileset)
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
package info.nightscout.androidaps.receivers
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import info.nightscout.androidaps.plugins.general.persistentNotification.DummyService
|
||||
import dagger.android.DaggerBroadcastReceiver
|
||||
import info.nightscout.androidaps.plugins.general.persistentNotification.DummyServiceHelper
|
||||
|
||||
class AutoStartReceiver : BroadcastReceiver() {
|
||||
class AutoStartReceiver constructor(
|
||||
private val dummyServiceHelper: DummyServiceHelper
|
||||
) : DaggerBroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
super.onReceive(context, intent)
|
||||
if (intent.action == Intent.ACTION_BOOT_COMPLETED)
|
||||
context.startForegroundService(Intent(context, DummyService::class.java))
|
||||
dummyServiceHelper.startService(context)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue