mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-24 09:13:04 +02:00
Merge branch 'master' into mgb_scales
# Conflicts: # android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCommunication.java
This commit is contained in:
@@ -27,6 +27,8 @@ import android.widget.Toast;
|
||||
import com.health.openscale.R;
|
||||
import com.health.openscale.core.alarm.AlarmHandler;
|
||||
import com.health.openscale.core.bluetooth.BluetoothCommunication;
|
||||
import com.health.openscale.core.bodymetric.EstimatedFatMetric;
|
||||
import com.health.openscale.core.bodymetric.EstimatedWaterMetric;
|
||||
import com.health.openscale.core.database.ScaleDatabase;
|
||||
import com.health.openscale.core.database.ScaleUserDatabase;
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
@@ -93,7 +95,7 @@ public class OpenScale {
|
||||
scaleUser.body_height = body_height;
|
||||
scaleUser.scale_unit = scale_unit;
|
||||
scaleUser.gender = gender;
|
||||
scaleUser.initial_weight = initial_weight;
|
||||
scaleUser.setConvertedInitialWeight(initial_weight);
|
||||
scaleUser.goal_weight = goal_weight;
|
||||
scaleUser.goal_date = new SimpleDateFormat("dd.MM.yyyy").parse(goal_date);
|
||||
|
||||
@@ -150,7 +152,7 @@ public class OpenScale {
|
||||
scaleUser.body_height = body_height;
|
||||
scaleUser.scale_unit = scale_unit;
|
||||
scaleUser.gender = gender;
|
||||
scaleUser.initial_weight = initial_weight;
|
||||
scaleUser.setConvertedInitialWeight(initial_weight);
|
||||
scaleUser.goal_weight = goal_weight;
|
||||
scaleUser.goal_date = new SimpleDateFormat("dd.MM.yyyy").parse(goal_date);
|
||||
} catch (ParseException e) {
|
||||
@@ -188,6 +190,18 @@ public class OpenScale {
|
||||
}
|
||||
}
|
||||
|
||||
if (prefs.getBoolean("estimateFatEnable", false)) {
|
||||
EstimatedFatMetric fatMetric = EstimatedFatMetric.getEstimatedFatMetric(EstimatedFatMetric.FORMULA_FAT.valueOf(prefs.getString("estimateFatFormula", "BF_DEURENBERG_II")));
|
||||
|
||||
scaleData.setFat(fatMetric.getFat(getScaleUser(scaleData.getUserId()), scaleData));
|
||||
}
|
||||
|
||||
if (prefs.getBoolean("estimateWaterEnable", false)) {
|
||||
EstimatedWaterMetric waterMetric = EstimatedWaterMetric.getEstimatedWaterMetric(EstimatedWaterMetric.FORMULA_WATER.valueOf(prefs.getString("estimateWaterFormula", "TBW_BEHNKE")));
|
||||
|
||||
scaleData.setWater(waterMetric.getWater(getScaleUser(scaleData.getUserId()), scaleData));
|
||||
}
|
||||
|
||||
if (scaleDB.insertEntry(scaleData)) {
|
||||
ScaleUser scaleUser = getScaleUser(scaleData.getUserId());
|
||||
|
||||
@@ -212,7 +226,7 @@ public class OpenScale {
|
||||
if (scaleUserData.size() > 0) {
|
||||
lastWeight = scaleUserData.get(0).getWeight();
|
||||
} else {
|
||||
lastWeight = scaleUser.get(i).initial_weight;
|
||||
lastWeight = scaleUser.get(i).getInitialWeight();
|
||||
}
|
||||
|
||||
if ((lastWeight - range) <= weight && (lastWeight + range) >= weight) {
|
||||
|
@@ -38,7 +38,7 @@ public abstract class BluetoothCommunication {
|
||||
BT_CONNECTION_LOST, BT_NO_DEVICE_FOUND, BT_UNEXPECTED_ERROR, BT_SCALE_MESSAGE
|
||||
};
|
||||
public enum BT_MACHINE_STATE {BT_INIT_STATE, BT_CMD_STATE, BT_CLEANUP_STATE}
|
||||
public enum BT_DEVICE_ID {CUSTOM_OPENSCALE, MI_SCALE_V1, SANITAS_SBF70, MEDISANA_BS444, DIGOO_DGS038H, EXCELVANT_CF369BLE, YUNMAI_MINI,MGB}
|
||||
public enum BT_DEVICE_ID {CUSTOM_OPENSCALE, MI_SCALE_V1, MI_SCALE_V2, SANITAS_SBF70, MEDISANA_BS444, DIGOO_DGS038H, EXCELVANT_CF369BLE, YUNMAI_MINI, YUNMAI_SE, MGB}
|
||||
|
||||
protected Context context;
|
||||
|
||||
@@ -81,6 +81,8 @@ public abstract class BluetoothCommunication {
|
||||
return new BluetoothCustomOpenScale(context);
|
||||
case MI_SCALE_V1:
|
||||
return new BluetoothMiScale(context);
|
||||
case MI_SCALE_V2:
|
||||
return new BluetoothMiScale2(context);
|
||||
case SANITAS_SBF70:
|
||||
return new BluetoothSanitasSbf70(context);
|
||||
case MEDISANA_BS444:
|
||||
@@ -91,8 +93,10 @@ public abstract class BluetoothCommunication {
|
||||
return new BluetoothExcelvanCF369BLE(context);
|
||||
case YUNMAI_MINI:
|
||||
return new BluetoothYunmaiMini(context);
|
||||
case MGB:
|
||||
return new BluetoothMGB(context);
|
||||
case YUNMAI_SE:
|
||||
return new BluetoothYunmaiSE(context);
|
||||
case MGB:
|
||||
return new BluetoothMGB(context);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@@ -0,0 +1,262 @@
|
||||
/* Copyright (C) 2014 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.health.openscale.core.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.health.openscale.core.OpenScale;
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.health.openscale.core.bluetooth.BluetoothCommunication.BT_STATUS_CODE.BT_UNEXPECTED_ERROR;
|
||||
|
||||
public class BluetoothMiScale2 extends BluetoothCommunication {
|
||||
private final UUID WEIGHT_MEASUREMENT_SERVICE = UUID.fromString("0000181b-0000-1000-8000-00805f9b34fb");
|
||||
private final UUID WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC = UUID.fromString("00002a2f-0000-3512-2118-0009af100700");
|
||||
private final UUID WEIGHT_MEASUREMENT_TIME_CHARACTERISTIC = UUID.fromString("00002a2b-0000-1000-8000-00805f9b34fb");
|
||||
private final UUID WEIGHT_MEASUREMENT_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
|
||||
private final UUID WEIGHT_MEASUREMENT_BODY_COMPOSITION_FEATURE = UUID.fromString("00002a9b-0000-1000-8000-00805f9b34fb");
|
||||
private final UUID WEIGHT_MEASUREMENT_BODY_COMPOSITION_MEASUREMENT = UUID.fromString("00002a9c-0000-1000-8000-00805f9b34fb");
|
||||
|
||||
private final UUID WEIGHT_CUSTOM_SERVICE = UUID.fromString("00001530-0000-3512-2118-0009af100700");
|
||||
private final UUID WEIGHT_CUSTOM_CONFIG = UUID.fromString("00001542-0000-3512-2118-0009af100700");
|
||||
|
||||
public BluetoothMiScale2(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceName() {
|
||||
return "Xiaomi Mi Scale v2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String defaultDeviceName() {
|
||||
return "MIBCS";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBluetoothDataChange(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic gattCharacteristic) {
|
||||
final byte[] data = gattCharacteristic.getValue();
|
||||
|
||||
if (data != null && data.length > 0) {
|
||||
Log.d("MIScale_v2", "DataChange hex data: "+ byteInHex(data));
|
||||
|
||||
// Stop command from mi scale received
|
||||
if (data[0] == 0x03) {
|
||||
setBtMachineState(BT_MACHINE_STATE.BT_CLEANUP_STATE);
|
||||
}
|
||||
|
||||
if (data.length == 26) {
|
||||
final byte[] firstWeight = Arrays.copyOfRange(data, 0, 10);
|
||||
final byte[] secondWeight = Arrays.copyOfRange(data, 10, 20);
|
||||
parseBytes(firstWeight);
|
||||
parseBytes(secondWeight);
|
||||
}
|
||||
|
||||
if (data.length == 13) {
|
||||
parseBytes(data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
boolean nextInitCmd(int stateNr) {
|
||||
switch (stateNr) {
|
||||
case 0:
|
||||
// set scale units
|
||||
final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser();
|
||||
byte[] setUnitCmd = new byte[]{(byte)0x06, (byte)0x04, (byte)0x00, (byte) selectedUser.scale_unit};
|
||||
writeBytes(WEIGHT_CUSTOM_SERVICE, WEIGHT_CUSTOM_CONFIG, setUnitCmd);
|
||||
break;
|
||||
case 1:
|
||||
// set current time
|
||||
Calendar currentDateTime = Calendar.getInstance();
|
||||
int year = currentDateTime.get(Calendar.YEAR);
|
||||
byte month = (byte)(currentDateTime.get(Calendar.MONTH)+1);
|
||||
byte day = (byte)currentDateTime.get(Calendar.DAY_OF_MONTH);
|
||||
byte hour = (byte)currentDateTime.get(Calendar.HOUR_OF_DAY);
|
||||
byte min = (byte)currentDateTime.get(Calendar.MINUTE);
|
||||
byte sec = (byte)currentDateTime.get(Calendar.SECOND);
|
||||
|
||||
byte[] dateTimeByte = {(byte)(year), (byte)(year >> 8), month, day, hour, min, sec, 0x03, 0x00, 0x00};
|
||||
|
||||
writeBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_TIME_CHARACTERISTIC, dateTimeByte);
|
||||
break;
|
||||
case 2:
|
||||
// set notification on for weight measurement history
|
||||
setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean nextBluetoothCmd(int stateNr) {
|
||||
switch (stateNr) {
|
||||
case 0:
|
||||
// configure scale to get only last measurements
|
||||
int uniqueNumber = getUniqueNumber();
|
||||
|
||||
byte[] userIdentifier = new byte[]{(byte)0x01, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
||||
writeBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
||||
break;
|
||||
case 1:
|
||||
// set notification off for weight measurement history
|
||||
setNotificationOff(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
case 2:
|
||||
// set notification on for weight measurement history
|
||||
setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
case 3:
|
||||
// invoke receiving history data
|
||||
writeBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x02});
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean nextCleanUpCmd(int stateNr) {
|
||||
|
||||
switch (stateNr) {
|
||||
case 0:
|
||||
// send stop command to mi scale
|
||||
writeBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x03});
|
||||
break;
|
||||
case 1:
|
||||
// acknowledge that you received the last history data
|
||||
int uniqueNumber = getUniqueNumber();
|
||||
|
||||
byte[] userIdentifier = new byte[]{(byte)0x04, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
||||
writeBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
||||
break;
|
||||
case 2:
|
||||
// set notification on for body composition measurement
|
||||
setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_BODY_COMPOSITION_MEASUREMENT, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseBytes(byte[] weightBytes) {
|
||||
try {
|
||||
float weight = 0.0f;
|
||||
|
||||
final byte ctrlByte0 = weightBytes[0];
|
||||
final byte ctrlByte1 = weightBytes[1];
|
||||
|
||||
final boolean isWeightRemoved = isBitSet(ctrlByte1, 7);
|
||||
final boolean isDateInvalid = isBitSet(ctrlByte1, 6);
|
||||
final boolean isStabilized = isBitSet(ctrlByte1, 5);
|
||||
final boolean isLBSUnit = isBitSet(ctrlByte0, 0);
|
||||
final boolean isCattyUnit = isBitSet(ctrlByte1, 6);
|
||||
|
||||
if (isStabilized && !isWeightRemoved && !isDateInvalid) {
|
||||
|
||||
final int year = ((weightBytes[3] & 0xFF) << 8) | (weightBytes[2] & 0xFF);
|
||||
final int month = (int) weightBytes[4];
|
||||
final int day = (int) weightBytes[5];
|
||||
final int hours = (int) weightBytes[6];
|
||||
final int min = (int) weightBytes[7];
|
||||
final int sec = (int) weightBytes[8];
|
||||
|
||||
if (isLBSUnit || isCattyUnit) {
|
||||
weight = (float) (((weightBytes[12] & 0xFF) << 8) | (weightBytes[11] & 0xFF)) / 100.0f;
|
||||
} else {
|
||||
weight = (float) (((weightBytes[12] & 0xFF) << 8) | (weightBytes[11] & 0xFF)) / 200.0f;
|
||||
}
|
||||
|
||||
String date_string = year + "/" + month + "/" + day + "/" + hours + "/" + min;
|
||||
Date date_time = new SimpleDateFormat("yyyy/MM/dd/HH/mm").parse(date_string);
|
||||
|
||||
// Is the year plausible? Check if the year is in the range of 20 years...
|
||||
if (validateDate(date_time, 20)) {
|
||||
ScaleData scaleBtData = new ScaleData();
|
||||
|
||||
scaleBtData.setWeight(weight);
|
||||
scaleBtData.setDateTime(date_time);
|
||||
|
||||
addScaleData(scaleBtData);
|
||||
} else {
|
||||
Log.e("BluetoothMiScale", "Invalid Mi scale weight year " + year);
|
||||
}
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
setBtStatus(BT_UNEXPECTED_ERROR, "Error while decoding bluetooth date string (" + e.getMessage() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validateDate(Date weightDate, int range) {
|
||||
|
||||
Calendar currentDatePos = Calendar.getInstance();
|
||||
currentDatePos.add(Calendar.YEAR, range);
|
||||
|
||||
Calendar currentDateNeg = Calendar.getInstance();
|
||||
currentDateNeg.add(Calendar.YEAR, -range);
|
||||
|
||||
if (weightDate.before(currentDatePos.getTime()) && weightDate.after(currentDateNeg.getTime())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getUniqueNumber() {
|
||||
int uniqueNumber;
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
uniqueNumber = prefs.getInt("uniqueNumber", 0x00);
|
||||
|
||||
if (uniqueNumber == 0x00) {
|
||||
Random r = new Random();
|
||||
uniqueNumber = r.nextInt(65535 - 100 + 1) + 100;
|
||||
|
||||
prefs.edit().putInt("uniqueNumber", uniqueNumber).commit();
|
||||
}
|
||||
|
||||
int userId = prefs.getInt("selectedUserId", -1);
|
||||
|
||||
return uniqueNumber + userId;
|
||||
}
|
||||
}
|
@@ -0,0 +1,168 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.health.openscale.core.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.health.openscale.core.OpenScale;
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BluetoothYunmaiSE extends BluetoothCommunication {
|
||||
private final UUID WEIGHT_MEASUREMENT_SERVICE = UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb");
|
||||
private final UUID WEIGHT_MEASUREMENT_CHARACTERISTIC = UUID.fromString("0000ffe4-0000-1000-8000-00805f9b34fb");
|
||||
private final UUID WEIGHT_CMD_SERVICE = UUID.fromString("0000ffe5-0000-1000-8000-00805f9b34fb");
|
||||
private final UUID WEIGHT_CMD_CHARACTERISTIC = UUID.fromString("0000ffe9-0000-1000-8000-00805f9b34fb");
|
||||
|
||||
private final UUID WEIGHT_MEASUREMENT_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
|
||||
|
||||
public BluetoothYunmaiSE(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceName() {
|
||||
return "Yunmai SE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String defaultDeviceName() {
|
||||
return "YUNMAI-ISSE-US";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkDeviceName(String btDeviceName) {
|
||||
if (btDeviceName.startsWith("YUNMAI-ISSE")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean nextInitCmd(int stateNr) {
|
||||
switch (stateNr) {
|
||||
case 0:
|
||||
int user_id = getUniqueNumber();
|
||||
|
||||
final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser();
|
||||
byte sex = selectedUser.isMale() ? (byte)0x01 : (byte)0x02;
|
||||
byte display_unit = selectedUser.scale_unit == 0 ? (byte) 0x01 : (byte) 0x02;
|
||||
|
||||
byte[] user_add_or_query = new byte[]{(byte)0x0d, (byte)0x12, (byte)0x10, (byte)0x01, (byte)0x00, (byte) 0x00, (byte) ((user_id & 0xFF00) >> 8), (byte) ((user_id & 0xFF) >> 0), (byte)selectedUser.body_height, (byte)sex, (byte) selectedUser.getAge(), (byte) 0x55, (byte) 0x5a, (byte) 0x00, (byte)0x00, (byte) display_unit, (byte) 0x03, (byte) 0x00 };
|
||||
user_add_or_query[17] = xor_checksum(user_add_or_query);
|
||||
writeBytes(WEIGHT_CMD_SERVICE, WEIGHT_CMD_CHARACTERISTIC, user_add_or_query);
|
||||
break;
|
||||
case 1:
|
||||
long unix_time = new Date().getTime() / 1000;
|
||||
|
||||
byte[] set_time = new byte[]{(byte)0x0d, (byte) 0x0d, (byte) 0x11, (byte)((unix_time & 0xFF000000) >> 32), (byte)((unix_time & 0xFF0000) >> 16), (byte)((unix_time & 0xFF00) >> 8), (byte)((unix_time & 0xFF) >> 0), (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00};
|
||||
|
||||
set_time[12] = xor_checksum(set_time);
|
||||
writeBytes(WEIGHT_CMD_SERVICE, WEIGHT_CMD_CHARACTERISTIC, set_time);
|
||||
break;
|
||||
case 2:
|
||||
setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
case 3:
|
||||
byte[] magic_bytes = new byte[]{(byte)0x0d, (byte)0x05, (byte)0x13, (byte)0x00, (byte)0x16};
|
||||
writeBytes(WEIGHT_CMD_SERVICE, WEIGHT_CMD_CHARACTERISTIC, magic_bytes);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean nextBluetoothCmd(int stateNr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean nextCleanUpCmd(int stateNr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBluetoothDataChange(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic gattCharacteristic) {
|
||||
final byte[] data = gattCharacteristic.getValue();
|
||||
|
||||
if (data != null && data.length > 0) {
|
||||
|
||||
// if finished weighting?
|
||||
if (data[3] == 0x02) {
|
||||
parseBytes(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseBytes(byte[] weightBytes) {
|
||||
long unix_timestamp = ((weightBytes[5] & 0xFF) << 24) | ((weightBytes[6] & 0xFF) << 16) | ((weightBytes[7] & 0xFF) << 8) | (weightBytes[8] & 0xFF);
|
||||
Date btDate = new Date();
|
||||
btDate.setTime(unix_timestamp*1000);
|
||||
|
||||
float weight = (float) (((weightBytes[13] & 0xFF) << 8) | (weightBytes[14] & 0xFF)) / 100.0f;
|
||||
|
||||
ScaleData scaleBtData = new ScaleData();
|
||||
|
||||
final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser();
|
||||
|
||||
scaleBtData.setConvertedWeight(weight, selectedUser.scale_unit);
|
||||
scaleBtData.setDateTime(btDate);
|
||||
|
||||
addScaleData(scaleBtData);
|
||||
}
|
||||
|
||||
private int getUniqueNumber() {
|
||||
int uniqueNumber;
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
uniqueNumber = prefs.getInt("uniqueNumber", 0x00);
|
||||
|
||||
if (uniqueNumber == 0x00) {
|
||||
Random r = new Random();
|
||||
uniqueNumber = r.nextInt(65535 - 100 + 1) + 100;
|
||||
|
||||
prefs.edit().putInt("uniqueNumber", uniqueNumber).commit();
|
||||
}
|
||||
|
||||
int userId = prefs.getInt("selectedUserId", -1);
|
||||
|
||||
return uniqueNumber + userId;
|
||||
}
|
||||
|
||||
private byte xor_checksum(byte[] data) {
|
||||
byte checksum = 0x00;
|
||||
|
||||
for (int i=0; i<data.length-1; i++) {
|
||||
checksum ^= data[i];
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class BFBJoN extends EstimatedFatMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "British Journal of Nutrition (1991)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFat(ScaleUser user, ScaleData data) {
|
||||
if (user.isMale()) {
|
||||
return (data.getBMI(user.body_height) * 1.2f) + (user.getAge() * 0.23f) - 16.2f;
|
||||
}
|
||||
|
||||
return (data.getBMI(user.body_height) * 1.2f) + (user.getAge() * 0.23f) - 5.4f;
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class BFDeurenberg extends EstimatedFatMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Deurenberg et. al (1998)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFat(ScaleUser user, ScaleData data) {
|
||||
if (user.getAge() >= 16) {
|
||||
return (1.2f * data.getBMI(user.body_height)) + (0.23f*user.getAge()) - (10.8f*(1-user.gender)) - 5.4f;
|
||||
}
|
||||
|
||||
return (1.294f * data.getBMI(user.body_height)) + (0.20f*user.getAge()) - (11.4f*(1-user.gender)) - 8.0f;
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class BFEddy extends EstimatedFatMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Eddy et. al (1976)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFat(ScaleUser user, ScaleData data) {
|
||||
if (user.isMale()) {
|
||||
return (1.281f* data.getBMI(user.body_height)) - 10.13f;
|
||||
}
|
||||
|
||||
return (1.48f* data.getBMI(user.body_height)) - 7.0f;
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class BFGallagher extends EstimatedFatMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Gallagher et. al [non-asian] (2000)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFat(ScaleUser user, ScaleData data) {
|
||||
if (user.isMale()) {
|
||||
// non-asian male
|
||||
return 64.5f - 848.0f * (1.0f / data.getBMI(user.body_height)) + 0.079f * user.getAge() - 16.4f + 0.05f * user.getAge() + 39.0f * (1.0f / data.getBMI(user.body_height));
|
||||
}
|
||||
|
||||
// non-asian female
|
||||
return 64.5f - 848.0f * (1.0f / data.getBMI(user.body_height)) + 0.079f * user.getAge();
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class BFGallagherAsian extends EstimatedFatMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Gallagher et. al [asian] (2000)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFat(ScaleUser user, ScaleData data) {
|
||||
if (user.isMale()) {
|
||||
// asian male
|
||||
return 51.9f - 740.0f * (1.0f / data.getBMI(user.body_height)) + 0.029f * user.getAge();
|
||||
}
|
||||
|
||||
// asian female
|
||||
return 64.8f - 752.0f * (1.0f / data.getBMI(user.body_height)) + 0.016f * user.getAge();
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public abstract class EstimatedFatMetric {
|
||||
public enum FORMULA_FAT { BF_DEURENBERG, BF_BJoN, BF_EDDY, BF_GALLAGHER, BF_GALLAGHER_ASIAN };
|
||||
|
||||
public static EstimatedFatMetric getEstimatedFatMetric( FORMULA_FAT fatMetric) {
|
||||
switch (fatMetric) {
|
||||
case BF_DEURENBERG:
|
||||
return new BFDeurenberg();
|
||||
case BF_BJoN:
|
||||
return new BFBJoN();
|
||||
case BF_EDDY:
|
||||
return new BFEddy();
|
||||
case BF_GALLAGHER:
|
||||
return new BFGallagher();
|
||||
case BF_GALLAGHER_ASIAN:
|
||||
return new BFGallagherAsian();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract String getName();
|
||||
public abstract float getFat(ScaleUser user, ScaleData data);
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public abstract class EstimatedWaterMetric {
|
||||
public enum FORMULA_WATER { TBW_BEHNKE, TBW_DELWAIDECRENIER, TBW_HUMEWEYERS, TBW_LEESONGKIM };
|
||||
|
||||
public static EstimatedWaterMetric getEstimatedWaterMetric( FORMULA_WATER waterMetric) {
|
||||
switch (waterMetric) {
|
||||
case TBW_BEHNKE:
|
||||
return new TBWBehnke();
|
||||
case TBW_DELWAIDECRENIER:
|
||||
return new TBWDelwaideCrenier();
|
||||
case TBW_HUMEWEYERS:
|
||||
return new TBWHumeWeyers();
|
||||
case TBW_LEESONGKIM:
|
||||
return new TBWLeeSongKim();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract String getName();
|
||||
public abstract float getWater(ScaleUser user, ScaleData data);
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class TBWBehnke extends EstimatedWaterMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Behnke et. al (1963)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getWater(ScaleUser user, ScaleData data) {
|
||||
if (user.isMale()) {
|
||||
return 0.72f * (0.204f * user.body_height * user.body_height) / 100.0f;
|
||||
}
|
||||
|
||||
return 0.72f * (0.18f * user.body_height * user.body_height) / 100.0f;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class TBWDelwaideCrenier extends EstimatedWaterMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Delwaide-Crenier et. al (1973)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getWater(ScaleUser user, ScaleData data) {
|
||||
return 0.72f * (-1.976f + 0.907f * data.getWeight());
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class TBWHumeWeyers extends EstimatedWaterMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Hume & Weyers (1971)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getWater(ScaleUser user, ScaleData data) {
|
||||
if (user.isMale()) {
|
||||
return (0.194786f * user.body_height) + (0.296785f * data.getWeight()) - 14.012934f;
|
||||
}
|
||||
|
||||
return (0.34454f * user.body_height) + (0.183809f * data.getWeight()) - 35.270121f;
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2017 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.core.bodymetric;
|
||||
|
||||
import com.health.openscale.core.datatypes.ScaleData;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
|
||||
public class TBWLeeSongKim extends EstimatedWaterMetric {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Lee, Song, Kim, Lee et. al (1999)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getWater(ScaleUser user, ScaleData data) {
|
||||
if (user.isMale()) {
|
||||
return -28.3497f + (0.243057f * user.body_height) + (0.366248f * data.getWeight());
|
||||
}
|
||||
|
||||
return -26.6224f + (0.262513f * user.body_height) + (0.232948f * data.getWeight());
|
||||
}
|
||||
}
|
@@ -113,7 +113,7 @@ public class ScaleUserDatabase extends SQLiteOpenHelper {
|
||||
values.put(COLUMN_NAME_BODY_HEIGHT, scaleUser.body_height);
|
||||
values.put(COLUMN_NAME_SCALE_UNIT, scaleUser.scale_unit);
|
||||
values.put(COLUMN_NAME_GENDER, scaleUser.gender);
|
||||
values.put(COLUMN_NAME_INITIAL_WEIGHT, scaleUser.initial_weight);
|
||||
values.put(COLUMN_NAME_INITIAL_WEIGHT, scaleUser.getInitialWeight());
|
||||
values.put(COLUMN_NAME_GOAL_WEIGHT, scaleUser.goal_weight);
|
||||
values.put(COLUMN_NAME_GOAL_DATE, formatDateTime.format(scaleUser.goal_date));
|
||||
|
||||
@@ -146,7 +146,7 @@ public class ScaleUserDatabase extends SQLiteOpenHelper {
|
||||
values.put(COLUMN_NAME_BODY_HEIGHT, scaleUser.body_height);
|
||||
values.put(COLUMN_NAME_SCALE_UNIT, scaleUser.scale_unit);
|
||||
values.put(COLUMN_NAME_GENDER, scaleUser.gender);
|
||||
values.put(COLUMN_NAME_INITIAL_WEIGHT, scaleUser.initial_weight);
|
||||
values.put(COLUMN_NAME_INITIAL_WEIGHT, scaleUser.getInitialWeight());
|
||||
values.put(COLUMN_NAME_GOAL_WEIGHT, scaleUser.goal_weight);
|
||||
values.put(COLUMN_NAME_GOAL_DATE, formatDateTime.format(scaleUser.goal_date));
|
||||
|
||||
@@ -222,7 +222,7 @@ public class ScaleUserDatabase extends SQLiteOpenHelper {
|
||||
scaleUser.birthday = formatDateTime.parse(birthday);
|
||||
scaleUser.goal_date = formatDateTime.parse(goal_date);
|
||||
|
||||
scaleUser.initial_weight = Math.round(initial_weight * 100.0f) / 100.0f;
|
||||
scaleUser.setInitialWeight(Math.round(initial_weight * 100.0f) / 100.0f);
|
||||
scaleUser.goal_weight = Math.round(goal_weight * 100.0f) / 100.0f;
|
||||
} catch (ParseException ex) {
|
||||
Log.e("ScaleDatabase", "Can't parse the date time string: " + ex.getMessage());
|
||||
|
@@ -21,6 +21,8 @@ import java.util.Date;
|
||||
|
||||
public class ScaleUser {
|
||||
public static final String[] UNIT_STRING = new String[] {"kg", "lb", "st"};
|
||||
private static float KG_LB = 2.20462f;
|
||||
private static float KG_ST = 0.157473f;
|
||||
|
||||
public int id;
|
||||
public String user_name;
|
||||
@@ -28,7 +30,7 @@ public class ScaleUser {
|
||||
public int body_height;
|
||||
public int scale_unit;
|
||||
public int gender;
|
||||
public float initial_weight;
|
||||
private float initial_weight;
|
||||
public float goal_weight;
|
||||
public Date goal_date;
|
||||
|
||||
@@ -62,6 +64,47 @@ public class ScaleUser {
|
||||
return userAge;
|
||||
}
|
||||
|
||||
public void setInitialWeight(float weight) {
|
||||
this.initial_weight = weight;
|
||||
|
||||
}
|
||||
|
||||
public void setConvertedInitialWeight(float weight) {
|
||||
switch (ScaleUser.UNIT_STRING[scale_unit]) {
|
||||
case "kg":
|
||||
this.initial_weight = weight;
|
||||
break;
|
||||
case "lb":
|
||||
this.initial_weight = weight / KG_LB;
|
||||
break;
|
||||
case "st":
|
||||
this.initial_weight = weight / KG_ST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public float getInitialWeight() {
|
||||
return initial_weight;
|
||||
}
|
||||
|
||||
public float getConvertedInitialWeight() {
|
||||
float converted_weight = 0.0f;
|
||||
|
||||
switch (ScaleUser.UNIT_STRING[scale_unit]) {
|
||||
case "kg":
|
||||
converted_weight = initial_weight;
|
||||
break;
|
||||
case "lb":
|
||||
converted_weight = initial_weight * KG_LB;
|
||||
break;
|
||||
case "st":
|
||||
converted_weight = initial_weight * KG_ST;
|
||||
break;
|
||||
}
|
||||
|
||||
return converted_weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@@ -133,7 +133,7 @@ public class UserSettingsActivity extends Activity {
|
||||
txtBodyHeight.setText(Integer.toString(scaleUser.body_height));
|
||||
txtBirthday.setText(dateFormat.format(scaleUser.birthday));
|
||||
txtGoalDate.setText(dateFormat.format(scaleUser.goal_date));
|
||||
txtInitialWeight.setText(scaleUser.initial_weight+"");
|
||||
txtInitialWeight.setText(Math.round(scaleUser.getConvertedInitialWeight()*100.0f)/100.0f + "");
|
||||
txtGoalWeight.setText(scaleUser.goal_weight+"");
|
||||
|
||||
switch (scaleUser.scale_unit)
|
||||
|
@@ -19,18 +19,37 @@ import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.MultiSelectListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.health.openscale.R;
|
||||
import com.health.openscale.core.OpenScale;
|
||||
import com.health.openscale.core.bodymetric.EstimatedFatMetric;
|
||||
import com.health.openscale.core.bodymetric.EstimatedWaterMetric;
|
||||
|
||||
public class MeasurementPreferences extends PreferenceFragment {
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MeasurementPreferences extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
public static final String PREFERENCE_KEY_DELETE_ALL = "deleteAll";
|
||||
public static final String PREFERENCE_KEY_ESTIMATE_FAT = "estimateFatEnable";
|
||||
public static final String PREFERENCE_KEY_ESTIMATE_FAT_FORMULA = "estimateFatFormula";
|
||||
public static final String PREFERENCE_KEY_ESTIMATE_WATER = "estimateWaterEnable";
|
||||
public static final String PREFERENCE_KEY_ESTIMATE_WATER_FORMULA = "estimateWaterFormula";
|
||||
|
||||
private Preference deleteAll;
|
||||
private CheckBoxPreference estimateFatEnable;
|
||||
private ListPreference estimateFatFormula;
|
||||
private CheckBoxPreference estimateWaterEnable;
|
||||
private ListPreference estimateWaterFormula;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@@ -40,6 +59,109 @@ public class MeasurementPreferences extends PreferenceFragment {
|
||||
|
||||
deleteAll = (Preference) findPreference(PREFERENCE_KEY_DELETE_ALL);
|
||||
deleteAll.setOnPreferenceClickListener(new onClickListenerDeleteAll());
|
||||
|
||||
estimateFatEnable = (CheckBoxPreference) findPreference(PREFERENCE_KEY_ESTIMATE_FAT);
|
||||
estimateFatFormula = (ListPreference) findPreference(PREFERENCE_KEY_ESTIMATE_FAT_FORMULA);
|
||||
estimateWaterEnable = (CheckBoxPreference) findPreference(PREFERENCE_KEY_ESTIMATE_WATER);
|
||||
estimateWaterFormula = (ListPreference) findPreference(PREFERENCE_KEY_ESTIMATE_WATER_FORMULA);
|
||||
|
||||
updateFatListPreferences();
|
||||
updateWaterListPreferences();
|
||||
initSummary(getPreferenceScreen());
|
||||
}
|
||||
|
||||
public void updateFatListPreferences() {
|
||||
ArrayList<String> listEntries = new ArrayList();
|
||||
ArrayList<String> listEntryValues = new ArrayList();
|
||||
|
||||
for (EstimatedFatMetric.FORMULA_FAT formulaFat : EstimatedFatMetric.FORMULA_FAT.values()) {
|
||||
EstimatedFatMetric fatMetric = EstimatedFatMetric.getEstimatedFatMetric(formulaFat);
|
||||
|
||||
listEntries.add(fatMetric.getName());
|
||||
listEntryValues.add(formulaFat.toString());
|
||||
}
|
||||
|
||||
estimateFatFormula.setEntries(listEntries.toArray(new CharSequence[listEntries.size()]));
|
||||
estimateFatFormula.setEntryValues(listEntryValues.toArray(new CharSequence[listEntryValues.size()]));
|
||||
}
|
||||
|
||||
public void updateWaterListPreferences() {
|
||||
ArrayList<String> listEntries = new ArrayList();
|
||||
ArrayList<String> listEntryValues = new ArrayList();
|
||||
|
||||
for (EstimatedWaterMetric.FORMULA_WATER formulaWater : EstimatedWaterMetric.FORMULA_WATER.values()) {
|
||||
EstimatedWaterMetric waterMetric = EstimatedWaterMetric.getEstimatedWaterMetric(formulaWater);
|
||||
|
||||
listEntries.add(waterMetric.getName());
|
||||
listEntryValues.add(formulaWater.toString());
|
||||
}
|
||||
|
||||
estimateWaterFormula.setEntries(listEntries.toArray(new CharSequence[listEntries.size()]));
|
||||
estimateWaterFormula.setEntryValues(listEntryValues.toArray(new CharSequence[listEntryValues.size()]));
|
||||
}
|
||||
|
||||
private void initSummary(Preference p) {
|
||||
if (p instanceof PreferenceGroup) {
|
||||
PreferenceGroup pGrp = (PreferenceGroup) p;
|
||||
for (int i = 0; i < pGrp.getPreferenceCount(); i++) {
|
||||
initSummary(pGrp.getPreference(i));
|
||||
}
|
||||
} else {
|
||||
updatePrefSummary(p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
updatePrefSummary(findPreference(key));
|
||||
}
|
||||
|
||||
private void updatePrefSummary(Preference p) {
|
||||
if (estimateFatEnable.isChecked()) {
|
||||
estimateFatFormula.setEnabled(true);
|
||||
} else {
|
||||
estimateFatFormula.setEnabled(false);
|
||||
}
|
||||
|
||||
if (estimateWaterEnable.isChecked()) {
|
||||
estimateWaterFormula.setEnabled(true);
|
||||
} else {
|
||||
estimateWaterFormula.setEnabled(false);
|
||||
}
|
||||
|
||||
estimateFatFormula.setSummary(EstimatedFatMetric.getEstimatedFatMetric(EstimatedFatMetric.FORMULA_FAT.valueOf(estimateFatFormula.getValue())).getName());
|
||||
estimateWaterFormula.setSummary(EstimatedWaterMetric.getEstimatedWaterMetric(EstimatedWaterMetric.FORMULA_WATER.valueOf(estimateWaterFormula.getValue())).getName());
|
||||
|
||||
if (p instanceof EditTextPreference) {
|
||||
EditTextPreference editTextPref = (EditTextPreference) p;
|
||||
if (p.getTitle().toString().contains("assword"))
|
||||
{
|
||||
p.setSummary("******");
|
||||
} else {
|
||||
p.setSummary(editTextPref.getText());
|
||||
}
|
||||
}
|
||||
|
||||
if (p instanceof MultiSelectListPreference) {
|
||||
MultiSelectListPreference editMultiListPref = (MultiSelectListPreference) p;
|
||||
|
||||
CharSequence[] entries = editMultiListPref.getEntries();
|
||||
CharSequence[] entryValues = editMultiListPref.getEntryValues();
|
||||
List<String> currentEntries = new ArrayList<>();
|
||||
Set<String> currentEntryValues = editMultiListPref.getValues();
|
||||
|
||||
for (int i = 0; i < entries.length; i++)
|
||||
if (currentEntryValues.contains(entryValues[i]))
|
||||
currentEntries.add(entries[i].toString());
|
||||
|
||||
p.setSummary(currentEntries.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private class onClickListenerDeleteAll implements Preference.OnPreferenceClickListener {
|
||||
|
@@ -26,13 +26,27 @@ import com.health.openscale.core.evaluation.EvaluationSheet;
|
||||
|
||||
public class FatMeasurementView extends MeasurementView {
|
||||
|
||||
private boolean estimateFatEnable;
|
||||
|
||||
public FatMeasurementView(Context context) {
|
||||
super(context, context.getResources().getString(R.string.label_fat), ContextCompat.getDrawable(context, R.drawable.ic_fat));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable() {
|
||||
if (estimateFatEnable && getMeasurementMode() == MeasurementViewMode.ADD) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateValue(ScaleData updateData) {
|
||||
setValueOnView(updateData.getFat());
|
||||
if (estimateFatEnable && getMeasurementMode() == MeasurementViewMode.ADD) {
|
||||
setValueOnView((getContext().getString(R.string.label_automatic)));
|
||||
} else {
|
||||
setValueOnView(updateData.getFat());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,6 +62,7 @@ public class FatMeasurementView extends MeasurementView {
|
||||
@Override
|
||||
public void updatePreferences(SharedPreferences preferences) {
|
||||
setVisible(preferences.getBoolean("fatEnable", true));
|
||||
estimateFatEnable = preferences.getBoolean("estimateFatEnable", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -21,16 +21,19 @@ import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.Html;
|
||||
import android.text.InputType;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Space;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
@@ -59,6 +62,9 @@ public abstract class MeasurementView extends TableLayout {
|
||||
private ImageView iconView;
|
||||
private TextView nameView;
|
||||
private TextView valueView;
|
||||
private LinearLayout incdecLayout;
|
||||
private Button incView;
|
||||
private Button decView;
|
||||
private ImageView editModeView;
|
||||
private ImageView indicatorView;
|
||||
|
||||
@@ -90,17 +96,22 @@ public abstract class MeasurementView extends TableLayout {
|
||||
iconView = new ImageView(context);
|
||||
nameView = new TextView(context);
|
||||
valueView = new TextView(context);
|
||||
incView = new Button(context);
|
||||
decView = new Button(context);
|
||||
editModeView = new ImageView(context);
|
||||
indicatorView = new ImageView(context);
|
||||
|
||||
evaluatorRow = new TableRow(context);
|
||||
evaluatorView = new LinearGaugeView(context);
|
||||
|
||||
incdecLayout = new LinearLayout(context);
|
||||
|
||||
measurementRow.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT, 1.0f));
|
||||
measurementRow.setGravity(Gravity.CENTER);
|
||||
measurementRow.addView(iconView);
|
||||
measurementRow.addView(nameView);
|
||||
measurementRow.addView(valueView);
|
||||
measurementRow.addView(incdecLayout);
|
||||
measurementRow.addView(editModeView);
|
||||
measurementRow.addView(indicatorView);
|
||||
|
||||
@@ -113,7 +124,7 @@ public abstract class MeasurementView extends TableLayout {
|
||||
nameView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
|
||||
nameView.setTextColor(Color.BLACK);
|
||||
nameView.setLines(2);
|
||||
nameView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 0.60f));
|
||||
nameView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 0.55f));
|
||||
|
||||
valueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
|
||||
valueView.setTextColor(Color.BLACK);
|
||||
@@ -121,6 +132,50 @@ public abstract class MeasurementView extends TableLayout {
|
||||
valueView.setPadding(0,0,20,0);
|
||||
valueView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.MATCH_PARENT, 0.29f));
|
||||
|
||||
incdecLayout.setOrientation(VERTICAL);
|
||||
incdecLayout.addView(incView);
|
||||
incdecLayout.addView(decView);
|
||||
incdecLayout.setVisibility(View.GONE);
|
||||
incdecLayout.setPadding(0,0,0,0);
|
||||
incdecLayout.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.MATCH_PARENT, 0.05f));
|
||||
|
||||
incView.setText("+");
|
||||
incView.setBackgroundColor(Color.TRANSPARENT);
|
||||
incView.setPadding(0,0,0,0);
|
||||
incView.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, 0, 0.50f));
|
||||
incView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
incValue();
|
||||
}
|
||||
});
|
||||
incView.setOnTouchListener(new RepeatListener(400, 100, new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
incValue();
|
||||
}
|
||||
}));
|
||||
incView.setVisibility(View.GONE);
|
||||
|
||||
decView.setText("-");
|
||||
decView.setBackgroundColor(Color.TRANSPARENT);
|
||||
decView.setPadding(0,0,0,0);
|
||||
decView.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, 0, 0.50f));
|
||||
decView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
decValue();
|
||||
}
|
||||
});
|
||||
|
||||
decView.setOnTouchListener(new RepeatListener(400, 100, new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
decValue();
|
||||
}
|
||||
}));
|
||||
decView.setVisibility(View.GONE);
|
||||
|
||||
editModeView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_editable));
|
||||
editModeView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
editModeView.setVisibility(View.GONE);
|
||||
@@ -153,8 +208,27 @@ public abstract class MeasurementView extends TableLayout {
|
||||
if (value.length() == 0) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
return Float.valueOf(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return Float.valueOf(value);
|
||||
public void incValue() {
|
||||
float incValue = getValue() + 0.1f;
|
||||
|
||||
if (incValue <= getMaxValue()) {
|
||||
setValueOnView(incValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void decValue() {
|
||||
float decValue = getValue() - 0.1f;
|
||||
|
||||
if (decValue >= 0) {
|
||||
setValueOnView(decValue);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValueAsString() {
|
||||
@@ -176,13 +250,26 @@ public abstract class MeasurementView extends TableLayout {
|
||||
case VIEW:
|
||||
indicatorView.setVisibility(View.VISIBLE);
|
||||
editModeView.setVisibility(View.GONE);
|
||||
incdecLayout.setVisibility(View.GONE);
|
||||
incView.setVisibility(View.GONE);
|
||||
decView.setVisibility(View.GONE);
|
||||
break;
|
||||
case EDIT:
|
||||
case ADD:
|
||||
editModeView.setVisibility(View.VISIBLE);
|
||||
incView.setVisibility(View.VISIBLE);
|
||||
decView.setVisibility(View.VISIBLE);
|
||||
incdecLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
if (!isEditable()) {
|
||||
editModeView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_noteeditable));
|
||||
incView.setVisibility(View.GONE);
|
||||
decView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (getUnit() == null) {
|
||||
incView.setVisibility(View.GONE);
|
||||
decView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
indicatorView.setVisibility(View.GONE);
|
||||
@@ -334,7 +421,7 @@ public abstract class MeasurementView extends TableLayout {
|
||||
input.setInputType(getInputType());
|
||||
input.setHint(getHintText());
|
||||
input.setText(value);
|
||||
input.setSelection(value.length());
|
||||
input.setSelectAllOnFocus(true);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton(getResources().getString(R.string.label_ok), null);
|
||||
@@ -396,5 +483,65 @@ public abstract class MeasurementView extends TableLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class RepeatListener implements OnTouchListener {
|
||||
|
||||
private Handler handler = new Handler();
|
||||
|
||||
private int initialInterval;
|
||||
private final int normalInterval;
|
||||
private final OnClickListener clickListener;
|
||||
|
||||
private Runnable handlerRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.postDelayed(this, normalInterval);
|
||||
clickListener.onClick(downView);
|
||||
}
|
||||
};
|
||||
|
||||
private View downView;
|
||||
|
||||
/**
|
||||
* RepeatListener cyclically runs a clickListener, emulating keyboard-like behaviour. First
|
||||
* click is fired immediately, next one after the initialInterval, and subsequent ones after the normalInterval.
|
||||
*
|
||||
* @param initialInterval The interval after first click event
|
||||
* @param normalInterval The interval after second and subsequent click events
|
||||
* @param clickListener The OnClickListener, that will be called periodically
|
||||
*/
|
||||
public RepeatListener(int initialInterval, int normalInterval,
|
||||
OnClickListener clickListener) {
|
||||
if (clickListener == null)
|
||||
throw new IllegalArgumentException("null runnable");
|
||||
if (initialInterval < 0 || normalInterval < 0)
|
||||
throw new IllegalArgumentException("negative interval");
|
||||
|
||||
this.initialInterval = initialInterval;
|
||||
this.normalInterval = normalInterval;
|
||||
this.clickListener = clickListener;
|
||||
}
|
||||
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
switch (motionEvent.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
handler.removeCallbacks(handlerRunnable);
|
||||
handler.postDelayed(handlerRunnable, initialInterval);
|
||||
downView = view;
|
||||
downView.setPressed(true);
|
||||
clickListener.onClick(view);
|
||||
return true;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
handler.removeCallbacks(handlerRunnable);
|
||||
downView.setPressed(false);
|
||||
downView = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -70,7 +70,7 @@ public class TimeMeasurementView extends MeasurementView {
|
||||
|
||||
@Override
|
||||
public String getUnit() {
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -26,13 +26,27 @@ import com.health.openscale.core.evaluation.EvaluationSheet;
|
||||
|
||||
public class WaterMeasurementView extends MeasurementView {
|
||||
|
||||
private boolean estimateWaterEnable;
|
||||
|
||||
public WaterMeasurementView(Context context) {
|
||||
super(context, context.getResources().getString(R.string.label_water), ContextCompat.getDrawable(context, R.drawable.ic_water));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable() {
|
||||
if (estimateWaterEnable && getMeasurementMode() == MeasurementViewMode.ADD) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateValue(ScaleData updateData) {
|
||||
setValueOnView(updateData.getWater());
|
||||
if (estimateWaterEnable && getMeasurementMode() == MeasurementViewMode.ADD) {
|
||||
setValueOnView((getContext().getString(R.string.label_automatic)));
|
||||
} else {
|
||||
setValueOnView(updateData.getWater());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,6 +62,7 @@ public class WaterMeasurementView extends MeasurementView {
|
||||
@Override
|
||||
public void updatePreferences(SharedPreferences preferences) {
|
||||
setVisible(preferences.getBoolean("waterEnable", true));
|
||||
estimateWaterEnable = preferences.getBoolean("estimateWaterEnable", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -34,10 +34,6 @@ public class WeightMeasurementView extends MeasurementView {
|
||||
@Override
|
||||
public void updateValue(ScaleData updateData) {
|
||||
setValueOnView(updateData.getConvertedWeight(getScaleUser().scale_unit));
|
||||
|
||||
if (getMeasurementMode() == MeasurementViewMode.ADD) {
|
||||
getInputDialog().show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -135,4 +135,15 @@
|
||||
<string name="label_bmr">Grundumsatz (BMR)</string>
|
||||
<string name="info_measuring">Messe Gewicht: %.2f</string>
|
||||
<string name="info_new_data_added">%1$.2f%2$s [%3$s] zu %4$s hinzugefügt</string>
|
||||
<string name="error_max_scale_users">Maximale Anzahl gleichzeitiger Benutzer erreicht.</string>
|
||||
<string name="info_step_on_scale">Bitte steigen Sie barfuß auf die Waage zur Referenzmessung</string>
|
||||
<string name="label_automatic">auto</string>
|
||||
<string name="label_category_body_metrics_estimation">Körpermetriken abschätzen</string>
|
||||
<string name="label_category_display">Anzeige</string>
|
||||
<string name="label_category_measurement_database">Messwertedatenbank</string>
|
||||
<string name="label_category_misc">Verschiedenes</string>
|
||||
<string name="label_estimate_fat">Körperfettschätzung</string>
|
||||
<string name="label_estimate_fat_formula">Körperfettformel</string>
|
||||
<string name="label_estimate_water">Körperwasserschätzung</string>
|
||||
<string name="label_estimate_water_formula">Körperwasserformel</string>
|
||||
</resources>
|
@@ -104,7 +104,7 @@
|
||||
<string name="label_enable_points">Bod na údajový bod</string>
|
||||
<string name="label_delete_confirmation">Potvrďte vymazanie</string>
|
||||
<string name="label_reminder">Pripomienka</string>
|
||||
<string name="label_reminder_weekdays">Pracovné dni</string>
|
||||
<string name="label_reminder_weekdays">Dni v týždni</string>
|
||||
<string name="label_reminder_time">Čas</string>
|
||||
<string name="label_reminder_notify_text">Text upozornenia</string>
|
||||
<string name="default_value_reminder_notify_text">Čas na váženie</string>
|
||||
@@ -114,7 +114,7 @@
|
||||
<string name="info_your_muscle">Vaše percento svalov v tele bolo</string>
|
||||
<string name="info_your_waist">Váš obvod pása bol</string>
|
||||
<string name="info_your_hip">Váš obvod bokov bol</string>
|
||||
<string name="info_on_date">do</string>
|
||||
<string name="info_on_date">v deň</string>
|
||||
<string name="Monday">Pondelok</string>
|
||||
<string name="Tuesday">Utorok</string>
|
||||
<string name="Wednesday">Streda</string>
|
||||
|
@@ -120,6 +120,18 @@
|
||||
|
||||
<string name="label_delete_confirmation">Delete confirmation</string>
|
||||
|
||||
<string name="label_estimate_fat">Estimate body fat</string>
|
||||
<string name="label_estimate_water">Estimate body water</string>
|
||||
|
||||
<string name="label_category_display">Display</string>
|
||||
<string name="label_category_body_metrics_estimation">Body metrics estimation</string>
|
||||
<string name="label_category_measurement_database">Measurement database</string>
|
||||
<string name="label_category_misc">Miscellaneous</string>
|
||||
|
||||
<string name="label_estimate_fat_formula">Body fat formula</string>
|
||||
<string name="label_estimate_water_formula">Body water formula</string>
|
||||
<string name="label_automatic">auto</string>
|
||||
|
||||
<string name="label_reminder">Reminder</string>
|
||||
<string name="label_reminder_weekdays">Weekdays</string>
|
||||
<string name="label_reminder_time">Time</string>
|
||||
|
@@ -1,10 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<CheckBoxPreference android:title="@string/label_enable_labels" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="labelsEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_enable_points" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="pointsEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_delete_confirmation" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="deleteConfirmationEnable" android:defaultValue="true" />
|
||||
<CheckBoxPreference android:title="@string/label_average_data" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="averageData" android:defaultValue="true" />
|
||||
<CheckBoxPreference android:title="@string/label_goal_line" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="goalLine" android:defaultValue="true" />
|
||||
<CheckBoxPreference android:title="@string/label_regression_line" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="regressionLine" android:defaultValue="false" />
|
||||
<EditTextPreference android:title="@string/label_regression_line_degree" android:key="regressionLineOrder" android:defaultValue="1" />
|
||||
<PreferenceCategory android:title="@string/label_category_display">
|
||||
<CheckBoxPreference android:title="@string/label_enable_labels" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="labelsEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_enable_points" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="pointsEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_goal_line" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="goalLine" android:defaultValue="true" />
|
||||
<CheckBoxPreference android:title="@string/label_regression_line" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="regressionLine" android:defaultValue="false" />
|
||||
<EditTextPreference android:title="@string/label_regression_line_degree" android:key="regressionLineOrder" android:defaultValue="1" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/label_category_misc">
|
||||
<CheckBoxPreference android:title="@string/label_delete_confirmation" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="deleteConfirmationEnable" android:defaultValue="true" />
|
||||
<CheckBoxPreference android:title="@string/label_average_data" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="averageData" android:defaultValue="true" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
@@ -1,10 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<CheckBoxPreference android:title="@string/label_fat" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="fatEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_water" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="waterEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_muscle" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="muscleEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_bone" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="boneEnable" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:title="@string/label_waist" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="waistEnable" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:title="@string/label_hip" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="hipEnable" android:defaultValue="false"/>
|
||||
<Preference android:title="@string/label_delete_all" android:key="deleteAll"></Preference>
|
||||
<PreferenceCategory android:title="@string/label_category_display">
|
||||
<CheckBoxPreference android:title="@string/label_fat" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="fatEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_water" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="waterEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_muscle" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="muscleEnable" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:title="@string/label_bone" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="boneEnable" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:title="@string/label_waist" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="waistEnable" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:title="@string/label_hip" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="hipEnable" android:defaultValue="false"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/label_category_body_metrics_estimation">
|
||||
<CheckBoxPreference android:title="@string/label_estimate_fat" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="estimateFatEnable" android:defaultValue="false"/>
|
||||
<ListPreference android:title="@string/label_estimate_fat_formula" android:key="estimateFatFormula" android:defaultValue="BF_GALLAGHER"/>
|
||||
<CheckBoxPreference android:title="@string/label_estimate_water" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="estimateWaterEnable" android:defaultValue="false"/>
|
||||
<ListPreference android:title="@string/label_estimate_water_formula" android:key="estimateWaterFormula" android:defaultValue="TBW_LEESONGKIM"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/label_category_measurement_database">
|
||||
<Preference android:title="@string/label_delete_all" android:key="deleteAll"></Preference>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
Reference in New Issue
Block a user