From b142add631bd685ed290a8e5c4879670658195fd Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 17 Apr 2017 23:00:16 +0200 Subject: [PATCH 1/4] Pass a GBDevice instead of GBDeviceCandidate to getBondingStyle() #651 --- .../gadgetbridge/activities/DiscoveryActivity.java | 2 +- .../gadgetbridge/devices/AbstractDeviceCoordinator.java | 2 +- .../gadgetbridge/devices/DeviceCoordinator.java | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java index b0a5f04a..6c80cf76 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java @@ -584,7 +584,7 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC startActivity(intent); } else { GBDevice device = DeviceHelper.getInstance().toSupportedDevice(deviceCandidate); - int bondingStyle = coordinator.getBondingStyle(deviceCandidate); + int bondingStyle = coordinator.getBondingStyle(device); if (bondingStyle == DeviceCoordinator.BONDING_STYLE_NONE) { LOG.info("No bonding needed, according to coordinator, so connecting right away"); connectAndFinish(device); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java index 055156a4..7c4e0412 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java @@ -121,7 +121,7 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { } @Override - public int getBondingStyle(GBDeviceCandidate deviceCandidate) { + public int getBondingStyle(GBDevice device) { return BONDING_STYLE_ASK; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index 9b74d3f7..515a6e23 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -23,7 +23,6 @@ import android.bluetooth.le.ScanFilter; import android.content.Context; import android.net.Uri; import android.os.Build; -import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -225,7 +224,7 @@ public interface DeviceCoordinator { /** * Returns how/if the given device should be bonded before connecting to it. - * @param deviceCandidate + * @param device */ - int getBondingStyle(GBDeviceCandidate deviceCandidate); + int getBondingStyle(GBDevice device); } From 9f0d260e7a3ae6459df8937a2d6ba7012fffcf94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Barraca?= Date: Tue, 18 Apr 2017 10:47:28 +0100 Subject: [PATCH 2/4] HPlus: Improve connection process (#651) * Clean HPlus services and characteristics * Improve connectivity --- .../devices/hplus/HPlusCoordinator.java | 5 + .../BluetoothPairingRequestReceiver.java | 73 ++++++++++++ .../service/DeviceCommunicationService.java | 13 +++ .../service/btle/BleNamesResolver.java | 3 + .../devices/hplus/HPlusDataRecordDaySlot.java | 4 + .../devices/hplus/HPlusHandlerThread.java | 109 +++++++++++++----- .../service/devices/hplus/HPlusSupport.java | 106 +++++++++-------- 7 files changed, 240 insertions(+), 73 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothPairingRequestReceiver.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java index 69093460..0be66cd6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java @@ -80,6 +80,11 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator { return DeviceType.UNKNOWN; } + @Override + public int getBondingStyle(GBDevice deviceCandidate){ + return BONDING_STYLE_NONE; + } + @Override public DeviceType getDeviceType() { return DeviceType.HPLUS; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothPairingRequestReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothPairingRequestReceiver.java new file mode 100644 index 00000000..f322e7f5 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothPairingRequestReceiver.java @@ -0,0 +1,73 @@ +/* Copyright (C) 2015-2017 João Paulo Barraca + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.externalevents; + +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; + +/** + * Created by jpbarraca on 13/04/2017. + */ + +public class BluetoothPairingRequestReceiver extends BroadcastReceiver { + + + private static final Logger LOG = LoggerFactory.getLogger(BluetoothConnectReceiver.class); + + final DeviceCommunicationService service; + + public BluetoothPairingRequestReceiver(DeviceCommunicationService service) { + this.service = service; + } + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + + if (!action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) { + return; + } + + GBDevice gbDevice = service.getGBDevice(); + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + if (gbDevice == null || device == null) + return; + + DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice); + try { + if (coordinator.getBondingStyle(gbDevice) == DeviceCoordinator.BONDING_STYLE_NONE) { + LOG.info("Aborting unwanted pairing request"); + abortBroadcast(); + } + } catch (Exception e) { + LOG.warn("Could not abort pairing request process"); + + } + } +} \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 7fb8a4d6..e04133e2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -44,6 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver; +import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothPairingRequestReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.MusicPlaybackReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.PebbleReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.PhoneCallReceiver; @@ -164,6 +165,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere private MusicPlaybackReceiver mMusicPlaybackReceiver = null; private TimeChangeReceiver mTimeChangeReceiver = null; private BluetoothConnectReceiver mBlueToothConnectReceiver = null; + private BluetoothPairingRequestReceiver mBlueToothPairingRequestReceiver = null; private AlarmClockReceiver mAlarmClockReceiver = null; private AlarmReceiver mAlarmReceiver = null; @@ -609,6 +611,11 @@ public class DeviceCommunicationService extends Service implements SharedPrefere mBlueToothConnectReceiver = new BluetoothConnectReceiver(this); registerReceiver(mBlueToothConnectReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED)); } + if (mBlueToothPairingRequestReceiver == null) { + mBlueToothPairingRequestReceiver = new BluetoothPairingRequestReceiver(this); + registerReceiver(mBlueToothPairingRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)); + } + if (mAlarmReceiver == null) { mAlarmReceiver = new AlarmReceiver(); registerReceiver(mAlarmReceiver, new IntentFilter("DAILY_ALARM")); @@ -645,6 +652,12 @@ public class DeviceCommunicationService extends Service implements SharedPrefere unregisterReceiver(mBlueToothConnectReceiver); mBlueToothConnectReceiver = null; } + + if (mBlueToothPairingRequestReceiver != null) { + unregisterReceiver(mBlueToothPairingRequestReceiver); + mBlueToothPairingRequestReceiver = null; + } + if (mAlarmReceiver != null) { unregisterReceiver(mAlarmReceiver); mAlarmReceiver = null; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BleNamesResolver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BleNamesResolver.java index 66d24cd4..9bdc0f88 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BleNamesResolver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BleNamesResolver.java @@ -101,6 +101,7 @@ public class BleNamesResolver { mServices.put("00001804-0000-1000-8000-00805f9b34fb", "Tx Power"); mServices.put("0000fee0-0000-3512-2118-0009af100700", "(Propr: Xiaomi MiLi Service)"); mServices.put("00001530-0000-3512-2118-0009af100700", "(Propr: Xiaomi Weight Service)"); + mServices.put("14701820-620a-3973-7c78-9cfff0876abd", "(Propr: HPLUS Service)"); mCharacteristics.put("00002a43-0000-1000-8000-00805f9b34fb", "Alert AlertCategory ID"); @@ -185,6 +186,8 @@ public class BleNamesResolver { mCharacteristics.put("00002a07-0000-1000-8000-00805f9b34fb", "Tx Power Level"); mCharacteristics.put("00002a45-0000-1000-8000-00805f9b34fb", "Unread Alert Status"); + mCharacteristics.put("14702856-620a-3973-7c78-9cfff0876abd", "(Propr: HPLUS Control)"); + mCharacteristics.put("14702853-620a-3973-7c78-9cfff0876abd", "(Propr: HPLUS Measurements)"); mValueFormats.put(Integer.valueOf(52), "32bit float"); mValueFormats.put(Integer.valueOf(50), "16bit float"); mValueFormats.put(Integer.valueOf(34), "16bit signed int"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySlot.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySlot.java index ee302582..abee8ff5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySlot.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySlot.java @@ -102,4 +102,8 @@ public class HPlusDataRecordDaySlot extends HPlusDataRecord { secondsInactive += other.secondsInactive; } + + public boolean isValid(){ + return steps != 0 || secondsInactive != 0 || heartRate != -1; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java index a8bce80e..fa8b3744 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java @@ -65,6 +65,8 @@ class HPlusHandlerThread extends GBDeviceIoThread { private int DAY_SUMMARY_SYNC_PERIOD = 24 * 60 * 60; private int DAY_SUMMARY_SYNC_RETRY_PERIOD = 30; + private int HELLO_PERIOD = 60; + private boolean mQuit = false; private HPlusSupport mHPlusSupport; @@ -76,6 +78,8 @@ class HPlusHandlerThread extends GBDeviceIoThread { private Calendar mGetSleepTime = GregorianCalendar.getInstance(); private Calendar mGetDaySummaryTime = GregorianCalendar.getInstance(); + private Calendar mHelloTime = GregorianCalendar.getInstance(); + private boolean mSlotsInitialSync = true; private HPlusDataRecordRealtime prevRealTimeRecord = null; @@ -88,7 +92,7 @@ class HPlusHandlerThread extends GBDeviceIoThread { public HPlusHandlerThread(GBDevice gbDevice, Context context, HPlusSupport hplusSupport) { super(gbDevice, context); - + LOG.info("Initializing HPlus Handler Thread"); mQuit = false; mHPlusSupport = hplusSupport; @@ -137,6 +141,10 @@ class HPlusHandlerThread extends GBDeviceIoThread { requestDaySummaryData(); } + if(now.compareTo(mHelloTime) > 0){ + sendHello(); + } + now = GregorianCalendar.getInstance(); waitTime = Math.min(mGetDaySummaryTime.getTimeInMillis(), Math.min(mGetDaySlotsTime.getTimeInMillis(), mGetSleepTime.getTimeInMillis())) - now.getTimeInMillis(); } @@ -152,10 +160,14 @@ class HPlusHandlerThread extends GBDeviceIoThread { } public void sync() { + LOG.info("HPlus: Starting data synchronization"); + mGetSleepTime.setTimeInMillis(0); mGetDaySlotsTime.setTimeInMillis(0); mGetDaySummaryTime.setTimeInMillis(0); mLastSleepDayReceived.setTimeInMillis(0); + mHelloTime = GregorianCalendar.getInstance(); + mHelloTime.add(Calendar.SECOND, HELLO_PERIOD); mSlotsInitialSync = true; mLastSlotReceived = -1; @@ -163,19 +175,41 @@ class HPlusHandlerThread extends GBDeviceIoThread { mCurrentDaySlot = null; mDaySlotRecords.clear(); - TransactionBuilder builder = new TransactionBuilder("startSyncDayStats"); + try { + if(!mHPlusSupport.isConnected()) + mHPlusSupport.connect(); - builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DEVICE_ID}); - builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_VERSION}); - builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_CURR_DATA}); + TransactionBuilder builder = new TransactionBuilder("startSyncDayStats"); - builder.queue(mHPlusSupport.getQueue()); + builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DEVICE_ID}); + builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_VERSION}); + builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_CURR_DATA}); + + builder.queue(mHPlusSupport.getQueue()); + }catch(Exception e){ + + } synchronized (waitObject) { waitObject.notify(); } } + public void sendHello(){ + try { + if(!mHPlusSupport.isConnected()) + mHPlusSupport.connect(); + + TransactionBuilder builder = new TransactionBuilder("hello"); + builder.write(mHPlusSupport.ctrlCharacteristic, HPlusConstants.CMD_ACTION_HELLO); + builder.queue(mHPlusSupport.getQueue()); + }catch(Exception e){ + + } + mHelloTime = GregorianCalendar.getInstance(); + mHelloTime.add(Calendar.SECOND, HELLO_PERIOD); + + } /** * Process a message containing information regarding a day slot * A slot summarizes 10 minutes of data @@ -190,7 +224,7 @@ class HPlusHandlerThread extends GBDeviceIoThread { try{ record = new HPlusDataRecordDaySlot(data); } catch(IllegalArgumentException e){ - LOG.debug((e.getMessage())); + LOG.info((e.getMessage())); return false; } @@ -254,6 +288,11 @@ class HPlusHandlerThread extends GBDeviceIoThread { List samples = new ArrayList<>(); for (HPlusDataRecordDaySlot storedRecord : mDaySlotRecords) { + + //Invalid records (no data) will be ignored + if(!storedRecord.isValid()) + continue; + HPlusHealthActivitySample sample = createSample(dbHandler, storedRecord.timestamp); sample.setRawHPlusHealthData(storedRecord.getRawData()); @@ -269,9 +308,9 @@ class HPlusHandlerThread extends GBDeviceIoThread { mDaySlotRecords.clear(); } catch (GBException ex) { - LOG.debug((ex.getMessage())); + LOG.info((ex.getMessage())); } catch (Exception ex) { - LOG.debug(ex.getMessage()); + LOG.info(ex.getMessage()); } } @@ -293,7 +332,7 @@ class HPlusHandlerThread extends GBDeviceIoThread { try{ record = new HPlusDataRecordSleep(data); } catch(IllegalArgumentException e){ - LOG.debug((e.getMessage())); + LOG.info((e.getMessage())); return false; } @@ -326,7 +365,7 @@ class HPlusHandlerThread extends GBDeviceIoThread { provider.addGBActivitySample(sample); } catch (Exception ex) { - LOG.debug(ex.getMessage()); + LOG.info(ex.getMessage()); } mGetSleepTime = GregorianCalendar.getInstance(); @@ -347,7 +386,7 @@ class HPlusHandlerThread extends GBDeviceIoThread { try{ record = new HPlusDataRecordRealtime(data); } catch(IllegalArgumentException e){ - LOG.debug((e.getMessage())); + LOG.info((e.getMessage())); return false; } @@ -397,9 +436,9 @@ class HPlusHandlerThread extends GBDeviceIoThread { //TODO: Handle Active Time. With Overlay? } catch (GBException ex) { - LOG.debug((ex.getMessage())); + LOG.info((ex.getMessage())); } catch (Exception ex) { - LOG.debug(ex.getMessage()); + LOG.info(ex.getMessage()); } return true; } @@ -417,7 +456,7 @@ class HPlusHandlerThread extends GBDeviceIoThread { try{ record = new HPlusDataRecordDaySummary(data); } catch(IllegalArgumentException e){ - LOG.debug((e.getMessage())); + LOG.info((e.getMessage())); return false; } @@ -437,9 +476,9 @@ class HPlusHandlerThread extends GBDeviceIoThread { sample.setProvider(provider); provider.addGBActivitySample(sample); } catch (GBException ex) { - LOG.debug((ex.getMessage())); + LOG.info((ex.getMessage())); } catch (Exception ex) { - LOG.debug(ex.getMessage()); + LOG.info(ex.getMessage()); } mGetDaySummaryTime = GregorianCalendar.getInstance(); @@ -468,10 +507,16 @@ class HPlusHandlerThread extends GBDeviceIoThread { * Issue a message requesting the next batch of sleep data */ private void requestNextSleepData() { - TransactionBuilder builder = new TransactionBuilder("requestSleepStats"); - builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_SLEEP}); - builder.queue(mHPlusSupport.getQueue()); + try { + if(!mHPlusSupport.isConnected()) + mHPlusSupport.connect(); + TransactionBuilder builder = new TransactionBuilder("requestSleepStats"); + builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_SLEEP}); + builder.queue(mHPlusSupport.getQueue()); + }catch(Exception e){ + + } mGetSleepTime = GregorianCalendar.getInstance(); mGetSleepTime.add(GregorianCalendar.SECOND, SLEEP_SYNC_RETRY_PERIOD); @@ -519,19 +564,31 @@ class HPlusHandlerThread extends GBDeviceIoThread { mLastSlotRequested = nextHour * 6 + (nextMinute / 10); byte[] msg = new byte[]{HPlusConstants.CMD_GET_ACTIVE_DAY, hour, minute, nextHour, nextMinute}; + try { + if(!mHPlusSupport.isConnected()) + mHPlusSupport.connect(); - TransactionBuilder builder = new TransactionBuilder("getNextDaySlot"); - builder.write(mHPlusSupport.ctrlCharacteristic, msg); - builder.queue(mHPlusSupport.getQueue()); + TransactionBuilder builder = new TransactionBuilder("getNextDaySlot"); + builder.write(mHPlusSupport.ctrlCharacteristic, msg); + builder.queue(mHPlusSupport.getQueue()); + }catch(Exception e){ + + } } /** * Request a batch of data with the summary of the previous days */ public void requestDaySummaryData(){ - TransactionBuilder builder = new TransactionBuilder("startSyncDaySummary"); - builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DAY_DATA}); - builder.queue(mHPlusSupport.getQueue()); + try { + if(!mHPlusSupport.isConnected()) + mHPlusSupport.connect(); + TransactionBuilder builder = new TransactionBuilder("startSyncDaySummary"); + builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DAY_DATA}); + builder.queue(mHPlusSupport.getQueue()); + }catch(Exception e){ + + } mGetDaySummaryTime = GregorianCalendar.getInstance(); mGetDaySummaryTime.add(Calendar.SECOND, DAY_SUMMARY_SYNC_RETRY_PERIOD); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 805c952f..3cb3a881 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -94,8 +94,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { deviceType = type; - addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS); - addSupportedService(GattService.UUID_SERVICE_GENERIC_ATTRIBUTE); addSupportedService(HPlusConstants.UUID_SERVICE_HP); LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext()); @@ -106,7 +104,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void dispose() { - LOG.debug("Dispose"); + LOG.info("Dispose"); LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext()); broadcastManager.unregisterReceiver(mReceiver); @@ -117,7 +115,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override protected TransactionBuilder initializeDevice(TransactionBuilder builder) { - LOG.debug("Initializing"); + LOG.info("Initializing"); builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); @@ -424,7 +422,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void onNotification(NotificationSpec notificationSpec) { //TODO: Show different notifications according to source as Band supports this - //LOG.debug("OnNotification: Title: "+notificationSpec.title+" Body: "+notificationSpec.body+" Source: "+notificationSpec.sourceName+" Sender: "+notificationSpec.sender+" Subject: "+notificationSpec.subject); + //LOG.info("OnNotification: Title: "+notificationSpec.title+" Body: "+notificationSpec.body+" Source: "+notificationSpec.sourceName+" Sender: "+notificationSpec.sender+" Subject: "+notificationSpec.subject); showText(notificationSpec.title, notificationSpec.body); } @@ -435,40 +433,46 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void onSetTime() { - TransactionBuilder builder = new TransactionBuilder("time"); + try { + TransactionBuilder builder = performInitialized("time"); - setCurrentDate(builder); - setCurrentTime(builder); + setCurrentDate(builder); + setCurrentTime(builder); - builder.queue(getQueue()); + builder.queue(getQueue()); + }catch(IOException e){ + + } } @Override public void onSetAlarms(ArrayList alarms) { + try { + TransactionBuilder builder = performInitialized("alarm"); - TransactionBuilder builder = new TransactionBuilder("alarm"); + for (Alarm alarm : alarms) { - for (Alarm alarm : alarms) { + if (!alarm.isEnabled()) + continue; - if (!alarm.isEnabled()) - continue; + if (alarm.isSmartWakeup()) //Not available + continue; - if (alarm.isSmartWakeup()) //Not available - continue; + Calendar t = alarm.getAlarmCal(); + setAlarm(builder, t); + builder.queue(getQueue()); - Calendar t = alarm.getAlarmCal(); - setAlarm(builder, t); + GB.toast(getContext(), getContext().getString(R.string.user_feedback_miband_set_alarms_ok), Toast.LENGTH_SHORT, GB.INFO); + + return; //Only first alarm + } + + setAlarm(builder, null); builder.queue(getQueue()); - GB.toast(getContext(), getContext().getString(R.string.user_feedback_miband_set_alarms_ok), Toast.LENGTH_SHORT, GB.INFO); + GB.toast(getContext(), getContext().getString(R.string.user_feedback_all_alarms_disabled), Toast.LENGTH_SHORT, GB.INFO); + }catch(Exception e){} - return; //Only first alarm - } - - setAlarm(builder, null); - builder.queue(getQueue()); - - GB.toast(getContext(), getContext().getString(R.string.user_feedback_all_alarms_disabled), Toast.LENGTH_SHORT, GB.INFO); } @@ -485,7 +489,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { - LOG.debug("Canned Messages: " + cannedMessagesSpec); + LOG.info("Canned Messages: " + cannedMessagesSpec); } @Override @@ -541,39 +545,47 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void onReboot() { - getQueue().clear(); + try { + getQueue().clear(); - TransactionBuilder builder = new TransactionBuilder("Shutdown"); - builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SHUTDOWN, HPlusConstants.ARG_SHUTDOWN_EN}); - builder.queue(getQueue()); + TransactionBuilder builder = performInitialized("Shutdown"); + builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SHUTDOWN, HPlusConstants.ARG_SHUTDOWN_EN}); + builder.queue(getQueue()); + }catch(Exception e){ + } } @Override public void onHeartRateTest() { getQueue().clear(); + try{ + TransactionBuilder builder = performInitialized("HeartRateTest"); - TransactionBuilder builder = new TransactionBuilder("HeartRateTest"); + builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_HEARTRATE_STATE, HPlusConstants.ARG_HEARTRATE_MEASURE_ON}); //Set Real Time... ? + builder.queue(getQueue()); + }catch(Exception e){ - builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_HEARTRATE_STATE, HPlusConstants.ARG_HEARTRATE_MEASURE_ON}); //Set Real Time... ? - builder.queue(getQueue()); + } } @Override public void onEnableRealtimeHeartRateMeasurement(boolean enable) { getQueue().clear(); + try { + TransactionBuilder builder = performInitialized("realTimeHeartMeasurement"); + byte state; - TransactionBuilder builder = new TransactionBuilder("realTimeHeartMeasurement"); - byte state; + if (enable) + state = HPlusConstants.ARG_HEARTRATE_ALLDAY_ON; + else + state = HPlusConstants.ARG_HEARTRATE_ALLDAY_OFF; - if (enable) - state = HPlusConstants.ARG_HEARTRATE_ALLDAY_ON; - else - state = HPlusConstants.ARG_HEARTRATE_ALLDAY_OFF; - - builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_ALLDAY_HRM, state}); - builder.queue(getQueue()); + builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_ALLDAY_HRM, state}); + builder.queue(getQueue()); + }catch(Exception e){ + } } @Override @@ -632,13 +644,13 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void onSendConfiguration(String config) { - LOG.debug("Send Configuration: " + config); + LOG.info("Send Configuration: " + config); } @Override public void onTestNewFunction() { - LOG.debug("Test New Function"); + LOG.info("Test New Function"); } @Override @@ -706,7 +718,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private void showText(String title, String body) { - LOG.debug("Show Notification: " + title + " --> " + body); + try { TransactionBuilder builder = performInitialized("notification"); @@ -844,7 +856,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { return syncHelper.processIncomingDaySlotData(data); default: - LOG.debug("Unhandled characteristic changed: " + characteristicUUID); + LOG.info("Unhandled characteristic change: " + characteristicUUID + " code: " + data[0]); return true; } } @@ -878,7 +890,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { getDevice().addDeviceInfo(new GenericItem("", info)); } } catch (IllegalArgumentException e) { - LOG.debug((e.getMessage())); + LOG.info((e.getMessage())); } } From 9decb7788b58ec92686fef094879408a3a1096b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Paulo=20Barraca?= Date: Tue, 18 Apr 2017 10:51:49 +0100 Subject: [PATCH 3/4] HPlus: use HR translated string --- .../gadgetbridge/service/devices/hplus/HPlusSupport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 3cb3a881..a67a0dd8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -870,7 +870,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { String DEVINFO_STEP = getContext().getString(R.string.chart_steps) + ": "; String DEVINFO_DISTANCE = getContext().getString(R.string.distance) + ": "; String DEVINFO_CALORY = getContext().getString(R.string.calories) + ": "; - String DEVINFO_HEART = "HR: "; + String DEVINFO_HEART = getContext().getString(R.string.charts_legend_heartrate); String info = ""; if (record.steps > 0) { From 18157daf468a7203e88b86da068abc7a9bc8c86e Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Wed, 19 Apr 2017 13:23:13 +0200 Subject: [PATCH 4/4] Ensure that the Notification listener service gets restarted if crashed. This change adds an additional service that checks the status of the NotificationListenerService, and restarts it if it's stale/crashed. Crashes happen mostly during development, but were reported also by users. --- app/src/main/AndroidManifest.xml | 1 + .../gadgetbridge/GBApplication.java | 3 + .../NotificationCollectorMonitorService.java | 79 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/NotificationCollectorMonitorService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b15323fc..140de6d7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -251,6 +251,7 @@ + runningServices = manager.getRunningServices(Integer.MAX_VALUE); + if (runningServices == null) { + LOG.info("ensureCollectorRunning() runningServices is NULL"); + return; + } + for (ActivityManager.RunningServiceInfo service : runningServices) { + if (service.service.equals(collectorComponent)) { + LOG.warn("ensureCollectorRunning service - pid: " + service.pid + ", currentPID: " + Process.myPid() + ", clientPackage: " + service.clientPackage + ", clientCount: " + service.clientCount + + ", clientLabel: " + ((service.clientLabel == 0) ? "0" : "(" + getResources().getString(service.clientLabel) + ")")); + if (service.pid == Process.myPid() /*&& service.clientCount > 0 && !TextUtils.isEmpty(service.clientPackage)*/) { + collectorRunning = true; + } + } + } + if (collectorRunning) { + LOG.debug("ensureCollectorRunning: collector is running"); + return; + } + LOG.debug("ensureCollectorRunning: collector not running, reviving..."); + toggleNotificationListenerService(); + } + + private void toggleNotificationListenerService() { + LOG.debug("toggleNotificationListenerService() called"); + ComponentName thisComponent = new ComponentName(this, NotificationListener.class); + PackageManager pm = getPackageManager(); + pm.setComponentEnabledSetting(thisComponent, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); + pm.setComponentEnabledSetting(thisComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); + + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } +} \ No newline at end of file