Merge branch 'dev' into eopatch2

This commit is contained in:
Milos Kozak 2022-09-28 11:09:08 +02:00 committed by GitHub
commit 21f53e40af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
136 changed files with 4688 additions and 477 deletions

View file

@ -105,7 +105,7 @@ android {
defaultConfig {
multiDexEnabled true
versionCode 1500
version "3.1.0.3-dev-a"
version "3.1.0.3-dev-b"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'

View file

@ -35,7 +35,6 @@
<!-- To receive data from Aidex -->
<uses-permission android:name="com.microtechmd.cgms.aidex.permissions.RECEIVE_BG_ESTIMATE" />
<application
android:name=".MainApp"
android:allowBackup="true"

View file

@ -92,6 +92,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
@Inject lateinit var poctechPlugin: PoctechPlugin
@Inject lateinit var tomatoPlugin: TomatoPlugin
@Inject lateinit var glunovoPlugin: GlunovoPlugin
@Inject lateinit var intelligoPlugin: IntelligoPlugin
@Inject lateinit var aidexPlugin: AidexPlugin
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@Inject lateinit var statusLinePlugin: StatusLinePlugin
@ -169,6 +170,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
addPreferencesFromResourceIfEnabled(dexcomPlugin, rootKey)
addPreferencesFromResourceIfEnabled(tomatoPlugin, rootKey)
addPreferencesFromResourceIfEnabled(glunovoPlugin, rootKey)
addPreferencesFromResourceIfEnabled(intelligoPlugin, rootKey)
addPreferencesFromResourceIfEnabled(poctechPlugin, rootKey)
addPreferencesFromResourceIfEnabled(aidexPlugin, rootKey)
addPreferencesFromResourceIfEnabled(glimpPlugin, rootKey)

View file

@ -69,13 +69,13 @@ class PreferencesActivity : NoSplashAppCompatActivity(), PreferenceFragmentCompa
super.attachBaseContext(LocaleHelper.wrap(newBase))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
override fun onOptionsItemSelected(item: MenuItem): Boolean =
when (item.itemId) {
android.R.id.home -> {
onBackPressed()
return true
true
}
else -> super.onOptionsItemSelected(item)
}
return super.onOptionsItemSelected(item)
}
}

View file

@ -175,29 +175,29 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
for (i in 0..1) {
if (typeSelected[i] == ProfileType.MOTOL_DEFAULT) {
if (ageUsed[i] < 1 || ageUsed[i] > 18) {
ToastUtils.showToastInUiThread(this, R.string.invalidage)
ToastUtils.warnToast(this, R.string.invalidage)
return@setOnClickListener
}
if ((weightUsed[i] < 5 || weightUsed[i] > 150) && tddUsed[i] == 0.0) {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
ToastUtils.warnToast(this, R.string.invalidweight)
return@setOnClickListener
}
if ((tddUsed[i] < 5 || tddUsed[i] > 150) && weightUsed[i] == 0.0) {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
ToastUtils.warnToast(this, R.string.invalidweight)
return@setOnClickListener
}
}
if (typeSelected[i] == ProfileType.DPV_DEFAULT) {
if (ageUsed[i] < 1 || ageUsed[i] > 18) {
ToastUtils.showToastInUiThread(this, R.string.invalidage)
ToastUtils.warnToast(this, R.string.invalidage)
return@setOnClickListener
}
if (tddUsed[i] < 5 || tddUsed[i] > 150) {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
ToastUtils.warnToast(this, R.string.invalidweight)
return@setOnClickListener
}
if ((pctUsed[i] < 32 || pctUsed[i] > 37)) {
ToastUtils.showToastInUiThread(this, R.string.invalidpct)
ToastUtils.warnToast(this, R.string.invalidpct)
return@setOnClickListener
}
}
@ -226,7 +226,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
return@setOnClickListener
}
}
ToastUtils.showToastInUiThread(this, R.string.invalidinput)
ToastUtils.warnToast(this, R.string.invalidinput)
}
binding.ageLabel.labelFor = binding.age.editTextId
binding.tddLabel.labelFor = binding.tdd.editTextId

View file

@ -27,25 +27,31 @@ class SingleFragmentActivity : DaggerAppCompatActivityWithResult() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction().replace(R.id.frame_layout,
supportFragmentManager.fragmentFactory.instantiate(ClassLoader.getSystemClassLoader(), plugin?.pluginDescription?.fragmentClass!!)).commit()
supportFragmentManager.beginTransaction().replace(
R.id.frame_layout,
supportFragmentManager.fragmentFactory.instantiate(ClassLoader.getSystemClassLoader(), plugin?.pluginDescription?.fragmentClass!!)
).commit()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
finish()
return true
} else if (item.itemId == R.id.nav_plugin_preferences) {
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, Runnable {
val i = Intent(this, PreferencesActivity::class.java)
i.putExtra("id", plugin?.preferencesId)
startActivity(i)
}, null)
return true
override fun onOptionsItemSelected(item: MenuItem): Boolean =
when (item.itemId) {
android.R.id.home -> {
finish()
true
}
R.id.nav_plugin_preferences -> {
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, {
val i = Intent(this, PreferencesActivity::class.java)
i.putExtra("id", plugin?.preferencesId)
startActivity(i)
}, null)
true
}
else -> super.onOptionsItemSelected(item)
}
return false
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
if (plugin?.preferencesId != -1) menuInflater.inflate(R.menu.menu_single_fragment, menu)

View file

@ -52,15 +52,15 @@ class SurveyActivity : NoSplashAppCompatActivity() {
val weight = SafeParse.stringToDouble(binding.weight.text.toString())
val tdd = SafeParse.stringToDouble(binding.tdd.text.toString())
if (age < 1 || age > 120) {
ToastUtils.showToastInUiThread(this, R.string.invalidage)
ToastUtils.warnToast(this, R.string.invalidage)
return@setOnClickListener
}
if ((weight < 5 || weight > 150) && tdd == 0.0) {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
ToastUtils.warnToast(this, R.string.invalidweight)
return@setOnClickListener
}
if ((tdd < 5 || tdd > 150) && weight == 0.0) {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
ToastUtils.warnToast(this, R.string.invalidweight)
return@setOnClickListener
}
profileFunction.getProfile()?.let { runningProfile ->
@ -84,11 +84,11 @@ class SurveyActivity : NoSplashAppCompatActivity() {
r.age = SafeParse.stringToInt(binding.age.text.toString())
r.weight = SafeParse.stringToInt(binding.weight.text.toString())
if (r.age < 1 || r.age > 120) {
ToastUtils.showToastInUiThread(this, R.string.invalidage)
ToastUtils.warnToast(this, R.string.invalidage)
return@setOnClickListener
}
if (r.weight < 5 || r.weight > 150) {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
ToastUtils.warnToast(this, R.string.invalidweight)
return@setOnClickListener
}
@ -110,7 +110,7 @@ class SurveyActivity : NoSplashAppCompatActivity() {
database.child("survey").child(r.id).setValue(r)
} else {
aapsLogger.error("signInAnonymously:failure", task.exception!!)
ToastUtils.showToastInUiThread(this, "Authentication failed.")
ToastUtils.warnToast(this, "Authentication failed.")
//updateUI(null)
}

View file

@ -7,7 +7,13 @@ import androidx.fragment.app.FragmentTransaction
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.fragments.*
import info.nightscout.androidaps.activities.fragments.TreatmentsBolusCarbsFragment
import info.nightscout.androidaps.activities.fragments.TreatmentsCareportalFragment
import info.nightscout.androidaps.activities.fragments.TreatmentsExtendedBolusesFragment
import info.nightscout.androidaps.activities.fragments.TreatmentsProfileSwitchFragment
import info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment
import info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment
import info.nightscout.androidaps.activities.fragments.TreatmentsUserEntryFragment
import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.ActivePlugin
@ -25,7 +31,7 @@ class TreatmentsActivity : NoSplashAppCompatActivity() {
super.onCreate(savedInstanceState)
binding = TreatmentsFragmentBinding.inflate(layoutInflater)
setContentView(binding.root)
// Use index, TabItems crashes with an id
val useFakeTempBasal = activePlugin.activePump.isFakingTempsByExtendedBoluses
binding.treatmentsTabs.getTabAt(1)?.view?.visibility = useFakeTempBasal.toVisibility()
@ -55,16 +61,15 @@ class TreatmentsActivity : NoSplashAppCompatActivity() {
})
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
override fun onOptionsItemSelected(item: MenuItem): Boolean =
when (item.itemId) {
android.R.id.home -> {
finish()
true
}
else -> false
else -> super.onOptionsItemSelected(item)
}
}
private fun setFragment(selectedFragment: Fragment) {
supportFragmentManager.beginTransaction()

View file

@ -270,6 +270,10 @@ class TreatmentsBolusCarbsFragment : DaggerFragment(), MenuProvider {
}
holder.binding.calculation.tag = ml
var notes = ml.carbs?.notes ?: ml.bolus?.notes ?: ""
holder.binding.notes.text = notes
holder.binding.notes.visibility = if (notes != "") View.VISIBLE else View.GONE
}
override fun getItemCount() = mealLinks.size
@ -315,7 +319,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment(), MenuProvider {
R.id.nav_show_invalidated -> {
showInvalidated = true
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
ToastUtils.infoToast(context, R.string.show_invalidated_records)
swapAdapter()
true
}
@ -323,7 +327,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment(), MenuProvider {
R.id.nav_hide_invalidated -> {
showInvalidated = false
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
ToastUtils.infoToast(context, R.string.hide_invalidated_records)
swapAdapter()
true
}

View file

@ -206,7 +206,7 @@ class TreatmentsCareportalFragment : DaggerFragment(), MenuProvider {
R.id.nav_show_invalidated -> {
showInvalidated = true
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
ToastUtils.infoToast(context, R.string.show_invalidated_records)
swapAdapter()
true
}
@ -214,7 +214,7 @@ class TreatmentsCareportalFragment : DaggerFragment(), MenuProvider {
R.id.nav_hide_invalidated -> {
showInvalidated = false
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
ToastUtils.infoToast(context, R.string.hide_invalidated_records)
swapAdapter()
true
}

View file

@ -194,7 +194,7 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment(), MenuProvider {
R.id.nav_show_invalidated -> {
showInvalidated = true
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
ToastUtils.infoToast(context, R.string.show_invalidated_records)
swapAdapter()
true
}
@ -202,7 +202,7 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment(), MenuProvider {
R.id.nav_hide_invalidated -> {
showInvalidated = false
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
ToastUtils.infoToast(context, R.string.hide_invalidated_records)
swapAdapter()
true
}

View file

@ -294,7 +294,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment(), MenuProvider {
R.id.nav_show_invalidated -> {
showInvalidated = true
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
ToastUtils.infoToast(context, R.string.show_invalidated_records)
swapAdapter()
true
}
@ -302,7 +302,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment(), MenuProvider {
R.id.nav_hide_invalidated -> {
showInvalidated = false
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
ToastUtils.infoToast(context, R.string.hide_invalidated_records)
swapAdapter()
true
}

View file

@ -225,7 +225,7 @@ class TreatmentsTempTargetFragment : DaggerFragment(), MenuProvider {
R.id.nav_show_invalidated -> {
showInvalidated = true
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
ToastUtils.infoToast(context, R.string.show_invalidated_records)
swapAdapter()
true
}
@ -233,7 +233,7 @@ class TreatmentsTempTargetFragment : DaggerFragment(), MenuProvider {
R.id.nav_hide_invalidated -> {
showInvalidated = false
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
ToastUtils.infoToast(context, R.string.show_invalidated_records)
swapAdapter()
true
}

View file

@ -236,7 +236,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment(), MenuProvider {
R.id.nav_show_invalidated -> {
showInvalidated = true
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
ToastUtils.infoToast(context, R.string.show_invalidated_records)
swapAdapter()
true
}
@ -244,7 +244,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment(), MenuProvider {
R.id.nav_hide_invalidated -> {
showInvalidated = false
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
ToastUtils.infoToast(context, R.string.hide_invalidated_records)
swapAdapter()
true
}

View file

@ -162,7 +162,7 @@ class TreatmentsUserEntryFragment : DaggerFragment(), MenuProvider {
R.id.nav_show_loop -> {
showLoop = true
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_loop_records))
ToastUtils.infoToast(context, R.string.show_loop_records)
swapAdapter()
true
}
@ -170,7 +170,7 @@ class TreatmentsUserEntryFragment : DaggerFragment(), MenuProvider {
R.id.nav_hide_loop -> {
showLoop = false
updateMenuVisibility()
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_hide_records))
ToastUtils.infoToast(context, R.string.show_hide_records)
swapAdapter()
true
}

View file

@ -31,31 +31,31 @@ class CompatDBHelper @Inject constructor(
*
*/
var newestGlucoseValue: GlucoseValue? = null
it.filterIsInstance<GlucoseValue>().lastOrNull()?.let { gv ->
it.filterIsInstance<GlucoseValue>().maxByOrNull { gv -> gv.timestamp }?.let { gv ->
aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg $gv")
rxBus.send(EventNewBG(gv))
newestGlucoseValue = gv
}
it.filterIsInstance<GlucoseValue>().map { gv -> gv.timestamp }.minOrNull()?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventNewHistoryData $newestGlucoseValue")
it.filterIsInstance<GlucoseValue>().minOfOrNull { gv -> gv.timestamp }?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventNewHistoryData $timestamp $newestGlucoseValue")
rxBus.send(EventNewHistoryData(timestamp, true, newestGlucoseValue))
}
it.filterIsInstance<Carbs>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
it.filterIsInstance<Carbs>().minOfOrNull { t -> t.timestamp }?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventTreatmentChange $timestamp")
rxBus.send(EventTreatmentChange())
rxBus.send(EventNewHistoryData(timestamp, false))
}
it.filterIsInstance<Bolus>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
it.filterIsInstance<Bolus>().minOfOrNull { t -> t.timestamp }?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventTreatmentChange $timestamp")
rxBus.send(EventTreatmentChange())
rxBus.send(EventNewHistoryData(timestamp, false))
}
it.filterIsInstance<TemporaryBasal>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
it.filterIsInstance<TemporaryBasal>().minOfOrNull { t -> t.timestamp }?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventTempBasalChange $timestamp")
rxBus.send(EventTempBasalChange())
rxBus.send(EventNewHistoryData(timestamp, false))
}
it.filterIsInstance<ExtendedBolus>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
it.filterIsInstance<ExtendedBolus>().minOfOrNull { t -> t.timestamp }?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventExtendedBolusChange $timestamp")
rxBus.send(EventExtendedBolusChange())
rxBus.send(EventNewHistoryData(timestamp, false))

View file

@ -377,6 +377,12 @@ abstract class PluginsModule {
@IntKey(470)
abstract fun bindGlunovoPlugin(plugin: GlunovoPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(473)
abstract fun bindIntelligoPlugin(plugin: IntelligoPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@ -419,4 +425,4 @@ abstract class PluginsModule {
@Qualifier
annotation class APS
}
}

View file

@ -78,15 +78,15 @@ class CarbsDialog : DialogFragmentWithDate() {
val time = binding.time.value.toInt()
if (time > 12 * 60 || time < -7 * 24 * 60) {
binding.time.value = 0.0
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.constraintapllied))
ToastUtils.warnToast(ctx, R.string.constraintapllied)
}
if (binding.duration.value > 10) {
binding.duration.value = 0.0
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.constraintapllied))
ToastUtils.warnToast(ctx, R.string.constraintapllied)
}
if (binding.carbs.value.toInt() > maxCarbs) {
binding.carbs.value = 0.0
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.carbsconstraintapplied))
ToastUtils.warnToast(ctx, R.string.carbsconstraintapplied)
}
}
@ -392,7 +392,7 @@ class CarbsDialog : DialogFragmentWithDate() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -120,7 +120,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -208,7 +208,7 @@ class FillDialog : DialogFragmentWithDate() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -83,11 +83,11 @@ class InsulinDialog : DialogFragmentWithDate() {
val maxInsulin = constraintChecker.getMaxBolusAllowed().value()
if (abs(binding.time.value.toInt()) > 12 * 60) {
binding.time.value = 0.0
ToastUtils.showToastInUiThread(context, rh.gs(R.string.constraintapllied))
ToastUtils.warnToast(context, R.string.constraintapllied)
}
if (binding.amount.value > maxInsulin) {
binding.amount.value = 0.0
ToastUtils.showToastInUiThread(context, rh.gs(R.string.bolusconstraintapplied))
ToastUtils.warnToast(context, R.string.bolusconstraintapplied)
}
}
@ -267,7 +267,7 @@ class InsulinDialog : DialogFragmentWithDate() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -304,7 +304,7 @@ class LoopDialog : DaggerDialogFragment() {
commandQueue.cancelTempBasal(true, object : Callback() {
override fun run() {
if (!result.success) {
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.tempbasaldeliveryerror))
ToastUtils.errorToast(ctx, rh.gs(R.string.tempbasaldeliveryerror))
}
}
})
@ -449,7 +449,7 @@ class LoopDialog : DaggerDialogFragment() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -258,7 +258,7 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -153,7 +153,7 @@ class TempBasalDialog : DialogFragmentWithDate() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -230,7 +230,7 @@ class TempTargetDialog : DialogFragmentWithDate() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -72,11 +72,11 @@ class TreatmentDialog : DialogFragmentWithDate() {
val maxInsulin = constraintChecker.getMaxBolusAllowed().value()
if (SafeParse.stringToInt(binding.carbs.text) > maxCarbs) {
binding.carbs.value = 0.0
ToastUtils.showToastInUiThread(context, rh.gs(R.string.carbsconstraintapplied))
ToastUtils.warnToast(context, R.string.carbsconstraintapplied)
}
if (SafeParse.stringToDouble(binding.insulin.text) > maxInsulin) {
binding.insulin.value = 0.0
ToastUtils.showToastInUiThread(context, rh.gs(R.string.bolusconstraintapplied))
ToastUtils.warnToast(context, R.string.bolusconstraintapplied)
}
}
@ -212,7 +212,7 @@ class TreatmentDialog : DialogFragmentWithDate() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -335,7 +335,7 @@ class WizardDialog : DaggerDialogFragment() {
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
if (profile == null || profileStore == null) {
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.noprofile))
ToastUtils.errorToast(ctx, R.string.noprofile)
dismiss()
return
}
@ -409,7 +409,7 @@ class WizardDialog : DaggerDialogFragment() {
val carbsAfterConstraint = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value()
if (abs(carbs - carbsAfterConstraint) > 0.01) {
binding.carbsInput.value = 0.0
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.carbsconstraintapplied))
ToastUtils.warnToast(ctx, R.string.carbsconstraintapplied)
return
}
@ -511,7 +511,7 @@ class WizardDialog : DaggerDialogFragment() {
val cancelFail = {
queryingProtection = false
aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}")
ToastUtils.showToastInUiThread(ctx, R.string.dialog_canceled)
ToastUtils.warnToast(ctx, R.string.dialog_canceled)
dismiss()
}
protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail)

View file

@ -130,13 +130,14 @@ class LoopFragment : DaggerFragment(), MenuProvider {
binding.smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
?: ""
val constraints =
var constraints =
it.constraintsProcessed?.let { constraintsProcessed ->
val allConstraints = Constraint(0.0)
constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) }
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
allConstraints.getMostLimitedReasons(aapsLogger)
} ?: ""
constraints += loop.closedLoopEnabled?.getReasons(aapsLogger) ?: ""
binding.constraints.text = constraints
binding.swipeRefresh.isRefreshing = false
}

