Merge pull request #735 from Philoul/Fix/FixCrashExportCSV

Fix crash during csv export
This commit is contained in:
Milos Kozak 2021-10-17 10:32:41 +02:00 committed by GitHub
commit 3093a84d65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 11 deletions

View file

@ -68,7 +68,7 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
activity?.let { activity -> activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.ue_export_to_csv) + "?") { OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.ue_export_to_csv) + "?") {
uel.log(Action.EXPORT_CSV, Sources.Treatments) uel.log(Action.EXPORT_CSV, Sources.Treatments)
importExportPrefs.exportUserEntriesCsv(activity, repository.getAllUserEntries()) importExportPrefs.exportUserEntriesCsv(activity)
} }
} }
} }

View file

@ -15,7 +15,7 @@ import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult
import info.nightscout.androidaps.activities.PreferencesActivity import info.nightscout.androidaps.activities.PreferencesActivity
import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.events.EventAppExit import info.nightscout.androidaps.events.EventAppExit
@ -28,6 +28,8 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.maintenance.formats.* import info.nightscout.androidaps.plugins.general.maintenance.formats.*
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.alertDialogs.PrefImportSummaryDialog import info.nightscout.androidaps.utils.alertDialogs.PrefImportSummaryDialog
@ -37,7 +39,6 @@ import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.protection.PasswordCheck import info.nightscout.androidaps.utils.protection.PasswordCheck
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.Single
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
@ -63,6 +64,7 @@ class ImportExportPrefsImpl @Inject constructor(
private val encryptedPrefsFormat: EncryptedPrefsFormat, private val encryptedPrefsFormat: EncryptedPrefsFormat,
private val prefFileList: PrefFileListProvider, private val prefFileList: PrefFileListProvider,
private val uel: UserEntryLogger, private val uel: UserEntryLogger,
private val repository: AppRepository,
private val dateUtil: DateUtil private val dateUtil: DateUtil
) : ImportExportPrefs { ) : ImportExportPrefs {
@ -360,8 +362,8 @@ class ImportExportPrefsImpl @Inject constructor(
} }
} }
override fun exportUserEntriesCsv(activity: FragmentActivity, singleEntries: Single<List<UserEntry>>) { override fun exportUserEntriesCsv(activity: FragmentActivity) {
val entries = singleEntries.blockingGet() val entries = repository.getUserEntryFilteredDataFromTime(MidnightTime.calc() - T.days(90).msecs()).blockingGet()
prefFileList.ensureExportDirExists() prefFileList.ensureExportDirExists()
val newFile = prefFileList.newExportCsvFile() val newFile = prefFileList.newExportCsvFile()

View file

@ -118,7 +118,7 @@ class MaintenanceFragment : DaggerFragment() {
activity?.let { activity -> activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.ue_export_to_csv) + "?") { OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.ue_export_to_csv) + "?") {
uel.log(Action.EXPORT_CSV, Sources.Maintenance) uel.log(Action.EXPORT_CSV, Sources.Maintenance)
importExportPrefs.exportUserEntriesCsv(activity, repository.getAllUserEntries()) importExportPrefs.exportUserEntriesCsv(activity)
} }
} }
} }

View file

@ -14,5 +14,5 @@ interface ImportExportPrefs {
fun prefsFileExists(): Boolean fun prefsFileExists(): Boolean
fun verifyStoragePermissions(fragment: Fragment, onGranted: Runnable) fun verifyStoragePermissions(fragment: Fragment, onGranted: Runnable)
fun exportSharedPreferences(f: Fragment) fun exportSharedPreferences(f: Fragment)
fun exportUserEntriesCsv(activity: FragmentActivity, singleEntries: Single<List<UserEntry>>) fun exportUserEntriesCsv(activity: FragmentActivity)
} }

View file

