Implement gain/loss via Bluetooth LE Environmental Sensing Sensor.

Fixes #1424.
This commit is contained in:
Dennis Guse
2023-12-28 15:10:44 +01:00
parent 8eed8e9d8d
commit 03dd0c2308
11 changed files with 170 additions and 134 deletions
@@ -17,6 +17,7 @@
package de.dennisguse.opentracks.sensors; package de.dennisguse.opentracks.sensors;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCallback;
@@ -33,19 +34,22 @@ import androidx.annotation.NonNull;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import de.dennisguse.opentracks.sensors.driver.Driver;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface; import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
/** /**
* Manages connection to a Bluetooth LE sensor and subscribes for onChange-notifications. * Manages connection to a Bluetooth LE sensor and subscribes for onChange-notifications.
*/ */
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
public class BluetoothConnectionManager { public class BluetoothConnectionManager implements Driver {
private static final String TAG = BluetoothConnectionManager.class.getSimpleName(); private static final String TAG = BluetoothConnectionManager.class.getSimpleName();
private final SensorManager.SensorDataChangedObserver observer; private final SensorManager.SensorDataChangedObserver observer;
private final SensorHandlerInterface sensorHandler; private final SensorHandlerInterface sensorHandler;
private final BluetoothAdapter bluetoothAdapter;
private BluetoothGatt bluetoothGatt; private BluetoothGatt bluetoothGatt;
private final BluetoothGattCallback connectCallback = new BluetoothGattCallback() { private final BluetoothGattCallback connectCallback = new BluetoothGattCallback() {
@Override @Override
@@ -127,17 +131,46 @@ public class BluetoothConnectionManager {
} }
}; };
BluetoothConnectionManager(SensorManager.SensorDataChangedObserver observer, SensorHandlerInterface sensorHandler) { BluetoothConnectionManager(BluetoothAdapter bluetoothAdapter, SensorManager.SensorDataChangedObserver observer, SensorHandlerInterface sensorHandler) {
this.bluetoothAdapter = bluetoothAdapter;
this.observer = observer; this.observer = observer;
this.sensorHandler = sensorHandler; this.sensorHandler = sensorHandler;
} }
synchronized void connect(Context context, Handler handler, @NonNull BluetoothDevice device) { @Override
if (bluetoothGatt != null) { public synchronized void connect(Context context, Handler handler, @NonNull String address) {
if (!isBluetoothEnabled()) {
Log.w(TAG, "Bluetooth not enabled.");
return;
}
if (SensorType.NONE.getPreferenceValue().equals(address)) {
Log.w(TAG, "NONE: going to disconnect");
if (isConnected()) {
disconnect();
}
return;
}
if (isConnected()) {
Log.w(TAG, "Already connected; ignoring."); Log.w(TAG, "Already connected; ignoring.");
return; return;
} }
if (isSameBluetoothDevice(address)) {
return;
} else {
disconnect();
}
BluetoothDevice device;
try {
device = bluetoothAdapter.getRemoteDevice(address);
} catch (IllegalArgumentException e) {
Log.e(TAG, address + ": Unable to get remote device for", e);
return;
}
Log.d(TAG, device + ": trying to connect"); Log.d(TAG, device + ": trying to connect");
bluetoothGatt = device.connectGatt(context, false, connectCallback, BluetoothDevice.TRANSPORT_AUTO, 0, handler); bluetoothGatt = device.connectGatt(context, false, connectCallback, BluetoothDevice.TRANSPORT_AUTO, 0, handler);
@@ -149,8 +182,10 @@ public class BluetoothConnectionManager {
observer.onDisconnect(sensorHandler.createEmptySensorData(bluetoothGatt.getDevice().getAddress(), bluetoothGatt.getDevice().getName())); observer.onDisconnect(sensorHandler.createEmptySensorData(bluetoothGatt.getDevice().getAddress(), bluetoothGatt.getDevice().getName()));
} }
synchronized void disconnect() { @Override
if (bluetoothGatt == null) { public synchronized void disconnect() {
if (!isConnected()) {
Log.w(TAG, "Not connected; no need to re-connect.");
return; return;
} }
Log.i(TAG, bluetoothGatt.getDevice() + ": start disconnect"); Log.i(TAG, bluetoothGatt.getDevice() + ": start disconnect");
@@ -161,11 +196,21 @@ public class BluetoothConnectionManager {
bluetoothGatt = null; bluetoothGatt = null;
} }
synchronized boolean isSameBluetoothDevice(String address) { private synchronized boolean isSameBluetoothDevice(String address) {
if (bluetoothGatt == null) { if (bluetoothGatt == null) {
return false; return false;
} }
return address.equals(bluetoothGatt.getDevice().getAddress()); return address.equals(bluetoothGatt.getDevice().getAddress());
} }
private boolean isBluetoothEnabled() {
return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
}
@Override
public boolean isConnected() {
return bluetoothGatt != null;
}
} }
@@ -1,6 +1,7 @@
package de.dennisguse.opentracks.sensors; package de.dennisguse.opentracks.sensors;
import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic;
import android.util.Log;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@@ -32,9 +33,15 @@ public class BluetoothHandlerBarometricPressure implements SensorHandlerInterfac
public void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { public void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
AtmosphericPressure value = parseEnvironmentalSensing(characteristic); AtmosphericPressure value = parseEnvironmentalSensing(characteristic);
if (value == null) return; if (value == null) return;
Log.i("ZXCV", "VALUE: " + value);
observer.onChange(new Raw<>(value)); observer.onChange(new Raw<>(value));
} }
/**
* Decoding:
* org.bluetooth.service.environmental_sensing.xml
* org.bluetooth.characteristic.pressure.xml
*/
public static AtmosphericPressure parseEnvironmentalSensing(BluetoothGattCharacteristic characteristic) { public static AtmosphericPressure parseEnvironmentalSensing(BluetoothGattCharacteristic characteristic) {
byte[] raw = characteristic.getValue(); byte[] raw = characteristic.getValue();
@@ -17,11 +17,9 @@
package de.dennisguse.opentracks.sensors; package de.dennisguse.opentracks.sensors;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Handler; import android.os.Handler;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -30,7 +28,6 @@ import java.time.Duration;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.util.PermissionRequester;
/** /**
* Bluetooth LE sensor manager: manages connections to Bluetooth LE sensors. * Bluetooth LE sensor manager: manages connections to Bluetooth LE sensors.
@@ -45,7 +42,6 @@ public class BluetoothRemoteSensorManager implements SensorConnector, SharedPref
public static final Duration MAX_SENSOR_DATE_SET_AGE = Duration.ofSeconds(5); public static final Duration MAX_SENSOR_DATE_SET_AGE = Duration.ofSeconds(5);
private final BluetoothAdapter bluetoothAdapter;
private final Context context; private final Context context;
private final Handler handler; private final Handler handler;
private boolean started = false; private boolean started = false;
@@ -59,14 +55,13 @@ public class BluetoothRemoteSensorManager implements SensorConnector, SharedPref
public BluetoothRemoteSensorManager(@NonNull Context context, @NonNull Handler handler, @Nullable SensorManager.SensorDataChangedObserver observer) { public BluetoothRemoteSensorManager(@NonNull Context context, @NonNull Handler handler, @Nullable SensorManager.SensorDataChangedObserver observer) {
this.context = context; this.context = context;
this.handler = handler; this.handler = handler;
bluetoothAdapter = BluetoothUtils.getAdapter(context);
this.heartRate = new BluetoothConnectionManager(observer, new BluetoothHandlerManagerHeartRate());
this.cyclingCadence = new BluetoothConnectionManager(observer, new BluetoothHandlerCyclingCadence());
this.cyclingSpeed = new BluetoothConnectionManager(observer, new BluetoothHandlerCyclingDistanceSpeed());
this.cyclingPower = new BluetoothConnectionManager(observer, new BluetoothHandlerManagerCyclingPower());
this.runningSpeedAndCadence = new BluetoothConnectionManager(observer, new BluetoothHandlerRunningSpeedAndCadence());
BluetoothAdapter bluetoothAdapter = BluetoothUtils.getAdapter(context);
this.heartRate = new BluetoothConnectionManager(bluetoothAdapter, observer, new BluetoothHandlerManagerHeartRate());
this.cyclingCadence = new BluetoothConnectionManager(bluetoothAdapter, observer, new BluetoothHandlerCyclingCadence());
this.cyclingSpeed = new BluetoothConnectionManager(bluetoothAdapter, observer, new BluetoothHandlerCyclingDistanceSpeed());
this.cyclingPower = new BluetoothConnectionManager(bluetoothAdapter, observer, new BluetoothHandlerManagerCyclingPower());
this.runningSpeedAndCadence = new BluetoothConnectionManager(bluetoothAdapter, observer, new BluetoothHandlerRunningSpeedAndCadence());
} }
@Override @Override
@@ -88,39 +83,8 @@ public class BluetoothRemoteSensorManager implements SensorConnector, SharedPref
started = false; started = false;
} }
public boolean isEnabled() {
return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
}
private synchronized void connect(BluetoothConnectionManager connectionManager, String address) { private synchronized void connect(BluetoothConnectionManager connectionManager, String address) {
if (!isEnabled()) { connectionManager.connect(context, handler, address);
Log.w(TAG, "Bluetooth not enabled.");
return;
}
if (SensorType.NONE.getPreferenceValue().equals(address)) {
Log.w(TAG, "No Bluetooth address.");
connectionManager.disconnect();
return;
}
// Check if there is an ongoing connection; if yes, check if the address changed.
if (connectionManager.isSameBluetoothDevice(address)) {
return;
} else {
connectionManager.disconnect();
}
if (!PermissionRequester.BLUETOOTH.hasPermission(context)) {
Log.w(TAG, "BLUETOOTH_SCAN and/or BLUETOOTH_CONNECT not granted; not connecting.");
}
Log.i(TAG, "Connecting to bluetooth address: " + address);
try {
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
connectionManager.connect(context, handler, device);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Unable to get remote device for: " + address, e);
}
} }
@Override @Override
@@ -5,12 +5,9 @@ import android.content.SharedPreferences;
import android.os.Handler; import android.os.Handler;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.sensors.driver.BarometerInternal; import de.dennisguse.opentracks.sensors.driver.BarometerInternal;
import de.dennisguse.opentracks.sensors.driver.Driver;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer; import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer;
import de.dennisguse.opentracks.sensors.sensorData.Raw;
import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.PreferencesUtils;
/** /**
@@ -20,7 +17,6 @@ public class GainManager implements SensorConnector {
private static final String TAG = GainManager.class.getSimpleName(); private static final String TAG = GainManager.class.getSimpleName();
private BarometerInternal driver;
private final SensorManager.SensorDataChangedObserver listener; private final SensorManager.SensorDataChangedObserver listener;
@@ -30,10 +26,10 @@ public class GainManager implements SensorConnector {
private Context context; private Context context;
private Handler handler; private Handler handler;
private Driver driver;
public GainManager(SensorManager.SensorDataChangedObserver listener) { public GainManager(SensorManager.SensorDataChangedObserver listener) {
this.listener = listener; this.listener = listener;
driver = new BarometerInternal();
} }
public void start(Context context, Handler handler) { public void start(Context context, Handler handler) {
@@ -48,37 +44,34 @@ public class GainManager implements SensorConnector {
this.handler = null; this.handler = null;
PreferencesUtils.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); PreferencesUtils.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
onDisconnect(context); onDisconnect();
}
public void onSensorValueChanged(AtmosphericPressure currentSensorValue) {
listener.onChange(new Raw<>(currentSensorValue));
} }
private void connect() { private void connect() {
onDisconnect(context); onDisconnect();
String address = PreferencesUtils.getBarometerSensorAddress(); String address = PreferencesUtils.getBarometerSensorAddress();
switch (PreferencesUtils.getSensorType(address)) { switch (PreferencesUtils.getSensorType(address)) {
case NONE -> driver = null; case NONE -> driver = null;
case INTERNAL -> driver = new BarometerInternal(); case INTERNAL -> driver = new BarometerInternal(listener);
case REMOTE -> throw new RuntimeException("Not implemented"); //TODO #1424 case REMOTE -> driver =
new BluetoothConnectionManager(
BluetoothUtils.getAdapter(context),
listener,
new BluetoothHandlerBarometricPressure()
);
default -> throw new RuntimeException("Not implemented"); default -> throw new RuntimeException("Not implemented");
} }
if (driver != null) { if (driver != null) {
driver.connect(context, handler, this); driver.connect(context, handler, address);
if (driver.isConnected()) {
listener.onConnect(new AggregatorBarometer("internal", null));
}
} }
} }
private void onDisconnect(@NonNull Context context) { private void onDisconnect() {
if (driver == null) return; if (driver == null) return;
driver.disconnect(context); driver.disconnect();
listener.onDisconnect(new AggregatorBarometer("internal", null)); listener.onDisconnect(new AggregatorBarometer("GainManager", null));
} }
} }
@@ -4,24 +4,29 @@ import android.content.Context;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
import android.hardware.SensorEventListener; import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler; import android.os.Handler;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import de.dennisguse.opentracks.data.models.AtmosphericPressure; import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.sensors.GainManager; import de.dennisguse.opentracks.sensors.SensorManager;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer;
import de.dennisguse.opentracks.sensors.sensorData.Raw;
public class BarometerInternal { public class BarometerInternal implements Driver {
private static final String TAG = BarometerInternal.class.getSimpleName(); private static final String TAG = BarometerInternal.class.getSimpleName();
private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5); private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5);
private GainManager observer; private final SensorManager.SensorDataChangedObserver listener;
private final SensorEventListener listener = new SensorEventListener() { private Context context;
private final SensorEventListener sensorEventListener = new SensorEventListener() {
@Override @Override
public void onSensorChanged(SensorEvent event) { public void onSensorChanged(SensorEvent event) {
if (!isConnected()) { if (!isConnected()) {
@@ -29,7 +34,7 @@ public class BarometerInternal {
return; return;
} }
observer.onSensorValueChanged(AtmosphericPressure.ofHPA(event.values[0])); listener.onChange(new Raw<>(AtmosphericPressure.ofHPA(event.values[0])));
} }
@Override @Override
@@ -38,30 +43,40 @@ public class BarometerInternal {
} }
}; };
public void connect(Context context, Handler handler, GainManager observer) { public BarometerInternal(@NonNull SensorManager.SensorDataChangedObserver listener) {
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); this.listener = listener;
}
@Override
public void connect(Context context, Handler handler, String addressIgnored) {
android.hardware.SensorManager sensorManager = (android.hardware.SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
Sensor pressureSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); Sensor pressureSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
if (pressureSensor == null) { if (pressureSensor == null) {
Log.w(TAG, "No pressure sensor available."); Log.w(TAG, "No pressure sensor available.");
this.observer = null;
return; return;
} }
if (sensorManager.registerListener(listener, pressureSensor, SAMPLING_PERIOD, handler)) { if (sensorManager.registerListener(sensorEventListener, pressureSensor, SAMPLING_PERIOD, handler)) {
this.observer = observer; this.context = context;
listener.onConnect(new AggregatorBarometer("internal", null));
return; return;
} }
disconnect(context); disconnect();
}
public void disconnect(Context context) {
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensorManager.unregisterListener(listener);
observer = null;
} }
public boolean isConnected() { public boolean isConnected() {
return observer != null; return context != null;
}
@Override
public void disconnect() {
if (!isConnected()) return;
android.hardware.SensorManager sensorManager = (android.hardware.SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensorManager.unregisterListener(sensorEventListener);
this.context = null;
} }
} }
@@ -0,0 +1,12 @@
package de.dennisguse.opentracks.sensors.driver;
import android.content.Context;
import android.os.Handler;
public interface Driver {
void connect(Context context, Handler handler, String address);
boolean isConnected();
void disconnect();
}
@@ -120,10 +120,6 @@ public final class SensorDataSet {
return; return;
} }
if (value instanceof AtmosphericPressure) { if (value instanceof AtmosphericPressure) {
if (this.barometer == null) {
//TODO Quick fix. This shouldn't happen, but it does. May be a race condition?
return;
}
this.barometer.add((Raw<AtmosphericPressure>) data); this.barometer.add((Raw<AtmosphericPressure>) data);
return; return;
} }
@@ -253,10 +253,6 @@ public class PreferencesUtils {
return SensorType.NONE.getPreferenceValue(); return SensorType.NONE.getPreferenceValue();
} }
public static boolean isBluetoothSensorAddressNone(String currentValue) {
return getBluetoothSensorAddressNone().equals(currentValue);
}
public static SensorType getSensorType(String address) { public static SensorType getSensorType(String address) {
return Arrays.stream(SensorType.values()) return Arrays.stream(SensorType.values())
.filter(it -> it.getPreferenceValue().equals(address)) .filter(it -> it.getPreferenceValue().equals(address))
@@ -1,5 +1,6 @@
package de.dennisguse.opentracks.settings.bluetooth; package de.dennisguse.opentracks.settings.bluetooth;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -7,10 +8,13 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@SuppressLint("MissingPermission")
public class BluetoothLeAdapter extends BaseAdapter { public class BluetoothLeAdapter extends BaseAdapter {
/** /**
@@ -50,22 +54,30 @@ public class BluetoothLeAdapter extends BaseAdapter {
return currentView; return currentView;
} }
public void add(String name, String address) { /**
Device device = new Device(name, address); * @return Data changed?
*/
public boolean add(String address, String name) {
Device device = new Device(address, name);
if (!devices.contains(device)) { if (!devices.contains(device)) {
devices.add(new Device(name, address)); devices.add(device);
return true;
} else { } else {
for (Device currentDevice : devices) { for (Device currentDevice : devices) {
if (currentDevice.getAddress().equals(address)) { if (currentDevice.address.equals(address)) {
currentDevice.setName(name); currentDevice.name = name;
return true;
} }
} }
} }
notifyDataSetChanged(); return false;
} }
public void add(BluetoothDevice bluetoothDevice) { public void addAll(List<BluetoothDevice> bluetoothDevices) {
add(bluetoothDevice.getName(), bluetoothDevice.getAddress()); boolean dataSetChanged = bluetoothDevices.stream()
.anyMatch(bluetoothDevice -> add(bluetoothDevice.getAddress(), bluetoothDevice.getName()));
if (dataSetChanged) notifyDataSetChanged();
} }
public Device get(int index) { public Device get(int index) {
@@ -73,19 +85,14 @@ public class BluetoothLeAdapter extends BaseAdapter {
} }
public static class Device { public static class Device {
private String name;
@NonNull
private final String address; private final String address;
private String name;
public Device(String name, String address) { Device(@NonNull String address, String name) {
this.name = name; Objects.requireNonNull(address);
this.address = address; this.address = address;
}
public String getNameOrAddress() {
return name != null ? name : getAddress();
}
public void setName(String name) {
this.name = name; this.name = name;
} }
@@ -93,16 +100,21 @@ public class BluetoothLeAdapter extends BaseAdapter {
return address; return address;
} }
public String getNameOrAddress() {
return name != null ? name : address;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (!(o instanceof Device device)) return false; if (!(o instanceof Device device)) return false;
return address.equals(device.address); return address.equals(device.address);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(name, address); return Objects.hash(address);
} }
} }
} }
@@ -7,7 +7,9 @@ import android.util.AttributeSet;
import androidx.preference.PreferenceDialogFragmentCompat; import androidx.preference.PreferenceDialogFragmentCompat;
import java.util.Collections; import java.util.List;
import de.dennisguse.opentracks.sensors.BluetoothHandlerBarometricPressure;
public class BluetoothLePressurePreference extends BluetoothLeSensorPreference { public class BluetoothLePressurePreference extends BluetoothLeSensorPreference {
@@ -34,7 +36,6 @@ public class BluetoothLePressurePreference extends BluetoothLeSensorPreference {
boolean hasInternalSensor = pressureSensor != null; boolean hasInternalSensor = pressureSensor != null;
return BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog return BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog
// .newInstance(getKey(), List.of(BluetoothHandlerBarometricPressure.BAROMETRIC_PRESSURE), hasInternalSensor); //TODO #1424 .newInstance(getKey(), List.of(BluetoothHandlerBarometricPressure.BAROMETRIC_PRESSURE), hasInternalSensor);
.newInstance(getKey(), Collections.emptyList(), hasInternalSensor);
} }
} }
@@ -102,7 +102,7 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(value); BluetoothDevice device = bluetoothAdapter.getRemoteDevice(value);
if (device != null && device.getName() != null) { if (device != null && device.getName() != null) {
return getContext().getString(R.string.bluetooth_sensor_summary, device.getAddress(), device.getName()); return getContext().getString(R.string.bluetooth_sensor_summary, device.getAddress(), device.getName());
} }
return value; return value;
} }
@@ -121,14 +121,12 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
@Override @Override
public void onScanResult(int callbackType, ScanResult result) { public void onScanResult(int callbackType, ScanResult result) {
Log.d(TAG, "Found device " + result.getDevice().getName() + " " + result); Log.d(TAG, "Found device " + result.getDevice().getName() + " " + result);
listAdapter.add(result.getDevice()); onBatchScanResults(List.of(result));
} }
@Override @Override
public void onBatchScanResults(List<ScanResult> results) { public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult result : results) { listAdapter.addAll(results.stream().map(ScanResult::getDevice).collect(Collectors.toList()));
onScanResult(-1, result);
}
} }
@Override @Override
@@ -205,24 +203,21 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
return; return;
} }
String deviceNone = getContext().getString(R.string.sensor_type_value_none); listAdapter.add(SensorType.NONE.getPreferenceValue(), getContext().getString(DEVICE_NONE_RESOURCEID));
String sensorInternal = getString(R.string.sensor_type_value_internal);
listAdapter.add(getContext().getString(DEVICE_NONE_RESOURCEID), deviceNone);
selectedEntryIndex = 0; selectedEntryIndex = 0;
BluetoothLeSensorPreference preference = (BluetoothLeSensorPreference) getPreference(); BluetoothLeSensorPreference preference = (BluetoothLeSensorPreference) getPreference();
String deviceSelected = preference.value; String deviceSelected = preference.value;
if (includeInternalSensor) { if (includeInternalSensor) {
listAdapter.add(getString(SENSOR_INTERNAL_RESOURCEID), sensorInternal); listAdapter.add(SensorType.INTERNAL.getPreferenceValue(), getString(SENSOR_INTERNAL_RESOURCEID));
if (sensorInternal.equals(deviceSelected)) { if (SensorType.INTERNAL.getPreferenceValue().equals(deviceSelected)) {
selectedEntryIndex = 1; selectedEntryIndex = 1;
} }
} }
if (deviceSelected != null && !deviceNone.equals(deviceSelected) && !sensorInternal.equals(deviceSelected)) { if (deviceSelected != null && SensorType.REMOTE.equals(PreferencesUtils.getSensorType(deviceSelected))) {
listAdapter.add(preference.value, preference.value); listAdapter.add(preference.value, preference.value);
selectedEntryIndex++; selectedEntryIndex = !includeInternalSensor ? 1 : 2;
} }
List<ScanFilter> scanFilter = null; List<ScanFilter> scanFilter = null;