mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-23 00:33:09 +02:00
Merge branch 'master' of https://github.com/oliexdev/openScale
This commit is contained in:
@@ -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}
|
||||
public enum BT_DEVICE_ID {CUSTOM_OPENSCALE, MI_SCALE_V1, SANITAS_SBF70, MEDISANA_BS444, DIGOO_DGS038H, EXCELVANT_CF369BLE, YUNMAI_MINI, MI_SCALE_V2}
|
||||
|
||||
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:
|
||||
|
@@ -0,0 +1,291 @@
|
||||
/* 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_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 onBluetoothDataRead(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic gattCharacteristic, int status) {
|
||||
byte[] data = gattCharacteristic.getValue();
|
||||
|
||||
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||
int currentMonth = Calendar.getInstance().get(Calendar.MONTH)+1;
|
||||
int currentDay = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
|
||||
int scaleYear = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
|
||||
int scaleMonth = (int) data[2];
|
||||
int scaleDay = (int) data[3];
|
||||
|
||||
if (currentYear == scaleYear && currentMonth == scaleMonth && currentDay == scaleDay) {
|
||||
setBtMachineState(BT_MACHINE_STATE.BT_CMD_STATE);
|
||||
} else {
|
||||
Log.d("BluetoothMiScale", "Current year and scale year is different");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBluetoothDataChange(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic gattCharacteristic) {
|
||||
final byte[] data = gattCharacteristic.getValue();
|
||||
|
||||
if (data != null && data.length > 0) {
|
||||
// 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:
|
||||
// read device time
|
||||
readBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_TIME_CHARACTERISTIC);
|
||||
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;
|
||||
case 3:
|
||||
// Set on history weight measurement
|
||||
byte[] magicBytes = new byte[]{(byte)0x01, (byte)0x96, (byte)0x8a, (byte)0xbd, (byte)0x62};
|
||||
|
||||
writeBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, magicBytes);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean nextBluetoothCmd(int stateNr) {
|
||||
switch (stateNr) {
|
||||
case 0:
|
||||
// set notification on for weight measurement history
|
||||
setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
case 1:
|
||||
// set notification on for weight measurement
|
||||
// FIXME: replacement characteristic for realtime measurements on Mi Scale 2?
|
||||
//setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
case 2:
|
||||
// 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 3:
|
||||
// set notification off for weight measurement history
|
||||
setNotificationOff(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
case 4:
|
||||
// set notification on for weight measurement history
|
||||
setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
|
||||
break;
|
||||
case 5:
|
||||
// invoke receiving history data
|
||||
writeBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x02});
|
||||
break;
|
||||
case 6:
|
||||
// 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;
|
||||
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;
|
||||
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); // FIXME: unconfirmed
|
||||
final boolean isStabilized = isBitSet(ctrlByte1, 5); // FIXME: unconfirmed
|
||||
final boolean isLBSUnit = isBitSet(ctrlByte0, 0);
|
||||
final boolean isCattyUnit = isBitSet(ctrlByte1, 6);
|
||||
|
||||
// Only if the value is stabilized and the weight is *not* removed, the date is valid
|
||||
if (isStabilized && !isWeightRemoved) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@@ -26,15 +26,23 @@ 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.ViewGroup;
|
||||
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;
|
||||
import android.widget.TextView;
|
||||
import android.os.Handler;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
|
||||
import com.health.openscale.R;
|
||||
import com.health.openscale.core.OpenScale;
|
||||
@@ -59,6 +67,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 +101,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 +129,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 +137,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);
|
||||
@@ -157,6 +217,22 @@ public abstract class MeasurementView extends TableLayout {
|
||||
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() {
|
||||
return value;
|
||||
}
|
||||
@@ -176,13 +252,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 +423,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 +485,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
|
||||
|
@@ -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
|
||||
|
162
android_app/app/src/main/res/values-pl/strings.xml
Normal file
162
android_app/app/src/main/res/values-pl/strings.xml
Normal file
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">openScale</string>
|
||||
<string name="title_overview">Przegląd</string>
|
||||
<string name="title_graph">Wykresy</string>
|
||||
<string name="title_table">Tabele</string>
|
||||
<string name="title_statistics">Statystyki</string>
|
||||
<string name="title_users">Użytkownicy</string>
|
||||
<string name="title_data">Dane</string>
|
||||
<string name="title_measurements">Pomiary</string>
|
||||
|
||||
<string name="action_settings">Ustawienia</string>
|
||||
<string name="action_bluetooth_status">Stan Bluetooth</string>
|
||||
|
||||
<string name="label_add">Dodaj</string>
|
||||
<string name="label_cancel">Anuluj</string>
|
||||
<string name="label_ok">OK</string>
|
||||
<string name="label_yes">Tak</string>
|
||||
<string name="label_no">Nie</string>
|
||||
<string name="label_delete">Usuń</string>
|
||||
<string name="label_add_user">Dodaj użytkownika</string>
|
||||
|
||||
<string name="label_id">Id</string>
|
||||
<string name="label_weight">Waga</string>
|
||||
<string name="label_bmi">Wskaźnik masy ciała (BMI)</string>
|
||||
<string name="label_bmr">Wskaźnik podstawowej przemiany materii (BMR)</string>
|
||||
<string name="label_fat">Procent tkanki tłuszczowej</string>
|
||||
<string name="label_water">Procent wody organizmie</string>
|
||||
<string name="label_muscle">Procent masy mięśniowej</string>
|
||||
<string name="label_waist">Obwód talii</string>
|
||||
<string name="label_hip">Obwód bioder</string>
|
||||
<string name="label_comment">Komentarz</string>
|
||||
<string name="label_whtr">Stosunek talii do wzrostu</string>
|
||||
<string name="label_whr">Stosunek obwodu talii do obwodu bioder</string>
|
||||
<string name="label_bone">Masa kostna</string>
|
||||
<string name="label_smartUserAssign">Inteligente przypisywanie użytkowników</string>
|
||||
|
||||
<string name="label_days">dni</string>
|
||||
<string name="label_measures">pomiarów</string>
|
||||
<string name="label_last_week">Ostatnie 7 dni</string>
|
||||
<string name="label_last_month">Ostatnie 30 dni</string>
|
||||
<string name="label_weight_difference">Różnica wagi</string>
|
||||
<string name="label_goal_date_is">Data celu to</string>
|
||||
<string name="label_days_left">Pozostało dni</string>
|
||||
|
||||
<string name="label_date">Data</string>
|
||||
<string name="label_time">Czas</string>
|
||||
<string name="label_birthday">Urodziny</string>
|
||||
<string name="label_user_name">Imie</string>
|
||||
<string name="label_body_height">Wzrost</string>
|
||||
<string name="label_scale_unit">Jednostka wagi</string>
|
||||
<string name="label_gender">Płęć</string>
|
||||
<string name="label_male">Mężczyzna</string>
|
||||
<string name="label_woman">Kobieta</string>
|
||||
<string name="label_goal_weight">Docelowa waga</string>
|
||||
<string name="label_goal_date">Data celu</string>
|
||||
|
||||
|
||||
<string name="label_title_user">użytkownik</string>
|
||||
<string name="label_title_last_measurement">ostatni pomiar</string>
|
||||
<string name="label_title_goal">cel</string>
|
||||
<string name="label_title_statistics">statystyki</string>
|
||||
|
||||
<string name="label_import">Import</string>
|
||||
<string name="label_export">Export</string>
|
||||
<string name="label_delete_all">Usuń wszystko</string>
|
||||
|
||||
<string name="error_value_required">Wartość jest wymagana</string>
|
||||
<string name="error_value_range">Wartość nie jest w zakresie</string>
|
||||
<string name="error_exporting">Błąd eksportu</string>
|
||||
<string name="error_importing">Błąd importu</string>
|
||||
<string name="error_user_name_required">Błąd nazwa użytkownika jest wymagana</string>
|
||||
<string name="error_body_height_required">Błąd wzrost jest wymagany</string>
|
||||
<string name="error_initial_weight_required">Błąd waga początkowa jest wymagana</string>
|
||||
<string name="error_goal_weight_required">Błąd waga docelowa jest wymagana</string>
|
||||
<string name="error_hip_value_required">Obwód bioder jest wymagany</string>
|
||||
|
||||
<string name="info_data_deleted">Wpis w bazie danych usunięty</string>
|
||||
<string name="info_data_all_deleted">Wszytkie wpisy w bazie danych usunięte</string>
|
||||
<string name="info_data_exported">Dane wyeksportowane do</string>
|
||||
<string name="info_data_imported">Dane zaimportowane z</string>
|
||||
<string name="info_set_filename">Ustaw nazwę pliku na</string>
|
||||
<string name="info_enter_value_cm">Wprowadź wartość w cm</string>
|
||||
<string name="info_enter_value_percent">Wprowadź wartość w %</string>
|
||||
<string name="info_enter_value_unit">Wprowadź wartość w</string>
|
||||
<string name="info_enter_comment">Wprowadź opcjonlany komentarz</string>
|
||||
<string name="info_enter_initial_weight">Wprowadź twoją wagę początkową w wybranej jednostce wagi</string>
|
||||
<string name="info_enter_goal_weight">Wprowadź twoją wagę docelową w wybranej jednostce wagi</string>
|
||||
<string name="info_is_visible">jest widoczne</string>
|
||||
<string name="info_is_not_visible">nie jest widoczne</string>
|
||||
<string name="info_is_enable">jest włączone</string>
|
||||
<string name="info_is_not_enable">jest wyłączone</string>
|
||||
<string name="info_is_not_available">jest niedostępne</string>
|
||||
<string name="info_delete_bluetooth_data">Wyczyść wszystkie dane Bluetooth</string>
|
||||
<string name="info_delete_bluetooth_data_success">Dane Bluetooth usunięte</string>
|
||||
<string name="info_bluetooth_try_connection">Próba połączenia do</string>
|
||||
<string name="info_bluetooth_connection_lost">Utracono połączenie Bluetooth.</string>
|
||||
<string name="info_bluetooth_no_device">Nie znaleziono urządzeń Bluetooth</string>
|
||||
<string name="info_bluetooth_connection_successful">Udało się nawiązać połączenie</string>
|
||||
<string name="info_bluetooth_init">Inicjalizacja urządzeń Bluetooth</string>
|
||||
<string name="info_bluetooth_connection_error">Nieznany błąd Bluetooth</string>
|
||||
<string name="info_new_data_added">%1$.2f%2$s [%3$s] dodano do %4$s</string>
|
||||
|
||||
<string name="info_enter_user_name">Wprowadź swoje imie</string>
|
||||
<string name="info_no_selected_user">Brak użytkowników. Proszę utworzyć nowego użytkownika w ustawieniach.</string>
|
||||
<string name="info_no_evaluation_available">Nie można określić wartości</string>
|
||||
|
||||
<string name="question_really_delete">Czy napewno chcesz usunąć wpis z bazy danych?</string>
|
||||
<string name="question_really_delete_all">Czy napewno chcesz usunąć wszystkie wpisy z bazy danych?</string>
|
||||
<string name="question_really_delete_user">Czy napewno chcesz usunąć użytkownika? </string>
|
||||
|
||||
<string name="label_bluetooth_title">Bluetooth</string>
|
||||
<string name="label_bluetooth_enable">Wyszukaj wagę przy starcie</string>
|
||||
<string name="label_bluetooth_searching">Wyszukuje wagi Bluetooth</string>
|
||||
<string name="label_device_type">Rodzaj urządzenia</string>
|
||||
|
||||
<string name="label_enable_labels">Label on data point</string>
|
||||
<string name="label_enable_points">Point on data point</string>
|
||||
|
||||
<string name="label_delete_confirmation">Potwierdzenie usnięcia</string>
|
||||
|
||||
<string name="label_reminder">Przypomnienie</string>
|
||||
<string name="label_reminder_weekdays">Dni tygodnia</string>
|
||||
<string name="label_reminder_time">Czas</string>
|
||||
<string name="label_reminder_notify_text">Tekst powiadomienia</string>
|
||||
<string name="default_value_reminder_notify_text">Pora by się zważyć</string>
|
||||
|
||||
<string name="info_your_weight">Twój wzrost</string>
|
||||
<string name="info_your_fat">Twój procent tkanki tłuszczowej</string>
|
||||
<string name="info_your_water">Twój procent wody organizmie</string>
|
||||
<string name="info_your_muscle">Twój procent masy mięśniowej</string>
|
||||
<string name="info_your_waist">Twój obwód talii</string>
|
||||
<string name="info_your_hip">Twój obwód bioder</string>
|
||||
<string name="info_on_date">na dzień</string>
|
||||
|
||||
<string name="Monday">Poniedziałek</string>
|
||||
<string name="Tuesday">Wtorek</string>
|
||||
<string name="Wednesday">Środa</string>
|
||||
<string name="Thursday">Czwartek</string>
|
||||
<string name="Friday">Piątek</string>
|
||||
<string name="Saturday">Sobota</string>
|
||||
<string name="Sunday">Niedziela</string>
|
||||
<string name="label_bt_device_no_support">urządzenie nie jest wspierane</string>
|
||||
<string name="label_exportBackup">Exportuj kopie zapasową</string>
|
||||
<string name="label_importBackup">Importuj kopie zapasową</string>
|
||||
<string name="label_backup">Kopia zapasowa</string>
|
||||
<string name="label_export_dir">Katalog do eksportu</string>
|
||||
<string name="label_not_found">nie znaleziono</string>
|
||||
<string name="label_ignoreOutOfRange">Ignoruj dane spoza zakresu</string>
|
||||
<string name="label_initial_weight">Waga początkowa</string>
|
||||
<string name="label_average_data">Oblicz średnią na dzień/miesiąc</string>
|
||||
<string name="label_regression_line">Regression weight line</string>
|
||||
<string name="label_regression_line_degree">Regression polynom degree</string>
|
||||
<string name="label_goal_line">Linia celu</string>
|
||||
|
||||
|
||||
<string name="error_max_scale_users">Osiągnięto maksymalną ilość użytkowników wagi.</string>
|
||||
<string name="info_step_on_scale">Proszę stanąć boso na wadze w celu przeprowadzenia pomiaru referencyjnego.</string>
|
||||
<string name="info_measuring">Mierzona waga: %.2f</string>
|
||||
|
||||
</resources>
|
@@ -19,7 +19,8 @@
|
||||
<string name="label_add_user">Pridať používateľa</string>
|
||||
<string name="label_id">ID</string>
|
||||
<string name="label_weight">Hmotnosť</string>
|
||||
<string name="label_bmi">BMI</string>
|
||||
<string name="label_bmi">Index telesnej hmotnosti (BMI)</string>
|
||||
<string name="label_bmr">Bazálny metabolický výdaj (BMR)</string>
|
||||
<string name="label_fat">Percento telesného tuku</string>
|
||||
<string name="label_water">Percento vody</string>
|
||||
<string name="label_muscle">Percento svalov</string>
|
||||
@@ -28,6 +29,7 @@
|
||||
<string name="label_comment">Komentár</string>
|
||||
<string name="label_whtr">Pomer pásu a výšky</string>
|
||||
<string name="label_whr">Pomer pásu a bokov</string>
|
||||
<string name="label_bone">Hmotnosť kostí</string>
|
||||
<string name="label_smartUserAssign">Chytré priradenie používateľa</string>
|
||||
<string name="label_days">dni</string>
|
||||
<string name="label_measures">merania</string>
|
||||
@@ -87,6 +89,7 @@
|
||||
<string name="info_bluetooth_connection_successful">Spojenie úspešné nadviazané</string>
|
||||
<string name="info_bluetooth_init">Inicializácia Bluetooth zariadenia</string>
|
||||
<string name="info_bluetooth_connection_error">Vyskytla neočakávaná chyba Bluetooth</string>
|
||||
<string name="info_new_data_added">Do %4$s boli pridané %1$.2f%2$s [%3$s]</string>
|
||||
<string name="info_enter_user_name">Zadajte vaše meno</string>
|
||||
<string name="info_no_selected_user">Žiadny používateľ. Prosím, vytvorte nového používateľa v nastaveniach.</string>
|
||||
<string name="info_no_evaluation_available">Nie je možné vypočítať hodnotu</string>
|
||||
@@ -95,13 +98,13 @@
|
||||
<string name="question_really_delete_user">Naozaj chcete vymazať používateľa? </string>
|
||||
<string name="label_bluetooth_title">Bluetooth</string>
|
||||
<string name="label_bluetooth_enable">Vyhľadať váhu po spustení</string>
|
||||
<string name="label_device_name">Názov zariadenia</string>
|
||||
<string name="label_bluetooth_searching">Prebieha vyhľadávanie Bluetooth váhy</string>
|
||||
<string name="label_device_type">Typ zariadenia</string>
|
||||
<string name="label_enable_labels">Štítok na údajový bod</string>
|
||||
<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>
|
||||
@@ -111,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>
|
||||
@@ -119,7 +122,7 @@
|
||||
<string name="Friday">Piatok</string>
|
||||
<string name="Saturday">Sobota</string>
|
||||
<string name="Sunday">Nedeľa</string>
|
||||
<string name="label_bt_device_support">Podporované budú</string>
|
||||
<string name="label_bt_device_no_support">nepodporované zariadenie</string>
|
||||
<string name="label_exportBackup">Export zálohy</string>
|
||||
<string name="label_importBackup">Import zálohy</string>
|
||||
<string name="label_backup">Zálohovanie</string>
|
||||
@@ -129,7 +132,7 @@
|
||||
<string name="label_initial_weight">Počiatočná hmotnosť</string>
|
||||
<string name="label_average_data">Vypočítať priemer za deň/mesiac</string>
|
||||
<string name="label_regression_line">Vývoj úbytku hmotnosti</string>
|
||||
<string name="label_regression_line_order">Radenie úbytku</string>
|
||||
<string name="label_regression_line_degree">Stupeň polynomiálnej regresie</string>
|
||||
<string name="label_goal_line">Cieľová línia</string>
|
||||
<string name="error_max_scale_users">Dosiahli ste maximálny počet viacerých používateľov.</string>
|
||||
<string name="info_step_on_scale">Prosím, postavte sa na váhu pre referenčné meranie.</string>
|
||||
|
@@ -1,22 +1,2 @@
|
||||
# copy apk file to home
|
||||
cp app/build/outputs/apk/app-debug.apk $HOME/openScale-dev-build.apk
|
||||
|
||||
#go to home and setup git
|
||||
cd $HOME
|
||||
git config --global user.email "olie.xdev@googlemail.com"
|
||||
git config --global user.name "oliexdev"
|
||||
|
||||
#clone the repository
|
||||
git clone --quiet --branch=master https://oliexdev:$GITHUB_API_KEY@github.com/oliexdev/openScale master > /dev/null
|
||||
|
||||
#copy generated apk from build folder to repository
|
||||
cp $HOME/openScale-dev-build.apk $HOME/master/openScale-dev-build.apk
|
||||
|
||||
#go into repository
|
||||
cd master
|
||||
|
||||
#add, commit and push apk file
|
||||
git add -f openScale-dev-build.apk
|
||||
git commit -m "openScale dev build $TRAVIS_BUILD_NUMBER by Travis CI [skip ci]" openScale-dev-build.apk
|
||||
git push -fq origin master > /dev/null
|
||||
echo -e "Done\n"
|
||||
|
Reference in New Issue
Block a user