diff --git a/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/5.json b/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/5.json
index cd6da352..02e1f958 100644
--- a/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/5.json
+++ b/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/5.json
@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 5,
- "identityHash": "f0e80a69f9fff0c48f2b7df10de3228f",
+ "identityHash": "d66fc1fc2752b2d6f41700fa2102492a",
"entities": [
{
"tableName": "scaleMeasurements",
@@ -174,7 +174,7 @@
},
{
"tableName": "scaleUsers",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `username` TEXT NOT NULL, `birthday` INTEGER NOT NULL, `bodyHeight` REAL NOT NULL, `scaleUnit` INTEGER NOT NULL, `gender` INTEGER NOT NULL, `initialWeight` REAL NOT NULL, `goalWeight` REAL NOT NULL, `goalDate` INTEGER, `measureUnit` INTEGER NOT NULL, `activityLevel` INTEGER NOT NULL, `assistedWeighing` INTEGER NOT NULL)",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `username` TEXT NOT NULL, `birthday` INTEGER NOT NULL, `bodyHeight` REAL NOT NULL, `scaleUnit` INTEGER NOT NULL, `gender` INTEGER NOT NULL, `initialWeight` REAL NOT NULL, `goalWeight` REAL NOT NULL, `goalDate` INTEGER, `measureUnit` INTEGER NOT NULL, `activityLevel` INTEGER NOT NULL, `assistedWeighing` INTEGER NOT NULL, `leftAmputationLevel` INTEGER NOT NULL, `rightAmputationLevel` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
@@ -247,6 +247,18 @@
"columnName": "assistedWeighing",
"affinity": "INTEGER",
"notNull": true
+ },
+ {
+ "fieldPath": "leftAmputationLevel",
+ "columnName": "leftAmputationLevel",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "rightAmputationLevel",
+ "columnName": "rightAmputationLevel",
+ "affinity": "INTEGER",
+ "notNull": true
}
],
"primaryKey": {
@@ -262,7 +274,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
- "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f0e80a69f9fff0c48f2b7df10de3228f')"
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd66fc1fc2752b2d6f41700fa2102492a')"
]
}
}
\ No newline at end of file
diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java
index 525ba382..cc4cae66 100644
--- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java
+++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java
@@ -274,6 +274,7 @@ public class OpenScale {
public int addScaleMeasurement(final ScaleMeasurement scaleMeasurement, boolean silent) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ // Check user id and do a smart user assign if option is enabled
if (scaleMeasurement.getUserId() == -1) {
if (prefs.getBoolean("smartUserAssign", false)) {
scaleMeasurement.setUserId(getSmartUserAssignment(scaleMeasurement.getWeight(), 15.0f));
@@ -288,6 +289,7 @@ public class OpenScale {
}
}
+ // Assisted weighing
if (getScaleUser(scaleMeasurement.getUserId()).isAssistedWeighing()) {
int assistedWeighingRefUserId = prefs.getInt("assistedWeighingRefUserId", -1);
if (assistedWeighingRefUserId != -1) {
@@ -303,6 +305,10 @@ public class OpenScale {
}
}
+ // Calculate the amputation correction factor for the weight, if available
+ scaleMeasurement.setWeight((scaleMeasurement.getWeight() * 100.0f) / getScaleUser(scaleMeasurement.getUserId()).getAmputationCorrectionFactor());
+
+ // If option is enabled then calculate body measurements from generic formulas
MeasurementViewSettings settings = new MeasurementViewSettings(prefs, WaterMeasurementView.KEY);
if (settings.isEnabled() && settings.isEstimationEnabled()) {
EstimatedWaterMetric waterMetric = EstimatedWaterMetric.getEstimatedMetric(
@@ -325,6 +331,7 @@ public class OpenScale {
scaleMeasurement.setLbm(lbmMetric.getLBM(getScaleUser(scaleMeasurement.getUserId()), scaleMeasurement));
}
+ // Insert measurement into the database, check return if it was successful inserted
if (measurementDAO.insert(scaleMeasurement) != -1) {
Timber.d("Added measurement: %s", scaleMeasurement);
if (!silent) {
diff --git a/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java
index 1cb7c05a..6a5e1eab 100644
--- a/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java
+++ b/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java
@@ -182,8 +182,10 @@ public abstract class AppDatabase extends RoomDatabase {
public void migrate(SupportSQLiteDatabase database) {
database.beginTransaction();
try {
- // Add assisted weighing to table
+ // Add assisted weighing and left/right amputation level to table
database.execSQL("ALTER TABLE scaleUsers ADD assistedWeighing INTEGER NOT NULL default 0");
+ database.execSQL("ALTER TABLE scaleUsers ADD leftAmputationLevel INTEGER NOT NULL default 0");
+ database.execSQL("ALTER TABLE scaleUsers ADD rightAmputationLevel INTEGER NOT NULL default 0");
database.setTransactionSuccessful();
}
diff --git a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java
index ff999cf6..1b781438 100644
--- a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java
+++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java
@@ -60,6 +60,12 @@ public class ScaleUser {
private Converters.ActivityLevel activityLevel;
@ColumnInfo(name = "assistedWeighing")
private boolean assistedWeighing;
+ @NonNull
+ @ColumnInfo(name = "leftAmputationLevel")
+ private Converters.AmputationLevel leftAmputationLevel;
+ @NonNull
+ @ColumnInfo(name = "rightAmputationLevel")
+ private Converters.AmputationLevel rightAmputationLevel;
public ScaleUser() {
userName = "";
@@ -73,6 +79,8 @@ public class ScaleUser {
measureUnit = Converters.MeasureUnit.CM;
activityLevel = Converters.ActivityLevel.SEDENTARY;
assistedWeighing = false;
+ leftAmputationLevel = Converters.AmputationLevel.NONE;
+ rightAmputationLevel = Converters.AmputationLevel.NONE;
}
public int getId() {
@@ -187,6 +195,76 @@ public class ScaleUser {
this.assistedWeighing = assistedWeighing;
}
+ @NonNull
+ public Converters.AmputationLevel getLeftAmputationLevel() {
+ return leftAmputationLevel;
+ }
+
+ public void setLeftAmputationLevel(@NonNull Converters.AmputationLevel leftAmputationLevel) {
+ this.leftAmputationLevel = leftAmputationLevel;
+ }
+
+ @NonNull
+ public Converters.AmputationLevel getRightAmputationLevel() {
+ return rightAmputationLevel;
+ }
+
+ public void setRightAmputationLevel(@NonNull Converters.AmputationLevel rightAmputationLevel) {
+ this.rightAmputationLevel = rightAmputationLevel;
+ }
+
+ public float getAmputationCorrectionFactor() {
+ float correctionFactor = 100.0f;
+
+ switch (rightAmputationLevel) {
+ case NONE:
+ break;
+ case HAND:
+ correctionFactor -= 0.8f;
+ break;
+ case FOREARM_HAND:
+ correctionFactor -= 3.0f;
+ break;
+ case ARM:
+ correctionFactor -= 11.5f;
+ break;
+ case FOOT:
+ correctionFactor -= 1.8f;
+ break;
+ case LOWER_LEG_FOOT:
+ correctionFactor -= 7.1f;
+ break;
+ case LEG:
+ correctionFactor -= 18.7f;
+ break;
+ }
+
+ switch (leftAmputationLevel) {
+ case NONE:
+ break;
+ case HAND:
+ correctionFactor -= 0.8f;
+ break;
+ case FOREARM_HAND:
+ correctionFactor -= 3.0f;
+ break;
+ case ARM:
+ correctionFactor -= 11.5f;
+ break;
+ case FOOT:
+ correctionFactor -= 1.8f;
+ break;
+ case LOWER_LEG_FOOT:
+ correctionFactor -= 7.1f;
+ break;
+ case LEG:
+ correctionFactor -= 18.7f;
+ break;
+ }
+
+ return correctionFactor;
+ }
+
public static String getPreferenceKey(int userId, String key) {
return String.format("user.%d.%s", userId, key);
}
diff --git a/android_app/app/src/main/java/com/health/openscale/core/utils/Converters.java b/android_app/app/src/main/java/com/health/openscale/core/utils/Converters.java
index d7c109b1..d401e395 100644
--- a/android_app/app/src/main/java/com/health/openscale/core/utils/Converters.java
+++ b/android_app/app/src/main/java/com/health/openscale/core/utils/Converters.java
@@ -145,6 +145,52 @@ public class Converters {
}
}
+ public enum AmputationLevel {
+ NONE, HAND, FOREARM_HAND, ARM, FOOT, LOWER_LEG_FOOT, LEG;
+
+ public static AmputationLevel fromInt(int unit) {
+ switch (unit) {
+ case 0:
+ return NONE;
+ case 1:
+ return HAND;
+ case 2:
+ return FOREARM_HAND;
+ case 3:
+ return ARM;
+ case 4:
+ return FOOT;
+ case 5:
+ return LOWER_LEG_FOOT;
+ case 6:
+ return LEG;
+ }
+
+ return NONE;
+ }
+
+ public int toInt() {
+ switch (this) {
+ case NONE:
+ return 0;
+ case HAND:
+ return 1;
+ case FOREARM_HAND:
+ return 2;
+ case ARM:
+ return 3;
+ case FOOT:
+ return 4;
+ case LOWER_LEG_FOOT:
+ return 5;
+ case LEG:
+ return 6;
+ }
+
+ return 0;
+ }
+ }
+
private static final float KG_LB = 2.20462f;
private static final float KG_ST = 0.157473f;
private static final float CM_IN = 0.393701f;
@@ -199,6 +245,16 @@ public class Converters {
return level.toInt();
}
+ @TypeConverter
+ public static AmputationLevel fromAmputationLevelInt(int level) {
+ return AmputationLevel.fromInt(level);
+ }
+
+ @TypeConverter
+ public static int toAmputationLevelInt(AmputationLevel level) {
+ return level.toInt();
+ }
+
public static float toCentimeter(float value, MeasureUnit unit) {
switch (unit) {
case INCH:
diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/UserSettingsFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/UserSettingsFragment.java
index 0a1f00f1..04f85b01 100644
--- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/UserSettingsFragment.java
+++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/UserSettingsFragment.java
@@ -68,6 +68,8 @@ public class UserSettingsFragment extends Fragment {
private CheckBox assistedWeighing;
private RadioGroup radioMeasurementUnit;
private Spinner spinnerActivityLevel;
+ private Spinner spinnerLeftAmputationLevel;
+ private Spinner spinnerRightAmputationLevel;
private final DateFormat dateFormat = DateFormat.getDateInstance();
@@ -93,6 +95,8 @@ public class UserSettingsFragment extends Fragment {
assistedWeighing = root.findViewById(R.id.asisstedWeighing);
radioMeasurementUnit = root.findViewById(R.id.groupMeasureUnit);
spinnerActivityLevel = root.findViewById(R.id.spinnerActivityLevel);
+ spinnerLeftAmputationLevel = root.findViewById(R.id.spinnerLeftAmputationLevel);
+ spinnerRightAmputationLevel = root.findViewById(R.id.spinnerRightAmputationLevel);
txtInitialWeight = root.findViewById(R.id.txtInitialWeight);
txtGoalWeight = root.findViewById(R.id.txtGoalWeight);
@@ -300,6 +304,8 @@ public class UserSettingsFragment extends Fragment {
assistedWeighing.setChecked(scaleUser.isAssistedWeighing());
spinnerActivityLevel.setSelection(scaleUser.getActivityLevel().toInt());
+ spinnerLeftAmputationLevel.setSelection(scaleUser.getLeftAmputationLevel().toInt());
+ spinnerRightAmputationLevel.setSelection(scaleUser.getRightAmputationLevel().toInt());
}
private boolean validateInput()
@@ -444,8 +450,9 @@ public class UserSettingsFragment extends Fragment {
scaleUser.setBodyHeight(Converters.toCentimeter(body_height, measure_unit));
scaleUser.setScaleUnit(scale_unit);
scaleUser.setMeasureUnit(measure_unit);
- scaleUser.setActivityLevel(Converters.fromActivityLevelInt(
- spinnerActivityLevel.getSelectedItemPosition()));
+ scaleUser.setActivityLevel(Converters.fromActivityLevelInt(spinnerActivityLevel.getSelectedItemPosition()));
+ scaleUser.setLeftAmputationLevel(Converters.fromAmputationLevelInt(spinnerLeftAmputationLevel.getSelectedItemPosition()));
+ scaleUser.setRightAmputationLevel(Converters.fromAmputationLevelInt(spinnerRightAmputationLevel.getSelectedItemPosition()));
scaleUser.setGender(gender);
scaleUser.setAssistedWeighing(assistedWeighing.isChecked());
scaleUser.setInitialWeight(Converters.toKilogram(initial_weight, scale_unit));
diff --git a/android_app/app/src/main/res/layout/fragment_usersettings.xml b/android_app/app/src/main/res/layout/fragment_usersettings.xml
index 873f6775..9fad3f01 100644
--- a/android_app/app/src/main/res/layout/fragment_usersettings.xml
+++ b/android_app/app/src/main/res/layout/fragment_usersettings.xml
@@ -126,6 +126,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@string/activity_level_heavy
- @string/activity_level_extreme
+
+
+ - @string/amputation_level_none
+ - @string/amputation_level_hand
+ - @string/amputation_level_forearm_hand
+ - @string/amputation_level_arm
+ - @string/amputation_level_foot
+ - @string/amputation_level_lower_leg_foot
+ - @string/amputation_level_leg
+
diff --git a/android_app/app/src/main/res/values/strings.xml b/android_app/app/src/main/res/values/strings.xml
index 1be988c7..443113a3 100644
--- a/android_app/app/src/main/res/values/strings.xml
+++ b/android_app/app/src/main/res/values/strings.xml
@@ -57,6 +57,9 @@
Scale unit
Gender
Assisted weighing
+ Amputation
+ Amputation left
+ Amputation right
Male
Female
Goal weight
@@ -238,6 +241,13 @@
Moderate
Heavy
Extreme
+ No amputation
+ Hand
+ Forearm and leg
+ Arm
+ Foot
+ Lower leg and foot
+ Leg
Please upgrade to openScale pro for Bluetooth support
Welcome to\nopenScale
Open-source software weight and body metrics tracker, with Bluetooth scale support.