diff --git a/app/build.gradle b/app/build.gradle
index 316c7cf77d..234d5a0c52 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -109,7 +109,7 @@ android {
targetSdkVersion 28
multiDexEnabled true
versionCode 1500
- version "2.4-dev-b"
+ version "2.4-dev-d"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b40188688c..aeeb53475d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -153,8 +153,7 @@
+ android:exported="false" />
@@ -173,7 +172,7 @@
+ android:exported="true" />
@@ -240,11 +239,11 @@
+ android:exported="true" />
+ android:exported="true" />
@@ -285,7 +284,7 @@
+ android:exported="true" />
diff --git a/app/src/main/java/info/nightscout/androidaps/Constants.java b/app/src/main/java/info/nightscout/androidaps/Constants.java
index f87e13d41f..adb3be4dc0 100644
--- a/app/src/main/java/info/nightscout/androidaps/Constants.java
+++ b/app/src/main/java/info/nightscout/androidaps/Constants.java
@@ -50,6 +50,11 @@ public class Constants {
public static final double defaultHypoTTmgdl = 120d;
public static final double defaultHypoTTmmol = 6.5d;
+ public static final double MIN_TT_MGDL = 72d;
+ public static final double MAX_TT_MGDL = 180d;
+ public static final double MIN_TT_MMOL = 4d;
+ public static final double MAX_TT_MMOL = 10d;
+
//NSClientInternal
public static final int MAX_LOG_LINES = 100;
diff --git a/app/src/main/java/info/nightscout/androidaps/data/Profile.java b/app/src/main/java/info/nightscout/androidaps/data/Profile.java
index 2bcd3794be..ee3d50aa16 100644
--- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java
+++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java
@@ -165,17 +165,18 @@ public class Profile {
final JSONObject o = array.getJSONObject(index);
long tas = 0;
try {
- tas = getShitfTimeSecs((int) o.getLong("timeAsSeconds"));
- } catch (JSONException e) {
String time = o.getString("time");
tas = getShitfTimeSecs(DateUtil.toSeconds(time));
+ } catch (JSONException e) {
//log.debug(">>>>>>>>>>>> Used recalculated timeAsSecons: " + time + " " + tas);
+ tas = getShitfTimeSecs((int) o.getLong("timeAsSeconds"));
}
double value = o.getDouble("value") * multiplier;
sparse.put(tas, value);
- } catch (JSONException e) {
+ } catch (Exception e) {
log.error("Unhandled exception", e);
log.error(json.toString());
+ FabricPrivacy.logException(e);
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt
index b4aa6b0991..2ab594c2a2 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt
@@ -15,19 +15,15 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper
+import info.nightscout.androidaps.utils.plusAssign
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.loop_fragment.*
class LoopFragment : Fragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.loop_fragment, container, false)
@@ -40,10 +36,9 @@ class LoopFragment : Fragment() {
loop_lastrun.text = MainApp.gs(R.string.executing)
Thread { LoopPlugin.getPlugin().invoke("Loop button", true) }.start()
}
-
- updateGUI()
}
+ @Synchronized
override fun onResume() {
super.onResume()
disposable += RxBus
@@ -64,14 +59,19 @@ class LoopFragment : Fragment() {
}, {
FabricPrivacy.logException(it)
})
+
+ updateGUI()
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
+ @Synchronized
fun updateGUI() {
+ if (loop_request == null) return
LoopPlugin.lastRun?.let {
loop_request.text = it.request?.toSpanned() ?: ""
loop_constraintsprocessed.text = it.constraintsProcessed?.toSpanned() ?: ""
@@ -96,7 +96,9 @@ class LoopFragment : Fragment() {
}
}
+ @Synchronized
private fun clearGUI() {
+ if (loop_request == null) return
loop_request.text = ""
loop_constraints.text = ""
loop_constraintsprocessed.text = ""
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java
index 47a477f382..0425190723 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java
@@ -416,7 +416,7 @@ public class LoopPlugin extends PluginBase {
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH)
.setCategory(Notification.CATEGORY_ALARM)
- .setVisibility(Notification.VISIBILITY_PUBLIC);
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
if (SP.getBoolean("wearcontrol", false)) {
builder.setLocalOnly(true);
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAFragment.kt
index 763c93aa8c..94747a4597 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAFragment.kt
@@ -15,9 +15,9 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.JSONFormatter
+import info.nightscout.androidaps.utils.plusAssign
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.openapsama_fragment.*
import org.json.JSONArray
import org.json.JSONException
@@ -27,10 +27,6 @@ class OpenAPSAMAFragment : Fragment() {
private val log = LoggerFactory.getLogger(L.APS)
private var disposable: CompositeDisposable = CompositeDisposable()
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.openapsama_fragment, container, false)
@@ -42,10 +38,9 @@ class OpenAPSAMAFragment : Fragment() {
openapsma_run.setOnClickListener {
OpenAPSAMAPlugin.getPlugin().invoke("OpenAPSAMA button", false)
}
-
- updateGUI()
}
+ @Synchronized
override fun onResume() {
super.onResume()
@@ -65,14 +60,19 @@ class OpenAPSAMAFragment : Fragment() {
}, {
FabricPrivacy.logException(it)
})
+
+ updateGUI()
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
+ @Synchronized
private fun updateGUI() {
+ if (openapsma_result == null) return
OpenAPSAMAPlugin.getPlugin().lastAPSResult?.let { lastAPSResult ->
openapsma_result.text = JSONFormatter.format(lastAPSResult.json)
openapsma_request.text = lastAPSResult.toSpanned()
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAFragment.kt
index 6525641332..1b72f57365 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAFragment.kt
@@ -13,9 +13,9 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.JSONFormatter
+import info.nightscout.androidaps.utils.plusAssign
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.openapsama_fragment.*
import org.slf4j.LoggerFactory
@@ -23,10 +23,6 @@ class OpenAPSMAFragment : Fragment() {
private val log = LoggerFactory.getLogger(L.APS)
private var disposable: CompositeDisposable = CompositeDisposable()
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.openapsma_fragment, container, false)
@@ -39,9 +35,9 @@ class OpenAPSMAFragment : Fragment() {
OpenAPSMAPlugin.getPlugin().invoke("OpenAPSMA button", false)
}
- updateGUI()
}
+ @Synchronized
override fun onResume() {
super.onResume()
@@ -61,14 +57,18 @@ class OpenAPSMAFragment : Fragment() {
}, {
FabricPrivacy.logException(it)
})
+ updateGUI()
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
- fun updateGUI() {
+ @Synchronized
+ private fun updateGUI() {
+ if (openapsma_result == null) return
OpenAPSMAPlugin.getPlugin().lastAPSResult?.let { lastAPSResult ->
openapsma_result.text = JSONFormatter.format(lastAPSResult.json)
openapsma_request.text = lastAPSResult.toSpanned()
@@ -85,7 +85,9 @@ class OpenAPSMAFragment : Fragment() {
}
}
+ @Synchronized
private fun updateResultGUI(text: String) {
+ if (openapsma_result == null) return
openapsma_result.text = text
openapsma_glucosestatus.text = ""
openapsma_currenttemp.text = ""
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBFragment.kt
index c102b65173..06ad0d01fd 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBFragment.kt
@@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.aps.openAPSSMB
+import android.annotation.SuppressLint
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
@@ -15,9 +16,9 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.JSONFormatter
+import info.nightscout.androidaps.utils.plusAssign
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.openapsama_fragment.*
import org.json.JSONArray
import org.json.JSONException
@@ -27,10 +28,6 @@ class OpenAPSSMBFragment : Fragment() {
private val log = LoggerFactory.getLogger(L.APS)
private var disposable: CompositeDisposable = CompositeDisposable()
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.openapsama_fragment, container, false)
@@ -42,10 +39,9 @@ class OpenAPSSMBFragment : Fragment() {
openapsma_run.setOnClickListener {
OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSSMB button", false)
}
-
- updateGUI()
}
+ @Synchronized
override fun onResume() {
super.onResume()
disposable += RxBus
@@ -64,14 +60,19 @@ class OpenAPSSMBFragment : Fragment() {
}, {
FabricPrivacy.logException(it)
})
+
+ updateGUI()
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
+ @Synchronized
fun updateGUI() {
+ if (openapsma_result == null) return
val plugin = OpenAPSSMBPlugin.getPlugin()
plugin.lastAPSResult?.let { lastAPSResult ->
openapsma_result.text = JSONFormatter.format(lastAPSResult.json)
@@ -85,6 +86,7 @@ class OpenAPSSMBFragment : Fragment() {
openapsma_iobdata.text = TextUtils.concat(String.format(MainApp.gs(R.string.array_of_elements), iobArray.length()) + "\n", JSONFormatter.format(iobArray.getString(0)))
} catch (e: JSONException) {
log.error("Unhandled exception", e)
+ @SuppressLint("SetTextl18n")
openapsma_iobdata.text = "JSONException see log for details"
}
@@ -103,7 +105,9 @@ class OpenAPSSMBFragment : Fragment() {
}
}
+ @Synchronized
private fun updateResultGUI(text: String) {
+ if (openapsma_result == null) return
openapsma_result.text = text
openapsma_glucosestatus.text = ""
openapsma_currenttemp.text = ""
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt
index a8bcda3944..f011ac57cf 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt
@@ -44,10 +44,9 @@ class ConfigBuilderFragment : Fragment() {
unlock.visibility = View.GONE
}, null)
}
-
- updateGUI()
}
+ @Synchronized
override fun onResume() {
super.onResume()
disposable.add(RxBus
@@ -58,13 +57,16 @@ class ConfigBuilderFragment : Fragment() {
}, {
FabricPrivacy.logException(it)
}))
+ updateGUI()
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
+ @Synchronized
private fun updateGUI() {
createViewsForPlugins(R.string.configbuilder_profile, R.string.configbuilder_profile_description, PluginType.PROFILE, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface::class.java, PluginType.PROFILE))
createViewsForPlugins(R.string.configbuilder_insulin, R.string.configbuilder_insulin_description, PluginType.INSULIN, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface::class.java, PluginType.INSULIN))
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.java
index b92dadc89b..6eb3be382b 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.java
@@ -16,6 +16,7 @@ public class AutomationEvent {
private Trigger trigger = new TriggerConnector();
private List actions = new ArrayList<>();
private String title;
+ private boolean enabled = true;
public void setTitle(String title) {
this.title = title;
@@ -33,6 +34,14 @@ public class AutomationEvent {
return actions;
}
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean newState) {
+ enabled = newState;
+ }
+
public TriggerConnector getPreconditions() {
TriggerConnector trigger = new TriggerConnector(TriggerConnector.Type.AND);
for (Action action : actions) {
@@ -55,6 +64,7 @@ public class AutomationEvent {
try {
// title
o.put("title", title);
+ o.put("enabled", enabled);
// trigger
o.put("trigger", trigger.toJSON());
// actions
@@ -72,11 +82,9 @@ public class AutomationEvent {
public AutomationEvent fromJSON(String data) {
try {
JSONObject d = new JSONObject(data);
- // title
title = d.optString("title", "");
- // trigger
+ enabled = d.optBoolean("enabled", true);
trigger = Trigger.instantiate(d.getString("trigger"));
- // actions
JSONArray array = d.getJSONArray("actions");
actions.clear();
for (int i = 0; i < array.length(); i++) {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt
index 0bf996bd52..8a0789acea 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt
@@ -12,9 +12,9 @@ import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDi
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
import info.nightscout.androidaps.utils.FabricPrivacy
+import info.nightscout.androidaps.utils.plusAssign
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.automation_fragment.*
class AutomationFragment : Fragment() {
@@ -22,10 +22,6 @@ class AutomationFragment : Fragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
private var eventListAdapter: EventListAdapter? = null
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.automation_fragment, container, false)
}
@@ -48,19 +44,14 @@ class AutomationFragment : Fragment() {
}
+ @Synchronized
override fun onResume() {
super.onResume()
disposable += RxBus
.toObservable(EventAutomationUpdateGui::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
- eventListAdapter?.notifyDataSetChanged()
- val sb = StringBuilder()
- for (l in AutomationPlugin.executionLog) {
- sb.append(l)
- sb.append("\n")
- }
- automation_logView.text = sb.toString()
+ updateGui()
}, {
FabricPrivacy.logException(it)
})
@@ -72,11 +63,25 @@ class AutomationFragment : Fragment() {
}, {
FabricPrivacy.logException(it)
})
+ updateGui()
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
+ @Synchronized
+ private fun updateGui() {
+ if (eventListAdapter == null) return
+ eventListAdapter?.notifyDataSetChanged()
+ val sb = StringBuilder()
+ for (l in AutomationPlugin.executionLog) {
+ sb.append(l)
+ sb.append("\n")
+ }
+ automation_logView.text = sb.toString()
+ }
+
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt
index 2ab2c91411..00a76778d8 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt
@@ -21,12 +21,8 @@ import info.nightscout.androidaps.plugins.general.automation.triggers.*
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.services.LocationService
-import info.nightscout.androidaps.utils.DateUtil
-import info.nightscout.androidaps.utils.FabricPrivacy
-import info.nightscout.androidaps.utils.SP
-import info.nightscout.androidaps.utils.T
+import info.nightscout.androidaps.utils.*
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.json.JSONArray
import org.json.JSONException
@@ -60,10 +56,6 @@ object AutomationPlugin : PluginBase(PluginDescription()
}
}
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
override fun onStart() {
val context = MainApp.instance().applicationContext
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
@@ -131,6 +123,7 @@ object AutomationPlugin : PluginBase(PluginDescription()
loopHandler.removeCallbacks(refreshLoop)
val context = MainApp.instance().applicationContext
context.stopService(Intent(context, LocationService::class.java))
+ super.onStop()
}
private fun storeToSP() {
@@ -171,7 +164,7 @@ object AutomationPlugin : PluginBase(PluginDescription()
if (L.isEnabled(L.AUTOMATION))
log.debug("processActions")
for (event in automationEvents) {
- if (event.trigger.shouldRun() && event.preconditions.shouldRun()) {
+ if (event.isEnabled() && event.trigger.shouldRun() && event.preconditions.shouldRun()) {
val actions = event.actions
for (action in actions) {
action.doAction(object : Callback() {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/EventListAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/EventListAdapter.java
index 4bbd4a0959..b4c6fb1f11 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/EventListAdapter.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/EventListAdapter.java
@@ -5,6 +5,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
@@ -20,8 +21,10 @@ import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
+import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog;
+import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
class EventListAdapter extends RecyclerView.Adapter {
@@ -51,6 +54,7 @@ class EventListAdapter extends RecyclerView.Adapter
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final AutomationEvent event = mEventList.get(position);
holder.eventTitle.setText(event.getTitle());
+ holder.enabled.setChecked(event.isEnabled());
holder.iconLayout.removeAllViews();
// trigger icons
@@ -77,6 +81,13 @@ class EventListAdapter extends RecyclerView.Adapter
addImage(res, holder.context, holder.iconLayout);
}
+ // enabled event
+ holder.enabled.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ event.setEnabled(isChecked);
+ notifyDataSetChanged();
+ RxBus.INSTANCE.send(new EventAutomationDataChanged());
+ });
+
// remove event
holder.iconTrash.setOnClickListener(v -> {
mEventList.remove(event);
@@ -107,6 +118,7 @@ class EventListAdapter extends RecyclerView.Adapter
final TextView eventTitle;
final Context context;
final ImageView iconTrash;
+ final CheckBox enabled;
ViewHolder(View view, Context context) {
super(view);
@@ -115,6 +127,7 @@ class EventListAdapter extends RecyclerView.Adapter
rootLayout = view.findViewById(R.id.rootLayout);
iconLayout = view.findViewById(R.id.iconLayout);
iconTrash = view.findViewById(R.id.iconTrash);
+ enabled = view.findViewById(R.id.automation_enabled);
}
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.java
index 66f262485b..05d06f0b3a 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.java
@@ -15,8 +15,8 @@ import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists;
-import info.nightscout.androidaps.plugins.general.automation.elements.InputBg;
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration;
+import info.nightscout.androidaps.plugins.general.automation.elements.InputTempTarget;
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTempTarget;
@@ -27,7 +27,7 @@ import info.nightscout.androidaps.utils.JsonHelper;
public class ActionStartTempTarget extends Action {
String reason = "";
- InputBg value = new InputBg();
+ InputTempTarget value = new InputTempTarget();
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
private TempTarget tempTarget;
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java
index 7e1ff75962..0809ed96d8 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java
@@ -11,27 +11,10 @@ import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.utils.NumberPicker;
public class InputBg extends Element {
-
- final TextWatcher textWatcher = new TextWatcher() {
- @Override
- public void afterTextChanged(Editable s) {
- if (units.equals(Constants.MMOL)) {
- value = Math.max(value, 4d);
- value = Math.min(value, 15d);
- } else {
- value = Math.max(value, 72d);
- value = Math.min(value, 270d);
- }
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
- };
+ static final int MMOL_MIN = 3;
+ static final int MMOL_MAX = 20;
+ static final int MGDL_MIN = 54;
+ static final int MGDL_MAX = 360;
private String units = Constants.MGDL;
private double value;
@@ -43,6 +26,10 @@ public class InputBg extends Element {
public InputBg() {
super();
setUnits(ProfileFunctions.getInstance().getProfileUnits());
+ if (getUnits().equals(Constants.MMOL))
+ value = MMOL_MIN;
+ else
+ value = MGDL_MIN;
}
public InputBg(InputBg another) {
@@ -55,7 +42,7 @@ public class InputBg extends Element {
@Override
public void addToLayout(LinearLayout root) {
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
- numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, textWatcher);
+ numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, null);
numberPicker.setOnValueChangedListener(value -> this.value = value);
root.addView(numberPicker);
}
@@ -68,21 +55,18 @@ public class InputBg extends Element {
// set default initial value
if (units.equals(Constants.MMOL)) {
// mmol
- minValue = 2;
- maxValue = 30;
+ minValue = MMOL_MIN;
+ maxValue = MMOL_MAX;
step = 0.1;
decimalFormat = new DecimalFormat("0.0");
} else {
// mg/dL
- minValue = 40;
- maxValue = 540;
+ minValue = MGDL_MIN;
+ maxValue = MGDL_MAX;
step = 1;
decimalFormat = new DecimalFormat("0");
}
- // make sure that value is in range
- textWatcher.afterTextChanged(null);
-
this.units = units;
return this;
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.java
index 10910220c3..ad0e84bec4 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.java
@@ -21,19 +21,6 @@ import info.nightscout.androidaps.utils.NumberPicker;
public class InputDelta extends Element {
private Comparator.Compare compare = Comparator.Compare.IS_EQUAL;
- final TextWatcher textWatcher = new TextWatcher() {
- @Override
- public void afterTextChanged(Editable s) {
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
- };
public enum DeltaType {
DELTA,
@@ -122,7 +109,7 @@ public class InputDelta extends Element {
spinner.setSelection(this.deltaType.ordinal());
// root.addView(spinner);
numberPicker = new NumberPicker(root.getContext(), null);
- numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, textWatcher);
+ numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, null);
numberPicker.setOnValueChangedListener(value -> this.value = value);
LinearLayout l = new LinearLayout(root.getContext());
l.setOrientation(LinearLayout.VERTICAL);
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java
new file mode 100644
index 0000000000..8175c496a5
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java
@@ -0,0 +1,77 @@
+package info.nightscout.androidaps.plugins.general.automation.elements;
+
+import android.widget.LinearLayout;
+
+import java.text.DecimalFormat;
+
+import info.nightscout.androidaps.Constants;
+import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
+import info.nightscout.androidaps.utils.NumberPicker;
+
+public class InputTempTarget extends Element {
+
+ private String units = Constants.MGDL;
+ private double value;
+ double minValue;
+ private double maxValue;
+ private double step;
+ private DecimalFormat decimalFormat;
+
+ public InputTempTarget() {
+ super();
+ setUnits(ProfileFunctions.getInstance().getProfileUnits());
+ if (getUnits().equals(Constants.MMOL))
+ value = Constants.MIN_TT_MMOL;
+ else
+ value = Constants.MIN_TT_MGDL;
+ }
+
+ public InputTempTarget(InputTempTarget another) {
+ super();
+ value = another.getValue();
+ setUnits(another.getUnits());
+ }
+
+
+ @Override
+ public void addToLayout(LinearLayout root) {
+ NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
+ numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, null);
+ numberPicker.setOnValueChangedListener(value -> this.value = value);
+ root.addView(numberPicker);
+ }
+
+ public String getUnits() {
+ return units;
+ }
+
+ public InputTempTarget setUnits(String units) {
+ // set default initial value
+ if (units.equals(Constants.MMOL)) {
+ // mmol
+ minValue = Constants.MIN_TT_MMOL;
+ maxValue = Constants.MAX_TT_MMOL;
+ step = 0.1;
+ decimalFormat = new DecimalFormat("0.0");
+ } else {
+ // mg/dL
+ minValue = Constants.MIN_TT_MGDL;
+ maxValue = Constants.MAX_TT_MGDL;
+ step = 1;
+ decimalFormat = new DecimalFormat("0");
+ }
+
+ this.units = units;
+ return this;
+ }
+
+ public InputTempTarget setValue(double value) {
+ this.value = value;
+ return this;
+ }
+
+ public double getValue() {
+ return value;
+ }
+
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java
index 00c3e21921..0b9edf148a 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java
@@ -33,15 +33,15 @@ import info.nightscout.androidaps.utils.T;
public class TriggerDelta extends Trigger {
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
- private double minValue = 0d;
- private double maxValue = 1d;
- private double step = 1;
- private DecimalFormat decimalFormat = new DecimalFormat("1");
+
+ private final int MMOL_MAX = 4;
+ private final int MGDL_MAX = 72;
+
private String units;
private DeltaType deltaType;
- private InputDelta value = new InputDelta( (double) minValue,(double) minValue, (double) maxValue, step, decimalFormat, deltaType);
- private Comparator comparator = new Comparator();
+ private InputDelta value;
+ private Comparator comparator;
public TriggerDelta() {
super();
@@ -62,6 +62,16 @@ public class TriggerDelta extends Trigger {
return value.getValue();
}
+ private void initializer() {
+ this.deltaType = DeltaType.DELTA;
+ comparator = new Comparator();
+ if (units.equals(Constants.MMOL))
+ value = new InputDelta(0, -MMOL_MAX, MMOL_MAX, 0.1d, new DecimalFormat("0.1"), DeltaType.DELTA);
+ else
+ value = new InputDelta(0, -MGDL_MAX, MGDL_MAX, 0.1d, new DecimalFormat("1"), DeltaType.DELTA);
+ }
+
+
public DeltaType getType() {
return deltaType;
}
@@ -150,7 +160,7 @@ public class TriggerDelta extends Trigger {
@Override
public Optional icon() {
- return Optional.of(R.drawable.icon_auto_delta);
+ return Optional.of(R.drawable.icon_auto_delta);
}
@Override
@@ -169,23 +179,6 @@ public class TriggerDelta extends Trigger {
return this;
}
- void initializer(){
- if (this.units.equals(Constants.MMOL)) {
- this.maxValue = 4d;
- this.minValue = -4d;
- this.step = 0.1d;
- this.decimalFormat = new DecimalFormat("0.1");
- this.deltaType = DeltaType.DELTA;
- } else {
- this.maxValue = 72d;
- this.minValue = -72d;
- this.step = 1d;
- this.deltaType = DeltaType.DELTA;
- }
- value = new InputDelta( (double) minValue,(double) minValue, (double) maxValue, step, decimalFormat, deltaType);
- }
-
-
TriggerDelta lastRun(long lastRun) {
this.lastRun = lastRun;
return this;
@@ -201,7 +194,7 @@ public class TriggerDelta extends Trigger {
new LayoutBuilder()
.add(new StaticLabel(R.string.deltalabel))
.add(comparator)
- .add(new LabelWithElement(MainApp.gs(R.string.deltalabel) + ": ", "", value))
+ .add(new LabelWithElement(MainApp.gs(R.string.deltalabel_u, getUnits()) + ": ", "", value))
.build(root);
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java
index 91cabe35c1..3489180d9d 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java
@@ -263,17 +263,17 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
if (sensorRadioButton.isChecked()) meterRadioButton.setChecked(true);
}
};
- editBg = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_bginput);
- editTemptarget = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_temptarget);
+ editBg = view.findViewById(R.id.careportal_newnstreatment_bginput);
+ editTemptarget = view.findViewById(R.id.careportal_newnstreatment_temptarget);
if (profile == null) {
- editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok), bgTextWatcher);
- editTemptarget.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok));
+ editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), bgTextWatcher);
+ editTemptarget.setParams(Constants.MIN_TT_MGDL, Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok));
} else if (units.equals(Constants.MMOL)) {
editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok), bgTextWatcher);
- editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok));
+ editTemptarget.setParams(Constants.MIN_TT_MMOL, Constants.MIN_TT_MMOL, Constants.MAX_TT_MMOL, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok));
} else {
editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), bgTextWatcher);
- editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
+ editTemptarget.setParams(Constants.MIN_TT_MGDL, Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
}
sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.java
index b5ff92ee0e..4b6072ee1e 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.java
@@ -113,6 +113,7 @@ public class NSClientPlugin extends PluginBase {
context.unbindService(mConnection);
nsClientReceiverDelegate.unregisterReceivers();
+ super.onStop();
}
@Subscribe
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.java
index 9633c8fbbe..4301ad6ec0 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.java
@@ -71,6 +71,7 @@ public class OverviewPlugin extends PluginBase {
@Override
protected void onStop() {
MainApp.bus().unregister(this);
+ super.onStop();
}
@Subscribe
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/DummyService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/DummyService.java
index 1400185afa..13310d70a8 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/DummyService.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/DummyService.java
@@ -31,7 +31,7 @@ public class DummyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
- startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, PersistentNotificationPlugin.getPlugin().updateNotification());
+ startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, PersistentNotificationPlugin.getPlugin().getLastNotification());
return START_STICKY;
}
@@ -48,8 +48,7 @@ public class DummyService extends Service {
super.onCreate();
// TODO: I guess this was moved here in order to adhere to the 5 seconds rule to call "startForeground" after a Service was called as Foreground service?
// As onCreate() is not called every time a service is started, copied to onStartCommand().
- Notification notification = PersistentNotificationPlugin.getPlugin().updateNotification();
- startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, notification);
+ startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, PersistentNotificationPlugin.getPlugin().getLastNotification());
MainApp.bus().register(this);
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java
index e06dc741be..655435f400 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java
@@ -55,14 +55,13 @@ public class PersistentNotificationPlugin extends PluginBase {
private Notification notification;
public static PersistentNotificationPlugin getPlugin() {
- if (plugin == null) plugin = new PersistentNotificationPlugin(MainApp.instance());
+ if (plugin == null) plugin = new PersistentNotificationPlugin();
return plugin;
}
public static final String CHANNEL_ID = "AndroidAPS-Ongoing";
public static final int ONGOING_NOTIFICATION_ID = 4711;
- private final Context ctx;
/// For Android Auto
/// Intents are not declared in manifest and not consumed, this is intentionally because actually we can't do anything with
@@ -76,7 +75,7 @@ public class PersistentNotificationPlugin extends PluginBase {
/// End Android Auto
- private PersistentNotificationPlugin(Context ctx) {
+ private PersistentNotificationPlugin() {
super(new PluginDescription()
.mainType(PluginType.GENERAL)
.neverVisible(true)
@@ -86,22 +85,21 @@ public class PersistentNotificationPlugin extends PluginBase {
.showInList(false)
.description(R.string.description_persistent_notification)
);
- this.ctx = ctx;
}
@Override
protected void onStart() {
+ super.onStart();
createNotificationChannel(); // make sure channels exist before triggering updates through the bus
MainApp.bus().register(this);
- triggerNotificationUpdate();
- super.onStart();
+ triggerNotificationUpdate(true);
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager =
- (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
+ (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE);
@SuppressLint("WrongConstant") NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH);
@@ -113,23 +111,26 @@ public class PersistentNotificationPlugin extends PluginBase {
protected void onStop() {
MainApp.bus().unregister(this);
MainApp.instance().stopService(new Intent(MainApp.instance(), DummyService.class));
+ super.onStop();
}
- private void triggerNotificationUpdate() {
+ private void triggerNotificationUpdate(boolean boot) {
+ updateNotification(boot);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
MainApp.instance().startForegroundService(new Intent(MainApp.instance(), DummyService.class));
else
MainApp.instance().startService(new Intent(MainApp.instance(), DummyService.class));
}
- @Nonnull
- public Notification updateNotification() {
- String line1 = null;
+ private void updateNotification(boolean boot) {
+ String line1;
String line2 = null;
String line3 = null;
NotificationCompat.CarExtender.UnreadConversation.Builder unreadConversationBuilder = null;
- if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ProfileFunctions.getInstance().isProfileValid("Notification")) {
+ if (boot) {
+ line1 = MainApp.gs(R.string.loading);
+ } else if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ProfileFunctions.getInstance().isProfileValid("Notification")) {
String line1_aa;
String units = ProfileFunctions.getInstance().getProfileUnits();
@@ -185,7 +186,7 @@ public class PersistentNotificationPlugin extends PluginBase {
.setPackage(PACKAGE);
PendingIntent msgReadPendingIntent =
- PendingIntent.getBroadcast(ctx,
+ PendingIntent.getBroadcast(MainApp.instance(),
ONGOING_NOTIFICATION_ID,
msgReadIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
@@ -197,7 +198,7 @@ public class PersistentNotificationPlugin extends PluginBase {
.setPackage(PACKAGE);
PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(
- ctx,
+ MainApp.instance(),
ONGOING_NOTIFICATION_ID,
msgReplyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
@@ -215,18 +216,20 @@ public class PersistentNotificationPlugin extends PluginBase {
/// Add dot to produce a "more natural sounding result"
unreadConversationBuilder.addMessage(line3_aa);
/// End Android Auto
+ } else {
+ line1 = MainApp.gs(R.string.noprofileset);
}
- NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID);
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(MainApp.instance(), CHANNEL_ID);
builder.setOngoing(true);
builder.setOnlyAlertOnce(true);
builder.setCategory(NotificationCompat.CATEGORY_STATUS);
builder.setSmallIcon(MainApp.getNotificationIcon());
- Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), MainApp.getIcon());
+ Bitmap largeIcon = BitmapFactory.decodeResource(MainApp.instance().getResources(), MainApp.getIcon());
builder.setLargeIcon(largeIcon);
- builder.setContentTitle(line1 != null ? line1 : MainApp.gs(R.string.noprofileset));
- builder.setContentText(line2 != null ? line2 : MainApp.gs(R.string.noprofileset));
- builder.setSubText(line3 != null ? line3 : MainApp.gs(R.string.noprofileset));
+ if (line1 != null) builder.setContentTitle(line1);
+ if (line2 != null) builder.setContentText(line2);
+ if (line3 != null) builder.setSubText(line3);
/// Android Auto
if (unreadConversationBuilder != null) {
builder.extend(new NotificationCompat.CarExtender()
@@ -235,9 +238,9 @@ public class PersistentNotificationPlugin extends PluginBase {
/// End Android Auto
- Intent resultIntent = new Intent(ctx, MainActivity.class);
+ Intent resultIntent = new Intent(MainApp.instance(), MainActivity.class);
- TaskStackBuilder stackBuilder = TaskStackBuilder.create(ctx);
+ TaskStackBuilder stackBuilder = TaskStackBuilder.create(MainApp.instance());
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
@@ -247,12 +250,11 @@ public class PersistentNotificationPlugin extends PluginBase {
);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
- (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
+ (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE);
android.app.Notification notification = builder.build();
mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification);
this.notification = notification;
- return notification;
}
private String deltastring(double deltaMGDL, double deltaMMOL, String units) {
@@ -279,48 +281,50 @@ public class PersistentNotificationPlugin extends PluginBase {
public Notification getLastNotification() {
if (notification != null) return notification;
- else return new Notification();
+ else {
+ throw new IllegalStateException("Notification is null");
+ }
}
@Subscribe
public void onStatusEvent(final EventPreferenceChange ev) {
- triggerNotificationUpdate();
+ triggerNotificationUpdate(false);
}
@Subscribe
public void onStatusEvent(final EventTreatmentChange ev) {
- triggerNotificationUpdate();
+ triggerNotificationUpdate(false);
}
@Subscribe
public void onStatusEvent(final EventTempBasalChange ev) {
- triggerNotificationUpdate();
+ triggerNotificationUpdate(false);
}
@Subscribe
public void onStatusEvent(final EventExtendedBolusChange ev) {
- triggerNotificationUpdate();
+ triggerNotificationUpdate(false);
}
@Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished ev) {
- triggerNotificationUpdate();
+ triggerNotificationUpdate(false);
}
@Subscribe
public void onStatusEvent(final EventNewBasalProfile ev) {
- triggerNotificationUpdate();
+ triggerNotificationUpdate(false);
}
@Subscribe
public void onStatusEvent(final EventInitializationChanged ev) {
- triggerNotificationUpdate();
+ triggerNotificationUpdate(false);
}
@Subscribe
public void onStatusEvent(final EventRefreshOverview ev) {
- triggerNotificationUpdate();
+ triggerNotificationUpdate(false);
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java
index 14dcb169c4..095997daf9 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java
@@ -98,6 +98,7 @@ public class SmsCommunicatorPlugin extends PluginBase {
@Override
protected void onStop() {
MainApp.bus().unregister(this);
+ super.onStop();
}
@Subscribe
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/TidepoolFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/TidepoolFragment.kt
index 86eb704bab..f83b9cc243 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/TidepoolFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/TidepoolFragment.kt
@@ -16,17 +16,12 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.SP
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.tidepool_fragment.*
class TidepoolFragment : Fragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.tidepool_fragment, container, false)
}
@@ -39,6 +34,7 @@ class TidepoolFragment : Fragment() {
tidepool_resertstart.setOnClickListener { SP.putLong(R.string.key_tidepool_last_end, 0) }
}
+ @Synchronized
override fun onResume() {
super.onResume()
disposable.add(RxBus
@@ -46,16 +42,17 @@ class TidepoolFragment : Fragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
TidepoolPlugin.updateLog()
- tidepool_log.text = TidepoolPlugin.textLog
- tidepool_status.text = TidepoolUploader.connectionStatus.name
- tidepool_log.text = TidepoolPlugin.textLog
- tidepool_logscrollview.fullScroll(ScrollView.FOCUS_DOWN)
+ tidepool_log?.text = TidepoolPlugin.textLog
+ tidepool_status?.text = TidepoolUploader.connectionStatus.name
+ tidepool_log?.text = TidepoolPlugin.textLog
+ tidepool_logscrollview?.fullScroll(ScrollView.FOCUS_DOWN)
}, {
FabricPrivacy.logException(it)
})
)
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/TidepoolPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/TidepoolPlugin.kt
index b7896d7e56..78ad0ab37d 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/TidepoolPlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/TidepoolPlugin.kt
@@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.general.tidepool
-import android.text.Html
import android.text.Spanned
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
@@ -23,7 +22,6 @@ import info.nightscout.androidaps.receivers.ChargingStateReceiver
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
import info.nightscout.androidaps.utils.*
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.slf4j.LoggerFactory
import java.util.*
@@ -43,10 +41,6 @@ object TidepoolPlugin : PluginBase(PluginDescription()
private val listLog = ArrayList()
var textLog: Spanned = HtmlHelper.fromHtml("")
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
override fun onStart() {
super.onStart()
disposable += RxBus
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/WearPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/WearPlugin.java
index 69e327a21b..53b421ace3 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/WearPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/WearPlugin.java
@@ -91,6 +91,7 @@ public class WearPlugin extends PluginBase {
protected void onStop() {
MainApp.bus().unregister(this);
disposable.clear();
+ super.onStop();
}
private void sendDataToWatch(boolean status, boolean basals, boolean bgValue) {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.kt
index 56abf0008c..7a76283074 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.kt
@@ -90,9 +90,9 @@ class NSProfileFragment : Fragment() {
}
}
}
- updateGUI()
}
+ @Synchronized
override fun onResume() {
super.onResume()
disposable.add(RxBus
@@ -104,14 +104,18 @@ class NSProfileFragment : Fragment() {
FabricPrivacy.logException(it)
})
)
+ updateGUI()
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
+ @Synchronized
fun updateGUI() {
+ if (profileview_noprofile == null) return
profileview_noprofile.visibility = View.VISIBLE
NSProfilePlugin.getPlugin().profile?.let { profileStore ->
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfilePlugin.java
index 88faee377a..a6088f5515 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfilePlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfilePlugin.java
@@ -65,6 +65,7 @@ public class NSProfilePlugin extends PluginBase implements ProfileInterface {
@Override
protected void onStop() {
MainApp.bus().unregister(this);
+ super.onStop();
}
public void handleNewData(Intent intent) {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java
index 3deda538be..fa68e55616 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java
@@ -100,6 +100,7 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
serviceRunning = false;
MainApp.bus().unregister(this);
+ super.onStop();
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRFragment.kt
index 377e417274..11a8f13412 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRFragment.kt
@@ -27,13 +27,9 @@ import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.plugins.treatments.fragments.ProfileViewerDialog
import info.nightscout.androidaps.queue.events.EventQueueChanged
-import info.nightscout.androidaps.utils.DateUtil
-import info.nightscout.androidaps.utils.FabricPrivacy
-import info.nightscout.androidaps.utils.SetWarnColor
-import info.nightscout.androidaps.utils.T
+import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.danar_fragment.*
import org.slf4j.LoggerFactory
@@ -41,10 +37,6 @@ class DanaRFragment : Fragment() {
private val log = LoggerFactory.getLogger(L.PUMP)
private var disposable: CompositeDisposable = CompositeDisposable()
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
private val loopHandler = Handler()
private lateinit var refreshLoop: Runnable
@@ -84,9 +76,9 @@ class DanaRFragment : Fragment() {
DanaRPump.getInstance().lastConnection = 0
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("Clicked connect to pump", null)
}
- updateGUI()
}
+ @Synchronized
override fun onResume() {
super.onResume()
MainApp.bus().register(this)
@@ -95,8 +87,10 @@ class DanaRFragment : Fragment() {
.toObservable(EventDanaRNewStatus::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
+ updateGUI()
}
+ @Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
@@ -105,12 +99,12 @@ class DanaRFragment : Fragment() {
}
@Subscribe
- public fun onStatusEvent(c: EventPumpStatusChanged) {
+ fun onStatusEvent(c: EventPumpStatusChanged) {
activity?.runOnUiThread {
when {
- c.sStatus == EventPumpStatusChanged.CONNECTING -> danar_btconnection.text = "{fa-bluetooth-b spin} " + c.sSecondsElapsed + "s"
- c.sStatus == EventPumpStatusChanged.CONNECTED -> danar_btconnection.text = "{fa-bluetooth}"
- c.sStatus == EventPumpStatusChanged.DISCONNECTED -> danar_btconnection.text = "{fa-bluetooth-b}"
+ c.sStatus == EventPumpStatusChanged.CONNECTING -> danar_btconnection?.text = "{fa-bluetooth-b spin} " + c.sSecondsElapsed + "s"
+ c.sStatus == EventPumpStatusChanged.CONNECTED -> danar_btconnection?.text = "{fa-bluetooth}"
+ c.sStatus == EventPumpStatusChanged.DISCONNECTED -> danar_btconnection?.text = "{fa-bluetooth-b}"
}
if (c.textStatus() != "") {
dana_pumpstatus.text = c.textStatus()
@@ -123,20 +117,22 @@ class DanaRFragment : Fragment() {
}
@Subscribe
- public fun onStatusEvent(s: EventTempBasalChange) =
+ fun onStatusEvent(s: EventTempBasalChange) =
activity?.runOnUiThread { updateGUI() }
@Subscribe
- public fun onStatusEvent(s: EventExtendedBolusChange) =
+ fun onStatusEvent(s: EventExtendedBolusChange) =
activity?.runOnUiThread { updateGUI() }
@Subscribe
- public fun onStatusEvent(s: EventQueueChanged) =
+ fun onStatusEvent(s: EventQueueChanged) =
activity?.runOnUiThread { updateGUI() }
// GUI functions
+ @Synchronized
internal fun updateGUI() {
+ if (danar_dailyunits == null) return
val pump = DanaRPump.getInstance()
val plugin: PumpInterface = ConfigBuilderPlugin.getPlugin().activePump ?: return
if (pump.lastConnection != 0L) {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPlugin.java
index 80d0390390..6a01c5fed8 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPlugin.java
@@ -65,6 +65,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
context.unbindService(mConnection);
MainApp.bus().unregister(this);
+ super.onStop();
}
private ServiceConnection mConnection = new ServiceConnection() {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPlugin.java
index 07df7fb29f..64eccf05f1 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPlugin.java
@@ -68,6 +68,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
context.unbindService(mConnection);
MainApp.bus().unregister(this);
+ super.onStop();
}
private ServiceConnection mConnection = new ServiceConnection() {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java
index 1e38ccc312..19005509cb 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java
@@ -123,6 +123,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
context.unbindService(mConnection);
MainApp.bus().unregister(this);
+ super.onStop();
}
@Override
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2Plugin.java
index 65fb602ff4..607f7346b6 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2Plugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2Plugin.java
@@ -71,6 +71,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
context.unbindService(mConnection);
MainApp.bus().unregister(this);
+ super.onStop();
}
private ServiceConnection mConnection = new ServiceConnection() {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt
index a77de2e4a4..d60a639106 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt
@@ -35,13 +35,9 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.events.EventQueueChanged
-import info.nightscout.androidaps.utils.DateUtil
-import info.nightscout.androidaps.utils.FabricPrivacy
-import info.nightscout.androidaps.utils.SetWarnColor
-import info.nightscout.androidaps.utils.T
+import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.medtronic_fragment.*
import org.slf4j.LoggerFactory
@@ -50,10 +46,6 @@ class MedtronicFragment : Fragment() {
private val log = LoggerFactory.getLogger(L.PUMP)
private var disposable: CompositeDisposable = CompositeDisposable()
- operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
- add(disposable)
- }
-
private val loopHandler = Handler()
private lateinit var refreshLoop: Runnable
@@ -94,7 +86,7 @@ class MedtronicFragment : Fragment() {
MedtronicPumpPlugin.getPlugin().resetStatusState()
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("Clicked refresh", object : Callback() {
override fun run() {
- activity?.runOnUiThread { medtronic_refresh.isEnabled = true }
+ activity?.runOnUiThread { medtronic_refresh?.isEnabled = true }
}
})
}
@@ -107,8 +99,6 @@ class MedtronicFragment : Fragment() {
MedtronicUtil.displayNotConfiguredDialog(context)
}
}
-
- updateGUI()
}
@Synchronized
@@ -141,6 +131,8 @@ class MedtronicFragment : Fragment() {
MedtronicUtil.getPumpStatus().verifyConfiguration()
updateGUI()
}, { FabricPrivacy.logException(it) })
+
+ updateGUI()
}
@Synchronized
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java
index a16178df18..f8568299d5 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java
@@ -1062,6 +1062,21 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
}
+ @Override
+ public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile,
+ boolean enforceNew) {
+ if (percent==0) {
+ return setTempBasalAbsolute(0.0d, durationInMinutes, profile, enforceNew);
+ } else {
+ double absoluteValue = profile.getBasal() * (percent /100.0d);
+ getMDTPumpStatus();
+ absoluteValue = pumpStatusLocal.pumpType.determineCorrectBasalSize(absoluteValue);
+ LOG.warn("setTempBasalPercent [MedtronicPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (%d). This will start setTempBasalAbsolute, with calculated value (%.3f). Result might not be 100% correct.", percent, absoluteValue);
+ return setTempBasalAbsolute(absoluteValue, durationInMinutes, profile, enforceNew);
+ }
+ }
+
+
private void finishAction(String overviewKey) {
if (overviewKey != null)
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.java
index 1c2cf1f954..6b561bc41d 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.java
@@ -128,6 +128,7 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface {
@Override
protected void onStop() {
MainApp.bus().unregister(this);
+ super.onStop();
}
@Subscribe
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java
index a9284dd366..c1a26adcbd 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java
@@ -110,6 +110,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
@Override
protected void onStop() {
MainApp.bus().register(this);
+ super.onStop();
}
public TreatmentService getService() {
@@ -294,14 +295,19 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
}
+ /**
+ * Returns all Treatments after specified timestamp. Also returns invalid entries (required to
+ * map "Fill Canulla" entries to history (and not to add double bolus for it)
+ *
+ * @param fromTimestamp
+ * @return
+ */
@Override
public List getTreatmentsFromHistoryAfterTimestamp(long fromTimestamp) {
List in5minback = new ArrayList<>();
long time = System.currentTimeMillis();
synchronized (treatments) {
for (Treatment t : treatments) {
- if (!t.isValid)
- continue;
if (t.date <= time && t.date >= fromTimestamp)
in5minback.add(t);
}
diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.java
index 95fd6bfb09..6c2e7c6920 100644
--- a/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.java
+++ b/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.java
@@ -1,9 +1,8 @@
package info.nightscout.androidaps.receivers;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import androidx.legacy.content.WakefulBroadcastReceiver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -11,16 +10,15 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.services.DataService;
-public class DataReceiver extends BroadcastReceiver {
+public class DataReceiver extends WakefulBroadcastReceiver {
private static Logger log = LoggerFactory.getLogger(L.DATASERVICE);
@Override
public void onReceive(Context context, Intent intent) {
if (L.isEnabled(L.DATASERVICE))
log.debug("onReceive " + intent);
- // Explicitly specify that GcmIntentService will handle the intent.
- ComponentName comp = new ComponentName(context.getPackageName(),
- DataService.class.getName());
- DataService.enqueueWork(context, intent.setComponent(comp));
+ startWakefulService(context, new Intent(context, DataService.class)
+ .setAction(intent.getAction())
+ .putExtras(intent));
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/services/DataService.java b/app/src/main/java/info/nightscout/androidaps/services/DataService.java
index 24a7698e9a..6b8ac46f11 100644
--- a/app/src/main/java/info/nightscout/androidaps/services/DataService.java
+++ b/app/src/main/java/info/nightscout/androidaps/services/DataService.java
@@ -1,13 +1,10 @@
package info.nightscout.androidaps.services;
-import android.content.Context;
+import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Telephony;
-import androidx.annotation.NonNull;
-import androidx.core.app.JobIntentService;
-
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -19,16 +16,15 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventNsFood;
import info.nightscout.androidaps.events.EventNsTreatment;
-import info.nightscout.androidaps.logging.BundleLogger;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
-import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin;
import info.nightscout.androidaps.plugins.pump.danaR.activities.DanaRNSHistorySync;
+import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
import info.nightscout.androidaps.plugins.source.SourceEversensePlugin;
import info.nightscout.androidaps.plugins.source.SourceGlimpPlugin;
@@ -38,30 +34,21 @@ import info.nightscout.androidaps.plugins.source.SourcePoctechPlugin;
import info.nightscout.androidaps.plugins.source.SourceTomatoPlugin;
import info.nightscout.androidaps.plugins.source.SourceXdripPlugin;
import info.nightscout.androidaps.receivers.DataReceiver;
+import info.nightscout.androidaps.logging.BundleLogger;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.SP;
-public class DataService extends JobIntentService {
+public class DataService extends IntentService {
private Logger log = LoggerFactory.getLogger(L.DATASERVICE);
- // Service unique ID
- static final int SERVICE_JOB_ID = 4378;
-
- // Enqueuing work in to this service.
- public static void enqueueWork(Context context, Intent work) {
- enqueueWork(context, DataService.class, SERVICE_JOB_ID, work);
+ public DataService() {
+ super("DataService");
+ registerBus();
}
@Override
- public void onDestroy() {
- super.onDestroy();
- if (L.isEnabled(L.DATASERVICE))
- log.debug("All work complete");
- }
-
- @Override
- protected void onHandleWork(@NonNull Intent intent) {
+ protected void onHandleIntent(final Intent intent) {
if (L.isEnabled(L.DATASERVICE)) {
log.debug("onHandleIntent " + intent);
log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras()));
@@ -113,7 +100,7 @@ public class DataService extends JobIntentService {
Intents.ACTION_REMOVED_TREATMENT.equals(action) ||
Intents.ACTION_NEW_CAL.equals(action) ||
Intents.ACTION_NEW_MBG.equals(action))
- ) {
+ ) {
handleNewDataFromNSClient(intent);
} else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) {
SmsCommunicatorPlugin.getPlugin().handleNewData(intent);
@@ -121,6 +108,22 @@ public class DataService extends JobIntentService {
if (L.isEnabled(L.DATASERVICE))
log.debug("onHandleIntent exit " + intent);
+ DataReceiver.completeWakefulIntent(intent);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ MainApp.bus().unregister(this);
+ }
+
+ private void registerBus() {
+ try {
+ MainApp.bus().unregister(this);
+ } catch (RuntimeException x) {
+ // Ignore
+ }
+ MainApp.bus().register(this);
}
private void handleNewDataFromNSClient(Intent intent) {
diff --git a/app/src/main/java/info/nightscout/androidaps/services/LocationService.java b/app/src/main/java/info/nightscout/androidaps/services/LocationService.java
index feec4dcab8..33f92d770a 100644
--- a/app/src/main/java/info/nightscout/androidaps/services/LocationService.java
+++ b/app/src/main/java/info/nightscout/androidaps/services/LocationService.java
@@ -11,10 +11,14 @@ import android.os.IBinder;
import androidx.core.app.ActivityCompat;
+import com.squareup.otto.Subscribe;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
+import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventLocationChange;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
@@ -80,12 +84,14 @@ public class LocationService extends Service {
super.onStartCommand(intent, flags, startId);
if (L.isEnabled(L.LOCATION))
log.debug("onStartCommand");
- startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, PersistentNotificationPlugin.getPlugin().updateNotification());
+ startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, PersistentNotificationPlugin.getPlugin().getLastNotification());
return START_STICKY;
}
@Override
public void onCreate() {
+ super.onCreate();
+ startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, PersistentNotificationPlugin.getPlugin().getLastNotification());
if (L.isEnabled(L.LOCATION))
log.debug("onCreate");
@@ -119,6 +125,7 @@ public class LocationService extends Service {
} catch (IllegalArgumentException ex) {
log.error("network provider does not exist, " + ex.getMessage());
}
+ MainApp.bus().register(this);
}
@Override
@@ -136,6 +143,15 @@ public class LocationService extends Service {
log.error("fail to remove location listener, ignore", ex);
}
}
+ MainApp.bus().unregister(this);
+ }
+
+ @Subscribe
+ public void onStatusEvent(EventAppExit event) {
+ if (L.isEnabled(L.CORE))
+ log.debug("EventAppExit received");
+
+ stopSelf();
}
private void initializeLocationManager() {
diff --git a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java
index 7963ae0545..11d584bb87 100644
--- a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java
+++ b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java
@@ -3,6 +3,7 @@ package info.nightscout.androidaps.utils;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -29,6 +30,8 @@ public class AndroidPermission {
public static final int CASE_BATTERY = 0x4;
public static final int CASE_PHONE_STATE = 0x5;
+ private static boolean permission_battery_optimization_failed = false;
+
@SuppressLint("BatteryLife")
private static void askForPermission(Activity activity, String[] permission, Integer requestCode) {
boolean test = false;
@@ -45,10 +48,15 @@ public class AndroidPermission {
ActivityCompat.requestPermissions(activity, permission, requestCode);
}
if (testBattery) {
- Intent i = new Intent();
- i.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
- i.setData(Uri.parse("package:" + activity.getPackageName()));
- activity.startActivityForResult(i, CASE_BATTERY);
+ try {
+ Intent i = new Intent();
+ i.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+ i.setData(Uri.parse("package:" + activity.getPackageName()));
+ activity.startActivityForResult(i, CASE_BATTERY);
+ } catch (ActivityNotFoundException e) {
+ permission_battery_optimization_failed = true;
+ OKDialog.show(activity, MainApp.gs(R.string.permission), MainApp.gs(R.string.alert_dialog_permission_battery_optimization_failed), activity::recreate);
+ }
}
}
@@ -60,9 +68,11 @@ public class AndroidPermission {
public static boolean permissionNotGranted(Context context, String permission) {
boolean selfCheck = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
if (permission.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) {
- PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- String packageName = context.getPackageName();
- selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName);
+ if (!permission_battery_optimization_failed) {
+ PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ String packageName = context.getPackageName();
+ selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName);
+ }
}
return !selfCheck;
}
diff --git a/app/src/main/java/info/nightscout/androidaps/utils/CompositeDisposablePlusAssign.kt b/app/src/main/java/info/nightscout/androidaps/utils/CompositeDisposablePlusAssign.kt
new file mode 100644
index 0000000000..1f2fb892e5
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/utils/CompositeDisposablePlusAssign.kt
@@ -0,0 +1,9 @@
+package info.nightscout.androidaps.utils
+
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.disposables.Disposable
+
+operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
+ add(disposable)
+}
+
diff --git a/app/src/main/java/info/nightscout/androidaps/utils/DigitsKeyListenerWithComma.java b/app/src/main/java/info/nightscout/androidaps/utils/DigitsKeyListenerWithComma.java
new file mode 100644
index 0000000000..a84ccd61a2
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/utils/DigitsKeyListenerWithComma.java
@@ -0,0 +1,199 @@
+package info.nightscout.androidaps.utils;
+
+import android.text.InputType;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.method.NumberKeyListener;
+import android.view.KeyEvent;
+
+class DigitsKeyListenerWithComma extends NumberKeyListener {
+
+ /**
+ * The characters that are used.
+ *
+ * @see KeyEvent#getMatch
+ * @see #getAcceptedChars
+ */
+ private static final char[][] CHARACTERS = new char[][]{
+ new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
+ new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-'},
+ new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', ','},
+ new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', ','},
+ };
+
+ private char[] mAccepted;
+ private boolean mSign;
+ private boolean mDecimal;
+
+ private static final int SIGN = 1;
+ private static final int DECIMAL = 2;
+
+ private static DigitsKeyListenerWithComma[] sInstance = new DigitsKeyListenerWithComma[4];
+
+ @Override
+ protected char[] getAcceptedChars() {
+ return mAccepted;
+ }
+
+ /**
+ * Allocates a DigitsKeyListener that accepts the digits 0 through 9.
+ */
+ public DigitsKeyListenerWithComma() {
+ this(false, false);
+ }
+
+ /**
+ * Allocates a DigitsKeyListener that accepts the digits 0 through 9,
+ * plus the minus sign (only at the beginning) and/or decimal point
+ * (only one per field) if specified.
+ */
+ public DigitsKeyListenerWithComma(boolean sign, boolean decimal) {
+ mSign = sign;
+ mDecimal = decimal;
+
+ int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0);
+ mAccepted = CHARACTERS[kind];
+ }
+
+ /**
+ * Returns a DigitsKeyListener that accepts the digits 0 through 9.
+ */
+ public static DigitsKeyListenerWithComma getInstance() {
+ return getInstance(false, false);
+ }
+
+ /**
+ * Returns a DigitsKeyListener that accepts the digits 0 through 9,
+ * plus the minus sign (only at the beginning) and/or decimal point
+ * (only one per field) if specified.
+ */
+ public static DigitsKeyListenerWithComma getInstance(boolean sign, boolean decimal) {
+ int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0);
+
+ if (sInstance[kind] != null)
+ return sInstance[kind];
+
+ sInstance[kind] = new DigitsKeyListenerWithComma(sign, decimal);
+ return sInstance[kind];
+ }
+
+ /**
+ * Returns a DigitsKeyListener that accepts only the characters
+ * that appear in the specified String. Note that not all characters
+ * may be available on every keyboard.
+ */
+ public static DigitsKeyListenerWithComma getInstance(String accepted) {
+ // TODO: do we need a cache of these to avoid allocating?
+
+ DigitsKeyListenerWithComma dim = new DigitsKeyListenerWithComma();
+
+ dim.mAccepted = new char[accepted.length()];
+ accepted.getChars(0, accepted.length(), dim.mAccepted, 0);
+
+ return dim;
+ }
+
+ public int getInputType() {
+ int contentType = InputType.TYPE_CLASS_NUMBER;
+ if (mSign) {
+ contentType |= InputType.TYPE_NUMBER_FLAG_SIGNED;
+ }
+ if (mDecimal) {
+ contentType |= InputType.TYPE_NUMBER_FLAG_DECIMAL;
+ }
+ return contentType;
+ }
+
+ @Override
+ public CharSequence filter(CharSequence source, int start, int end,
+ Spanned dest, int dstart, int dend) {
+ CharSequence out = super.filter(source, start, end, dest, dstart, dend);
+
+ if (mSign == false && mDecimal == false) {
+ return out;
+ }
+
+ if (out != null) {
+ source = out;
+ start = 0;
+ end = out.length();
+ }
+
+ int sign = -1;
+ int decimal = -1;
+ int dlen = dest.length();
+
+ /*
+ * Find out if the existing text has '-' or '.' characters.
+ */
+
+ for (int i = 0; i < dstart; i++) {
+ char c = dest.charAt(i);
+
+ if (c == '-') {
+ sign = i;
+ } else if (c == '.' || c == ',') {
+ decimal = i;
+ }
+ }
+ for (int i = dend; i < dlen; i++) {
+ char c = dest.charAt(i);
+
+ if (c == '-') {
+ return ""; // Nothing can be inserted in front of a '-'.
+ } else if (c == '.' || c == ',') {
+ decimal = i;
+ }
+ }
+
+ /*
+ * If it does, we must strip them out from the source.
+ * In addition, '-' must be the very first character,
+ * and nothing can be inserted before an existing '-'.
+ * Go in reverse order so the offsets are stable.
+ */
+
+ SpannableStringBuilder stripped = null;
+
+ for (int i = end - 1; i >= start; i--) {
+ char c = source.charAt(i);
+ boolean strip = false;
+
+ if (c == '-') {
+ if (i != start || dstart != 0) {
+ strip = true;
+ } else if (sign >= 0) {
+ strip = true;
+ } else {
+ sign = i;
+ }
+ } else if (c == '.' || c == ',') {
+ if (decimal >= 0) {
+ strip = true;
+ } else {
+ decimal = i;
+ }
+ }
+
+ if (strip) {
+ if (end == start + 1) {
+ return ""; // Only one character, and it was stripped.
+ }
+
+ if (stripped == null) {
+ stripped = new SpannableStringBuilder(source, start, end);
+ }
+
+ stripped.delete(i - start, i + 1 - start);
+ }
+ }
+
+ if (stripped != null) {
+ return stripped;
+ } else if (out != null) {
+ return out;
+ } else {
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/androidaps/utils/NumberPicker.java b/app/src/main/java/info/nightscout/androidaps/utils/NumberPicker.java
index b125d0b2a3..e2a7489fc2 100644
--- a/app/src/main/java/info/nightscout/androidaps/utils/NumberPicker.java
+++ b/app/src/main/java/info/nightscout/androidaps/utils/NumberPicker.java
@@ -183,7 +183,8 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
}
setParams(initValue, minValue, maxValue, step, formater, allowZero, okButton);
this.textWatcher = textWatcher;
- editText.addTextChangedListener(textWatcher);
+ if (textWatcher != null)
+ editText.addTextChangedListener(textWatcher);
}
public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero, Button okButton) {
@@ -196,7 +197,7 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
callValueChangedListener();
this.okButton = okButton;
- editText.setKeyListener(DigitsKeyListener.getInstance(minValue < 0, step != Math.rint(step)));
+ editText.setKeyListener(DigitsKeyListenerWithComma.getInstance(minValue < 0, step != Math.rint(step)));
if (textWatcher != null)
editText.removeTextChangedListener(textWatcher);
diff --git a/app/src/main/java/info/nightscout/androidaps/utils/TimeListEdit.java b/app/src/main/java/info/nightscout/androidaps/utils/TimeListEdit.java
index 436043fd36..be8b89dff4 100644
--- a/app/src/main/java/info/nightscout/androidaps/utils/TimeListEdit.java
+++ b/app/src/main/java/info/nightscout/androidaps/utils/TimeListEdit.java
@@ -80,6 +80,7 @@ public class TimeListEdit {
private void buildView() {
layout = view.findViewById(resLayoutId);
+ layout.removeAllViewsInLayout();
textlabel = new TextView(context);
textlabel.setText(label);
@@ -235,8 +236,8 @@ public class TimeListEdit {
if (i == 0) next = ONEHOURINSECONDS;
fillSpinner(timeSpinner, secondFromMidnight(i), previous, next);
- editText1.setParams(value1(i), min, max, step, formatter, false, view.findViewById(R.id.localprofile_save));
- editText2.setParams(value2(i), min, max, step, formatter, false, view.findViewById(R.id.localprofile_save));
+ editText1.setParams(value1(i), min, max, step, formatter, false,null);
+ editText2.setParams(value2(i), min, max, step, formatter, false, null);
if (data2 == null) {
editText2.setVisibility(View.GONE);
@@ -350,7 +351,7 @@ public class TimeListEdit {
data1.put(index, newObject1);
if (data2 != null) {
JSONObject newObject2 = new JSONObject();
- newObject1.put("time", time);
+ newObject2.put("time", time);
newObject2.put("timeAsSeconds", timeAsSeconds);
newObject2.put("value", value2);
data2.put(index, newObject2);
diff --git a/app/src/main/res/layout/automation_event_item.xml b/app/src/main/res/layout/automation_event_item.xml
index ce377a6aa0..6cbc138278 100644
--- a/app/src/main/res/layout/automation_event_item.xml
+++ b/app/src/main/res/layout/automation_event_item.xml
@@ -11,6 +11,27 @@
android:background="@color/ribbonDefault"
android:padding="8dp">
+
+
+
+
+ android:layout_below="@id/automation_enabled"
+ android:orientation="horizontal" />
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/localprofile_fragment.xml b/app/src/main/res/layout/localprofile_fragment.xml
index be5f994302..1edeeb0b31 100644
--- a/app/src/main/res/layout/localprofile_fragment.xml
+++ b/app/src/main/res/layout/localprofile_fragment.xml
@@ -1,197 +1,194 @@
-
-
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ android:text="@string/reset" />
-
-
-
-
-
+ android:layout_marginLeft="10dp"
+ android:layout_marginTop="3dp"
+ android:layout_marginRight="10dp"
+ android:layout_marginBottom="3dp"
+ android:layout_weight="1"
+ android:drawableStart="@drawable/icon_local_save"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:text="@string/save" />
-
+
+
+
+
-
diff --git a/app/src/main/res/values-el-rGR/insight_exceptions.xml b/app/src/main/res/values-el-rGR/insight_exceptions.xml
index e19a9b177d..0ebc1db351 100644
--- a/app/src/main/res/values-el-rGR/insight_exceptions.xml
+++ b/app/src/main/res/values-el-rGR/insight_exceptions.xml
@@ -4,4 +4,12 @@
Αποτυχία σύνδεσης
Απώλεια σύνδεσης
Σύζευξη απορρίφθηκε
+ Αποτυχία δημιουργίας σύνδεσης
+ Τέλος χρονικού ορίου
+ Μέγιστος αριθμός τύπων bolus ήδη τρέχει
+ Μη ενεργός TBR για ακύρωση
+ Μη ενεργός TBR για αλλαγή
+ Όχι τέτοιο bolus για ακύρωση
+ Η αντλία είναι ήδη σε αυτό το στάδιο
+ Δεν επιτρέπεται το στάδιο Run
diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml
index 13e36d84ae..a14b9e6e77 100644
--- a/app/src/main/res/values-el-rGR/strings.xml
+++ b/app/src/main/res/values-el-rGR/strings.xml
@@ -146,6 +146,7 @@
Τελευταία εφαρμογή
ΟΚ
Ακύρωση
+ Κλείσιμο
ΔΕΝ ΕΠΙΛΕΧΘΗΚΕ APS Ή ΒΡΕΘΗΚΕ ΑΠΟΤΕΛΕΣΜΑ
Ασφάλεια
Προσθήκη απενεργοποιημένη
@@ -830,6 +831,7 @@
Μη συμβατό
δευτερόλεπτο
λεπτό
+ %1$.2f h
ώρα
ημέρα
εβδομάδα
@@ -1079,6 +1081,7 @@
Σφάλμα ταχύτητας
Υπέρβαση του ορίου ινσουλίνης
Ελάχιστο αίτημα για αλλαγή [%]
+ Το Ανοιχτό κύκλωμα θα εμφανίσει νέο μήνυμα αλλαγής μόνο αν η αλλαγή είναι μεγαλύτερη από αυτήν τη τιμή %. Προεπιλεγμένη τιμή 20%
Παρακαλώ συνδέστε την αντλία στο τηλέφωνο!
Αναζήτηση συσκευών…
Περιμένετε…
@@ -1188,6 +1191,7 @@
Αυτόματο
Αυτοματισμός
== ∑ %1$s U
+ U/h
g/U
/U
Αλλαγή αρχείου αισθητήρα σε NS
@@ -1234,7 +1238,14 @@
Κατάσταση:
Ενέργεια:
ΙΟΒ [U]:
+ Γλυκόζη [%1$s]:
+ ΔΙΑΓΡ
+ Προσθ
+ Αντιγραφή
+ Προσθήκη νέου
Έλεγχος Έκδοσης
+ Έλεγχος υπογραφής
+ Διαπιστώσαμε ότι εκτελείτε μη έγκυρη έκδοση. Κύκλωμα απενεργοποιήθηκε!
παλιά έκδοση
πολύ παλιά έκδοση
Νέα έκδοση για τουλάχιστον %1$d ημέρες διαθέσιμη! Επιστροφή σε LGS μετά από 60 ημέρες, το κύκλωμα θα απενεργοποιηθεί μετά από 90 ημέρες
@@ -1243,9 +1254,52 @@
Εφαρμογή Dexcom (τροποποιημένη)
DXCM
Λάβετε τις τιμές BG από την εφαρμογή του Dexcom.
+ Ειδοποίηση
+ Ειδοποίηση: %1$s
+ Μην:
+ Προφίλ ποσοστό
+ Ποσοστό [%]:
+ Έναρξη προφίλ %1$d%% για %2$d λεπτά
+ Έναρξη προφίλ %1$d%%
+ υπάρχει
+ δεν υπάρχει
+ Προσ. στόχος %1$s
+ WiFi SSID %1$s %2$s
+ Autosens %1$s %2$s %%
+ Autosens %
+ %3$s %1$s %2$s
+ Διαφορά BG
+ Τρέχουσα θέση
+ Τοποθεσία
+ Lat:
+ Lon:
+ Αποστ [m]:
+ Όνομα:
+ Η τοποθεσία είναι %1$s
+ Τελευταίο Bolus
+ Τελευταίο bolus %1$s %2$s λεπτά πριν
+ COB
+ COB %1$s %2$.0f
+ Όνομα εργασίας
+ Όνομα συμβάντος
+ Επεξεργασία
+ Επιλέξτε έναν τύπο δράσης:
+ Επιλέξτε έναν τύπο ενεργοποίησης:
+ Αν:
+ Έπειτα:
+ Ενεργοποιήσεις:
+ ΜΕΤΑΚΙΝΗΣΗ
+ Προϋποθέσεις:
+ Η λειτουργία δεν υποστηρίζεται από την αντλία ή/και οδηγό.
+ Η λειτουργία δεν υποστηρίζεται ΑΚΟΜΑ από την αντλία.
+ Η ολοκλήρωση της αντλίας για τη Medtronic, απαιτεί τη συσκευή RileyLink και το συγκεκριμένο μοντέλο αντλίας
+ Σειριακός Αριθμός Αντλίας
+ Τύπος Αντλίας
+ Συχνότητα Αντλίας
+ Η καθυστέρηση πριν το bolus ξεκίνησε (s)
Μέγιστο Bolus στην αντλία (U)
Μέγιστος Βασικός στην αντλία (U/h)
Αποκωδικοποίηση Medtronic
@@ -1299,16 +1353,67 @@
Επαναφορά Bluetooth…
Σφάλμα Bluetooth
+ Bluetooth Έτοιμο
+ Δεν ξεκίνησε
+ Αρχικοποίηση του RileyLink…
+ RileyLink Σφάλμα
+ Ρύθμιση του RileyLink και της αντλίας
+ Πρόβλημα σύνδεσης με την Αντλία
+ Συνδέθηκε
+ Η συσκευή δεν είναι RileyLink
+ Το RileyLink μη προσπελάσιμο
+ Bluetooth απενεργοποιημένο
+ Δεν υπάρχει προσαρμογέας Bluetooth
+ TuneUp απέτυχε
+ Η αντλία δεν είναι διαθέσιμη
+ Το Pod δεν είναι διαθέσιμο
+ Μη ορισμένο
+ Αντλία Medtronic
+ Omnipod
+ Σφάλματα
+ Δεν ορίστηκε # Serial.
+ Serial # μη έγκυρο.
+ Δεν ορίστηκε Τύπος Αντλίας.
+ Τύπος Αντλίας δεν υποστηρίζεται.
+ Δεν ορίστηκε Συχνότητα Αντλίας.
+ Συχνότητα Αντλίας δεν υποστηρίζεται.
+ Διεύθυνση RileyLink μη έγκυρη.
+ Ο τύπος αντλίας που ανιχνεύτηκε δεν είναι ο ίδιος με αυτόν που ορίστηκε.
+ Τα προφίλ βασικού δεν είναι ενεργοποιημένα στην αντλία.
+ Το βασικό προφίλ που ορίστηκε στην αντλία είναι λάθoς (πρέπει να είναι STD).
+ Λάθος τύπος TBR ορίστηκε στην αντλία (πρέπει να είναι Absolute).
+ Λάθος μέγιστο bolus ορίστηκε στην αντλία (πρέπει να είναι %1$.2f).
+ Λάθος μέγιστο Βασικού ορίστηκε στην αντλία (πρέπει να είναι %1$.2f).
+ Λειτουργία δεν είναι δυνατή. \n\n Χρειάζεται να ρυθμίσετε την αντλία Medtronic πρώτα, προτού να μπορέσετε να χρησιμοποιήσετε αυτή την λειτουργία.
+ Απαιτήθηκε αλλαγή ώρας πάνω από 24h.
+ Βασικοί
+ Ρύθμιση παραμέτρων
+ Ειδοποιήσεις
+ Στατιστικά
+ Άγνωστα
+ Όλα
+ Ιστορικό Αντλίας Medtronic
+ Ποτέ δεν επικοινωνήσατε
+ Ξύπνημα
+ Σφάλμα με επικοινωνία
+ Λήξη χρόνου επικοινωνίας
+ Πρόβλημα επικοινωνίας με Αντλία
+ Η αντλία δεν είναι διαθέσιμη
+ Μη έγκυρη παραμετροποίηση
+ Ενεργή
+ Sleeping
+ Ακυρώσατε τον Bolus, αφού είχε ήδη σταλεί στην αντλία. Επειδή η αντλία Medtronic δεν υποστηρίζει ακύρωση, θα χρειαστεί να ακυρωθεί χειροκίνητα. Βάλτε την αντλία σε αναστολή λειτουργίας και μετά κάντε Συνέχιση (αν θέλετε να ακυρώσετε ακόμα). Η εφαρμογή θα πάρει τις αλλαγές, στην επόμενη ενημέρωση (σε λιγότερο από 5 λεπτά).
Αδυναμία ανάγνωσης τρέχοντος TBR.
Αδυναμία ακύρωσης τρέχοντος TBR. Αναστολή λειτουργίας.
Η δημιουργία προφίλ απέτυχε, επειδή ακολουθώντας πρότυπα, έχετε υπερβολικά μεγάλο βασικό ρυθμό: %1$s
Το Bolus δεν μπορεί να χορηγηθεί.
+ Το Bolus δεν μπορεί να παραδοθεί διότι η διαθέσιμη ποσότητα ινσουλίνης (%1$.2f) είναι μικρότερη από αυτήν που ζητείται (%2$.2f).
TBR δεν μπορεί να μπει.
Αδυναμία ακύρωσης τρέχοντος TBR.
Το Βασικό Προφίλ δεν μπορεί να τοποθετηθεί.
@@ -1327,6 +1432,9 @@
Αποσυνδεδεμένο για %1$d ώρες %2$d λεπτά
Αποσυνδεδεμένο για %1$d μέρες %2$d ώρες
%2$.1fg %3$.2f]]>
+ Bolus constraint applied: %2$.2fU to %3$.2fU]]>
+ !!!!! Μικρή απορρόφηση υδατανθράκων ανιχνεύτηκε: %2$d%% της ώρας. Τσεκάρετε τους υπολογισμούς σας. COB μπορεί να είναι κλειστό]]>
+ %1$.0f / %2$d U
- %1$d ημέρα
- %1$d ημέρες
diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml
index cf8df22345..371fe786c3 100644
--- a/app/src/main/res/values-pl-rPL/strings.xml
+++ b/app/src/main/res/values-pl-rPL/strings.xml
@@ -146,6 +146,7 @@
Ostatnie działanie
OK
Anuluj
+ Zamknij
NIE WYBRANO APS LUB NIE UZYSKANO WYNIKU
Zabezpieczenia
Wtyczka jest wyłączona
@@ -831,6 +832,7 @@
Niekompatybilny
sekunda
minuta
+ %1$.2f h
godzina
dzień
tydzień
@@ -1190,6 +1192,7 @@
Auto
Automatyzacja
== ∑ %1$s U
+ U/h
g/U
/U
Prześlij zmianę sensora do NS
@@ -1247,7 +1250,6 @@
stara wersja
bardzo stara wersja
Nowa wersja dostępna co najmniej %1$d dni! Powrót do LGS (zawieszania podawania bazy przy niskim poziomie) po 60 dniach, pętla zostanie wyłączona po 90 dniach
- Graficzny wykres aktywności insuliny [U/min]
2 h
%1$.2fU
Apka Dexcom (spatchowana)
@@ -1412,6 +1414,7 @@
Nie udało się anulować aktualnej dawki tymczasowej (TBR). Operacja zatrzymania.
Ustawienia Profilu nie powiodły się ponieważ następująca wartość jest za duża: %1$s
Nie udało się dostarczyć bolusa.
+ Bolus nie mógł być dostarczony ponieważ Ilość dostępnej insuliny (%1$.2f) jest mniejsza niż wymagany bolus (%2$.2f).
Nie udało się ustawić dawki tymczasowej (TBR).
Nie udało się anulować bazy tymczasowej (TBR).
Profil bazy nie został ustawiony.
@@ -1432,6 +1435,7 @@
%2$.1fg %3$.2fU]]>
Wprowadzono ograniczenie bolusa: %2$.2fU to %3$.2fU]]>
!!!!! Wykryto powolne wchłanianie węglowodanów: %2$d%% czasu. Sprawdź ponownie swoje obliczenia. COB mogą się znacznie różnić !!!!!]]>
+ %1$.0f / %2$d U
- %1$d dzień
- %1$d dni
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f899566377..209d6347ef 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -38,6 +38,7 @@
DanaR Bluetooth device
Always use basal absolute values
Please reboot your phone or restart AndroidAPS from the System Settings \notherwise Android APS will not have logging (important to track and verify that the algorithms are working correctly)!
+ This device does not appear to support battery optimization whitelisting - you may experience performance issues.
Some buttons to quickly access common features
Enter advanced log book entries.
@@ -1462,6 +1463,7 @@
Autosens %
%3$s %1$s %2$s
BG difference
+ BG difference [%1$s]
Current Location
Location
Lat:
@@ -1670,6 +1672,7 @@
boluswizard_percentage
Deliver this part of bolus wizard result [%]
Bolus wizard performs calculation but only this part of calculated insulin is delivered. Useful with SMB algorithm.
+ Loading ...
- %1$d day
diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/AutomationEventTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/AutomationEventTest.java
index a40bcdb2fe..e3030b8a91 100644
--- a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/AutomationEventTest.java
+++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/AutomationEventTest.java
@@ -22,7 +22,7 @@ public class AutomationEventTest {
event.addAction(new ActionLoopEnable());
// export to json
- final String eventJsonExpected = "{\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\",\"title\":\"Test\",\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"]}";
+ final String eventJsonExpected = "{\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\",\"title\":\"Test\",\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"],\"enabled\":true}";
Assert.assertEquals(eventJsonExpected, event.toJSON());
// clone
diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTargetTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTargetTest.java
index 93be03f059..ff2baf6198 100644
--- a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTargetTest.java
+++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTargetTest.java
@@ -16,8 +16,8 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
-import info.nightscout.androidaps.plugins.general.automation.elements.InputBg;
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration;
+import info.nightscout.androidaps.plugins.general.automation.elements.InputTempTarget;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.SP;
@@ -40,7 +40,7 @@ public class ActionStartTempTargetTest {
public void shortDescriptionTest() {
actionStartTempTarget = new ActionStartTempTarget();
actionStartTempTarget.reason = "Test";
- actionStartTempTarget.value = new InputBg().setValue(100).setUnits(Constants.MGDL);
+ actionStartTempTarget.value = new InputTempTarget().setValue(100).setUnits(Constants.MGDL);
actionStartTempTarget.duration = new InputDuration(30, InputDuration.TimeUnit.MINUTES);
Assert.assertEquals("Start temp target: 100mg/dl@null(Test)", actionStartTempTarget.shortDescription());
}
@@ -70,7 +70,7 @@ public class ActionStartTempTargetTest {
public void toJSONTest() {
actionStartTempTarget = new ActionStartTempTarget();
actionStartTempTarget.reason = "Test";
- actionStartTempTarget.value = new InputBg().setValue(100).setUnits(Constants.MGDL);
+ actionStartTempTarget.value = new InputTempTarget().setValue(100).setUnits(Constants.MGDL);
actionStartTempTarget.duration = new InputDuration(30, InputDuration.TimeUnit.MINUTES);
Assert.assertEquals("{\"data\":{\"reason\":\"Test\",\"durationInMinutes\":30,\"units\":\"mg/dl\",\"value\":100},\"type\":\"info.nightscout.androidaps.plugins.general.automation.actions.ActionStartTempTarget\"}", actionStartTempTarget.toJSON());
}
diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBgTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBgTest.java
index e3bbfeb7c8..8a56a65459 100644
--- a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBgTest.java
+++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBgTest.java
@@ -16,27 +16,14 @@ import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
@PrepareForTest({MainApp.class, ProfileFunctions.class})
public class InputBgTest {
- @Test
- public void textWatcherTest() {
- InputBg t = new InputBg().setUnits(Constants.MMOL).setValue(1d);
- t.textWatcher.beforeTextChanged(null, 0, 0, 0);
- t.textWatcher.onTextChanged(null, 0, 0, 0);
- t.textWatcher.afterTextChanged(null);
- Assert.assertEquals(4d, t.getValue(), 0.01d);
-
- t = new InputBg().setValue(300d).setUnits(Constants.MGDL);
- t.textWatcher.afterTextChanged(null);
- Assert.assertEquals(270d, t.getValue(), 0.01d);
- }
-
@Test
public void getSetValueTest() {
InputBg i = new InputBg().setUnits(Constants.MMOL).setValue(5d);
Assert.assertEquals(5d, i.getValue(), 0.01d);
- Assert.assertEquals(2, i.minValue, 0.01d);
+ Assert.assertEquals(InputBg.MMOL_MIN, i.minValue, 0.01d);
i = new InputBg().setValue(100d).setUnits(Constants.MGDL);
Assert.assertEquals(100d, i.getValue(), 0.01d);
- Assert.assertEquals(40, i.minValue, 0.01d);
+ Assert.assertEquals(InputBg.MGDL_MIN, i.minValue, 0.01d);
Assert.assertEquals(Constants.MGDL, i.getUnits());
}
diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTargetTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTargetTest.java
new file mode 100644
index 0000000000..a9a0a4c91f
--- /dev/null
+++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTargetTest.java
@@ -0,0 +1,38 @@
+package info.nightscout.androidaps.plugins.general.automation.elements;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import info.AAPSMocker;
+import info.nightscout.androidaps.Constants;
+import info.nightscout.androidaps.MainApp;
+import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({MainApp.class, ProfileFunctions.class})
+public class InputTempTargetTest {
+
+ @Test
+ public void getSetValueTest() {
+ InputTempTarget i = new InputTempTarget().setUnits(Constants.MMOL).setValue(5d);
+ Assert.assertEquals(5d, i.getValue(), 0.01d);
+ Assert.assertEquals(Constants.MIN_TT_MMOL, i.minValue, 0.01d);
+ i = new InputTempTarget().setValue(100d).setUnits(Constants.MGDL);
+ Assert.assertEquals(100d, i.getValue(), 0.01d);
+ Assert.assertEquals(Constants.MIN_TT_MGDL, i.minValue, 0.01d);
+ Assert.assertEquals(Constants.MGDL, i.getUnits());
+ }
+
+
+ @Before
+ public void prepare() {
+ AAPSMocker.mockMainApp();
+ AAPSMocker.mockBus();
+ AAPSMocker.mockStrings();
+ AAPSMocker.mockProfileFunctions();
+ }
+}
\ No newline at end of file