View file

@ -105,6 +105,7 @@ class LoopPlugin @Inject constructor(
private var carbsSuggestionsSuspendedUntil: Long = 0
private var prevCarbsreq = 0
override var lastRun: LastRun? = null
override var closedLoopEnabled: Constraint<Boolean>? = null
override fun onStart() {
createNotificationChannel()
@ -294,8 +295,8 @@ class LoopPlugin @Inject constructor(
rxBus.send(EventLoopSetLastRunGui(rh.gs(R.string.pumpsuspended)))
return
}
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
if (closedLoopEnabled.value()) {
closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
if (closedLoopEnabled?.value() == true) {
if (allowNotification) {
if (resultAfterConstraints.isCarbsRequired
&& resultAfterConstraints.carbsReq >= sp.getInt(
@ -369,12 +370,17 @@ class LoopPlugin @Inject constructor(
if (resultAfterConstraints.bolusRequested()) lastRun.smbSetByPump = waiting
rxBus.send(EventLoopUpdateGui())
fabricPrivacy.logCustom("APSRequest")
// TBR request must be applied first to prevent situation where
// SMB was executed and zero TBR afterwards failed
applyTBRRequest(resultAfterConstraints, profile, object : Callback() {
override fun run() {
if (result.enacted || result.success) {
lastRun.tbrSetByPump = result
lastRun.lastTBRRequest = lastRun.lastAPSRun
lastRun.lastTBREnact = dateUtil.now()
// deliverAt is used to prevent executing too old SMB request (older than 1 min)
// executing TBR may take some time thus give more time to SMB
resultAfterConstraints.deliverAt = lastRun.lastTBREnact
rxBus.send(EventLoopUpdateGui())
applySMBRequest(resultAfterConstraints, object : Callback() {
override fun run() {

View file

@ -109,7 +109,7 @@ class ObjectivesExamDialog : DaggerDialogFragment() {
task.answered = result
if (!result) {
task.disabledTo = dateUtil.now() + T.hours(1).msecs()
context?.let { it1 -> ToastUtils.showToastInUiThread(it1, R.string.wronganswer) }
context?.let { it1 -> ToastUtils.infoToast(it1, R.string.wronganswer) }
} else task.disabledTo = 0
updateGui()
rxBus.send(EventObjectivesUpdateGui())

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.general.autotune
import android.content.Context
import android.graphics.Paint
import android.graphics.Typeface
import android.os.Bundle
@ -262,6 +263,7 @@ class AutotuneFragment : DaggerFragment() {
binding.tuneLastrun.setOnClickListener {
if (!autotunePlugin.calculationRunning) {
autotunePlugin.loadLastRun()
binding.tuneDays.value = autotunePlugin.lastNbDays.toDouble()
updateGui()
}
}
@ -418,11 +420,12 @@ class AutotuneFragment : DaggerFragment() {
setTextAppearance(android.R.style.TextAppearance_Material_Medium)
})
autotunePlugin.tunedProfile?.let { tuned ->
layout.addView(toTableRowHeader())
layout.addView(toTableRowHeader(context))
val tuneInsulin = sp.getBoolean(R.string.key_autotune_tune_insulin_curve, false)
if (tuneInsulin) {
layout.addView(
toTableRowValue(
context,
rh.gs(R.string.insulin_peak),
autotunePlugin.pumpProfile.localInsulin.peak.toDouble(),
tuned.localInsulin.peak.toDouble(),
@ -431,6 +434,7 @@ class AutotuneFragment : DaggerFragment() {
)
layout.addView(
toTableRowValue(
context,
rh.gs(R.string.dia),
Round.roundTo(autotunePlugin.pumpProfile.localInsulin.dia, 0.1),
Round.roundTo(tuned.localInsulin.dia, 0.1),
@ -440,13 +444,14 @@ class AutotuneFragment : DaggerFragment() {
}
layout.addView(
toTableRowValue(
context,
rh.gs(R.string.isf_short),
Round.roundTo(autotunePlugin.pumpProfile.isf / toMgDl, 0.001),
Round.roundTo(tuned.isf / toMgDl, 0.001),
isfFormat
)
)
layout.addView(toTableRowValue(rh.gs(R.string.ic_short), Round.roundTo(autotunePlugin.pumpProfile.ic, 0.001), Round.roundTo(tuned.ic, 0.001), "%.2f"))
layout.addView(toTableRowValue(context, rh.gs(R.string.ic_short), Round.roundTo(autotunePlugin.pumpProfile.ic, 0.001), Round.roundTo(tuned.ic, 0.001), "%.2f"))
layout.addView(
TextView(context).apply {
text = rh.gs(R.string.basal)
@ -455,7 +460,7 @@ class AutotuneFragment : DaggerFragment() {
setTextAppearance(android.R.style.TextAppearance_Material_Medium)
}
)
layout.addView(toTableRowHeader(true))
layout.addView(toTableRowHeader(context,true))
var totalPump = 0.0
var totalTuned = 0.0
for (h in 0 until tuned.basal.size) {
@ -463,9 +468,9 @@ class AutotuneFragment : DaggerFragment() {
val time = df.format(h.toLong()) + ":00"
totalPump += autotunePlugin.pumpProfile.basal[h]
totalTuned += tuned.basal[h]
layout.addView(toTableRowValue(time, autotunePlugin.pumpProfile.basal[h], tuned.basal[h], "%.3f", tuned.basalUntuned[h].toString()))
layout.addView(toTableRowValue(context, time, autotunePlugin.pumpProfile.basal[h], tuned.basal[h], "%.3f", tuned.basalUntuned[h].toString()))
}
layout.addView(toTableRowValue("", totalPump, totalTuned, "%.3f", " "))
layout.addView(toTableRowValue(context, "", totalPump, totalTuned, "%.3f", " "))
}
}
)
@ -476,7 +481,7 @@ class AutotuneFragment : DaggerFragment() {
}
}
private fun toTableRowHeader(basal: Boolean = false): TableRow =
private fun toTableRowHeader(context: Context, basal: Boolean = false): TableRow =
TableRow(context).also { header ->
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT).apply { weight = 1f }
header.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT).apply { gravity = Gravity.CENTER_HORIZONTAL }
@ -507,7 +512,7 @@ class AutotuneFragment : DaggerFragment() {
})
}
private fun toTableRowValue(hour: String, inputValue: Double, tunedValue: Double, format: String = "%.3f", missing: String = ""): TableRow =
private fun toTableRowValue(context: Context, hour: String, inputValue: Double, tunedValue: Double, format: String = "%.3f", missing: String = ""): TableRow =
TableRow(context).also { row ->
val percentValue = Round.roundTo(tunedValue / inputValue * 100 - 100, 1.0).toInt().toString() + "%"
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT).apply { weight = 1f }

View file

@ -9,6 +9,7 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.extensions.durationInMinutes
import info.nightscout.androidaps.extensions.safeQueryBroadcastReceivers
import info.nightscout.androidaps.extensions.toStringFull
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui
@ -17,16 +18,16 @@ import info.nightscout.androidaps.plugins.general.nsclient.data.DeviceStatusData
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.receivers.Intents
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
import javax.inject.Inject
import javax.inject.Singleton
@ -64,21 +65,18 @@ class DataBroadcastPlugin @Inject constructor(
private val disposable = CompositeDisposable()
override fun onStart() {
super.onStart()
disposable.add(rxBus
.toObservable(EventOpenAPSUpdateGui::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ sendData(it) }, fabricPrivacy::logException)
)
disposable.add(rxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ sendData(it) }, fabricPrivacy::logException)
)
disposable.add(rxBus
.toObservable(EventOverviewBolusProgress::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ sendData(it) }, fabricPrivacy::logException)
)
disposable += rxBus
.toObservable(EventOpenAPSUpdateGui::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ sendData(it) }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ sendData(it) }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventOverviewBolusProgress::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ sendData(it) }, fabricPrivacy::logException)
}
override fun onStop() {
@ -186,7 +184,7 @@ class DataBroadcastPlugin @Inject constructor(
}
private fun sendBroadcast(intent: Intent) {
val receivers: List<ResolveInfo> = context.packageManager.queryBroadcastReceivers(intent, 0)
val receivers: List<ResolveInfo> = context.packageManager.safeQueryBroadcastReceivers(intent, 0)
for (resolveInfo in receivers)
resolveInfo.activityInfo.packageName?.let {
intent.setPackage(it)

View file

@ -88,7 +88,7 @@ class NSClientAddUpdateWorker(
.also { result ->
result.inserted.forEach {
uel.log(
Action.BOLUS, Sources.NSClient,
Action.BOLUS, Sources.NSClient, it.notes,
ValueWithUnit.Timestamp(it.timestamp),
ValueWithUnit.Insulin(it.amount)
)
@ -124,7 +124,7 @@ class NSClientAddUpdateWorker(
.also { result ->
result.inserted.forEach {
uel.log(
Action.CARBS, Sources.NSClient,
Action.CARBS, Sources.NSClient, it.notes,
ValueWithUnit.Timestamp(it.timestamp),
ValueWithUnit.Gram(it.amount.toInt())
)
@ -140,7 +140,7 @@ class NSClientAddUpdateWorker(
}
result.updated.forEach {
uel.log(
Action.CARBS, Sources.NSClient,
Action.CARBS, Sources.NSClient, it.notes,
ValueWithUnit.Timestamp(it.timestamp),
ValueWithUnit.Gram(it.amount.toInt())
)

View file

@ -54,6 +54,8 @@ import javax.inject.Singleton
"predBGs": {
"IOB": [116, 114, 112, 110, 109, 107, 106, 105, 105, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 106, 106, 106, 106, 106, 107]
},
"sensitivityRatio": 0.81,
"variable_sens": 137.3,
"COB": 0,
"IOB": -0.035,
"reason": "COB: 0, Dev: -18, BGI: 0.43, ISF: 216, Target: 99; Eventual BG 105 > 99 but Min. Delta -2.60 < Exp. Delta 0.1; setting current basal of 0.4 as temp. Suggested rate is same as profile rate, no temp basal is active, doing nothing",

View file

@ -67,6 +67,7 @@ import info.nightscout.androidaps.skins.SkinProvider
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.TrendCalculator
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
@ -379,7 +380,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
dexcomMediator.findDexcomPackageName()?.let {
openCgmApp(it)
}
?: ToastUtils.showToastInUiThread(activity, rh.gs(R.string.dexcom_app_not_installed))
?: ToastUtils.infoToast(activity, rh.gs(R.string.dexcom_app_not_installed))
}
}
@ -395,9 +396,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
)
}
?: ToastUtils.showToastInUiThread(activity, rh.gs(R.string.dexcom_app_not_installed))
?: ToastUtils.infoToast(activity, rh.gs(R.string.dexcom_app_not_installed))
} catch (e: ActivityNotFoundException) {
ToastUtils.showToastInUiThread(activity, rh.gs(R.string.g5appnotdetected))
ToastUtils.infoToast(activity, rh.gs(R.string.g5appnotdetected))
}
}
}
@ -544,7 +545,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
// **** Various treatment buttons ****
binding.buttonsLayout.carbsButton.visibility =
((!activePlugin.activePump.pumpDescription.storesCarbInfo || pump.isInitialized() && !pump.isSuspended()) && profile != null
(/*(!activePlugin.activePump.pumpDescription.storesCarbInfo || pump.isInitialized() && !pump.isSuspended()) &&*/ profile != null
&& sp.getBoolean(R.string.key_show_carbs_button, true)).toVisibility()
binding.buttonsLayout.treatmentButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null
&& sp.getBoolean(R.string.key_show_treatment_button, false)).toVisibility()
@ -602,7 +603,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
private fun processAps() {
val pump = activePlugin.activePump
val profile = profileFunction.getProfile()
// aps mode
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
@ -681,21 +681,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.apsModeText.visibility = View.GONE
}
}
// Show variable sensitivity
val request = loop.lastRun?.request
if (request is DetermineBasalResultSMB) {
val isfMgdl = profile?.getIsfMgdl()
val variableSens = request.variableSens
if (variableSens != isfMgdl && variableSens != null && isfMgdl != null) {
binding.infoLayout.variableSensitivity.text =
String.format(
Locale.getDefault(), "%1$.1f→%2$.1f",
Profile.toUnits(isfMgdl, isfMgdl * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()),
Profile.toUnits(variableSens, variableSens * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
)
binding.infoLayout.variableSensitivity.visibility = View.VISIBLE
} else binding.infoLayout.variableSensitivity.visibility = View.GONE
} else binding.infoLayout.variableSensitivity.visibility = View.GONE
} else {
//nsclient
binding.infoLayout.apsMode.visibility = View.GONE
@ -1094,6 +1079,24 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
overviewData.lastAutosensData(iobCobCalculator)?.let { autosensData ->
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
} ?: ""
// Show variable sensitivity
val profile = profileFunction.getProfile()
val request = loop.lastRun?.request
val isfMgdl = profile?.getIsfMgdl()
val variableSens =
if (config.APS && request is DetermineBasalResultSMB) request.variableSens ?: 0.0
else if (config.NSCLIENT) JsonHelper.safeGetDouble(nsDeviceStatus.getAPSResult(injector).json, "variable_sens")
else 0.0
if (variableSens != isfMgdl && variableSens != 0.0 && isfMgdl != null) {
binding.infoLayout.variableSensitivity.text =
String.format(
Locale.getDefault(), "%1$.1f→%2$.1f",
Profile.toUnits(isfMgdl, isfMgdl * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()),
Profile.toUnits(variableSens, variableSens * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
)
binding.infoLayout.variableSensitivity.visibility = View.VISIBLE
} else binding.infoLayout.variableSensitivity.visibility = View.GONE
}
private fun updatePumpStatus() {

View file

@ -56,7 +56,7 @@ class GraphData(
addSeries(overviewData.bgReadingGraphSeries)
if (addPredictions) addSeries(overviewData.predictionsGraphSeries)
overviewData.bgReadingGraphSeries.setOnDataPointTapListener { _, dataPoint ->
if (dataPoint is GlucoseValueDataPoint) ToastUtils.showToastInUiThread(context, dataPoint.label)
if (dataPoint is GlucoseValueDataPoint) ToastUtils.infoToast(context, dataPoint.label)
}
}
@ -93,14 +93,14 @@ class GraphData(
maxY = maxOf(maxY, overviewData.maxTreatmentsValue)
addSeries(overviewData.treatmentsSeries)
overviewData.treatmentsSeries.setOnDataPointTapListener { _, dataPoint ->
if (dataPoint is BolusDataPoint) ToastUtils.showToastInUiThread(context, dataPoint.label)
if (dataPoint is BolusDataPoint) ToastUtils.infoToast(context, dataPoint.label)
}
}
fun addEps(context: Context?, scale: Double) {
addSeries(overviewData.epsSeries)
overviewData.epsSeries.setOnDataPointTapListener { _, dataPoint ->
if (dataPoint is EffectiveProfileSwitchDataPoint) ToastUtils.showToastInUiThread(context, dataPoint.data.originalCustomizedName)
if (dataPoint is EffectiveProfileSwitchDataPoint) ToastUtils.infoToast(context, dataPoint.data.originalCustomizedName)
}
overviewData.epsScale.multiplier = maxY * scale / overviewData.maxEpsValue
}

View file

@ -8,11 +8,11 @@ import android.os.IBinder
import dagger.android.DaggerService
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.interfaces.NotificationHolder
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import io.reactivex.rxjava3.disposables.CompositeDisposable
import javax.inject.Inject
@ -59,7 +59,7 @@ class DummyService : DaggerService() {
aapsLogger.debug(LTag.CORE, "onDestroy")
disposable.clear()
super.onDestroy()
stopForeground(true)
stopForeground(STOP_FOREGROUND_REMOVE)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

View file

@ -190,7 +190,7 @@ class SmsCommunicatorPlugin @Inject constructor(
?: return Result.failure(workDataOf("Error" to "missing input data"))
val format = bundle.getString("format")
?: return Result.failure(workDataOf("Error" to "missing format in input data"))
val pdus = bundle["pdus"] as Array<*>
@Suppress("DEPRECATION") val pdus = bundle["pdus"] as Array<*>
for (pdu in pdus) {
val message = SmsMessage.createFromPdu(pdu as ByteArray, format)
smsCommunicatorPlugin.processSms(Sms(message))

View file

@ -369,7 +369,7 @@ class IobCobCalculatorPlugin @Inject constructor(
@Synchronized
private fun scheduleHistoryDataChange(event: EventNewHistoryData) {
// if there is nothing scheduled or asking reload deeper to the past
if (scheduledEvent == null || event.oldDataTimestamp < (scheduledEvent?.oldDataTimestamp) ?: 0L) {
if (scheduledEvent == null || event.oldDataTimestamp < (scheduledEvent?.oldDataTimestamp ?: 0L)) {
// cancel waiting task to prevent sending multiple posts
scheduledHistoryPost?.cancel(false)
// prepare task for execution in 1 sec

View file

@ -91,7 +91,7 @@ open class VirtualPumpPlugin @Inject constructor(
it.basalStep = 0.01
it.basalMinimumRate = 0.01
it.isRefillingCapable = true
it.storesCarbInfo = false
//it.storesCarbInfo = false
it.is30minBasalRatesCapable = true
}

View file

@ -119,7 +119,8 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
}
override fun onMenuItemSelected(item: MenuItem) =
actionHelper.onOptionsItemSelected(item)
if (actionHelper.onOptionsItemSelected(item)) true
else super.onContextItemSelected(item)
inner class RecyclerViewAdapter internal constructor(private var glucoseValues: List<GlucoseValue>) : RecyclerView.Adapter<RecyclerViewAdapter.GlucoseValuesViewHolder>() {
@ -195,6 +196,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
R.string.poctech -> Sources.PocTech
R.string.tomato -> Sources.Tomato
R.string.glunovo -> Sources.Glunovo
R.string.intelligo -> Sources.Intelligo
R.string.xdrip -> Sources.Xdrip
R.string.aidex -> Sources.Aidex
else -> Sources.Unknown

View file

@ -19,13 +19,19 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
import info.nightscout.androidaps.database.transactions.InvalidateGlucoseValueTransaction
import info.nightscout.androidaps.extensions.fromConstant
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.extensions.safeGetInstalledPackages
import info.nightscout.androidaps.interfaces.BgSource
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.XDripBroadcast
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
@ -244,7 +250,7 @@ class DexcomPlugin @Inject constructor(
fun findDexcomPackageName(): String? {
val packageManager = context.packageManager
for (packageInfo in packageManager.getInstalledPackages(0)) {
for (packageInfo in packageManager.safeGetInstalledPackages(0)) {
if (PACKAGE_NAMES.contains(packageInfo.packageName)) return packageInfo.packageName
}
return null

View file

@ -0,0 +1,193 @@
package info.nightscout.androidaps.plugins.source
import android.content.Context
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Handler
import android.os.HandlerThread
import android.util.Log
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
import info.nightscout.androidaps.extensions.safeGetInstalledPackages
import info.nightscout.androidaps.interfaces.BgSource
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.XDripBroadcast
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
import io.reactivex.rxjava3.disposables.CompositeDisposable
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class IntelligoPlugin @Inject constructor(
injector: HasAndroidInjector,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val sp: SP,
private val context: Context,
private val repository: AppRepository,
private val xDripBroadcast: XDripBroadcast,
private val dateUtil: DateUtil,
private val uel: UserEntryLogger,
private val fabricPrivacy: FabricPrivacy
) : PluginBase(
PluginDescription()
.mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name)
.pluginIcon(R.drawable.ic_intelligo)
.pluginName(R.string.intelligo)
.preferencesId(R.xml.pref_bgsource)
.shortName(R.string.intelligo)
.description(R.string.description_source_intelligo),
aapsLogger, resourceHelper, injector
), BgSource {
private val handler = Handler(HandlerThread(this::class.java.simpleName + "Handler").also { it.start() }.looper)
private lateinit var refreshLoop: Runnable
private val contentUri: Uri = Uri.parse("content://$AUTHORITY/$TABLE_NAME")
init {
refreshLoop = Runnable {
try {
handleNewData()
} catch (e: Exception) {
fabricPrivacy.logException(e)
aapsLogger.error("Error while processing data", e)
}
val lastReadTimestamp = sp.getLong(R.string.key_last_processed_intelligo_timestamp, 0L)
val differenceToNow = INTERVAL - (dateUtil.now() - lastReadTimestamp) % INTERVAL + T.secs(10).msecs()
handler.postDelayed(refreshLoop, differenceToNow)
}
}
private val disposable = CompositeDisposable()
override fun onStart() {
super.onStart()
handler.postDelayed(refreshLoop, T.secs(30).msecs()) // do not start immediately, app may be still starting
}
override fun onStop() {
super.onStop()
handler.removeCallbacks(refreshLoop)
disposable.clear()
}
private fun handleNewData() {
if (!isEnabled()) return
for (pack in context.packageManager.safeGetInstalledPackages(PackageManager.GET_PROVIDERS)) {
val providers = pack.providers
if (providers != null) {
for (provider in providers) {
Log.d("Example", "provider: " + provider.authority)
}
}
}
context.contentResolver.query(contentUri, null, null, null, null)?.let { cr ->
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
val calibrations = mutableListOf<CgmSourceTransaction.Calibration>()
cr.moveToFirst()
while (!cr.isAfterLast) {
val timestamp = cr.getLong(0)
val value = cr.getDouble(1) //value in mmol/l...
val curr = cr.getDouble(2)
// bypass already processed
if (timestamp < sp.getLong(R.string.key_last_processed_intelligo_timestamp, 0L)) {
cr.moveToNext()
continue
}
if (timestamp > dateUtil.now() || timestamp == 0L) {
aapsLogger.error(LTag.BGSOURCE, "Error in received data date/time $timestamp")
cr.moveToNext()
continue
}
if (value < 2 || value > 25) {
aapsLogger.error(LTag.BGSOURCE, "Error in received data value (value out of bounds) $value")
cr.moveToNext()
continue
}
if (curr != 0.0)
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
timestamp = timestamp,
value = value * Constants.MMOLL_TO_MGDL,
raw = 0.0,
noise = null,
trendArrow = GlucoseValue.TrendArrow.NONE,
sourceSensor = GlucoseValue.SourceSensor.INTELLIGO_NATIVE
)
else
calibrations.add(
CgmSourceTransaction.Calibration(
timestamp = timestamp,
value = value,
glucoseUnit = TherapyEvent.GlucoseUnit.MMOL
)
)
sp.putLong(R.string.key_last_processed_intelligo_timestamp, timestamp)
cr.moveToNext()
}
cr.close()
if (glucoseValues.isNotEmpty() || calibrations.isNotEmpty())
repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, calibrations, null))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving values from IntelliGO App", it)
}
.blockingGet()
.also { savedValues ->
savedValues.inserted.forEach {
xDripBroadcast.send(it)
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
}
savedValues.calibrationsInserted.forEach { calibration ->
calibration.glucose?.let { glucoseValue ->
uel.log(
UserEntry.Action.CALIBRATION,
UserEntry.Sources.Dexcom,
ValueWithUnit.Timestamp(calibration.timestamp),
ValueWithUnit.TherapyEventType(calibration.type),
ValueWithUnit.fromGlucoseUnit(glucoseValue, calibration.glucoseUnit.toString)
)
}
aapsLogger.debug(LTag.DATABASE, "Inserted calibration $calibration")
}
}
}
}
override fun shouldUploadToNs(glucoseValue: GlucoseValue): Boolean =
glucoseValue.sourceSensor == GlucoseValue.SourceSensor.INTELLIGO_NATIVE && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)
companion object {
@Suppress("SpellCheckingInspection")
const val AUTHORITY = "alexpr.co.uk.infinivocgm.intelligo.cgm_db.CgmExternalProvider"
//const val AUTHORITY = "alexpr.co.uk.infinivocgm.cgm_db.CgmExternalProvider/"
const val TABLE_NAME = "CgmReading"
const val INTERVAL = 180000L // 3 min
}
}

View file

@ -232,10 +232,10 @@ class CommandQueueImplementation @Inject constructor(
var carbsRunnable = Runnable { }
val originalCarbs = detailedBolusInfo.carbs
if ((detailedBolusInfo.carbs > 0) &&
if ((detailedBolusInfo.carbs > 0) /*&&
(!activePlugin.activePump.pumpDescription.storesCarbInfo ||
detailedBolusInfo.carbsDuration != 0L ||
(detailedBolusInfo.carbsTimestamp ?: detailedBolusInfo.timestamp) > dateUtil.now())
(detailedBolusInfo.carbsTimestamp ?: detailedBolusInfo.timestamp) > dateUtil.now())*/
) {
carbsRunnable = Runnable {
aapsLogger.debug(LTag.PUMPQUEUE, "Going to store carbs")

View file

@ -8,6 +8,8 @@ import android.os.SystemClock
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.extensions.safeDisable
import info.nightscout.androidaps.extensions.safeEnable
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.Config
@ -77,10 +79,8 @@ class QueueThread internal constructor(
pump.disconnect("watchdog")
SystemClock.sleep(1000)
(context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter?.let { bluetoothAdapter ->
bluetoothAdapter.disable()
SystemClock.sleep(1000)
bluetoothAdapter.enable()
SystemClock.sleep(1000)
bluetoothAdapter.safeDisable(1000)
bluetoothAdapter.safeEnable(1000)
}
//start over again once after watchdog barked
//Notification notification = new Notification(Notification.OLD_NSCLIENT, "Watchdog", Notification.URGENT);

View file

@ -5,15 +5,17 @@ import android.content.Context
import android.content.Intent
import dagger.android.DaggerBroadcastReceiver
import info.nightscout.androidaps.events.EventBTChange
import info.nightscout.androidaps.extensions.safeGetParcelableExtra
import info.nightscout.androidaps.plugins.bus.RxBus
import javax.inject.Inject
class BTReceiver : DaggerBroadcastReceiver() {
@Inject lateinit var rxBus: RxBus
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
val device: BluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) ?: return
val device = intent.safeGetParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java) ?: return
when (intent.action) {
BluetoothDevice.ACTION_ACL_CONNECTED ->

View file

@ -33,7 +33,7 @@ class SWHtmlLink(injector: HasAndroidInjector) : SWItem(injector, Type.HTML_LINK
val context = layout.context
l = TextView(context)
l?.id = View.generateViewId()
l?.autoLinkMask = Linkify.ALL
l?.autoLinkMask = Linkify.WEB_URLS
if (textLabel != null) l?.text = textLabel else l?.setText(label!!)
layout.addView(l)
}

View file

@ -6,18 +6,19 @@ import android.os.Bundle
import info.nightscout.androidaps.R
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.extensions.safeQueryBroadcastReceivers
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.receivers.Intents
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.receivers.Intents
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
@ -41,13 +42,13 @@ class XDripBroadcast @Inject constructor(
intent.putExtras(bundle)
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
context.sendBroadcast(intent)
val q = context.packageManager.queryBroadcastReceivers(intent, 0)
return if (q.size < 1) {
ToastUtils.showToastInUiThread(context, rh.gs(R.string.xdripnotinstalled))
val q = context.packageManager.safeQueryBroadcastReceivers(intent, 0)
return if (q.isEmpty()) {
ToastUtils.errorToast(context, R.string.xdripnotinstalled)
aapsLogger.debug(rh.gs(R.string.xdripnotinstalled))
false
} else {
ToastUtils.showToastInUiThread(context, rh.gs(R.string.calibrationsent))
ToastUtils.errorToast(context, R.string.calibrationsent)
aapsLogger.debug(rh.gs(R.string.calibrationsent))
true
}
@ -74,8 +75,8 @@ class XDripBroadcast @Inject constructor(
val intent = Intent(Intents.XDRIP_PLUS_NS_EMULATOR)
intent.putExtras(bundle).addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
context.sendBroadcast(intent)
val receivers = context.packageManager.queryBroadcastReceivers(intent, 0)
if (receivers.size < 1) {
val receivers = context.packageManager.safeQueryBroadcastReceivers(intent, 0)
if (receivers.isEmpty()) {
//NSUpload.log.debug("No xDrip receivers found. ")
aapsLogger.debug(LTag.BGSOURCE, "No xDrip receivers found.")
} else {
@ -150,7 +151,7 @@ class XDripBroadcast @Inject constructor(
}
private fun broadcast(intent: Intent) {
context.packageManager.queryBroadcastReceivers(intent, 0).forEach { resolveInfo ->
context.packageManager.safeQueryBroadcastReceivers(intent, 0).forEach { resolveInfo ->
resolveInfo.activityInfo.packageName?.let {
intent.setPackage(it)
context.sendBroadcast(intent)

View file

@ -60,12 +60,13 @@ class CalculationWorkflow @Inject constructor(
private val overviewData: OverviewData
get() = (iobCobCalculator as IobCobCalculatorPlugin).overviewData
enum class ProgressData(val pass: Int, val percentOfTotal: Int) {
enum class ProgressData(private val pass: Int, val percentOfTotal: Int) {
PREPARE_BASAL_DATA(0, 5),
PREPARE_TEMPORARY_TARGET_DATA(1, 5),
PREPARE_TREATMENTS_DATA(2, 5),
IOB_COB_OREF(3, 75),
PREPARE_IOB_AUTOSENS_DATA(4, 10);
IOB_COB_OREF(3, 74),
PREPARE_IOB_AUTOSENS_DATA(4, 10),
DRAW(5, 1);
fun finalPercent(progress: Int): Int {
var total = 0

View file

@ -7,6 +7,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewGraph
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import javax.inject.Inject
class UpdateGraphWorker(
@ -26,6 +27,7 @@ class UpdateGraphWorker(
overviewPlugin.overviewBus.send(EventUpdateOverviewGraph("UpdateGraphWorker"))
else
rxBus.send(EventUpdateOverviewGraph("UpdateGraphWorker"))
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.DRAW, 100, null))
return Result.success()
}
}

View file

@ -271,6 +271,16 @@
</LinearLayout>
<TextView
android:id="@+id/notes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:paddingEnd="10dp"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="RtlSymmetry"
tools:text="Notes" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -656,6 +656,8 @@
<string name="description_source_poctech">Získávat glykémie z aplikace Poctech</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">Získávat glykémie z aplikace Glunovo</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">Přijímat hodnoty z aplikace Intelligo</string>
<string name="description_source_tomato">Přijímat hodnoty glykémií z Tomato aplikace (MiaoMiao zařízení)</string>
<string name="high_temptarget_raises_sensitivity_title">Vysoký dočasný cíl zvýší senzitivitu</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Zvýšení senzitivity pro dočasné cíle >= 5.5]]></string>

View file

@ -656,6 +656,8 @@
<string name="description_source_poctech">Recibir los valores de glucosa de Poctech</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">Recibir los valores de glucosa de la aplicación Glunovo</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">Recibir los valores de glucosa de Intelligo</string>
<string name="description_source_tomato">Recibir los valores de glucosa de Tomato App (MiaoMiao) </string>
<string name="high_temptarget_raises_sensitivity_title">Objetivo temporal elevado aumenta sensibilidad</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Aumentar la sensibilidad para objetivos temporales >= 100]]></string>

View file

@ -657,6 +657,8 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="description_source_poctech">Recevoir les glycémies depuis l\'app Poctech</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">Recevoir des valeurs de l\'application Glunovo</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">Recevoir des valeurs depuis l\'application Intelligo</string>
<string name="description_source_tomato">Recevoir les valeurs de glycémie de l\'application Tomato (appareil MiaoMiao)</string>
<string name="high_temptarget_raises_sensitivity_title">Cible temp. haute élève la sensibilité</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Augmente la Sensibilité pour les cibles temporaires >= 100]]></string>

View file

@ -656,6 +656,8 @@
<string name="description_source_poctech">Ricevi valori glicemia da app Poctech</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">Ricevi valori glicemia da app Glunovo</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">Ricevi valori da app Intelligo</string>
<string name="description_source_tomato">Ricevi valori glicemia da app Tomato (dispositivo MiaoMiao)</string>
<string name="high_temptarget_raises_sensitivity_title">Temp-Target \"alto\" aumenta la sensibilità</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Aumenta la sensibilità per temp-target >= 100]]></string>
@ -665,6 +667,7 @@
<string name="resistance_lowers_target_summary">Quando viene rilevata resistenza, ridurre la glicemia target</string>
<string name="sensitivity_raises_target_title">La sensibilità aumenta il target</string>
<string name="sensitivity_raises_target_summary">Quando viene rilevata sensibilità, aumentare la glicemia target</string>
<string name="careportal_removestartedevents">Rimuovi le voci \"AAPS avviato\"</string>
<string name="show_invalidated">Mostra invalidato</string>
<string name="hide_invalidated">Nascondi invalidato</string>
<string name="remove_items">Rimuovi elementi</string>

View file

@ -656,6 +656,8 @@
<string name="description_source_poctech">קבלת ערכי סוכר מיישום Poctech</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">קבלת ערכי סוכר מיישום Glunovo</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">קבלת ערכי סוכר מיישום Intelligo</string>
<string name="description_source_tomato">קבלת ערכי סוכר מאפליקציית Tomato (התקן MiaoMiao)</string>
<string name="high_temptarget_raises_sensitivity_title">ערך מטרה זמני גבוה מעלה את הרגישות</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[הגבר רגישות עבור ערך מטרה זמני >= 100]]></string>

View file

@ -656,6 +656,8 @@
<string name="description_source_poctech">Motta BS verdier fra Poctech app</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">Motta BS verdier fra Glunovo app</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">Motta BS-verdier fra Intelligo-app</string>
<string name="description_source_tomato">Motta BS verdier fra Tomato app (MiaoMiao enhet)</string>
<string name="high_temptarget_raises_sensitivity_title">Høy temp target øker sensitiviteten</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Øk sensitiviteten for temp target >= 100]]></string>
@ -665,6 +667,7 @@
<string name="resistance_lowers_target_summary">Hvis resistens oppdages vil det redusere BS målverdi</string>
<string name="sensitivity_raises_target_title">Sensitivitet øker BS målverdi</string>
<string name="sensitivity_raises_target_summary">Når systemet oppdager økt insulinsensitivitet, vil BS målverdi økes</string>
<string name="careportal_removestartedevents">Fjern oppføringer startet av AAPS</string>
<string name="show_invalidated">Vis ugyldige oppføringer</string>
<string name="hide_invalidated">Skjul ugyldige oppføringer</string>
<string name="remove_items">Fjern oppføringer</string>

View file

@ -656,6 +656,8 @@
<string name="description_source_poctech">Получать данные гликемии от приложения Poctech</string>
<string name="glunovo">Приложение Glunovo</string>
<string name="description_source_glunovo">Получать данные гликемии от приложения Glunovo</string>
<string name="intelligo">Приложение Intelligo</string>
<string name="description_source_intelligo">Получать данные гликемии от приложения Intelligo</string>
<string name="description_source_tomato">Получать значения ГК от приложения Tomato (устройство MiaoMiao)</string>
<string name="high_temptarget_raises_sensitivity_title">Высокая врем. цель temptarget повышает чувствительность</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Повысить чувствительность для temptargets > = 100]]></string>

View file

@ -656,6 +656,8 @@
<string name="description_source_poctech">Získavať glykémie z aplikácie Poctech</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">Získavať glykémie z aplikácie Glunovo</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">Prijímať hodnoty z aplikácie Intelligo</string>
<string name="description_source_tomato">Prijímať glykémie z aplikácie Tomato (zariadenie MiaoMiao)</string>
<string name="high_temptarget_raises_sensitivity_title">Vysoký dočasný cieľ zvýši citlivosť</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Zvýšenie citlivosti pre dočasné ciele >= 5.5]]></string>

View file

@ -657,6 +657,8 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d
<string name="description_source_poctech">Poctech uygulamasından KŞ değerlerini alır</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">Glunovo uygulamasından değerler alır</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">Intelligo uygulamasından değerler alır</string>
<string name="description_source_tomato">KŞ değerlerini Tomato uygulamasından (MiaoMiao Cihazından) al</string>
<string name="high_temptarget_raises_sensitivity_title">Yüksek geçici hedefler duyarlılığı artırır</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Geçici Hedefler için duyarlılığı artırın >= 100]]></string>

View file

@ -801,6 +801,8 @@
<string name="description_source_poctech">Receive BG values from Poctech app</string>
<string name="glunovo">Glunovo</string>
<string name="description_source_glunovo">Receive values from Glunovo app</string>
<string name="intelligo">Intelligo</string>
<string name="description_source_intelligo">Receive values from Intelligo app</string>
<string name="description_source_tomato">Receive BG values from Tomato app (MiaoMiao device)</string>
<string name="key_high_temptarget_raises_sensitivity" translatable="false">high_temptarget_raises_sensitivity</string>
<string name="key_low_temptarget_lowers_sensitivity" translatable="false">low_temptarget_lowers_sensitivity</string>
@ -1126,6 +1128,8 @@
<string name="recalculated_data_used">Recalculated data used</string>
<string name="bg_too_close">BG too close:\n%1$s\n%2$s</string>
<string name="key_last_processed_glunovo_timestamp" translatable="false">last_processed_glunovo_timestamp</string>
<string name="key_last_processed_intelligo_timestamp" translatable="false">
last_processed_intelligo_timestamp</string>
<string name="identification">Identification (email, FB or Discord nick etc)</string>
<string name="identification_not_set">Identification not set in dev mode</string>
<string name="a11y_dialog">dialog</string>

View file

@ -121,7 +121,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener, MenuProvider {
true
}
else -> false
else -> super.onContextItemSelected(item)
}
@SuppressLint("NotifyDataSetChanged")

View file

@ -128,7 +128,7 @@ class EditEventDialog : DialogFragmentWithDate() {
// check for title
val title = binding.inputEventTitle.text?.toString() ?: return false
if (title.isEmpty()) {
context?.let { ToastUtils.showToastInUiThread(it, R.string.automation_missing_task_name) }
context?.let { ToastUtils.errorToast(it, R.string.automation_missing_task_name) }
return false
}
event.title = title
@ -137,12 +137,12 @@ class EditEventDialog : DialogFragmentWithDate() {
// check for at least one trigger
val con = event.trigger
if (con.size() == 0 && !event.userAction) {
context?.let { ToastUtils.showToastInUiThread(it, R.string.automation_missing_trigger) }
context?.let { ToastUtils.errorToast(it, R.string.automation_missing_trigger) }
return false
}
// check for at least one action
if (event.actions.isEmpty()) {
context?.let { ToastUtils.showToastInUiThread(it, R.string.automation_missing_action) }
context?.let { ToastUtils.errorToast(it, R.string.automation_missing_action) }
return false
}
// store

View file

@ -31,6 +31,7 @@ ActionsTestBase : TestBaseWithProfile() {
private var suspended = false
override var lastRun: Loop.LastRun? = Loop.LastRun()
override var closedLoopEnabled: Constraint<Boolean>? = Constraint(true)
override val isSuspended: Boolean = suspended
override val isLGS: Boolean = false
override val isSuperBolus: Boolean = false

View file

@ -3,20 +3,20 @@
buildscript {
ext {
kotlin_version = '1.7.10'
core_version = '1.8.0'
core_version = '1.9.0'
rxjava_version = '3.1.5'
rxandroid_version = '3.0.0'
rxkotlin_version = '3.0.1'
room_version = '2.4.3'
lifecycle_version = '2.5.1'
dagger_version = '2.43'
dagger_version = '2.44'
coroutines_version = '1.6.4'
activity_version = '1.4.0'
fragmentktx_version = '1.4.1'
ormLite_version = '4.46'
gson_version = '2.9.1'
nav_version = '2.4.2'
appcompat_version = '1.4.2'
appcompat_version = '1.5.1'
material_version = '1.6.1'
constraintlayout_version = '2.1.4'
preferencektx_version = '1.2.0'
@ -26,7 +26,7 @@ buildscript {
work_version = '2.7.1'
tink_version = '1.5.0'
json_version = '20220320'
joda_version = '2.11.0.1'
joda_version = '2.11.2'
junit_version = '4.13.2'
mockito_version = '4.4.0'
@ -51,9 +51,9 @@ buildscript {
maven { url "https://plugins.gradle.org/m2/" } // jacoco 0.2
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath 'com.google.gms:google-services:4.3.13'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.1'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View file

@ -107,7 +107,8 @@ class DetailedBolusInfo {
Bolus(
timestamp = bolusTimestamp ?: timestamp,
amount = insulin,
type = bolusType.toDBbBolusType()
type = bolusType.toDBbBolusType(),
notes = notes,
)
else null
@ -116,7 +117,8 @@ class DetailedBolusInfo {
Carbs(
timestamp = carbsTimestamp ?: timestamp,
amount = carbs,
duration = carbsDuration
duration = carbsDuration,
notes = notes,
)
else null

View file

@ -0,0 +1,36 @@
package info.nightscout.androidaps.extensions
import android.bluetooth.BluetoothAdapter
import android.os.SystemClock
/**
* @param waitMilliseconds if !=0 wait after enable()
* @param after Runnable to execute after enable()
*
* @return true if enable was executed or not necessary
*/
fun BluetoothAdapter.safeEnable(waitMilliseconds: Long = 0, after: Runnable? = null): Boolean =
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) false
else @Suppress("DEPRECATION") {
if (!isEnabled) {
val result = enable()
if (waitMilliseconds != 0L) SystemClock.sleep(waitMilliseconds)
after?.run()
result
} else true
}
/**
* @param waitMilliseconds if !=0 wait after disable()
*
* @return true if disable was executed or not necessary
*/
fun BluetoothAdapter.safeDisable(waitMilliseconds: Long = 0): Boolean =
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) false
else @Suppress("DEPRECATION") {
if (isEnabled) {
val result = disable()
if (waitMilliseconds != 0L) SystemClock.sleep(waitMilliseconds)
result
} else true
}

View file

@ -30,6 +30,7 @@ fun Bolus.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
.put("created_at", dateUtil.toISOString(timestamp))
.put("date", timestamp)
.put("type", type.name)
.put("notes", notes)
.put("isValid", isValid)
.put("isSMB", type == Bolus.Type.SMB).also {
if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId)
@ -55,6 +56,7 @@ fun bolusFromJson(jsonObject: JSONObject): Bolus? {
val amount = JsonHelper.safeGetDoubleAllowNull(jsonObject, "insulin") ?: return null
val type = Bolus.Type.fromString(JsonHelper.safeGetString(jsonObject, "type"))
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
val notes = JsonHelper.safeGetStringAllowNull(jsonObject, "notes", null)
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null) ?: return null
val pumpId = JsonHelper.safeGetLongAllowNull(jsonObject, "pumpId", null)
val pumpType = InterfaceIDs.PumpType.fromString(JsonHelper.safeGetStringAllowNull(jsonObject, "pumpType", null))
@ -67,7 +69,8 @@ fun bolusFromJson(jsonObject: JSONObject): Bolus? {
timestamp = timestamp,
amount = amount,
type = type,
isValid = isValid
notes = notes,
isValid = isValid,
).also {
it.interfaceIDs.nightscoutId = id
it.interfaceIDs.pumpId = pumpId

View file

@ -11,6 +11,7 @@ fun Carbs.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
JSONObject()
.put("eventType", if (amount < 12) TherapyEvent.Type.CARBS_CORRECTION.text else TherapyEvent.Type.MEAL_BOLUS.text)
.put("carbs", amount)
.put("notes", notes)
.put("created_at", dateUtil.toISOString(timestamp))
.put("isValid", isValid)
.put("date", timestamp).also {
@ -29,6 +30,7 @@ fun carbsFromNsIdForInvalidating(nsId: String): Carbs =
JSONObject()
.put("mills", 1)
.put("carbs", -1.0)
.put("notes", null)
.put("_id", nsId)
.put("isValid", false)
)!!
@ -37,6 +39,7 @@ fun carbsFromJson(jsonObject: JSONObject): Carbs? {
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
val duration = JsonHelper.safeGetLong(jsonObject, "duration")
val amount = JsonHelper.safeGetDoubleAllowNull(jsonObject, "carbs") ?: return null
val notes = JsonHelper.safeGetStringAllowNull(jsonObject, "notes", null)
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null) ?: return null
val pumpId = JsonHelper.safeGetLongAllowNull(jsonObject, "pumpId", null)
@ -50,6 +53,7 @@ fun carbsFromJson(jsonObject: JSONObject): Carbs? {
timestamp = timestamp,
duration = duration,
amount = amount,
notes = notes,
isValid = isValid
).also {
it.interfaceIDs.nightscoutId = id

View file

@ -0,0 +1,19 @@
package info.nightscout.androidaps.extensions
import android.content.Intent
import java.io.Serializable
/**
* Safe version of getParcelableExtra depending on Android version running
*/
fun <T> Intent.safeGetParcelableExtra(name: String?, clazz: Class<T>): T? =
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) getParcelableExtra(name, clazz)
else @Suppress("DEPRECATION") getParcelableExtra(name)
/**
* Safe version of getSerializableExtra depending on Android version running
*/
@Suppress("UNCHECKED_CAST")
fun <T : Serializable?> Intent.safeGetSerializableExtra(name: String?, clazz: Class<T>): T? =
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) getSerializableExtra(name, clazz)
else @Suppress("DEPRECATION") (getSerializableExtra(name) as T?)

View file

@ -22,6 +22,7 @@ interface Loop {
}
var lastRun: LastRun?
var closedLoopEnabled: Constraint<Boolean>?
val isSuspended: Boolean
val isLGS: Boolean
val isSuperBolus: Boolean

View file

@ -33,7 +33,7 @@ class PumpDescription() {
var basalMaximumRate = 0.0
var isRefillingCapable = false
var isBatteryReplaceable = false
var storesCarbInfo = false
//var storesCarbInfo = false
var is30minBasalRatesCapable = false
var supportsTDDs = false
var needsManualTDDLoad = false
@ -41,7 +41,7 @@ class PumpDescription() {
var isPatchPump = false
var useHardwareLink = false
fun resetSettings() {
private fun resetSettings() {
isBolusCapable = true
bolusStep = 0.1
isExtendedBolusCapable = true
@ -65,7 +65,7 @@ class PumpDescription() {
is30minBasalRatesCapable = false
isRefillingCapable = true
isBatteryReplaceable = true
storesCarbInfo = false
//storesCarbInfo = false
supportsTDDs = false
needsManualTDDLoad = true
hasCustomUnreachableAlertCheck = false
@ -101,7 +101,7 @@ class PumpDescription() {
basalMinimumRate = pumpType.baseBasalMinValue
isRefillingCapable = pumpCapability.hasCapability(PumpCapability.Refill)
isBatteryReplaceable = pumpCapability.hasCapability(PumpCapability.ReplaceBattery)
storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo)
//storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo)
supportsTDDs = pumpCapability.hasCapability(PumpCapability.TDD)
needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad)
is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min)

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import androidx.activity.result.contract.ActivityResultContract
import androidx.fragment.app.FragmentActivity
import info.nightscout.androidaps.extensions.safeGetParcelableExtra
import info.nightscout.androidaps.plugins.general.maintenance.activities.PrefImportListActivity
class PrefsFileContract : ActivityResultContract<Void?, PrefsFile?>() {
@ -15,7 +16,7 @@ class PrefsFileContract : ActivityResultContract<Void?, PrefsFile?>() {
override fun parseResult(resultCode: Int, intent: Intent?): PrefsFile? {
return when (resultCode) {
FragmentActivity.RESULT_OK -> intent?.getParcelableExtra(OUTPUT_PARAM)
FragmentActivity.RESULT_OK -> intent?.safeGetParcelableExtra(OUTPUT_PARAM, PrefsFile::class.java)
else -> null
}
}

View file

@ -114,7 +114,7 @@ class PrefImportListActivity : DaggerAppCompatActivity() {
finish()
return true
}
return false
return super.onOptionsItemSelected(item)
}
override fun attachBaseContext(newBase: Context) {

View file

@ -7,14 +7,14 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Build
import android.os.SystemClock
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.extensions.safeEnable
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import javax.inject.Inject
import javax.inject.Singleton
@ -54,10 +54,7 @@ class BlePreCheck @Inject constructor(
val bluetoothAdapter = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (bluetoothAdapter?.isEnabled != true) {
bluetoothAdapter?.enable()
SystemClock.sleep(3000)
}
bluetoothAdapter?.safeEnable(3000)
if (bluetoothAdapter?.isEnabled != true) {
OKDialog.show(activity, rh.gs(R.string.message), rh.gs(R.string.ble_not_enabled))
return false

View file

@ -8,7 +8,7 @@ enum class PumpCapability {
BasalProfileSet, // isSetBasalProfileCapable
Refill, // isRefillingCapable
ReplaceBattery, // isBatteryReplaceable
StoreCarbInfo, // storesCarbInfo
// StoreCarbInfo, // removed. incompatible with storing notes with carbs
TDD, // supportsTDDs
ManualTDDLoad, // needsManualTDDLoad
BasalRate30min, // is30minBasalRatesCapable
@ -18,7 +18,8 @@ enum class PumpCapability {
VirtualPumpCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery)),
ComboCapabilities(arrayOf(Bolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad)),
DanaCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad)),
DanaWithHistoryCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, StoreCarbInfo, TDD, ManualTDDLoad)),
//DanaWithHistoryCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, StoreCarbInfo, TDD, ManualTDDLoad)),
DanaWithHistoryCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad)),
InsightCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, BasalRate30min)),
MedtronicCapabilities(arrayOf(Bolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD)),
OmnipodCapabilities(arrayOf(Bolus, TempBasal, BasalProfileSet, BasalRate30min)),

View file

@ -10,11 +10,13 @@ import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.appcompat.view.ContextThemeWrapper
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.utils.resources.getThemeColor
object ToastUtils {
@ -27,10 +29,18 @@ object ToastUtils {
graphicalToast(ctx, string, R.drawable.ic_toast_warn, true)
}
fun warnToast(ctx: Context?, @StringRes id: Int) {
graphicalToast(ctx, ctx?.getString(id), R.drawable.ic_toast_warn, true)
}
fun infoToast(ctx: Context?, string: String?) {
graphicalToast(ctx, string, R.drawable.ic_toast_info, true)
}
fun infoToast(ctx: Context?, @StringRes id: Int) {
graphicalToast(ctx, ctx?.getString(id), R.drawable.ic_toast_info, true)
}
fun okToast(ctx: Context?, string: String?) {
graphicalToast(ctx, string, R.drawable.ic_toast_check, true)
}
@ -39,6 +49,10 @@ object ToastUtils {
graphicalToast(ctx, string, R.drawable.ic_toast_error, true)
}
fun errorToast(ctx: Context?, @StringRes id: Int) {
graphicalToast(ctx, ctx?.getString(id), R.drawable.ic_toast_error, true)
}
fun graphicalToast(ctx: Context?, string: String?, @DrawableRes iconId: Int) {
graphicalToast(ctx, string, iconId, true)
}
@ -63,7 +77,15 @@ object ToastUtils {
fun showToastInUiThread(ctx: Context?, string: String?) {
val mainThread = Handler(Looper.getMainLooper())
mainThread.post { Toast.makeText(ctx, string, Toast.LENGTH_SHORT).show() }
mainThread.post {
val toast: Toast =
Toast.makeText(
ctx,
HtmlHelper.fromHtml("<font color='" + ContextThemeWrapper(ctx, R.style.AppTheme).getThemeColor(R.attr.toastBaseTextColor) + "'>" + string + "</font>"),
Toast.LENGTH_SHORT
)
toast.show()
}
}
fun showToastInUiThread(

View file

@ -23,7 +23,7 @@ object BiometricCheck {
ERROR_VENDOR,
ERROR_LOCKOUT_PERMANENT,
ERROR_USER_CANCELED -> {
ToastUtils.showToastInUiThread(activity.baseContext, errString.toString())
ToastUtils.errorToast(activity.baseContext, errString.toString())
// fallback to master password
runOnUiThread {
passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { ok?.run() }, { cancel?.run() }, { fail?.run() })
@ -34,7 +34,7 @@ object BiometricCheck {
cancel?.run()
ERROR_NO_DEVICE_CREDENTIAL -> {
ToastUtils.showToastInUiThread(activity.baseContext, errString.toString())
ToastUtils.errorToast(activity.baseContext, errString.toString())
// no pin set
// fallback to master password
runOnUiThread {

View file

@ -148,7 +148,7 @@ class PasswordCheck @Inject constructor(
.setNegativeButton(context.getString(R.string.cancel)
) { dialog, _ ->
val msg = if (pinInput) R.string.pin_not_changed else R.string.password_not_changed
ToastUtils.infoToast(context, context.getString(msg))
ToastUtils.infoToast(context, msg)
cancel?.invoke()
dialog.cancel()
}

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.utils.ui
import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.os.Message
@ -146,14 +147,17 @@ open class NumberPicker(context: Context, attrs: AttributeSet? = null) : LinearL
.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
if (manager.isEnabled) {
val valueDescription = formatter?.format(currentValue)
AccessibilityEvent.obtain().apply {
eventType = AccessibilityEvent.TYPE_ANNOUNCEMENT
className = javaClass.name
packageName = context.packageName
text.add(valueDescription)
}.also {
manager.sendAccessibilityEvent(it)
}
@Suppress("DEPRECATION")
(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) AccessibilityEvent()
else AccessibilityEvent.obtain())
.apply {
eventType = AccessibilityEvent.TYPE_ANNOUNCEMENT
className = javaClass.name
packageName = context.packageName
text.add(valueDescription)
}.also {
manager.sendAccessibilityEvent(it)
}
}
}
@ -173,13 +177,13 @@ open class NumberPicker(context: Context, attrs: AttributeSet? = null) : LinearL
currentValue = SafeParse.stringToDouble(binding.editText.text.toString())
if (currentValue > maxValue) {
currentValue = maxValue
ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit))
ToastUtils.warnToast(context, R.string.youareonallowedlimit)
updateEditText()
okButton?.visibility = VISIBLE
}
if (currentValue < minValue) {
currentValue = minValue
ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit))
ToastUtils.warnToast(context, R.string.youareonallowedlimit)
updateEditText()
okButton?.visibility = VISIBLE
}
@ -216,11 +220,11 @@ open class NumberPicker(context: Context, attrs: AttributeSet? = null) : LinearL
get() {
if (currentValue > maxValue) {
currentValue = maxValue
ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit))
ToastUtils.warnToast(context, R.string.youareonallowedlimit)
}
if (currentValue < minValue) {
currentValue = minValue
ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit))
ToastUtils.warnToast(context, R.string.youareonallowedlimit)
}
return currentValue
}
@ -229,11 +233,11 @@ open class NumberPicker(context: Context, attrs: AttributeSet? = null) : LinearL
currentValue = value
if (currentValue > maxValue) {
currentValue = maxValue
ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit))
ToastUtils.warnToast(context, R.string.youareonallowedlimit)
}
if (currentValue < minValue) {
currentValue = minValue
ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit))
ToastUtils.warnToast(context, R.string.youareonallowedlimit)
}
callValueChangedListener()
updateEditText()
@ -248,7 +252,7 @@ open class NumberPicker(context: Context, attrs: AttributeSet? = null) : LinearL
if (currentValue > maxValue) {
currentValue = maxValue
callValueChangedListener()
ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit))
ToastUtils.warnToast(context, R.string.youareonallowedlimit)
stopUpdating()
}
updateEditText()
@ -259,7 +263,7 @@ open class NumberPicker(context: Context, attrs: AttributeSet? = null) : LinearL
if (currentValue < minValue) {
currentValue = minValue
callValueChangedListener()
ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit))
ToastUtils.warnToast(context, R.string.youareonallowedlimit)
stopUpdating()
}
updateEditText()

View file

@ -73,6 +73,7 @@ class UserEntryPresentationHelper @Inject constructor(
Sources.PocTech -> R.drawable.ic_poctech
Sources.Tomato -> R.drawable.ic_sensor
Sources.Glunovo -> R.drawable.ic_glunovo
Sources.Intelligo -> R.drawable.ic_intelligo
Sources.Xdrip -> R.drawable.ic_blooddrop_48
Sources.LocalProfile -> R.drawable.ic_local_profile
Sources.Loop -> R.drawable.ic_loop_closed_white

View file

@ -0,0 +1,85 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="64dp"
android:height="64dp"
android:viewportWidth="64"
android:viewportHeight="64">
<path
android:pathData="M51.787,23.533c-0.01,-10.925 -8.888,-19.787 -19.813,-19.777c-10.925,0.01 -19.787,8.889 -19.777,19.814l0.016,16.897c0.01,10.925 8.888,19.787 19.813,19.777c10.925,-0.01 19.787,-8.889 19.777,-19.814l-0.016,-16.897Z"
android:fillColor="#ebeae3"/>
<path
android:pathData="M46.353,25.52c-0.007,-7.925 -6.447,-14.353 -14.372,-14.346c-7.925,0.008 -14.353,6.448 -14.346,14.373l0.015,16.092c0.006,6.181 5.029,11.195 11.21,11.19l6.318,-0.006c6.182,-0.006 11.196,-5.029 11.19,-11.211l-0.015,-16.092Z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="31.4229"
android:startX="17.6405"
android:endY="30.819769"
android:endX="58.322098"
android:type="linear">
<item android:offset="0" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FFB3B3B3"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M22.928,44.362l-0.021,-22.414c-0.004,-4.01 3.249,-7.27 7.26,-7.273l3.634,-0.004c4.011,-0.003 7.27,3.25 7.274,7.261l0.02,22.413c-0.638,2.068 -1.683,3.934 -3.208,5.56l-11.85,0.011c-1.578,-1.46 -2.517,-3.384 -3.119,-5.554l0.01,-0Z"
android:strokeWidth="0.56"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:fillColor="@android:color/black"
android:pathData="M28.826,46.02l-2.759,0.002l-0.001,-0.899c-0,-0.158 0.008,-0.279 0.026,-0.362c0.022,-0.117 0.065,-0.216 0.129,-0.295c0.063,-0.079 0.152,-0.143 0.266,-0.191c0.114,-0.048 0.239,-0.073 0.376,-0.073c0.235,0 0.434,0.064 0.596,0.193c0.163,0.129 0.244,0.362 0.245,0.699l0,0.611l1.122,-0.001l0,0.316ZM27.378,45.706l-0,-0.616c-0,-0.204 -0.044,-0.349 -0.132,-0.434c-0.088,-0.086 -0.212,-0.129 -0.371,-0.129c-0.116,0.001 -0.214,0.026 -0.297,0.076c-0.082,0.051 -0.136,0.117 -0.162,0.2c-0.017,0.053 -0.025,0.151 -0.025,0.294l0.001,0.61l0.986,-0.001Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M27.48,43.896c-0.458,0.001 -0.816,-0.105 -1.076,-0.317c-0.259,-0.213 -0.389,-0.487 -0.389,-0.823c-0,-0.22 0.06,-0.418 0.182,-0.595c0.122,-0.177 0.291,-0.311 0.509,-0.404c0.217,-0.093 0.464,-0.14 0.74,-0.14c0.28,-0 0.531,0.048 0.752,0.146c0.221,0.097 0.388,0.235 0.502,0.414c0.114,0.179 0.171,0.371 0.171,0.578c-0,0.225 -0.063,0.425 -0.188,0.602c-0.125,0.177 -0.297,0.311 -0.514,0.402c-0.217,0.091 -0.446,0.137 -0.689,0.137ZM27.486,43.571c0.332,-0 0.594,-0.078 0.786,-0.232c0.191,-0.155 0.286,-0.349 0.286,-0.582c-0,-0.237 -0.097,-0.432 -0.29,-0.585c-0.194,-0.154 -0.468,-0.23 -0.823,-0.23c-0.225,0 -0.421,0.033 -0.588,0.099c-0.168,0.066 -0.298,0.162 -0.39,0.288c-0.092,0.127 -0.138,0.268 -0.138,0.425c0,0.224 0.089,0.416 0.267,0.576c0.178,0.161 0.474,0.241 0.89,0.241Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M27.853,39.51l0.092,-0.316c0.3,0.066 0.529,0.185 0.687,0.357c0.157,0.171 0.236,0.381 0.236,0.629c0.001,0.257 -0.06,0.466 -0.181,0.627c-0.121,0.161 -0.296,0.284 -0.526,0.368c-0.229,0.084 -0.476,0.127 -0.739,0.127c-0.288,0 -0.538,-0.047 -0.752,-0.142c-0.215,-0.094 -0.377,-0.229 -0.488,-0.404c-0.112,-0.175 -0.167,-0.368 -0.168,-0.578c0,-0.238 0.07,-0.439 0.211,-0.602c0.14,-0.162 0.338,-0.276 0.593,-0.34l0.085,0.311c-0.201,0.055 -0.347,0.135 -0.439,0.24c-0.091,0.106 -0.137,0.238 -0.137,0.397c0,0.183 0.051,0.336 0.153,0.459c0.102,0.123 0.238,0.21 0.41,0.259c0.171,0.05 0.348,0.075 0.53,0.075c0.234,-0.001 0.439,-0.03 0.614,-0.089c0.175,-0.06 0.306,-0.152 0.392,-0.276c0.087,-0.125 0.13,-0.26 0.13,-0.405c-0,-0.177 -0.059,-0.326 -0.177,-0.449c-0.118,-0.122 -0.294,-0.205 -0.526,-0.248Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M28.82,38.199l-2.434,0.002l0,0.785l-0.325,0l-0.002,-1.889l0.326,0l0,0.789l2.434,-0.003l0.001,0.316Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M28.174,36.055l0.043,-0.302c0.205,0.047 0.363,0.135 0.477,0.264c0.113,0.129 0.169,0.294 0.169,0.494c0.001,0.253 -0.089,0.453 -0.269,0.601c-0.18,0.148 -0.433,0.222 -0.758,0.223c-0.336,-0 -0.597,-0.075 -0.783,-0.224c-0.186,-0.149 -0.279,-0.343 -0.279,-0.582c-0,-0.231 0.09,-0.419 0.272,-0.566c0.182,-0.146 0.438,-0.22 0.768,-0.22c0.02,0 0.05,0.001 0.091,0.002l0.001,1.287c0.219,-0.011 0.387,-0.065 0.504,-0.161c0.117,-0.097 0.175,-0.217 0.175,-0.361c-0,-0.107 -0.033,-0.199 -0.098,-0.275c-0.066,-0.076 -0.17,-0.136 -0.313,-0.18ZM27.627,37.016l-0.001,-0.964c-0.168,0.013 -0.294,0.05 -0.378,0.111c-0.131,0.093 -0.196,0.214 -0.196,0.363c0,0.134 0.053,0.247 0.157,0.339c0.104,0.091 0.244,0.142 0.418,0.151Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M28.084,34.259l0.043,-0.288c0.23,0.031 0.41,0.112 0.54,0.241c0.13,0.129 0.195,0.288 0.195,0.477c0,0.236 -0.089,0.426 -0.268,0.57c-0.179,0.144 -0.435,0.216 -0.769,0.216c-0.216,0 -0.405,-0.031 -0.567,-0.092c-0.161,-0.062 -0.283,-0.156 -0.364,-0.282c-0.081,-0.126 -0.122,-0.263 -0.122,-0.412c0,-0.187 0.055,-0.341 0.164,-0.46c0.11,-0.119 0.266,-0.196 0.468,-0.23l0.051,0.285c-0.134,0.027 -0.235,0.075 -0.303,0.144c-0.067,0.069 -0.101,0.152 -0.101,0.249c-0,0.148 0.061,0.268 0.184,0.36c0.122,0.092 0.316,0.137 0.581,0.137c0.268,-0 0.463,-0.045 0.585,-0.134c0.122,-0.089 0.182,-0.205 0.182,-0.348c0,-0.115 -0.041,-0.21 -0.122,-0.287c-0.082,-0.077 -0.208,-0.126 -0.377,-0.146Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M28.816,33.72l-2.76,0.002l-0,-0.292l0.99,-0.001c-0.183,-0.136 -0.275,-0.309 -0.275,-0.517c-0,-0.128 0.029,-0.239 0.087,-0.333c0.058,-0.094 0.139,-0.162 0.242,-0.203c0.102,-0.04 0.252,-0.061 0.448,-0.061l1.267,-0.001l-0,0.292l-1.267,0.002c-0.17,-0 -0.293,0.032 -0.37,0.095c-0.077,0.063 -0.116,0.153 -0.116,0.269c0.001,0.087 0.027,0.168 0.079,0.245c0.052,0.076 0.123,0.13 0.212,0.163c0.089,0.032 0.212,0.048 0.369,0.048l1.094,-0.001l-0,0.293Z"
android:fillType="nonZero"/>
<path
android:fillColor="#FF000000"
android:pathData="M27.844,29.206l0.092,-0.315c0.3,0.066 0.529,0.185 0.687,0.356c0.157,0.172 0.236,0.382 0.237,0.63c-0,0.257 -0.061,0.466 -0.182,0.627c-0.121,0.161 -0.296,0.283 -0.525,0.368c-0.23,0.084 -0.477,0.126 -0.74,0.126c-0.288,0.001 -0.538,-0.047 -0.752,-0.141c-0.214,-0.095 -0.377,-0.23 -0.488,-0.405c-0.112,-0.175 -0.167,-0.367 -0.167,-0.577c-0.001,-0.239 0.069,-0.439 0.21,-0.602c0.14,-0.163 0.338,-0.276 0.593,-0.34l0.085,0.31c-0.201,0.056 -0.347,0.136 -0.439,0.241c-0.091,0.105 -0.137,0.237 -0.137,0.397c0,0.183 0.051,0.336 0.153,0.459c0.102,0.123 0.238,0.209 0.41,0.259c0.171,0.05 0.348,0.074 0.53,0.074c0.234,-0 0.439,-0.03 0.614,-0.089c0.175,-0.059 0.306,-0.151 0.393,-0.276c0.086,-0.125 0.129,-0.26 0.129,-0.405c-0,-0.176 -0.059,-0.326 -0.177,-0.448c-0.118,-0.123 -0.294,-0.205 -0.526,-0.249Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M28.811,27.895l-2.434,0.002l0,0.786l-0.325,-0l-0.002,-1.889l0.326,-0l0,0.788l2.434,-0.002l0.001,0.315Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M27.982,26.833l-0.341,-0l-0.001,-0.899l0.341,-0l0.001,0.899Z"
android:fillType="nonZero"/>
<path
android:fillColor="#FF000000"
android:pathData="M28.808,24.589l0,0.292l-2.159,0.002c0.078,0.07 0.156,0.163 0.234,0.277c0.077,0.114 0.136,0.217 0.175,0.308l-0.328,0c-0.089,-0.163 -0.197,-0.306 -0.324,-0.429c-0.127,-0.122 -0.25,-0.209 -0.369,-0.259l-0,-0.189l2.771,-0.002Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M27.446,23.84c-0.326,0.001 -0.589,-0.028 -0.788,-0.086c-0.199,-0.058 -0.352,-0.144 -0.46,-0.258c-0.108,-0.114 -0.162,-0.258 -0.163,-0.431c0,-0.128 0.03,-0.241 0.09,-0.337c0.059,-0.097 0.145,-0.176 0.257,-0.239c0.113,-0.063 0.249,-0.113 0.411,-0.149c0.161,-0.035 0.378,-0.054 0.652,-0.054c0.324,-0 0.585,0.028 0.784,0.086c0.199,0.057 0.353,0.143 0.461,0.257c0.109,0.114 0.163,0.259 0.164,0.433c-0,0.23 -0.095,0.41 -0.286,0.542c-0.23,0.157 -0.604,0.236 -1.122,0.236ZM27.446,23.54c0.453,-0.001 0.754,-0.047 0.904,-0.139c0.15,-0.091 0.225,-0.204 0.225,-0.339c-0,-0.134 -0.075,-0.247 -0.226,-0.338c-0.151,-0.092 -0.452,-0.137 -0.904,-0.137c-0.454,0 -0.756,0.046 -0.905,0.138c-0.15,0.092 -0.224,0.206 -0.224,0.343c0,0.134 0.066,0.241 0.198,0.321c0.168,0.101 0.479,0.151 0.932,0.151Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M27.445,21.989c-0.327,0 -0.589,-0.029 -0.788,-0.087c-0.199,-0.057 -0.353,-0.143 -0.461,-0.258c-0.108,-0.114 -0.162,-0.258 -0.162,-0.431c-0,-0.128 0.029,-0.24 0.089,-0.337c0.059,-0.096 0.145,-0.176 0.258,-0.239c0.112,-0.063 0.249,-0.112 0.41,-0.148c0.161,-0.036 0.379,-0.054 0.652,-0.054c0.324,-0.001 0.585,0.028 0.784,0.085c0.199,0.057 0.353,0.143 0.462,0.257c0.108,0.115 0.163,0.259 0.163,0.433c0,0.23 -0.095,0.411 -0.286,0.542c-0.229,0.157 -0.603,0.236 -1.121,0.237ZM27.444,21.688c0.453,-0 0.755,-0.046 0.905,-0.138c0.15,-0.092 0.225,-0.205 0.224,-0.339c0,-0.135 -0.075,-0.248 -0.226,-0.339c-0.15,-0.091 -0.452,-0.137 -0.904,-0.137c-0.454,0.001 -0.756,0.047 -0.905,0.139c-0.149,0.091 -0.224,0.205 -0.224,0.342c0,0.134 0.066,0.242 0.198,0.322c0.169,0.1 0.479,0.15 0.932,0.15Z"
android:fillType="nonZero"/>
<path
android:fillColor="@android:color/black"
android:pathData="M27.307,19.687c-0.051,0.121 -0.125,0.211 -0.22,0.27c-0.095,0.059 -0.21,0.088 -0.343,0.088c-0.2,0 -0.369,-0.062 -0.506,-0.186c-0.137,-0.125 -0.206,-0.291 -0.206,-0.498c0,-0.208 0.07,-0.375 0.21,-0.502c0.14,-0.127 0.31,-0.191 0.511,-0.191c0.128,0 0.239,0.029 0.334,0.087c0.095,0.058 0.168,0.146 0.219,0.264c0.056,-0.147 0.145,-0.258 0.267,-0.334c0.123,-0.077 0.27,-0.115 0.441,-0.115c0.236,-0.001 0.434,0.071 0.595,0.215c0.161,0.144 0.241,0.334 0.241,0.569c0.001,0.235 -0.08,0.425 -0.241,0.569c-0.161,0.144 -0.362,0.217 -0.603,0.217c-0.18,0 -0.33,-0.039 -0.451,-0.118c-0.121,-0.078 -0.204,-0.19 -0.248,-0.335ZM26.733,19.746c0.13,-0 0.237,-0.037 0.32,-0.109c0.083,-0.073 0.124,-0.167 0.124,-0.283c-0,-0.113 -0.041,-0.205 -0.124,-0.277c-0.082,-0.072 -0.183,-0.108 -0.302,-0.108c-0.124,0 -0.229,0.037 -0.313,0.112c-0.085,0.074 -0.127,0.166 -0.127,0.277c-0,0.111 0.041,0.204 0.124,0.278c0.083,0.073 0.182,0.11 0.298,0.11ZM28.007,19.839c0.097,0 0.191,-0.02 0.281,-0.059c0.09,-0.04 0.16,-0.099 0.21,-0.177c0.049,-0.078 0.074,-0.162 0.074,-0.252c-0,-0.14 -0.052,-0.255 -0.157,-0.346c-0.104,-0.091 -0.236,-0.136 -0.397,-0.136c-0.163,-0 -0.298,0.047 -0.405,0.141c-0.106,0.093 -0.16,0.211 -0.159,0.352c-0,0.137 0.053,0.251 0.158,0.342c0.106,0.09 0.237,0.135 0.395,0.135Z"
android:fillType="nonZero"/>
</vector>

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/toast_border_ok">
android:background="?attr/toastBackgroundColor">
<ImageView
android:id="@android:id/icon"
@ -26,7 +26,7 @@
android:layout_marginTop="4dp"
android:layout_marginEnd="18dp"
android:layout_marginBottom="4dp"
android:textColor="?attr/toastBaseTextColor"
android:textColor="?attr/defaultTextColor"
android:textSize="18sp"
tools:ignore="RtlHardcoded"
tools:text="Toast goes here..." />

View file

@ -31,6 +31,7 @@
<string name="format_mins">%1$d min</string>
<string name="pumpbusy">Bomba ocupada</string>
<string name="connectionerror">Error de conexión de la bomba</string>
<string name="youareonallowedlimit">Límite permitido alcanzado</string>
<string name="objectives">Objetivos</string>
<string name="close">Cerrar</string>
<string name="please_wait">Por favor, espere…</string>
@ -39,6 +40,7 @@
<string name="stoppressed">STOP pulsado</string>
<string name="stop">Detener</string>
<string name="carbs">Carbohidratos [g]</string>
<string name="invalidprofile">¡Perfil inválido!</string>
<string name="noprofileset">NINGÚN PERFIL ACTIVO</string>
<string name="active"><![CDATA[<Activo>]]></string>
<string name="date">Fecha</string>
@ -51,6 +53,7 @@
<string name="dia_long_label">Duración de la insulina activa</string>
<string name="ic_long_label">Ratio de insulina/carbohidratos</string>
<string name="isf_long_label">Factor de sensibilidad a la insulina</string>
<string name="basal_long_label">Tasa basal</string>
<string name="target_long_label">Objetivo de glucosa en sangre</string>
<string name="initializing">Iniciando...</string>
<string name="serialnumber">Número de serie</string>
@ -137,6 +140,7 @@
<string name="pin_dont_match">Los códigos PIN no coinciden</string>
<!-- Profile-->
<string name="basalprofilenotaligned">Valores basales no alineados a las horas: %1$s</string>
<string name="minimalbasalvaluereplaced">Valor basal cambiado al valor mínimo soportado: %1$s</string>
<string name="maximumbasalvaluereplaced">Valor basal reemplazado por el valor máximo soportado: %1$s</string>
<string name="profile_per_unit">/U</string>
<string name="profile_ins_units_per_hour">U/h</string>
@ -217,6 +221,7 @@
<string name="waitingforpumpresult">Esperando resultado</string>
<string name="smb_shortname">SMB</string>
<!-- CarbsReq-->
<string name="carbsreq">%1$d g carbohidratos adicionales necesarios en %2$d minutos</string>
<!-- TDDStatsActivity-->
<string name="stats">Estadísticas</string>
<string name="cumulative_tdd">TDD acumulada</string>
@ -228,6 +233,7 @@
<string name="amount_days"># Días</string>
<string name="weight">Peso</string>
<string name="warning_Message">Probablemente impreciso si se usan bolos para llenar/rellenar!</string>
<string name="olddata_Message">Datos caducados, por favor pulsa \"RECARGAR\"</string>
<string name="tbb">Basal total</string>
<string name="tbb2">Basal diaria *2</string>
<!-- Ntp-->
@ -391,6 +397,9 @@
<string name="valueoutofrange">»%1$s« está fuera del límite estricto</string>
<string name="value_out_of_hard_limits">»%1$s« %2$.2f está fuera de los límites estrictos</string>
<string name="basal_value">Valor basal</string>
<string name="nsclient_version_does_not_match">La versión de NSClient no coincide con la versión de AndroidAPS. Por favor, actualízala.
.</string>
<!-- Command Queue + readStatus reasons -->
<string name="bolus_u_min">BOLO %1$.2f U</string>
<string name="carbs_g">CARBOHIDRATOS %1$d g</string>

View file

@ -446,7 +446,7 @@
<string name="autotune_description">Aide pour ajuster le profil (SI, rapport G/I et débits de basal)</string>
<string name="autotune_shortname">AT</string>
<string name="autotune_settings">Paramètres Autotune</string>
<string name="autotune_auto_title">Changr le profil avec l\'automatisation</string>
<string name="autotune_auto_title">Changer le profil avec l\'automatisation</string>
<string name="autotune_auto_summary">Si activé, Autotune mettra à jour automatiquement à jour le profil sélectionné et activera le profil calculé effectué à partir d\'une règle d\'automatisation.</string>
<string name="autotune_categorize_uam_as_basal_title">Catégoriser UAM en tant que Basal</string>
<string name="autotune_categorize_uam_as_basal_summary">Activer uniquement si vous avez correctement saisi tous les glucides consommés, avec cette option, des hausses soudaines vues par Autotune seront utilisées pour modifier les débits de basal.</string>

View file

@ -31,6 +31,7 @@
<string name="format_mins">%1$d min</string>
<string name="pumpbusy">Il micro è occupato</string>
<string name="connectionerror">Errore connessione micro</string>
<string name="youareonallowedlimit">Limite consentito raggiunto</string>
<string name="objectives">Obiettivi</string>
<string name="close">Chiudi</string>
<string name="please_wait">Attendi…</string>
@ -39,6 +40,7 @@
<string name="stoppressed">STOP PREMUTO</string>
<string name="stop">Stop</string>
<string name="carbs">CHO</string>
<string name="invalidprofile">Profilo non valido!</string>
<string name="noprofileset">NESSUN PROFILO IMPOSTATO</string>
<string name="active"><![CDATA[<Active>]]></string>
<string name="date">Data</string>
@ -51,6 +53,7 @@
<string name="dia_long_label">Durata dellazione dellinsulina</string>
<string name="ic_long_label">Rapporto Insulina-Carboidrati (I:C)</string>
<string name="isf_long_label">Fattore di sensibilità insulinica (ISF)</string>
<string name="basal_long_label">Velocità basale</string>
<string name="target_long_label">Target glicemia</string>
<string name="initializing">Inizializzazione...</string>
<string name="serialnumber">Numero seriale</string>
@ -137,6 +140,7 @@
<string name="pin_dont_match">I PIN non coincidono</string>
<!-- Profile-->
<string name="basalprofilenotaligned">Valori basali non allineati alle ore: %1$s</string>
<string name="minimalbasalvaluereplaced">Valore basale sostituito dal minimo valore supportato: %1$s</string>
<string name="maximumbasalvaluereplaced">Valore basale sostituito dal massimo valore supportato: %1$s</string>
<string name="profile_per_unit">/U</string>
<string name="profile_ins_units_per_hour">U/h</string>
@ -217,6 +221,7 @@
<string name="waitingforpumpresult">In attesa del risultato</string>
<string name="smb_shortname">SMB</string>
<!-- CarbsReq-->
<string name="carbsreq">%1$d g di CHO aggiuntivi richiesti entro %2$d minuti</string>
<!-- TDDStatsActivity-->
<string name="stats">Statistiche</string>
<string name="cumulative_tdd">TDD cumulativo</string>
@ -228,6 +233,7 @@
<string name="amount_days"># Giorni</string>
<string name="weight">Peso</string>
<string name="warning_Message">Probabilmente inaccurato se per il caricamento/riempimento si usano i boli al posto dell\'apposita funzione!</string>
<string name="olddata_Message">Dati vecchi, premi \"RICARICA\"</string>
<string name="tbb">Basale originale totale</string>
<string name="tbb2">TBB * 2</string>
<!-- Ntp-->
@ -391,6 +397,7 @@
<string name="valueoutofrange">»%1$s« è fuori dai limiti consentiti</string>
<string name="value_out_of_hard_limits">»%1$s« %2$.2f è fuori dai limiti consentiti</string>
<string name="basal_value">Valore basale</string>
<string name="nsclient_version_does_not_match">La versione di NSClient non corrisponde alla versione di AndroidAPS. Aggiorna.</string>
<!-- Command Queue + readStatus reasons -->
<string name="bolus_u_min">BOLO %1$.2f U</string>
<string name="carbs_g">CHO %1$d g</string>

View file

@ -109,7 +109,7 @@
<!-- Toasts-->
<color name="toastBorder">#666666</color>
<color name="toastBase">#ffffff</color>
<color name="toastBase">#000000</color>
<color name="toastOk">#77dd77</color>
<color name="toastError">#ff0400</color>
<color name="toastWarn">#FF8C00</color>

View file

@ -95,6 +95,7 @@
<item name="defaultBackground">@color/defaultBackground</item>
<!---Toast -->
<item name="toastBaseTextColor">@color/toastBase</item>
<item name="toastBackgroundColor">@color/buttonBackground</item>
<!---Dialog Helper -->
<item name="materialAlertDialogTheme">@style/DialogTheme</item>
<item name="android:alertDialogTheme">@style/DialogTheme</item>

View file

@ -31,6 +31,7 @@
<string name="format_mins">%1$d min</string>
<string name="pumpbusy">Pumpen er opptatt</string>
<string name="connectionerror">Tilkoblingsfeil til pumpe</string>
<string name="youareonallowedlimit">Tillatt grense nådd</string>
<string name="objectives">Opplæringsmål</string>
<string name="close">Lukk</string>
<string name="please_wait">Vennligst vent…</string>
@ -39,6 +40,7 @@
<string name="stoppressed">STOPP trykket</string>
<string name="stop">Stopp</string>
<string name="carbs">Karbohydrater</string>
<string name="invalidprofile">Ugyldig profil!</string>
<string name="noprofileset">INGEN PROFIL VALGT</string>
<string name="active"><![CDATA[<Active>]]></string>
<string name="date">Dato</string>
@ -51,6 +53,7 @@
<string name="dia_long_label">Insulinets virkningstid (DIA)</string>
<string name="ic_long_label">Insulin- til karbohydratfaktor</string>
<string name="isf_long_label">Insulin sensitivitetsfaktor (ISF)</string>
<string name="basal_long_label">Basalrate</string>
<string name="target_long_label">Blodsukkermål</string>
<string name="initializing">Starter opp...</string>
<string name="serialnumber">Serienummer</string>
@ -137,6 +140,7 @@
<string name="pin_dont_match">PIN-kodene samsvarer ikke</string>
<!-- Profile-->
<string name="basalprofilenotaligned">Basal verdier er ikke angitt på hele timer: %1$s</string>
<string name="minimalbasalvaluereplaced">Basalverdi erstattet med minste tillate verdi: %1$s</string>
<string name="maximumbasalvaluereplaced">Basal verdi erstattet med høyeste tillate verdi: %1$s</string>
<string name="profile_per_unit">/E</string>
<string name="profile_ins_units_per_hour">E/t</string>
@ -217,6 +221,7 @@
<string name="waitingforpumpresult">Venter på resultat</string>
<string name="smb_shortname">SMB</string>
<!-- CarbsReq-->
<string name="carbsreq">%1$d g ekstra karbohydrater kreves innen %2$d minutter</string>
<!-- TDDStatsActivity-->
<string name="stats">Statistikk</string>
<string name="cumulative_tdd">Akkumulert TDD</string>
@ -228,6 +233,7 @@
<string name="amount_days">Antall dager</string>
<string name="weight">Vekt</string>
<string name="warning_Message">Kan vise feil hvis bolus brukes for priming/fylling!</string>
<string name="olddata_Message">Gamle data. Vennligst trykk \"HENT\"</string>
<string name="tbb">Total grunnbasal</string>
<string name="tbb2">TBB * 2</string>
<!-- Ntp-->
@ -391,6 +397,7 @@
<string name="valueoutofrange">»%1$s« er utenfor lovlige grenseverdier</string>
<string name="value_out_of_hard_limits">»%1$s« %2$.2f er utenfor lovlige grenseverdier</string>
<string name="basal_value">Basal verdi</string>
<string name="nsclient_version_does_not_match">NSClient-versjonen samsvarer ikke med AndroidAPS-versjonen. Vennligst oppdater.</string>
<!-- Command Queue + readStatus reasons -->
<string name="bolus_u_min">BOLUS %1$.2f E</string>
<string name="carbs_g">CARBS %1$d g</string>

View file

@ -31,6 +31,7 @@
<string name="format_mins">%1$d мин</string>
<string name="pumpbusy">помпа занята</string>
<string name="connectionerror">ошибка соединения</string>
<string name="youareonallowedlimit">Разрешенный предел достигнут</string>
<string name="objectives">Цели</string>
<string name="close">Закрыть</string>
<string name="please_wait">Подождите…</string>
@ -39,6 +40,7 @@
<string name="stoppressed">нажат стоп</string>
<string name="stop">стоп</string>
<string name="carbs">Углеводы</string>
<string name="invalidprofile">Недопустимый профиль!</string>
<string name="noprofileset">ПРОФИЛЬ НЕ ЗАДАН</string>
<string name="active"><![CDATA[Активен]]></string>
<string name="date">дата</string>
@ -51,6 +53,7 @@
<string name="dia_long_label">Продолжительность действия инсулина</string>
<string name="ic_long_label">Соотношение инсулин/углеводы I: C</string>
<string name="isf_long_label">Фактор Чувствительности к Инсулину (ISF)</string>
<string name="basal_long_label">Базальная скорость</string>
<string name="target_long_label">Целевая ГК</string>
<string name="initializing">инициализация...</string>
<string name="serialnumber">Серийный номер</string>
@ -137,6 +140,7 @@
<string name="pin_dont_match">PIN-коды не совпадают</string>
<!-- Profile-->
<string name="basalprofilenotaligned">Базальные значения не выровнены по часам: %1$s</string>
<string name="minimalbasalvaluereplaced">Значение базала заменено минимальной поддерживаемой величиной: %1$s</string>
<string name="maximumbasalvaluereplaced">Значение базала заменено максимальной поддерживаемой величиной: %1$s</string>
<string name="profile_per_unit">/ед</string>
<string name="profile_ins_units_per_hour">ед/ч</string>
@ -217,6 +221,7 @@
<string name="waitingforpumpresult">Ожидание результата</string>
<string name="smb_shortname">Супер микро болюс SMB</string>
<!-- CarbsReq-->
<string name="carbsreq">Необходимо дополнительно %1$d г углеводов в течение %2$d минут</string>
<!-- TDDStatsActivity-->
<string name="stats">Статистика</string>
<string name="cumulative_tdd">накопительные TDD</string>
@ -228,6 +233,7 @@
<string name="amount_days">количество дней</string>
<string name="weight">вес</string>
<string name="warning_Message">возможны неточности если болюсы использовались для заполнения</string>
<string name="olddata_Message">Старые данные. Нажмите \"перезагрузка\"</string>
<string name="tbb">общий базал</string>
<string name="tbb2">общий базал*2</string>
<!-- Ntp-->
@ -391,6 +397,7 @@
<string name="valueoutofrange">»%1$s« за пределами жестких ограничений</string>
<string name="value_out_of_hard_limits">»%1$s« %2$.2f за пределами жестких ограничений</string>
<string name="basal_value">Величина базала</string>
<string name="nsclient_version_does_not_match">Версия NSClient не совпадает с версией AndroidAPS. Обновите версию.</string>
<!-- Command Queue + readStatus reasons -->
<string name="bolus_u_min">БОЛЮС %1$.2f ЕД</string>
<string name="carbs_g">УГЛ %1$d г</string>

View file

@ -65,6 +65,7 @@
<attr name="defaultBackground" format="reference|color" />
<!---Toast -->
<attr name="toastBaseTextColor" format="reference|color" />
<attr name="toastBackgroundColor" format="reference|color" />
<declare-styleable name="NumberPicker">
<attr name="customContentDescription" format="string" />
</declare-styleable>

View file

@ -111,7 +111,7 @@
<!-- Toasts-->
<color name="toastBorder">#666666</color>
<color name="toastBase">#ffffff</color>
<color name="toastBase">#000000</color>
<color name="toastOk">#77dd77</color>
<color name="toastError">#ff0400</color>
<color name="toastWarn">#FF8C00</color>

View file

@ -100,6 +100,7 @@
<item name="defaultBackground">@color/white</item>
<!---Toast -->
<item name="toastBaseTextColor">@color/toastBase</item>
<item name="toastBackgroundColor">@color/colorLightGray</item>
<!---Dialog Helper -->
<item name="materialAlertDialogTheme">@style/DialogTheme</item>
<item name="android:alertDialogTheme">@style/DialogTheme</item>

View file

@ -90,12 +90,13 @@ open class TestBaseWithProfile : TestBase() {
json.put("store", store)
return ProfileStore(profileInjector, json, dateUtil)
}
fun getInvalidProfileStore2(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
store.put("invalid", JSONObject(invalidProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("defaultProfile", TESTPROFILENAME + "invalid")
json.put("store", store)
return ProfileStore(profileInjector, json, dateUtil)
}

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.data.PureProfile
import org.json.JSONObject
import org.junit.Assert
import org.junit.Test
@ -20,6 +21,7 @@ internal class ProfileStoreTest : TestBaseWithProfile() {
@Test
fun getDefaultProfileJsonTest() {
Assert.assertTrue(getValidProfileStore().getDefaultProfileJson()?.has("dia") ?: false)
Assert.assertEquals(null, getInvalidProfileStore2().getDefaultProfileJson())
}
@Test

View file

@ -215,13 +215,13 @@ public abstract class AbstractDanaRExecutionService extends DaggerService {
}
}
} else {
ToastUtils.INSTANCE.showToastInUiThread(context.getApplicationContext(), rh.gs(R.string.nobtadapter));
ToastUtils.INSTANCE.errorToast(context.getApplicationContext(), R.string.nobtadapter);
}
if (mBTDevice == null) {
ToastUtils.INSTANCE.showToastInUiThread(context.getApplicationContext(), rh.gs(R.string.devicenotfound));
ToastUtils.INSTANCE.errorToast(context.getApplicationContext(), R.string.devicenotfound);
}
} else {
ToastUtils.INSTANCE.errorToast(context, context.getString(R.string.needconnectpermission));
ToastUtils.INSTANCE.errorToast(context, R.string.needconnectpermission);
}
}

View file

@ -146,7 +146,7 @@ class DanaRSPlugin @Inject constructor(
aapsLogger.debug(LTag.PUMP, "RS connect from: $reason")
if (danaRSService != null && mDeviceAddress != "" && mDeviceName != "") {
val success = danaRSService?.connect(reason, mDeviceAddress) ?: false
if (!success) ToastUtils.showToastInUiThread(context, rh.gs(R.string.ble_not_supported_or_not_paired))
if (!success) ToastUtils.errorToast(context, R.string.ble_not_supported_or_not_paired)
}
}

View file

@ -24,6 +24,7 @@ import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.danars.R
import info.nightscout.androidaps.danars.databinding.DanarsBlescannerActivityBinding
import info.nightscout.androidaps.danars.events.EventDanaRSDeviceChange
import info.nightscout.androidaps.extensions.safeEnable
import info.nightscout.androidaps.plugins.pump.common.ble.BlePreCheck
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.shared.sharedPreferences.SP
@ -62,7 +63,7 @@ class BLEScanActivity : NoSplashAppCompatActivity() {
super.onResume()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
if (bluetoothAdapter?.isEnabled != true) bluetoothAdapter?.enable()
bluetoothAdapter?.safeEnable()
startScan()
} else {
ToastUtils.errorToast(context, context.getString(info.nightscout.androidaps.core.R.string.needconnectpermission))
@ -180,20 +181,13 @@ class BLEScanActivity : NoSplashAppCompatActivity() {
if (other !is BluetoothDeviceItem) {
return false
}
return stringEquals(device.address, other.device.address)
}
private fun stringEquals(arg1: String, arg2: String): Boolean {
return try {
arg1 == arg2
} catch (e: Exception) {
false
}
return device.address == other.device.address
}
override fun hashCode(): Int = device.hashCode()
}
@Suppress("RegExpSimplifiable")
private fun isSNCheck(sn: String): Boolean {
val regex = "^([a-zA-Z]{3})([0-9]{5})([a-zA-Z]{2})$"
val p = Pattern.compile(regex)

View file

@ -158,7 +158,7 @@ class BLEComm @Inject internal constructor(
// assume pairing keys are invalid
val lastClearRequest = sp.getLong(R.string.key_rs_last_clear_key_request, 0)
if (lastClearRequest != 0L && dateUtil.isOlderThan(lastClearRequest, 5)) {
ToastUtils.showToastInUiThread(context, R.string.invalidpairing)
ToastUtils.errorToast(context, R.string.invalidpairing)
danaRSPlugin.changePump()
removeBond()
} else if (lastClearRequest == 0L) {
@ -175,7 +175,7 @@ class BLEComm @Inject internal constructor(
sp.remove(rh.gs(R.string.key_danars_v3_randompairingkey) + danaRSPlugin.mDeviceName)
sp.remove(rh.gs(R.string.key_danars_v3_pairingkey) + danaRSPlugin.mDeviceName)
sp.remove(rh.gs(R.string.key_danars_v3_randomsynckey) + danaRSPlugin.mDeviceName)
ToastUtils.showToastInUiThread(context, R.string.invalidpairing)
ToastUtils.errorToast(context, R.string.invalidpairing)
danaRSPlugin.changePump()
} else if (lastClearRequest == 0L) {
aapsLogger.error("Clearing pairing keys postponed")
@ -213,35 +213,12 @@ class BLEComm @Inject internal constructor(
@SuppressLint("MissingPermission")
@Synchronized fun close() {
/*
if (!encryptedDataRead && !encryptedCommandSent) {
// there was no response from pump before started encryption
// assume pairing is invalid
val lastClearRequest = sp.getLong(R.string.key_rs_last_clear_key_request, 0)
if (lastClearRequest != 0L && dateUtil.isOlderThan(lastClearRequest, 5)) {
ToastUtils.showToastInUiThread(context, R.string.invalidpairing)
danaRSPlugin.changePump()
sp.getStringOrNull(R.string.key_danars_address, null)?.let { address ->
bluetoothAdapter?.getRemoteDevice(address)?.let { device ->
try {
aapsLogger.debug(LTag.PUMPBTCOMM, "Removing bond")
device::class.java.getMethod("removeBond").invoke(device)
} catch (e: Exception) {
aapsLogger.error("Removing bond has been failed. ${e.message}")
}
}
}
} else if (lastClearRequest == 0L) {
aapsLogger.error("Clearing pairing keys postponed")
sp.putLong(R.string.key_rs_last_clear_key_request, dateUtil.now())
}
}
*/
aapsLogger.debug(LTag.PUMPBTCOMM, "BluetoothAdapter close")
bluetoothGatt?.close()
bluetoothGatt = null
}
@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
private val mGattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
onConnectionStateChangeSynchronized(gatt, newState) // call it synchronized
@ -289,6 +266,7 @@ class BLEComm @Inject internal constructor(
}
}
@Suppress("DEPRECATION")
@SuppressLint("MissingPermission")
@Synchronized
private fun setCharacteristicNotification(characteristic: BluetoothGattCharacteristic?, enabled: Boolean) {
@ -309,6 +287,7 @@ class BLEComm @Inject internal constructor(
}
}
@Suppress("DEPRECATION")
@SuppressLint("MissingPermission")
@Synchronized
private fun writeCharacteristicNoResponse(characteristic: BluetoothGattCharacteristic, data: ByteArray) {

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more