mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-03 05:27:44 +01:00
Initial heart rate support by KashaMalaga #178
(removed unrelated Android M fixes and squashed commits)
This commit is contained in:
parent
0ef738067d
commit
9e636d66f6
@ -53,6 +53,7 @@ public class DebugActivity extends Activity {
|
|||||||
private Button setMusicInfoButton;
|
private Button setMusicInfoButton;
|
||||||
private Button setTimeButton;
|
private Button setTimeButton;
|
||||||
private Button rebootButton;
|
private Button rebootButton;
|
||||||
|
private Button HearRateButton;
|
||||||
private Button exportDBButton;
|
private Button exportDBButton;
|
||||||
private Button importDBButton;
|
private Button importDBButton;
|
||||||
private Button deleteDBButton;
|
private Button deleteDBButton;
|
||||||
@ -185,6 +186,13 @@ public class DebugActivity extends Activity {
|
|||||||
GBApplication.deviceService().onReboot();
|
GBApplication.deviceService().onReboot();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
HearRateButton = (Button) findViewById(R.id.HearRateButton);
|
||||||
|
HearRateButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
GBApplication.deviceService().onHearRateTest();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setMusicInfoButton = (Button) findViewById(R.id.setMusicInfoButton);
|
setMusicInfoButton = (Button) findViewById(R.id.setMusicInfoButton);
|
||||||
setMusicInfoButton.setOnClickListener(new View.OnClickListener() {
|
setMusicInfoButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@ -40,6 +40,8 @@ public interface EventHandler {
|
|||||||
|
|
||||||
void onReboot();
|
void onReboot();
|
||||||
|
|
||||||
|
void onHearRateTest();
|
||||||
|
|
||||||
void onFindDevice(boolean start);
|
void onFindDevice(boolean start);
|
||||||
|
|
||||||
void onScreenshotReq();
|
void onScreenshotReq();
|
||||||
|
@ -14,6 +14,8 @@ public class MiBandService {
|
|||||||
|
|
||||||
public static final UUID UUID_SERVICE_MIBAND_SERVICE = UUID.fromString(String.format(BASE_UUID, "FEE0"));
|
public static final UUID UUID_SERVICE_MIBAND_SERVICE = UUID.fromString(String.format(BASE_UUID, "FEE0"));
|
||||||
|
|
||||||
|
public static final UUID UUID_SERVICE_HEART_RATE = UUID.fromString(String.format(BASE_UUID, "180D"));
|
||||||
|
|
||||||
public static final UUID UUID_CHARACTERISTIC_DEVICE_INFO = UUID.fromString(String.format(BASE_UUID, "FF01"));
|
public static final UUID UUID_CHARACTERISTIC_DEVICE_INFO = UUID.fromString(String.format(BASE_UUID, "FF01"));
|
||||||
|
|
||||||
public static final UUID UUID_CHARACTERISTIC_DEVICE_NAME = UUID.fromString(String.format(BASE_UUID, "FF02"));
|
public static final UUID UUID_CHARACTERISTIC_DEVICE_NAME = UUID.fromString(String.format(BASE_UUID, "FF02"));
|
||||||
@ -44,6 +46,11 @@ public class MiBandService {
|
|||||||
|
|
||||||
public static final UUID UUID_CHARACTERISTIC_PAIR = UUID.fromString(String.format(BASE_UUID, "FF0F"));
|
public static final UUID UUID_CHARACTERISTIC_PAIR = UUID.fromString(String.format(BASE_UUID, "FF0F"));
|
||||||
|
|
||||||
|
public static final UUID UUID_CHAR_HEART_RATE_CONTROL_POINT = UUID.fromString(String.format(BASE_UUID, "2A39"));
|
||||||
|
public static final UUID UUID_CHAR_HEART_RATE_MEASUREMENT = UUID.fromString(String.format(BASE_UUID, "2A37"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* FURTHER UUIDS that were mixed with the other params below. The base UUID for these is unknown */
|
/* FURTHER UUIDS that were mixed with the other params below. The base UUID for these is unknown */
|
||||||
|
|
||||||
public static final String UUID_SERVICE_WEIGHT_SERVICE = "00001530-0000-3512-2118-0009af100700";
|
public static final String UUID_SERVICE_WEIGHT_SERVICE = "00001530-0000-3512-2118-0009af100700";
|
||||||
@ -153,6 +160,12 @@ public class MiBandService {
|
|||||||
|
|
||||||
public static final byte COMMAND_SET_REALTIME_STEP = 0x10;
|
public static final byte COMMAND_SET_REALTIME_STEP = 0x10;
|
||||||
|
|
||||||
|
// Test HR
|
||||||
|
public static final byte COMMAND_SET_HR_SLEEP = 0x0 ;
|
||||||
|
public static final byte COMMAND_SET__HR_CONTINUOUS = 0x1 ;
|
||||||
|
public static final byte COMMAND_SET_HR_MANUAL = 0x2 ;
|
||||||
|
|
||||||
|
|
||||||
/* FURTHER COMMANDS: unchecked therefore left commented
|
/* FURTHER COMMANDS: unchecked therefore left commented
|
||||||
|
|
||||||
|
|
||||||
@ -213,6 +226,7 @@ public class MiBandService {
|
|||||||
static {
|
static {
|
||||||
MIBAND_DEBUG = new HashMap<>();
|
MIBAND_DEBUG = new HashMap<>();
|
||||||
MIBAND_DEBUG.put(UUID_SERVICE_MIBAND_SERVICE, "MiBand Service");
|
MIBAND_DEBUG.put(UUID_SERVICE_MIBAND_SERVICE, "MiBand Service");
|
||||||
|
MIBAND_DEBUG.put(UUID_SERVICE_HEART_RATE, "MiBand HR Service");
|
||||||
|
|
||||||
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_DEVICE_INFO, "Device Info");
|
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_DEVICE_INFO, "Device Info");
|
||||||
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_DEVICE_NAME, "Device Name");
|
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_DEVICE_NAME, "Device Name");
|
||||||
@ -229,6 +243,8 @@ public class MiBandService {
|
|||||||
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_TEST, "Test");
|
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_TEST, "Test");
|
||||||
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_SENSOR_DATA, "Sensor Data");
|
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_SENSOR_DATA, "Sensor Data");
|
||||||
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_PAIR, "Pair");
|
MIBAND_DEBUG.put(UUID_CHARACTERISTIC_PAIR, "Pair");
|
||||||
|
MIBAND_DEBUG.put(UUID_CHAR_HEART_RATE_CONTROL_POINT, "Heart Rate Control Point");
|
||||||
|
MIBAND_DEBUG.put(UUID_CHAR_HEART_RATE_MEASUREMENT, "Heart Rate Measure");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String lookup(UUID uuid, String fallback) {
|
public static String lookup(UUID uuid, String fallback) {
|
||||||
|
@ -171,6 +171,12 @@ public class GBDeviceService implements DeviceService {
|
|||||||
invokeService(intent);
|
invokeService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onHearRateTest() {
|
||||||
|
Intent intent = createIntent().setAction(ACTION_HEARTRATE_TEST);
|
||||||
|
invokeService(intent);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFindDevice(boolean start) {
|
public void onFindDevice(boolean start) {
|
||||||
Intent intent = createIntent().setAction(ACTION_FIND_DEVICE)
|
Intent intent = createIntent().setAction(ACTION_FIND_DEVICE)
|
||||||
|
@ -26,13 +26,13 @@ public interface DeviceService extends EventHandler {
|
|||||||
String ACTION_DELETEAPP = PREFIX + ".action.deleteapp";
|
String ACTION_DELETEAPP = PREFIX + ".action.deleteapp";
|
||||||
String ACTION_INSTALL = PREFIX + ".action.install";
|
String ACTION_INSTALL = PREFIX + ".action.install";
|
||||||
String ACTION_REBOOT = PREFIX + ".action.reboot";
|
String ACTION_REBOOT = PREFIX + ".action.reboot";
|
||||||
|
String ACTION_HEARTRATE_TEST = PREFIX + ".action.heartrate_test";
|
||||||
String ACTION_FETCH_ACTIVITY_DATA = PREFIX + ".action.fetch_activity_data";
|
String ACTION_FETCH_ACTIVITY_DATA = PREFIX + ".action.fetch_activity_data";
|
||||||
String ACTION_DISCONNECT = PREFIX + ".action.disconnect";
|
String ACTION_DISCONNECT = PREFIX + ".action.disconnect";
|
||||||
String ACTION_FIND_DEVICE = PREFIX + ".action.find_device";
|
String ACTION_FIND_DEVICE = PREFIX + ".action.find_device";
|
||||||
String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms";
|
String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms";
|
||||||
String ACTION_ENABLE_REALTIME_STEPS = PREFIX + ".action.enable_realtime_steps";
|
String ACTION_ENABLE_REALTIME_STEPS = PREFIX + ".action.enable_realtime_steps";
|
||||||
String ACTION_REALTIME_STEPS = PREFIX + ".action.realtime_steps";
|
String ACTION_REALTIME_STEPS = PREFIX + ".action.realtime_steps";
|
||||||
|
|
||||||
String EXTRA_DEVICE_ADDRESS = "device_address";
|
String EXTRA_DEVICE_ADDRESS = "device_address";
|
||||||
String EXTRA_NOTIFICATION_BODY = "notification_body";
|
String EXTRA_NOTIFICATION_BODY = "notification_body";
|
||||||
String EXTRA_NOTIFICATION_FLAGS = "notification_flags";
|
String EXTRA_NOTIFICATION_FLAGS = "notification_flags";
|
||||||
|
@ -47,6 +47,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_DI
|
|||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ENABLE_REALTIME_STEPS;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ENABLE_REALTIME_STEPS;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FETCH_ACTIVITY_DATA;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FETCH_ACTIVITY_DATA;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FIND_DEVICE;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FIND_DEVICE;
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_HEARTRATE_TEST;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_INSTALL;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_INSTALL;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REBOOT;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REBOOT;
|
||||||
@ -251,6 +252,10 @@ public class DeviceCommunicationService extends Service {
|
|||||||
mDeviceSupport.onReboot();
|
mDeviceSupport.onReboot();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ACTION_HEARTRATE_TEST: {
|
||||||
|
mDeviceSupport.onHearRateTest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ACTION_FETCH_ACTIVITY_DATA: {
|
case ACTION_FETCH_ACTIVITY_DATA: {
|
||||||
mDeviceSupport.onFetchActivityData();
|
mDeviceSupport.onFetchActivityData();
|
||||||
break;
|
break;
|
||||||
|
@ -194,6 +194,14 @@ public class ServiceDeviceSupport implements DeviceSupport {
|
|||||||
delegate.onReboot();
|
delegate.onReboot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onHearRateTest() {
|
||||||
|
if (checkBusy("heartrate")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delegate.onHearRateTest();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFindDevice(boolean start) {
|
public void onFindDevice(boolean start) {
|
||||||
if (checkBusy("find device")) {
|
if (checkBusy("find device")) {
|
||||||
|
@ -89,6 +89,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS);
|
addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS);
|
||||||
addSupportedService(GattService.UUID_SERVICE_GENERIC_ATTRIBUTE);
|
addSupportedService(GattService.UUID_SERVICE_GENERIC_ATTRIBUTE);
|
||||||
addSupportedService(MiBandService.UUID_SERVICE_MIBAND_SERVICE);
|
addSupportedService(MiBandService.UUID_SERVICE_MIBAND_SERVICE);
|
||||||
|
addSupportedService(MiBandService.UUID_SERVICE_HEART_RATE);
|
||||||
addSupportedService(GattService.UUID_SERVICE_IMMEDIATE_ALERT);
|
addSupportedService(GattService.UUID_SERVICE_IMMEDIATE_ALERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +107,8 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
.setCurrentTime(builder)
|
.setCurrentTime(builder)
|
||||||
.requestBatteryInfo(builder)
|
.requestBatteryInfo(builder)
|
||||||
.setInitialized(builder);
|
.setInitialized(builder);
|
||||||
|
// heartrate(builder)
|
||||||
|
// .requestHRInfo(builder);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +201,10 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static final byte[] reboot = new byte[]{MiBandService.COMMAND_REBOOT};
|
static final byte[] reboot = new byte[]{MiBandService.COMMAND_REBOOT};
|
||||||
|
|
||||||
|
// static final byte[] HeartMode = new byte[]{MiBandService.COMMAND_SET_HR_MANUAL};
|
||||||
|
static final byte[] HeartMode = new byte[]{MiBandService.COMMAND_SET_HR_SLEEP};
|
||||||
|
|
||||||
static final byte[] startRealTimeStepsNotifications = new byte[]{MiBandService.COMMAND_SET_REALTIME_STEPS_NOTIFICATION, 1};
|
static final byte[] startRealTimeStepsNotifications = new byte[]{MiBandService.COMMAND_SET_REALTIME_STEPS_NOTIFICATION, 1};
|
||||||
static final byte[] stopRealTimeStepsNotifications = new byte[]{MiBandService.COMMAND_SET_REALTIME_STEPS_NOTIFICATION, 0};
|
static final byte[] stopRealTimeStepsNotifications = new byte[]{MiBandService.COMMAND_SET_REALTIME_STEPS_NOTIFICATION, 0};
|
||||||
|
|
||||||
@ -245,6 +251,30 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* private MiBandSupport requestHRInfo(TransactionBuilder builder) {
|
||||||
|
LOG.debug("Requesting HR Info!");
|
||||||
|
BluetoothGattCharacteristic HRInfo = getCharacteristic(MiBandService.UUID_CHAR_HEART_RATE_MEASUREMENT);
|
||||||
|
builder.read(HRInfo);
|
||||||
|
BluetoothGattCharacteristic HR_Point = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT);
|
||||||
|
builder.read(HR_Point);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
*//**
|
||||||
|
* Part of HR test. Do not call manually.
|
||||||
|
*
|
||||||
|
* @param transaction
|
||||||
|
* @return
|
||||||
|
*//*
|
||||||
|
private MiBandSupport heartrate(TransactionBuilder transaction) {
|
||||||
|
LOG.info("Attempting to read HR ...");
|
||||||
|
BluetoothGattCharacteristic characteristic = getCharacteristic(MiBandService.UUID_CHAR_HEART_RATE_MEASUREMENT);
|
||||||
|
if (characteristic != null) {
|
||||||
|
transaction.write(characteristic, new byte[]{MiBandService.COMMAND_SET__HR_CONTINUOUS});
|
||||||
|
} else {
|
||||||
|
LOG.info("Unable to read HR from MI device -- characteristic not available");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}*/
|
||||||
/**
|
/**
|
||||||
* Part of device initialization process. Do not call manually.
|
* Part of device initialization process. Do not call manually.
|
||||||
*
|
*
|
||||||
@ -493,7 +523,16 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
LOG.error("Unable to reboot MI", ex);
|
LOG.error("Unable to reboot MI", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public void onHearRateTest() {
|
||||||
|
try {
|
||||||
|
TransactionBuilder builder = performInitialized("HeartRateTest");
|
||||||
|
builder.write(getCharacteristic(MiBandService.UUID_CHAR_HEART_RATE_CONTROL_POINT), HeartMode);
|
||||||
|
builder.queue(getQueue());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOG.error("Unable to read HearRate in MI1S", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onFindDevice(boolean start) {
|
public void onFindDevice(boolean start) {
|
||||||
isLocatingDevice = start;
|
isLocatingDevice = start;
|
||||||
@ -613,7 +652,12 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
handleNotificationNotif(characteristic.getValue());
|
handleNotificationNotif(characteristic.getValue());
|
||||||
} else if (MiBandService.UUID_CHARACTERISTIC_REALTIME_STEPS.equals(characteristicUUID)) {
|
} else if (MiBandService.UUID_CHARACTERISTIC_REALTIME_STEPS.equals(characteristicUUID)) {
|
||||||
handleRealtimeSteps(characteristic.getValue());
|
handleRealtimeSteps(characteristic.getValue());
|
||||||
} else {
|
} else if (MiBandService.UUID_CHARACTERISTIC_REALTIME_STEPS.equals(characteristicUUID)) {
|
||||||
|
handleRealtimeSteps(characteristic.getValue());
|
||||||
|
} else if (MiBandService.UUID_CHAR_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
|
||||||
|
logMessageContent(characteristic.getValue());
|
||||||
|
}
|
||||||
|
else {
|
||||||
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
|
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
|
||||||
logMessageContent(characteristic.getValue());
|
logMessageContent(characteristic.getValue());
|
||||||
}
|
}
|
||||||
@ -631,8 +675,8 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
handleDeviceName(characteristic.getValue(), status);
|
handleDeviceName(characteristic.getValue(), status);
|
||||||
} else if (MiBandService.UUID_CHARACTERISTIC_BATTERY.equals(characteristicUUID)) {
|
} else if (MiBandService.UUID_CHARACTERISTIC_BATTERY.equals(characteristicUUID)) {
|
||||||
handleBatteryInfo(characteristic.getValue(), status);
|
handleBatteryInfo(characteristic.getValue(), status);
|
||||||
} else if (MiBandService.UUID_CHARACTERISTIC_REALTIME_STEPS.equals(characteristicUUID)) {
|
} else if (MiBandService.UUID_CHAR_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
|
||||||
handleRealtimeSteps(characteristic.getValue());
|
logMessageContent(characteristic.getValue());
|
||||||
} else {
|
} else {
|
||||||
LOG.info("Unhandled characteristic read: "+ characteristicUUID);
|
LOG.info("Unhandled characteristic read: "+ characteristicUUID);
|
||||||
logMessageContent(characteristic.getValue());
|
logMessageContent(characteristic.getValue());
|
||||||
|
@ -37,6 +37,11 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
|
|||||||
getDeviceIOThread().installApp(uri, 0);
|
getDeviceIOThread().installApp(uri, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onHearRateTest() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized PebbleIoThread getDeviceIOThread() {
|
public synchronized PebbleIoThread getDeviceIOThread() {
|
||||||
return (PebbleIoThread) super.getDeviceIOThread();
|
return (PebbleIoThread) super.getDeviceIOThread();
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
android:layout_column="0"
|
android:layout_column="0"
|
||||||
android:layout_columnSpan="3"
|
android:layout_columnSpan="3"
|
||||||
android:layout_gravity="fill_horizontal"
|
android:layout_gravity="fill_horizontal"
|
||||||
android:layout_row="9"
|
android:layout_row="10"
|
||||||
android:text="create test notification" />
|
android:text="create test notification" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -83,7 +83,7 @@
|
|||||||
android:layout_column="0"
|
android:layout_column="0"
|
||||||
android:layout_columnSpan="3"
|
android:layout_columnSpan="3"
|
||||||
android:layout_gravity="fill_horizontal"
|
android:layout_gravity="fill_horizontal"
|
||||||
android:layout_row="8"
|
android:layout_row="9"
|
||||||
android:text="set time" />
|
android:text="set time" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -133,7 +133,15 @@
|
|||||||
android:layout_gravity="fill_horizontal"
|
android:layout_gravity="fill_horizontal"
|
||||||
android:layout_row="5"
|
android:layout_row="5"
|
||||||
android:text="set music info" />
|
android:text="set music info" />
|
||||||
|
<Button
|
||||||
|
android:id="@+id/HearRateButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_column="0"
|
||||||
|
android:layout_columnSpan="3"
|
||||||
|
android:layout_gravity="fill_horizontal"
|
||||||
|
android:layout_row="8"
|
||||||
|
android:text="HR Rate Test" />
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/rebootButton"
|
android:id="@+id/rebootButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -144,6 +152,7 @@
|
|||||||
android:layout_row="7"
|
android:layout_row="7"
|
||||||
android:text="reboot" />
|
android:text="reboot" />
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/exportDBButton"
|
android:id="@+id/exportDBButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user