mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-07 11:53:07 +02:00
Bluetooth LE: implemented cycling cadence and speed sensors.
Cadence is working while speed still requires the wheel size.
This commit is contained in:
@@ -45,6 +45,7 @@ import de.dennisguse.opentracks.TrackDetailActivity;
|
||||
import de.dennisguse.opentracks.TrackListActivity;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.data.TrackPointSensorDataSet;
|
||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.content.provider.CustomContentProvider;
|
||||
@@ -575,7 +576,7 @@ public class TrackRecordingService extends Service {
|
||||
return;
|
||||
}
|
||||
|
||||
TrackPoint trackPoint = new TrackPoint(location, getSensorDataSet());
|
||||
TrackPoint trackPoint = new TrackPoint(location, getTrackPointSensorDataSet());
|
||||
notificationManager.updateTrackPoint(this, trackPoint, recordingGpsAccuracy);
|
||||
|
||||
if (!TrackPointUtils.fulfillsAccuracy(trackPoint, recordingGpsAccuracy)) {
|
||||
@@ -708,10 +709,20 @@ public class TrackRecordingService extends Service {
|
||||
}
|
||||
|
||||
SensorDataSet getSensorDataSet() {
|
||||
if (remoteSensorManager == null || !remoteSensorManager.isEnabled() || !remoteSensorManager.isSensorDataSetValid()) {
|
||||
if (remoteSensorManager == null || !remoteSensorManager.isEnabled()) {
|
||||
return null;
|
||||
}
|
||||
return remoteSensorManager.getSensorDataSet();
|
||||
|
||||
return remoteSensorManager.getSensorData();
|
||||
}
|
||||
|
||||
TrackPointSensorDataSet getTrackPointSensorDataSet() {
|
||||
SensorDataSet sensorData = getSensorDataSet();
|
||||
if (sensorData != null) {
|
||||
return sensorData.createTrackPointSensorDataSet();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void registerLocationListener() {
|
||||
|
||||
@@ -95,8 +95,13 @@ public interface TrackRecordingServiceInterface {
|
||||
long insertWaypoint(String name, String category, String description, String photoUrl);
|
||||
|
||||
/**
|
||||
* ONLY FOR TESTING
|
||||
* Gets the current sensor data. Returns null if there is no data.
|
||||
*
|
||||
* @return SensorDataSet object.
|
||||
*/
|
||||
SensorDataSet getSensorData();
|
||||
|
||||
/**
|
||||
* Inserts a location in the current recording track.
|
||||
* <p>
|
||||
* When recording a track, GPS locations are automatically inserted.
|
||||
@@ -107,13 +112,6 @@ public interface TrackRecordingServiceInterface {
|
||||
@VisibleForTesting
|
||||
void insertLocation(Location location);
|
||||
|
||||
/**
|
||||
* Gets the current sensor data. Returns null if there is no data.
|
||||
*
|
||||
* @return SensorDataSet object.
|
||||
*/
|
||||
SensorDataSet getSensorData();
|
||||
|
||||
/**
|
||||
* Disables processing of location updates from {@link android.location.LocationManager}.
|
||||
*/
|
||||
|
||||
+90
-52
@@ -30,27 +30,24 @@ import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorState;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorData;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataHeartRate;
|
||||
import de.dennisguse.opentracks.util.BluetoothUtils;
|
||||
|
||||
/**
|
||||
* Manages connection to Bluetooth LE heart rate monitor.
|
||||
* Manages connection to a Bluetooth LE sensor and subscribes for onChange-notifications.
|
||||
* Also parses the transferred data into {@link SensorDataObserver}.
|
||||
*/
|
||||
public class BluetoothConnectionManager {
|
||||
|
||||
private static final UUID HEART_RATE_MEASUREMENT_CHAR_UUID = new UUID(0x2A3700001000L, 0x800000805f9b34fbL);
|
||||
private static final UUID CLIENT_CHARACTERISTIC_CONFIG_UUID = new UUID(0x290200001000L, 0x800000805f9b34fbL);
|
||||
public abstract class BluetoothConnectionManager {
|
||||
|
||||
private static final String TAG = BluetoothConnectionManager.class.getSimpleName();
|
||||
|
||||
private final Context context;
|
||||
private final EventCallback observer;
|
||||
|
||||
private SensorState sensorState;
|
||||
private final SensorDataObserver observer;
|
||||
|
||||
private final UUID serviceUUUID;
|
||||
private final UUID measurementUUID;
|
||||
private BluetoothGatt bluetoothGatt;
|
||||
private final BluetoothDevice bluetoothDevice;
|
||||
|
||||
private final BluetoothGattCallback connectCallback = new BluetoothGattCallback() {
|
||||
@Override
|
||||
@@ -58,80 +55,70 @@ public class BluetoothConnectionManager {
|
||||
switch (newState) {
|
||||
case BluetoothProfile.STATE_CONNECTING:
|
||||
Log.d(TAG, "Connecting to sensor: " + gatt.getDevice());
|
||||
setState(SensorState.CONNECTING);
|
||||
|
||||
observer.connecting(gatt.getDevice().getName());
|
||||
case BluetoothProfile.STATE_CONNECTED:
|
||||
Log.d(TAG, "Connected to sensor: " + gatt.getDevice());
|
||||
setState(SensorState.CONNECTED);
|
||||
|
||||
gatt.discoverServices();
|
||||
|
||||
observer.connected(gatt.getDevice().getName());
|
||||
break;
|
||||
case BluetoothProfile.STATE_DISCONNECTING:
|
||||
Log.d(TAG, "Disconnecting from sensor: " + gatt.getDevice());
|
||||
setState(SensorState.DISCONNECTING);
|
||||
|
||||
case BluetoothProfile.STATE_DISCONNECTED:
|
||||
Log.d(TAG, "Disconnected from sensor: " + gatt.getDevice());
|
||||
setState(SensorState.DISCONNECTED);
|
||||
|
||||
observer.disconnected(gatt.getDevice().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServicesDiscovered(@NonNull BluetoothGatt gatt, int status) {
|
||||
BluetoothGattService service = gatt.getService(BluetoothUtils.HEART_RATE_SERVICE_UUID);
|
||||
BluetoothGattService service = gatt.getService(serviceUUUID);
|
||||
if (service == null) {
|
||||
Log.e(TAG, "Could not get heart rate service for " + gatt.getDevice().getAddress());
|
||||
Log.e(TAG, "Could not get service for address=" + gatt.getDevice().getAddress() + " serviceUUID=" + serviceUUUID);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BluetoothGattCharacteristic characteristic = service.getCharacteristic(HEART_RATE_MEASUREMENT_CHAR_UUID);
|
||||
BluetoothGattCharacteristic characteristic = service.getCharacteristic(measurementUUID);
|
||||
if (characteristic == null) {
|
||||
Log.e(TAG, "Could not get BluetoothCharacteristic for " + gatt.getDevice().getAddress());
|
||||
Log.e(TAG, "Could not get BluetoothCharacteristic for address=" + gatt.getDevice().getAddress() + " serviceUUID=" + serviceUUUID + " characteristicUUID=" + measurementUUID);
|
||||
return;
|
||||
}
|
||||
gatt.setCharacteristicNotification(characteristic, true);
|
||||
|
||||
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID);
|
||||
// Register for updates.
|
||||
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(BluetoothUtils.CLIENT_CHARACTERISTIC_CONFIG_UUID);
|
||||
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
|
||||
gatt.writeDescriptor(descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCharacteristicChanged(BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic) {
|
||||
int heartRate = BluetoothUtils.parseHeartRate(characteristic);
|
||||
String deviceName = gatt.getDevice().getName();
|
||||
String sensorName = gatt.getDevice().getName();
|
||||
Log.d(TAG, "Received data from " + sensorName);
|
||||
|
||||
Log.d(TAG, "Received heart beat rate " + deviceName + ": " + heartRate);
|
||||
observer.onSensorDataReceived(new SensorDataSet(heartRate, deviceName, gatt.getDevice().getAddress()));
|
||||
SensorData sensorData = parsePayload(sensorName, gatt.getDevice().getAddress(), characteristic);
|
||||
if (sensorData != null) {
|
||||
observer.onChanged(sensorData);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BluetoothConnectionManager(@NonNull Context context, @NonNull BluetoothDevice bluetoothDevice, EventCallback observer) {
|
||||
this.context = context;
|
||||
this.bluetoothDevice = bluetoothDevice;
|
||||
this.sensorState = SensorState.NONE;
|
||||
BluetoothConnectionManager(UUID serviceUUUID, UUID measurementUUID, SensorDataObserver observer) {
|
||||
this.serviceUUUID = serviceUUUID;
|
||||
this.measurementUUID = measurementUUID;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
public synchronized void connect() {
|
||||
synchronized void connect(Context context, @NonNull BluetoothDevice device) {
|
||||
if (bluetoothGatt != null) {
|
||||
Log.w(TAG, "Already connected; ignoring.");
|
||||
}
|
||||
|
||||
Log.d(TAG, "Connecting to: " + bluetoothDevice);
|
||||
Log.d(TAG, "Connecting to: " + device);
|
||||
|
||||
bluetoothGatt = bluetoothDevice.connectGatt(this.context, true, this.connectCallback);
|
||||
bluetoothGatt = device.connectGatt(context, true, this.connectCallback);
|
||||
|
||||
setState(SensorState.CONNECTING);
|
||||
}
|
||||
|
||||
public synchronized void disconnect() {
|
||||
synchronized void disconnect() {
|
||||
if (bluetoothGatt == null) {
|
||||
Log.w(TAG, "Cannot disconnect if not connected.");
|
||||
return;
|
||||
@@ -140,27 +127,78 @@ public class BluetoothConnectionManager {
|
||||
bluetoothGatt = null;
|
||||
}
|
||||
|
||||
public synchronized boolean isSameBluetoothDevice(String address) {
|
||||
return this.bluetoothDevice.getAddress().equals(address);
|
||||
synchronized boolean isSameBluetoothDevice(String address) {
|
||||
if (bluetoothGatt == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return address.equals(bluetoothGatt.getDevice().getAddress());
|
||||
}
|
||||
|
||||
synchronized SensorState getSensorState() {
|
||||
return sensorState;
|
||||
/**
|
||||
* @return null if data could not be parsed.
|
||||
*/
|
||||
protected abstract de.dennisguse.opentracks.content.sensor.SensorData parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic);
|
||||
|
||||
public static class HeartRate extends BluetoothConnectionManager {
|
||||
|
||||
HeartRate(@NonNull SensorDataObserver observer) {
|
||||
super(BluetoothUtils.HEART_RATE_SERVICE_UUID, BluetoothUtils.HEART_RATE_MEASUREMENT_CHAR_UUID, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SensorDataHeartRate parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) {
|
||||
Integer heartRate = BluetoothUtils.parseHeartRate(characteristic);
|
||||
|
||||
return heartRate != null ? new SensorDataHeartRate(address, sensorName, heartRate) : null;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void setState(SensorState sensorState) {
|
||||
this.sensorState = sensorState;
|
||||
public static class CyclingCadence extends BluetoothConnectionManager {
|
||||
|
||||
CyclingCadence(SensorDataObserver observer) {
|
||||
super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPPED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SensorDataCycling.Cadence parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) {
|
||||
SensorDataCycling.CadenceAndSpeed cadenceAndSpeed = BluetoothUtils.parseCyclingCrankAndWheel(address, sensorName, characteristic);
|
||||
if (cadenceAndSpeed == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cadenceAndSpeed.getCadence() != null) {
|
||||
return cadenceAndSpeed.getCadence();
|
||||
}
|
||||
|
||||
//Workaround for Wahoo CADENCE: this sensor reports speed (instead of cadence)
|
||||
if (cadenceAndSpeed.getSpeed() != null) {
|
||||
return new SensorDataCycling.Cadence(cadenceAndSpeed.getSpeed());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CyclingSpeed extends BluetoothConnectionManager {
|
||||
|
||||
interface EventCallback {
|
||||
CyclingSpeed(SensorDataObserver observer) {
|
||||
super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPPED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
|
||||
}
|
||||
|
||||
void connecting(String sensorName);
|
||||
@Override
|
||||
protected SensorDataCycling.Speed parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) {
|
||||
SensorDataCycling.CadenceAndSpeed cadenceAndSpeed = BluetoothUtils.parseCyclingCrankAndWheel(address, sensorName, characteristic);
|
||||
if (cadenceAndSpeed != null) {
|
||||
return cadenceAndSpeed.getSpeed();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void connected(String sensorName);
|
||||
interface SensorDataObserver {
|
||||
|
||||
void onSensorDataReceived(SensorDataSet sensorDataSet);
|
||||
void onChanged(SensorData sensorData);
|
||||
|
||||
void disconnected(String sensorName);
|
||||
}
|
||||
}
|
||||
|
||||
+78
-67
@@ -21,53 +21,72 @@ import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
import de.dennisguse.opentracks.util.BluetoothUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.util.UnitConversions;
|
||||
|
||||
/**
|
||||
* Bluetooth LE sensor manager.
|
||||
* Should only be instantiated once!
|
||||
* Bluetooth LE sensor manager: manages connections to Bluetooth LE sensors.
|
||||
*
|
||||
* Note: should only be instantiated once.
|
||||
*
|
||||
* TODO: listen for Bluetooth enabled/disabled events.
|
||||
*
|
||||
* TODO: In case, a cycling (Cadence and Speed) sensor reports both values, testing is required.
|
||||
* We establish two GATT separate GATT connections (as if two different sensors were used).
|
||||
* However, it is not clear if this is allowed.
|
||||
* Even if this works, it is not clear what happens if a user (while recording) changes one of the sensors in the settings as this will trigger a disconnect of one GATT.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.EventCallback {
|
||||
public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.SensorDataObserver {
|
||||
|
||||
public static final long MAX_SENSOR_DATE_SET_AGE_MS = 5000;
|
||||
private static final String TAG = BluetoothRemoteSensorManager.class.getSimpleName();
|
||||
|
||||
private static final String TAG = BluetoothConnectionManager.class.getSimpleName();
|
||||
public static final long MAX_SENSOR_DATE_SET_AGE_MS = 5 * UnitConversions.S_TO_MS;
|
||||
|
||||
private static final BluetoothAdapter bluetoothAdapter = BluetoothUtils.getDefaultBluetoothAdapter(TAG);
|
||||
|
||||
private final Context context;
|
||||
|
||||
private final SharedPreferences sharedPreferences;
|
||||
|
||||
private boolean started = false;
|
||||
|
||||
private final BluetoothConnectionManager heartRate = new BluetoothConnectionManager.HeartRate(this);
|
||||
private final BluetoothConnectionManager cyclingCadence = new BluetoothConnectionManager.CyclingCadence(this);
|
||||
|
||||
private final SensorDataSet sensorDataSet = new SensorDataSet();
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (bluetoothConnectionManager != null && PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_heart_rate_key, key)) {
|
||||
if (PreferencesUtils.isBluetoothHeartRateSensorAddressDefault(context)) {
|
||||
if (!started) return;
|
||||
|
||||
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_heart_rate_key, key)) {
|
||||
if (PreferencesUtils.isBluetoothHeartRateSensorAddressNone(context)) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
String address = PreferencesUtils.getBluetoothHeartRateSensorAddress(context);
|
||||
if (bluetoothConnectionManager.isSameBluetoothDevice(address)) {
|
||||
connect(heartRate, address);
|
||||
}
|
||||
|
||||
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_cadence_key, key)) {
|
||||
if (PreferencesUtils.isBluetoothCyclingCadenceSensorAddressNone(context)) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
String address = PreferencesUtils.getBluetoothCyclingCadenceSensorAddress(context);
|
||||
|
||||
disconnect();
|
||||
startCurrentSensor();
|
||||
connect(cyclingCadence, address);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private SensorDataSet sensorDataSet = null;
|
||||
private BluetoothConnectionManager bluetoothConnectionManager;
|
||||
|
||||
/**
|
||||
* @param context the context
|
||||
*/
|
||||
@@ -77,84 +96,76 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
|
||||
}
|
||||
|
||||
public void start() {
|
||||
started = true;
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
startCurrentSensor();
|
||||
|
||||
//Trigger connection startup
|
||||
sharedPreferenceChangeListener.onSharedPreferenceChanged(null, null);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
disconnect();
|
||||
public synchronized void stop() {
|
||||
// Disconnecting
|
||||
heartRate.disconnect();
|
||||
cyclingCadence.disconnect();
|
||||
|
||||
sensorDataSet.clear();
|
||||
|
||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
started = false;
|
||||
}
|
||||
|
||||
|
||||
public boolean isEnabled() {
|
||||
return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
|
||||
}
|
||||
|
||||
public SensorDataSet getSensorDataSet() {
|
||||
return sensorDataSet;
|
||||
}
|
||||
|
||||
public boolean isSensorDataSetValid() {
|
||||
SensorDataSet sensorDataSet = getSensorDataSet();
|
||||
if (sensorDataSet == null) {
|
||||
return false;
|
||||
}
|
||||
return sensorDataSet.isRecent(MAX_SENSOR_DATE_SET_AGE_MS);
|
||||
}
|
||||
|
||||
private void startCurrentSensor() {
|
||||
private synchronized void connect(BluetoothConnectionManager connectionManager, String address) {
|
||||
if (!isEnabled()) {
|
||||
Log.w(TAG, "Bluetooth not enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (PreferencesUtils.isBluetoothHeartRateSensorAddressDefault(context)) {
|
||||
Log.w(TAG, "No bluetooth address.");
|
||||
if (PreferencesUtils.isBluetoothSensorAddressNone(context, address)) {
|
||||
Log.w(TAG, "No Bluetooth address.");
|
||||
return;
|
||||
}
|
||||
String address = PreferencesUtils.getBluetoothHeartRateSensorAddress(context);
|
||||
|
||||
// Check if there is an ongoing connection; if yes, check if the address changed.
|
||||
if (connectionManager.isSameBluetoothDevice(address)) {
|
||||
return;
|
||||
} else {
|
||||
connectionManager.disconnect();
|
||||
}
|
||||
|
||||
Log.i(TAG, "Connecting to bluetooth address: " + address);
|
||||
|
||||
BluetoothDevice device;
|
||||
try {
|
||||
device = bluetoothAdapter.getRemoteDevice(address);
|
||||
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
|
||||
connectionManager.connect(context, device);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.w(TAG, "Unable to get remote device for: " + address, e);
|
||||
|
||||
String toastMessage = context.getString(R.string.sensor_not_known, address);
|
||||
Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
disconnect();
|
||||
|
||||
bluetoothConnectionManager = new BluetoothConnectionManager(context, device, this);
|
||||
bluetoothConnectionManager.connect();
|
||||
}
|
||||
|
||||
private void disconnect() {
|
||||
if (bluetoothConnectionManager != null) {
|
||||
bluetoothConnectionManager.disconnect();
|
||||
bluetoothConnectionManager = null;
|
||||
Log.e(TAG, "Unable to get remote device for: " + address, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connecting(String sensorName) {
|
||||
public SensorDataSet getSensorData() {
|
||||
return sensorDataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(String sensorName) {
|
||||
}
|
||||
public synchronized void onChanged(de.dennisguse.opentracks.content.sensor.SensorData sensorData) {
|
||||
if (sensorData instanceof SensorDataCycling.Cadence) {
|
||||
if (sensorData.equals(sensorDataSet.getCyclingCadence())) {
|
||||
Log.d(TAG, "onChanged: cadence data repeated.");
|
||||
return;
|
||||
}
|
||||
((SensorDataCycling.Cadence) sensorData).compute(sensorDataSet.getCyclingCadence());
|
||||
}
|
||||
if (sensorData instanceof SensorDataCycling.Speed) {
|
||||
if (sensorData.equals(sensorDataSet.getCyclingSpeed())) {
|
||||
Log.d(TAG, "onChanged: speed data repeated.");
|
||||
return;
|
||||
}
|
||||
((SensorDataCycling.Speed) sensorData).compute(sensorDataSet.getCyclingSpeed());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorDataReceived(SensorDataSet sensorDataSet) {
|
||||
this.sensorDataSet = sensorDataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected(String sensorName) {
|
||||
sensorDataSet.set(sensorData);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user