mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-28 21:06:50 +01:00
Merge pull request #523 from jpbarraca/Makibes-F68
HPlus: Support for Makibes F68
This commit is contained in:
commit
896eb19b3e
@ -15,8 +15,8 @@ public final class HPlusConstants {
|
|||||||
public static final UUID UUID_SERVICE_HP = UUID.fromString("14701820-620a-3973-7c78-9cfff0876abd");
|
public static final UUID UUID_SERVICE_HP = UUID.fromString("14701820-620a-3973-7c78-9cfff0876abd");
|
||||||
|
|
||||||
|
|
||||||
public static final byte ARG_COUNTRY_CN = 1;
|
public static final byte ARG_LANGUAGE_CN = 1;
|
||||||
public static final byte ARG_COUNTRY_OTHER = 2;
|
public static final byte ARG_LANGUAGE_EN = 2;
|
||||||
|
|
||||||
public static final byte ARG_TIMEMODE_24H = 0;
|
public static final byte ARG_TIMEMODE_24H = 0;
|
||||||
public static final byte ARG_TIMEMODE_12H = 1;
|
public static final byte ARG_TIMEMODE_12H = 1;
|
||||||
@ -111,7 +111,7 @@ public final class HPlusConstants {
|
|||||||
public static final String PREF_HPLUS_ALERT_TIME = "hplus_alert_time";
|
public static final String PREF_HPLUS_ALERT_TIME = "hplus_alert_time";
|
||||||
public static final String PREF_HPLUS_SIT_START_TIME = "hplus_sit_start_time";
|
public static final String PREF_HPLUS_SIT_START_TIME = "hplus_sit_start_time";
|
||||||
public static final String PREF_HPLUS_SIT_END_TIME = "hplus_sit_end_time";
|
public static final String PREF_HPLUS_SIT_END_TIME = "hplus_sit_end_time";
|
||||||
public static final String PREF_HPLUS_COUNTRY = "hplus_country";
|
public static final String PREF_HPLUS_LANGUAGE = "hplus_language";
|
||||||
|
|
||||||
public static final Map<Character, Byte> transliterateMap = new HashMap<Character, Byte>(){
|
public static final Map<Character, Byte> transliterateMap = new HashMap<Character, Byte>(){
|
||||||
{
|
{
|
||||||
|
@ -38,8 +38,8 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(HPlusCoordinator.class);
|
protected static final Logger LOG = LoggerFactory.getLogger(HPlusCoordinator.class);
|
||||||
private static Prefs prefs = GBApplication.getPrefs();
|
protected static Prefs prefs = GBApplication.getPrefs();
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
@ -144,8 +144,8 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
|||||||
return activityUser.getStepsGoal();
|
return activityUser.getStepsGoal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte getCountry(String address) {
|
public static byte getLanguage(String address) {
|
||||||
return (byte) prefs.getInt(HPlusConstants.PREF_HPLUS_COUNTRY + "_" + address, 10);
|
return (byte) prefs.getInt(HPlusConstants.PREF_HPLUS_LANGUAGE + "_" + address, HPlusConstants.ARG_LANGUAGE_EN);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,30 +141,46 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
today.set(Calendar.SECOND, 0);
|
today.set(Calendar.SECOND, 0);
|
||||||
today.set(Calendar.MILLISECOND, 0);
|
today.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
int stepsToday = 0;
|
int stepsTodayMax = 0;
|
||||||
|
int stepsTodayCount = 0;
|
||||||
|
HPlusHealthActivitySample lastSample = null;
|
||||||
|
|
||||||
for(HPlusHealthActivitySample sample: samples){
|
for(HPlusHealthActivitySample sample: samples){
|
||||||
if(sample.getTimestamp() >= today.getTimeInMillis() / 1000){
|
if(sample.getTimestamp() >= today.getTimeInMillis() / 1000){
|
||||||
//Only consider these for the current day as a single message is enough for steps
|
|
||||||
//HR and Overlays will still benefit from the full set of samples
|
/**Strategy is:
|
||||||
|
* Calculate max steps from realtime messages
|
||||||
|
* Calculate sum of steps from day 10 minute slot summaries
|
||||||
|
*/
|
||||||
|
|
||||||
if(sample.getRawKind() == HPlusDataRecord.TYPE_REALTIME) {
|
if(sample.getRawKind() == HPlusDataRecord.TYPE_REALTIME) {
|
||||||
int aux = sample.getSteps();
|
stepsTodayMax = Math.max(stepsTodayMax, sample.getSteps());
|
||||||
sample.setSteps(sample.getSteps() - stepsToday);
|
}else if(sample.getRawKind() == HPlusDataRecord.TYPE_DAY_SLOT) {
|
||||||
stepsToday = aux;
|
stepsTodayCount += sample.getSteps();
|
||||||
}else
|
}
|
||||||
sample.setSteps(ActivitySample.NOT_MEASURED);
|
|
||||||
|
sample.setSteps(ActivitySample.NOT_MEASURED);
|
||||||
|
lastSample = sample;
|
||||||
}else{
|
}else{
|
||||||
if (sample.getRawKind() != HPlusDataRecord.TYPE_DAY_SUMMARY) {
|
if (sample.getRawKind() != HPlusDataRecord.TYPE_DAY_SUMMARY) {
|
||||||
sample.setSteps(ActivityKind.TYPE_NOT_MEASURED);
|
sample.setSteps(ActivitySample.NOT_MEASURED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(lastSample != null)
|
||||||
|
lastSample.setSteps(Math.max(stepsTodayCount, stepsTodayMax));
|
||||||
|
|
||||||
for (HPlusHealthActivityOverlay overlay : overlayRecords) {
|
for (HPlusHealthActivityOverlay overlay : overlayRecords) {
|
||||||
|
|
||||||
//Create fake events to improve activity counters if there are no events around the overlay
|
//Create fake events to improve activity counters if there are no events around the overlay
|
||||||
//timestamp boundaries
|
//timestamp boundaries
|
||||||
|
//Insert one before, one at the beginning, one at the end, and one 1s after.
|
||||||
|
insertVirtualItem(samples, Math.max(overlay.getTimestampFrom() - 1, timestamp_from), overlay.getDeviceId(), overlay.getUserId());
|
||||||
insertVirtualItem(samples, Math.max(overlay.getTimestampFrom(), timestamp_from), overlay.getDeviceId(), overlay.getUserId());
|
insertVirtualItem(samples, Math.max(overlay.getTimestampFrom(), timestamp_from), overlay.getDeviceId(), overlay.getUserId());
|
||||||
insertVirtualItem(samples, Math.min(overlay.getTimestampTo() - 1, timestamp_to - 1), overlay.getDeviceId(), overlay.getUserId());
|
insertVirtualItem(samples, Math.min(overlay.getTimestampTo() - 1, timestamp_to - 1), overlay.getDeviceId(), overlay.getUserId());
|
||||||
|
insertVirtualItem(samples, Math.min(overlay.getTimestampTo(), timestamp_to), overlay.getDeviceId(), overlay.getUserId());
|
||||||
|
|
||||||
for (HPlusHealthActivitySample sample : samples) {
|
for (HPlusHealthActivitySample sample : samples) {
|
||||||
|
|
||||||
if (sample.getTimestamp() >= overlay.getTimestampFrom() && sample.getTimestamp() < overlay.getTimestampTo()) {
|
if (sample.getTimestamp() >= overlay.getTimestampFrom() && sample.getTimestamp() < overlay.getTimestampTo()) {
|
||||||
@ -191,7 +207,7 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
userId, // User id
|
userId, // User id
|
||||||
null, // Raw Data
|
null, // Raw Data
|
||||||
ActivityKind.TYPE_UNKNOWN,
|
ActivityKind.TYPE_UNKNOWN,
|
||||||
0, // Intensity
|
1, // Intensity
|
||||||
ActivitySample.NOT_MEASURED, // Steps
|
ActivitySample.NOT_MEASURED, // Steps
|
||||||
ActivitySample.NOT_MEASURED, // HR
|
ActivitySample.NOT_MEASURED, // HR
|
||||||
ActivitySample.NOT_MEASURED, // Distance
|
ActivitySample.NOT_MEASURED, // Distance
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pseudo Coordinator for the Makibes F68, a sub type of the HPLUS devices
|
||||||
|
*/
|
||||||
|
public class MakibesF68Coordinator extends HPlusCoordinator {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public DeviceType getSupportedType(GBDeviceCandidate candidate) {
|
||||||
|
String name = candidate.getDevice().getName();
|
||||||
|
if(name != null && name.startsWith("SPORT")){
|
||||||
|
return DeviceType.MAKIBESF68;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DeviceType.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeviceType getDeviceType() {
|
||||||
|
return DeviceType.MAKIBESF68;
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ public enum DeviceType {
|
|||||||
VIBRATISSIMO(20),
|
VIBRATISSIMO(20),
|
||||||
LIVEVIEW(30),
|
LIVEVIEW(30),
|
||||||
HPLUS(40),
|
HPLUS(40),
|
||||||
|
MAKIBESF68(50),
|
||||||
TEST(1000);
|
TEST(1000);
|
||||||
|
|
||||||
private final int key;
|
private final int key;
|
||||||
|
@ -10,6 +10,7 @@ import java.util.EnumSet;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.liveview.LiveviewSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.liveview.LiveviewSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.MiBand2Support;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.MiBand2Support;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.MiBandSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.MiBandSupport;
|
||||||
@ -98,7 +99,10 @@ public class DeviceSupportFactory {
|
|||||||
deviceSupport = new ServiceDeviceSupport(new LiveviewSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
deviceSupport = new ServiceDeviceSupport(new LiveviewSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||||
break;
|
break;
|
||||||
case HPLUS:
|
case HPLUS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(DeviceType.HPLUS), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||||
|
break;
|
||||||
|
case MAKIBESF68:
|
||||||
|
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(DeviceType.MAKIBESF68), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (deviceSupport != null) {
|
if (deviceSupport != null) {
|
||||||
|
@ -8,7 +8,7 @@ import java.util.Calendar;
|
|||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
|
|
||||||
|
|
||||||
public class HPlusDataRecordDaySlot extends HPlusDataRecord {
|
public class HPlusDataRecordDaySlot extends HPlusDataRecord {
|
||||||
@ -47,9 +47,9 @@ public class HPlusDataRecordDaySlot extends HPlusDataRecord {
|
|||||||
heartRate = data[1] & 0xFF;
|
heartRate = data[1] & 0xFF;
|
||||||
|
|
||||||
if(heartRate == 255 || heartRate == 0)
|
if(heartRate == 255 || heartRate == 0)
|
||||||
heartRate = ActivityKind.TYPE_NOT_MEASURED;
|
heartRate = ActivitySample.NOT_MEASURED;
|
||||||
|
|
||||||
steps = (data[2] & 0xFF) * 256 + data[3] & 0xFF;
|
steps = (data[2] & 0xFF) * 256 + (data[3] & 0xFF);
|
||||||
|
|
||||||
//?? data[6]; atemp?? always 0
|
//?? data[6]; atemp?? always 0
|
||||||
secondsInactive = data[7] & 0xFF; // ?
|
secondsInactive = data[7] & 0xFF; // ?
|
||||||
@ -69,16 +69,21 @@ public class HPlusDataRecordDaySlot extends HPlusDataRecord {
|
|||||||
return String.format(Locale.US, "Slot: %d, Time: %s, Steps: %d, InactiveSeconds: %d, HeartRate: %d", slot, slotTime.getTime(), steps, secondsInactive, heartRate);
|
return String.format(Locale.US, "Slot: %d, Time: %s, Steps: %d, InactiveSeconds: %d, HeartRate: %d", slot, slotTime.getTime(), steps, secondsInactive, heartRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(HPlusDataRecordDaySlot other){
|
public void accumulate(HPlusDataRecordDaySlot other){
|
||||||
if(other == null)
|
if(other == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
steps += other.steps;
|
if(steps == ActivitySample.NOT_MEASURED)
|
||||||
secondsInactive += other.secondsInactive;
|
steps = other.steps;
|
||||||
if(heartRate == -1)
|
else if(other.steps != ActivitySample.NOT_MEASURED)
|
||||||
|
steps += other.steps;
|
||||||
|
|
||||||
|
if(heartRate == ActivitySample.NOT_MEASURED)
|
||||||
heartRate = other.heartRate;
|
heartRate = other.heartRate;
|
||||||
else if(other.heartRate != -1) {
|
else if(other.heartRate != ActivitySample.NOT_MEASURED) {
|
||||||
heartRate = (heartRate + other.heartRate) / 2;
|
heartRate = (heartRate + other.heartRate) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secondsInactive += other.secondsInactive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,8 @@ class HPlusDataRecordRealtime extends HPlusDataRecord {
|
|||||||
timestamp = (int) (GregorianCalendar.getInstance().getTimeInMillis() / 1000);
|
timestamp = (int) (GregorianCalendar.getInstance().getTimeInMillis() / 1000);
|
||||||
distance = 10 * ((data[4] & 0xFF) * 256 + (data[3] & 0xFF)); // meters
|
distance = 10 * ((data[4] & 0xFF) * 256 + (data[3] & 0xFF)); // meters
|
||||||
steps = (data[2] & 0xFF) * 256 + (data[1] & 0xFF);
|
steps = (data[2] & 0xFF) * 256 + (data[1] & 0xFF);
|
||||||
int x = (data[6] & 0xFF) * 256 + data[5] & 0xFF;
|
int x = (data[6] & 0xFF) * 256 + (data[5] & 0xFF);
|
||||||
int y = (data[8] & 0xFF) * 256 + data[7] & 0xFF;
|
int y = (data[8] & 0xFF) * 256 + (data[7] & 0xFF);
|
||||||
|
|
||||||
battery = data[9];
|
battery = data[9];
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -19,8 +18,6 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
@ -52,8 +49,6 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
private int DAY_SUMMARY_SYNC_PERIOD = 24 * 60 * 60;
|
private int DAY_SUMMARY_SYNC_PERIOD = 24 * 60 * 60;
|
||||||
private int DAY_SUMMARY_SYNC_RETRY_PERIOD = 30;
|
private int DAY_SUMMARY_SYNC_RETRY_PERIOD = 30;
|
||||||
|
|
||||||
private int HELLO_INTERVAL = 60;
|
|
||||||
|
|
||||||
private boolean mQuit = false;
|
private boolean mQuit = false;
|
||||||
private HPlusSupport mHPlusSupport;
|
private HPlusSupport mHPlusSupport;
|
||||||
|
|
||||||
@ -61,7 +56,6 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
private int mLastSlotRequested = 0;
|
private int mLastSlotRequested = 0;
|
||||||
|
|
||||||
private Calendar mLastSleepDayReceived = GregorianCalendar.getInstance();
|
private Calendar mLastSleepDayReceived = GregorianCalendar.getInstance();
|
||||||
private Calendar mHelloTime = GregorianCalendar.getInstance();
|
|
||||||
private Calendar mGetDaySlotsTime = GregorianCalendar.getInstance();
|
private Calendar mGetDaySlotsTime = GregorianCalendar.getInstance();
|
||||||
private Calendar mGetSleepTime = GregorianCalendar.getInstance();
|
private Calendar mGetSleepTime = GregorianCalendar.getInstance();
|
||||||
private Calendar mGetDaySummaryTime = GregorianCalendar.getInstance();
|
private Calendar mGetDaySummaryTime = GregorianCalendar.getInstance();
|
||||||
@ -72,7 +66,9 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
|
|
||||||
private final Object waitObject = new Object();
|
private final Object waitObject = new Object();
|
||||||
|
|
||||||
List<HPlusDataRecordDaySlot> mDaySlotSamples = new ArrayList<>();
|
List<HPlusDataRecordDaySlot> mDaySlotRecords = new ArrayList<>();
|
||||||
|
|
||||||
|
private HPlusDataRecordDaySlot mCurrentDaySlot = null;
|
||||||
|
|
||||||
public HPlusHandlerThread(GBDevice gbDevice, Context context, HPlusSupport hplusSupport) {
|
public HPlusHandlerThread(GBDevice gbDevice, Context context, HPlusSupport hplusSupport) {
|
||||||
super(gbDevice, context);
|
super(gbDevice, context);
|
||||||
@ -113,10 +109,6 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
|
|
||||||
Calendar now = GregorianCalendar.getInstance();
|
Calendar now = GregorianCalendar.getInstance();
|
||||||
|
|
||||||
if (now.compareTo(mHelloTime) > 0) {
|
|
||||||
sendHello();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now.compareTo(mGetDaySlotsTime) > 0) {
|
if (now.compareTo(mGetDaySlotsTime) > 0) {
|
||||||
requestNextDaySlots();
|
requestNextDaySlots();
|
||||||
}
|
}
|
||||||
@ -130,7 +122,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
now = GregorianCalendar.getInstance();
|
now = GregorianCalendar.getInstance();
|
||||||
waitTime = Math.min(mGetDaySummaryTime.getTimeInMillis(), Math.min(Math.min(mGetDaySlotsTime.getTimeInMillis(), mGetSleepTime.getTimeInMillis()), mHelloTime.getTimeInMillis())) - now.getTimeInMillis();
|
waitTime = Math.min(mGetDaySummaryTime.getTimeInMillis(), Math.min(mGetDaySlotsTime.getTimeInMillis(), mGetSleepTime.getTimeInMillis())) - now.getTimeInMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -152,54 +144,22 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
mSlotsInitialSync = true;
|
mSlotsInitialSync = true;
|
||||||
mLastSlotReceived = -1;
|
mLastSlotReceived = -1;
|
||||||
mLastSlotRequested = 0;
|
mLastSlotRequested = 0;
|
||||||
|
mCurrentDaySlot = null;
|
||||||
|
mDaySlotRecords.clear();
|
||||||
|
|
||||||
TransactionBuilder builder = new TransactionBuilder("startSyncDayStats");
|
TransactionBuilder builder = new TransactionBuilder("startSyncDayStats");
|
||||||
|
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DEVICE_ID});
|
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DEVICE_ID});
|
||||||
builder.wait(400);
|
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_VERSION});
|
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_VERSION});
|
||||||
builder.wait(400);
|
|
||||||
|
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_SLEEP});
|
|
||||||
builder.wait(400);
|
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DAY_DATA});
|
|
||||||
builder.wait(400);
|
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_ACTIVE_DAY});
|
|
||||||
builder.wait(400);
|
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_CURR_DATA});
|
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_CURR_DATA});
|
||||||
|
|
||||||
builder.queue(mHPlusSupport.getQueue());
|
builder.queue(mHPlusSupport.getQueue());
|
||||||
scheduleHello();
|
|
||||||
|
|
||||||
synchronized (waitObject) {
|
synchronized (waitObject) {
|
||||||
waitObject.notify();
|
waitObject.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an Hello/Null Packet to keep connection
|
|
||||||
*/
|
|
||||||
private void sendHello() {
|
|
||||||
TransactionBuilder builder = new TransactionBuilder("hello");
|
|
||||||
|
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, HPlusConstants.CMD_ACTION_HELLO);
|
|
||||||
builder.queue(mHPlusSupport.getQueue());
|
|
||||||
|
|
||||||
scheduleHello();
|
|
||||||
|
|
||||||
synchronized (waitObject) {
|
|
||||||
waitObject.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedule an Hello Packet in the future
|
|
||||||
*/
|
|
||||||
public void scheduleHello(){
|
|
||||||
mHelloTime = GregorianCalendar.getInstance();
|
|
||||||
mHelloTime.add(Calendar.SECOND, HELLO_INTERVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a message containing information regarding a day slot
|
* Process a message containing information regarding a day slot
|
||||||
* A slot summarizes 10 minutes of data
|
* A slot summarizes 10 minutes of data
|
||||||
@ -218,32 +178,56 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ignore real time messages as they are still not understood
|
|
||||||
if(!mSlotsInitialSync){
|
|
||||||
mGetDaySlotsTime.set(Calendar.SECOND, CURRENT_DAY_SYNC_PERIOD);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Calendar now = GregorianCalendar.getInstance();
|
Calendar now = GregorianCalendar.getInstance();
|
||||||
int nowSlot = now.get(Calendar.HOUR_OF_DAY) * 6 + (now.get(Calendar.MINUTE) / 10);
|
int nowSlot = now.get(Calendar.HOUR_OF_DAY) * 6 + (now.get(Calendar.MINUTE) / 10);
|
||||||
|
if(record.slot == nowSlot){
|
||||||
//If the slot is in the future, actually it is from the previous day
|
if(mCurrentDaySlot != null && mCurrentDaySlot != record){
|
||||||
//Subtract a day of seconds
|
mCurrentDaySlot.accumulate(record);
|
||||||
if(record.slot >= nowSlot){
|
mDaySlotRecords.add(mCurrentDaySlot);
|
||||||
record.timestamp -= 3600 * 24;
|
mCurrentDaySlot = null;
|
||||||
|
}else{
|
||||||
|
//Store it to a temp variable as this is an intermediate value
|
||||||
|
mCurrentDaySlot = record;
|
||||||
|
if(!mSlotsInitialSync)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ignore out of order messages
|
if(mSlotsInitialSync) {
|
||||||
if(record.slot == mLastSlotReceived + 1) {
|
|
||||||
mLastSlotReceived = record.slot;
|
//If the slot is in the future, actually it is from the previous day
|
||||||
|
//Subtract a day of seconds
|
||||||
|
if(record.slot > nowSlot){
|
||||||
|
record.timestamp -= 3600 * 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.slot == mLastSlotReceived + 1) {
|
||||||
|
mLastSlotReceived = record.slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ignore the current slot as it is incomplete
|
||||||
|
if(record.slot != nowSlot)
|
||||||
|
mDaySlotRecords.add(record);
|
||||||
|
|
||||||
|
//Still fetching ring buffer. Request the next slots
|
||||||
|
if (record.slot == mLastSlotRequested) {
|
||||||
|
mGetDaySlotsTime.clear();
|
||||||
|
synchronized (waitObject) {
|
||||||
|
waitObject.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Keep buffering
|
||||||
|
if(record.slot != 143)
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
mGetDaySlotsTime = GregorianCalendar.getInstance();
|
||||||
|
mGetDaySlotsTime.add(Calendar.DAY_OF_MONTH, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(record.slot < 143){
|
if(mDaySlotRecords.size() > 0) {
|
||||||
mDaySlotSamples.add(record);
|
|
||||||
}else {
|
|
||||||
|
|
||||||
//Sort the samples
|
//Sort the samples
|
||||||
Collections.sort(mDaySlotSamples, new Comparator<HPlusDataRecordDaySlot>() {
|
Collections.sort(mDaySlotRecords, new Comparator<HPlusDataRecordDaySlot>() {
|
||||||
public int compare(HPlusDataRecordDaySlot one, HPlusDataRecordDaySlot other) {
|
public int compare(HPlusDataRecordDaySlot one, HPlusDataRecordDaySlot other) {
|
||||||
return one.timestamp - other.timestamp;
|
return one.timestamp - other.timestamp;
|
||||||
}
|
}
|
||||||
@ -253,20 +237,20 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
HPlusHealthSampleProvider provider = new HPlusHealthSampleProvider(getDevice(), dbHandler.getDaoSession());
|
HPlusHealthSampleProvider provider = new HPlusHealthSampleProvider(getDevice(), dbHandler.getDaoSession());
|
||||||
List<HPlusHealthActivitySample> samples = new ArrayList<>();
|
List<HPlusHealthActivitySample> samples = new ArrayList<>();
|
||||||
|
|
||||||
for(HPlusDataRecordDaySlot storedRecord : mDaySlotSamples) {
|
for (HPlusDataRecordDaySlot storedRecord : mDaySlotRecords) {
|
||||||
HPlusHealthActivitySample sample = createSample(dbHandler, storedRecord.timestamp);
|
HPlusHealthActivitySample sample = createSample(dbHandler, storedRecord.timestamp);
|
||||||
|
|
||||||
sample.setRawHPlusHealthData(record.getRawData());
|
sample.setRawHPlusHealthData(storedRecord.getRawData());
|
||||||
sample.setSteps(record.steps);
|
sample.setSteps(storedRecord.steps);
|
||||||
sample.setHeartRate(record.heartRate);
|
sample.setHeartRate(storedRecord.heartRate);
|
||||||
sample.setRawKind(record.type);
|
sample.setRawKind(storedRecord.type);
|
||||||
|
|
||||||
sample.setProvider(provider);
|
sample.setProvider(provider);
|
||||||
samples.add(sample);
|
samples.add(sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.getSampleDao().insertOrReplaceInTx(samples);
|
provider.getSampleDao().insertOrReplaceInTx(samples);
|
||||||
mDaySlotSamples.clear();
|
mDaySlotRecords.clear();
|
||||||
|
|
||||||
} catch (GBException ex) {
|
} catch (GBException ex) {
|
||||||
LOG.debug((ex.getMessage()));
|
LOG.debug((ex.getMessage()));
|
||||||
@ -274,13 +258,6 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
LOG.debug(ex.getMessage());
|
LOG.debug(ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Still fetching ring buffer. Request the next slots
|
|
||||||
if (record.slot == mLastSlotRequested) {
|
|
||||||
mGetDaySlotsTime.clear();
|
|
||||||
synchronized (waitObject) {
|
|
||||||
waitObject.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -357,6 +334,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
LOG.debug((e.getMessage()));
|
LOG.debug((e.getMessage()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Skip duplicated messages as the device seems to send the same record multiple times
|
//Skip duplicated messages as the device seems to send the same record multiple times
|
||||||
//This can be used to detect the user is moving (not sleeping)
|
//This can be used to detect the user is moving (not sleeping)
|
||||||
if(prevRealTimeRecord != null && record.same(prevRealTimeRecord))
|
if(prevRealTimeRecord != null && record.same(prevRealTimeRecord))
|
||||||
@ -490,7 +468,6 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
* Messages will be provided every 10 minutes after they are available
|
* Messages will be provided every 10 minutes after they are available
|
||||||
*/
|
*/
|
||||||
private void requestNextDaySlots() {
|
private void requestNextDaySlots() {
|
||||||
|
|
||||||
Calendar now = GregorianCalendar.getInstance();
|
Calendar now = GregorianCalendar.getInstance();
|
||||||
int currentSlot = now.get(Calendar.HOUR_OF_DAY) * 6 + now.get(Calendar.MINUTE) / 10;
|
int currentSlot = now.get(Calendar.HOUR_OF_DAY) * 6 + now.get(Calendar.MINUTE) / 10;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
@ -54,6 +55,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
public BluetoothGattCharacteristic measureCharacteristic = null;
|
public BluetoothGattCharacteristic measureCharacteristic = null;
|
||||||
|
|
||||||
private HPlusHandlerThread syncHelper;
|
private HPlusHandlerThread syncHelper;
|
||||||
|
private DeviceType deviceType = DeviceType.UNKNOWN;
|
||||||
|
|
||||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
@ -65,8 +67,11 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public HPlusSupport() {
|
public HPlusSupport(DeviceType type) {
|
||||||
super(LOG);
|
super(LOG);
|
||||||
|
|
||||||
|
deviceType = type;
|
||||||
|
|
||||||
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(HPlusConstants.UUID_SERVICE_HP);
|
addSupportedService(HPlusConstants.UUID_SERVICE_HP);
|
||||||
@ -75,7 +80,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
|
||||||
broadcastManager.registerReceiver(mReceiver, intentFilter);
|
broadcastManager.registerReceiver(mReceiver, intentFilter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -107,7 +111,9 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
sendUserInfo(builder); //Sync preferences
|
sendUserInfo(builder); //Sync preferences
|
||||||
setSIT(builder); //Sync SIT Interval
|
setSIT(builder); //Sync SIT Interval
|
||||||
setCurrentDate(builder); // Sync Current Date
|
setCurrentDate(builder); // Sync Current Date
|
||||||
|
setDayOfWeek(builder);
|
||||||
setCurrentTime(builder); // Sync Current Time
|
setCurrentTime(builder); // Sync Current Time
|
||||||
|
setLanguage(builder);
|
||||||
|
|
||||||
requestDeviceInfo(builder);
|
requestDeviceInfo(builder);
|
||||||
|
|
||||||
@ -133,51 +139,69 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private HPlusSupport syncPreferences(TransactionBuilder transaction) {
|
private HPlusSupport syncPreferences(TransactionBuilder transaction) {
|
||||||
byte gender = HPlusCoordinator.getUserGender(getDevice().getAddress());
|
|
||||||
byte age = HPlusCoordinator.getUserAge(getDevice().getAddress());
|
|
||||||
byte bodyHeight = HPlusCoordinator.getUserHeight(getDevice().getAddress());
|
|
||||||
byte bodyWeight = HPlusCoordinator.getUserWeight(getDevice().getAddress());
|
|
||||||
int goal = HPlusCoordinator.getGoal(getDevice().getAddress());
|
|
||||||
byte displayTime = HPlusCoordinator.getScreenTime(getDevice().getAddress());
|
|
||||||
byte country = HPlusCoordinator.getCountry(getDevice().getAddress());
|
|
||||||
byte social = HPlusCoordinator.getSocial(getDevice().getAddress()); // ??
|
|
||||||
byte allDayHeart = HPlusCoordinator.getAllDayHR(getDevice().getAddress());
|
|
||||||
byte wrist = HPlusCoordinator.getUserWrist(getDevice().getAddress());
|
|
||||||
byte alertTimeHour = 0;
|
|
||||||
byte alertTimeMinute = 0;
|
|
||||||
|
|
||||||
if (HPlusCoordinator.getSWAlertTime(getDevice().getAddress())) {
|
if(deviceType == DeviceType.HPLUS) {
|
||||||
int t = HPlusCoordinator.getAlertTime(getDevice().getAddress());
|
byte gender = HPlusCoordinator.getUserGender(getDevice().getAddress());
|
||||||
|
byte age = HPlusCoordinator.getUserAge(getDevice().getAddress());
|
||||||
|
byte bodyHeight = HPlusCoordinator.getUserHeight(getDevice().getAddress());
|
||||||
|
byte bodyWeight = HPlusCoordinator.getUserWeight(getDevice().getAddress());
|
||||||
|
int goal = HPlusCoordinator.getGoal(getDevice().getAddress());
|
||||||
|
byte displayTime = HPlusCoordinator.getScreenTime(getDevice().getAddress());
|
||||||
|
byte country = HPlusCoordinator.getLanguage(getDevice().getAddress());
|
||||||
|
byte social = HPlusCoordinator.getSocial(getDevice().getAddress()); // ??
|
||||||
|
byte allDayHeart = HPlusCoordinator.getAllDayHR(getDevice().getAddress());
|
||||||
|
byte wrist = HPlusCoordinator.getUserWrist(getDevice().getAddress());
|
||||||
|
byte alertTimeHour = 0;
|
||||||
|
byte alertTimeMinute = 0;
|
||||||
|
|
||||||
alertTimeHour = (byte) ((t / 256) & 0xff);
|
if (HPlusCoordinator.getSWAlertTime(getDevice().getAddress())) {
|
||||||
alertTimeMinute = (byte) (t % 256);
|
int t = HPlusCoordinator.getAlertTime(getDevice().getAddress());
|
||||||
|
|
||||||
|
alertTimeHour = (byte) ((t / 256) & 0xff);
|
||||||
|
alertTimeMinute = (byte) (t % 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte unit = HPlusCoordinator.getUnit(getDevice().getAddress());
|
||||||
|
byte timemode = HPlusCoordinator.getTimeMode((getDevice().getAddress()));
|
||||||
|
|
||||||
|
transaction.write(ctrlCharacteristic, new byte[]{
|
||||||
|
HPlusConstants.CMD_SET_PREFS,
|
||||||
|
gender,
|
||||||
|
age,
|
||||||
|
bodyHeight,
|
||||||
|
bodyWeight,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
(byte) ((goal / 256) & 0xff),
|
||||||
|
(byte) (goal % 256),
|
||||||
|
displayTime,
|
||||||
|
country,
|
||||||
|
0,
|
||||||
|
social,
|
||||||
|
allDayHeart,
|
||||||
|
wrist,
|
||||||
|
0,
|
||||||
|
alertTimeHour,
|
||||||
|
alertTimeMinute,
|
||||||
|
unit,
|
||||||
|
timemode
|
||||||
|
});
|
||||||
|
|
||||||
|
}else if(deviceType == DeviceType.MAKIBESF68){
|
||||||
|
//Makibes doesn't support setting everything at once.
|
||||||
|
|
||||||
|
setGender(transaction);
|
||||||
|
setAge(transaction);
|
||||||
|
setWeight(transaction);
|
||||||
|
setHeight(transaction);
|
||||||
|
setGoal(transaction);
|
||||||
|
setLanguage(transaction);
|
||||||
|
setScreenTime(transaction);
|
||||||
|
//setAlarm(transaction, t);
|
||||||
|
setUnit(transaction);
|
||||||
|
setTimeMode(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte unit = HPlusCoordinator.getUnit(getDevice().getAddress());
|
|
||||||
byte timemode = HPlusCoordinator.getTimeMode((getDevice().getAddress()));
|
|
||||||
|
|
||||||
transaction.write(ctrlCharacteristic, new byte[]{
|
|
||||||
HPlusConstants.CMD_SET_PREFS,
|
|
||||||
gender,
|
|
||||||
age,
|
|
||||||
bodyHeight,
|
|
||||||
bodyWeight,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
(byte) ((goal / 256) & 0xff),
|
|
||||||
(byte) (goal % 256),
|
|
||||||
displayTime,
|
|
||||||
country,
|
|
||||||
0,
|
|
||||||
social,
|
|
||||||
allDayHeart,
|
|
||||||
wrist,
|
|
||||||
0,
|
|
||||||
alertTimeHour,
|
|
||||||
alertTimeMinute,
|
|
||||||
unit,
|
|
||||||
timemode
|
|
||||||
});
|
|
||||||
|
|
||||||
setAllDayHeart(transaction);
|
setAllDayHeart(transaction);
|
||||||
|
|
||||||
@ -185,7 +209,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private HPlusSupport setLanguage(TransactionBuilder transaction) {
|
private HPlusSupport setLanguage(TransactionBuilder transaction) {
|
||||||
byte value = HPlusCoordinator.getCountry(getDevice().getAddress());
|
byte value = HPlusCoordinator.getLanguage(getDevice().getAddress());
|
||||||
transaction.write(ctrlCharacteristic, new byte[]{
|
transaction.write(ctrlCharacteristic, new byte[]{
|
||||||
HPlusConstants.CMD_SET_LANGUAGE,
|
HPlusConstants.CMD_SET_LANGUAGE,
|
||||||
value
|
value
|
||||||
@ -248,13 +272,20 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
transaction.write(ctrlCharacteristic, new byte[]{
|
transaction.write(ctrlCharacteristic, new byte[]{
|
||||||
HPlusConstants.CMD_SET_WEEK,
|
HPlusConstants.CMD_SET_WEEK,
|
||||||
(byte) c.get(Calendar.DAY_OF_WEEK)
|
(byte) (c.get(Calendar.DAY_OF_WEEK) - 1)
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private HPlusSupport setSIT(TransactionBuilder transaction) {
|
private HPlusSupport setSIT(TransactionBuilder transaction) {
|
||||||
|
|
||||||
|
//Makibes F68 doesn't like this command.
|
||||||
|
//Just ignore.
|
||||||
|
if(deviceType == DeviceType.MAKIBESF68){
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
int startTime = HPlusCoordinator.getSITStartTime(getDevice().getAddress());
|
int startTime = HPlusCoordinator.getSITStartTime(getDevice().getAddress());
|
||||||
int endTime = HPlusCoordinator.getSITEndTime(getDevice().getAddress());
|
int endTime = HPlusCoordinator.getSITEndTime(getDevice().getAddress());
|
||||||
|
|
||||||
@ -646,8 +677,17 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void showIncomingCall(String name, String number) {
|
private void showIncomingCall(String name, String rawNumber) {
|
||||||
try {
|
try {
|
||||||
|
StringBuilder number = new StringBuilder();
|
||||||
|
|
||||||
|
//Clean up number as the device only accepts digits
|
||||||
|
for(char c : rawNumber.toCharArray()){
|
||||||
|
if(Character.isDigit(c)){
|
||||||
|
number.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TransactionBuilder builder = performInitialized("incomingCall");
|
TransactionBuilder builder = performInitialized("incomingCall");
|
||||||
|
|
||||||
//Enable call notifications
|
//Enable call notifications
|
||||||
|
@ -23,6 +23,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.UnknownDeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.UnknownDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.MakibesF68Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||||
@ -172,6 +173,8 @@ public class DeviceHelper {
|
|||||||
result.add(new VibratissimoCoordinator());
|
result.add(new VibratissimoCoordinator());
|
||||||
result.add(new LiveviewCoordinator());
|
result.add(new LiveviewCoordinator());
|
||||||
result.add(new HPlusCoordinator());
|
result.add(new HPlusCoordinator());
|
||||||
|
result.add(new MakibesF68Coordinator());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user