@ -114,7 +114,7 @@ class Translator @Inject internal constructor(
else -> "" else -> ""
} }
fun translate(meterType: TherapyEvent.MeterType): String = when (meterType) { fun translate(meterType: TherapyEvent.MeterType?): String = when (meterType) {
TherapyEvent.MeterType.FINGER -> resourceHelper.gs(R.string.glucosetype_finger) TherapyEvent.MeterType.FINGER -> resourceHelper.gs(R.string.glucosetype_finger)
TherapyEvent.MeterType.SENSOR -> resourceHelper.gs(R.string.glucosetype_sensor) TherapyEvent.MeterType.SENSOR -> resourceHelper.gs(R.string.glucosetype_sensor)
TherapyEvent.MeterType.MANUAL -> resourceHelper.gs(R.string.manual) TherapyEvent.MeterType.MANUAL -> resourceHelper.gs(R.string.manual)
@ -122,7 +122,7 @@ class Translator @Inject internal constructor(
else -> resourceHelper.gs(R.string.unknown) else -> resourceHelper.gs(R.string.unknown)
} }
fun translate(type: TherapyEvent.Type): String = when (type) { fun translate(type: TherapyEvent.Type?): String = when (type) {
TherapyEvent.Type.FINGER_STICK_BG_VALUE -> resourceHelper.gs(R.string.careportal_bgcheck) TherapyEvent.Type.FINGER_STICK_BG_VALUE -> resourceHelper.gs(R.string.careportal_bgcheck)
TherapyEvent.Type.SNACK_BOLUS -> resourceHelper.gs(R.string.careportal_snackbolus) TherapyEvent.Type.SNACK_BOLUS -> resourceHelper.gs(R.string.careportal_snackbolus)
TherapyEvent.Type.MEAL_BOLUS -> resourceHelper.gs(R.string.careportal_mealbolus) TherapyEvent.Type.MEAL_BOLUS -> resourceHelper.gs(R.string.careportal_mealbolus)
@ -173,7 +173,7 @@ class Translator @Inject internal constructor(
else -> resourceHelper.gs(R.string.unknown) else -> resourceHelper.gs(R.string.unknown)
} }
fun translate(reason: TemporaryTarget.Reason): String = when (reason) { fun translate(reason: TemporaryTarget.Reason?): String = when (reason) {
TemporaryTarget.Reason.CUSTOM -> resourceHelper.gs(R.string.custom) TemporaryTarget.Reason.CUSTOM -> resourceHelper.gs(R.string.custom)
TemporaryTarget.Reason.HYPOGLYCEMIA -> resourceHelper.gs(R.string.hypo) TemporaryTarget.Reason.HYPOGLYCEMIA -> resourceHelper.gs(R.string.hypo)
TemporaryTarget.Reason.EATING_SOON -> resourceHelper.gs(R.string.eatingsoon) TemporaryTarget.Reason.EATING_SOON -> resourceHelper.gs(R.string.eatingsoon)
@ -184,7 +184,7 @@ class Translator @Inject internal constructor(
else -> resourceHelper.gs(R.string.unknown) else -> resourceHelper.gs(R.string.unknown)
} }
fun translate(reason: OfflineEvent.Reason): String = when (reason) { fun translate(reason: OfflineEvent.Reason?): String = when (reason) {
OfflineEvent.Reason.SUSPEND -> resourceHelper.gs(R.string.uel_suspend) OfflineEvent.Reason.SUSPEND -> resourceHelper.gs(R.string.uel_suspend)
OfflineEvent.Reason.DISABLE_LOOP -> resourceHelper.gs(R.string.disableloop) OfflineEvent.Reason.DISABLE_LOOP -> resourceHelper.gs(R.string.disableloop)
OfflineEvent.Reason.DISCONNECT_PUMP -> resourceHelper.gs(R.string.uel_disconnect) OfflineEvent.Reason.DISCONNECT_PUMP -> resourceHelper.gs(R.string.uel_disconnect)

View file

@ -5,6 +5,7 @@ import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
import info.nightscout.androidaps.database.TABLE_TEMPORARY_TARGETS import info.nightscout.androidaps.database.TABLE_TEMPORARY_TARGETS
import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration
@ -62,11 +63,17 @@ data class TemporaryTarget(
interfaceIDs.nightscoutId != null interfaceIDs.nightscoutId != null
enum class Reason(val text: String) { enum class Reason(val text: String) {
@SerializedName("Custom")
CUSTOM("Custom"), CUSTOM("Custom"),
@SerializedName("Hypo")
HYPOGLYCEMIA("Hypo"), HYPOGLYCEMIA("Hypo"),
@SerializedName("Activity")
ACTIVITY("Activity"), ACTIVITY("Activity"),
@SerializedName("Eating Soon")
EATING_SOON("Eating Soon"), EATING_SOON("Eating Soon"),
@SerializedName("Automation")
AUTOMATION("Automation"), AUTOMATION("Automation"),
@SerializedName("Wear")
WEAR("Wear") WEAR("Wear")
; ;

View file

@ -5,6 +5,7 @@ import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
import info.nightscout.androidaps.database.TABLE_THERAPY_EVENTS import info.nightscout.androidaps.database.TABLE_THERAPY_EVENTS
import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration
@ -73,8 +74,11 @@ data class TherapyEvent(
} }
enum class MeterType(val text: String) { enum class MeterType(val text: String) {
@SerializedName("Finger")
FINGER("Finger"), FINGER("Finger"),
@SerializedName("Sensor")
SENSOR("Sensor"), SENSOR("Sensor"),
@SerializedName("Manual")
MANUAL("Manual") MANUAL("Manual")
; ;
@ -87,55 +91,99 @@ data class TherapyEvent(
@Suppress("unused") @Suppress("unused")
enum class Type(val text: String, val nsNative: Boolean = false) { enum class Type(val text: String, val nsNative: Boolean = false) {
@SerializedName("Site Change")
CANNULA_CHANGE("Site Change", nsNative = true), CANNULA_CHANGE("Site Change", nsNative = true),
@SerializedName("Insulin Change")
INSULIN_CHANGE("Insulin Change", nsNative = true), INSULIN_CHANGE("Insulin Change", nsNative = true),
@SerializedName("Pump Battery Change")
PUMP_BATTERY_CHANGE("Pump Battery Change", nsNative = true), PUMP_BATTERY_CHANGE("Pump Battery Change", nsNative = true),
@SerializedName("Sensor Change")
SENSOR_CHANGE("Sensor Change", nsNative = true), SENSOR_CHANGE("Sensor Change", nsNative = true),
@SerializedName("Sensor Start")
SENSOR_STARTED("Sensor Start", nsNative = true), SENSOR_STARTED("Sensor Start", nsNative = true),
@SerializedName("Sensor Stop")
SENSOR_STOPPED("Sensor Stop", nsNative = true), SENSOR_STOPPED("Sensor Stop", nsNative = true),
@SerializedName("BG Check")
FINGER_STICK_BG_VALUE("BG Check", nsNative = true), FINGER_STICK_BG_VALUE("BG Check", nsNative = true),
@SerializedName("Exercise")
EXERCISE("Exercise", nsNative = true), EXERCISE("Exercise", nsNative = true),
@SerializedName("Announcement")
ANNOUNCEMENT("Announcement", nsNative = true), ANNOUNCEMENT("Announcement", nsNative = true),
@SerializedName("Question")
QUESTION("Question", nsNative = true), QUESTION("Question", nsNative = true),
@SerializedName("Note")
NOTE("Note", nsNative = true), NOTE("Note", nsNative = true),
@SerializedName("OpenAPS Offline")
APS_OFFLINE("OpenAPS Offline", nsNative = true), APS_OFFLINE("OpenAPS Offline", nsNative = true),
@SerializedName("D.A.D. Alert")
DAD_ALERT("D.A.D. Alert", nsNative = true), DAD_ALERT("D.A.D. Alert", nsNative = true),
@SerializedName("Mbg")
NS_MBG("Mbg", nsNative = true), NS_MBG("Mbg", nsNative = true),
// Used but not as a Therapy Event (use constants only) // Used but not as a Therapy Event (use constants only)
@SerializedName("Carb Correction")
CARBS_CORRECTION("Carb Correction", nsNative = true), CARBS_CORRECTION("Carb Correction", nsNative = true),
@SerializedName("Bolus Wizard")
BOLUS_WIZARD("Bolus Wizard", nsNative = true), BOLUS_WIZARD("Bolus Wizard", nsNative = true),
@SerializedName("Correction Bolus")
CORRECTION_BOLUS("Correction Bolus", nsNative = true), CORRECTION_BOLUS("Correction Bolus", nsNative = true),
@SerializedName("Meal Bolus")
MEAL_BOLUS("Meal Bolus", nsNative = true), MEAL_BOLUS("Meal Bolus", nsNative = true),
@SerializedName("Combo Bolus")
COMBO_BOLUS("Combo Bolus", nsNative = true), COMBO_BOLUS("Combo Bolus", nsNative = true),
@SerializedName("Temporary Target")
TEMPORARY_TARGET("Temporary Target", nsNative = true), TEMPORARY_TARGET("Temporary Target", nsNative = true),
@SerializedName("Temporary Target Cancel")
TEMPORARY_TARGET_CANCEL("Temporary Target Cancel", nsNative = true), TEMPORARY_TARGET_CANCEL("Temporary Target Cancel", nsNative = true),
@SerializedName("Profile Switch")
PROFILE_SWITCH("Profile Switch", nsNative = true), PROFILE_SWITCH("Profile Switch", nsNative = true),
@SerializedName("Snack Bolus")
SNACK_BOLUS("Snack Bolus", nsNative = true), SNACK_BOLUS("Snack Bolus", nsNative = true),
@SerializedName("Temp Basal")
TEMPORARY_BASAL("Temp Basal", nsNative = true), TEMPORARY_BASAL("Temp Basal", nsNative = true),
@SerializedName("Temp Basal Start")
TEMPORARY_BASAL_START("Temp Basal Start", nsNative = true), TEMPORARY_BASAL_START("Temp Basal Start", nsNative = true),
@SerializedName("Temp Basal End")
TEMPORARY_BASAL_END("Temp Basal End", nsNative = true), TEMPORARY_BASAL_END("Temp Basal End", nsNative = true),
// Not supported by NS // Not supported by NS
@SerializedName("Tube Change")
TUBE_CHANGE("Tube Change"), TUBE_CHANGE("Tube Change"),
@SerializedName("Falling Asleep")
FALLING_ASLEEP("Falling Asleep"), FALLING_ASLEEP("Falling Asleep"),
@SerializedName("Battery Empty")
BATTERY_EMPTY("Battery Empty"), BATTERY_EMPTY("Battery Empty"),
@SerializedName("Reservoir Empty")
RESERVOIR_EMPTY("Reservoir Empty"), RESERVOIR_EMPTY("Reservoir Empty"),
@SerializedName("Occlusion")
OCCLUSION("Occlusion"), OCCLUSION("Occlusion"),
@SerializedName("Pump Stopped")
PUMP_STOPPED("Pump Stopped"), PUMP_STOPPED("Pump Stopped"),
@SerializedName("Pump Started")
PUMP_STARTED("Pump Started"), PUMP_STARTED("Pump Started"),
@SerializedName("Pump Paused")
PUMP_PAUSED("Pump Paused"), PUMP_PAUSED("Pump Paused"),
@SerializedName("Waking Up")
WAKING_UP("Waking Up"), WAKING_UP("Waking Up"),
@SerializedName("Sickness")
SICKNESS("Sickness"), SICKNESS("Sickness"),
@SerializedName("Stress")
STRESS("Stress"), STRESS("Stress"),
@SerializedName("Pre Period")
PRE_PERIOD("Pre Period"), PRE_PERIOD("Pre Period"),
@SerializedName("Alcohol")
ALCOHOL("Alcohol"), ALCOHOL("Alcohol"),
@SerializedName("Cortisone")
CORTISONE("Cortisone"), CORTISONE("Cortisone"),
@SerializedName("Feeling Low")
FEELING_LOW("Feeling Low"), FEELING_LOW("Feeling Low"),
@SerializedName("Feeling High")
FEELING_HIGH("Feeling High"), FEELING_HIGH("Feeling High"),
@SerializedName("Leaking Infusion Set")
LEAKING_INFUSION_SET("Leaking Infusion Set"), LEAKING_INFUSION_SET("Leaking Infusion Set"),
// Default // Default
@SerializedName("<none>")
NONE("<none>") NONE("<none>")
; ;