From 3f6a4975fa5a4ce8abd58a3a15271b201c715426 Mon Sep 17 00:00:00 2001 From: stickflowerfightclub Date: Sun, 12 Apr 2026 10:27:19 +0200 Subject: [PATCH 1/2] Fix: Allow selection of internal sensors when Bluetooth is disabled --- .../BluetoothLeSensorPreference.java | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/settings/bluetooth/BluetoothLeSensorPreference.java b/src/main/java/de/dennisguse/opentracks/settings/bluetooth/BluetoothLeSensorPreference.java index 7e90f94d9..4eef96022 100644 --- a/src/main/java/de/dennisguse/opentracks/settings/bluetooth/BluetoothLeSensorPreference.java +++ b/src/main/java/de/dennisguse/opentracks/settings/bluetooth/BluetoothLeSensorPreference.java @@ -191,26 +191,6 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference { List serviceUUIDs = getArguments().getParcelableArrayList(ARG_BLE_SERVICE_UUIDS); boolean includeInternalSensor = getArguments().getBoolean(ARG_INCLUDE_INTERNAL); - BluetoothAdapter bluetoothAdapter = BluetoothUtils.getAdapter(getContext()); - if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { - Log.w(TAG, "Bluetooth adapter is present or not enabled."); - Toast.makeText(getContext(), R.string.bluetooth_disabled, Toast.LENGTH_SHORT).show(); - dismiss(); - return; - } - - if (bluetoothAdapter.isDiscovering()) { - Log.i(TAG, "Cancelling ongoing Bluetooth discovery."); - bluetoothAdapter.cancelDiscovery(); - } - - scanner = bluetoothAdapter.getBluetoothLeScanner(); - if (scanner == null) { - Log.e(TAG, "BluetoothLeScanner is null."); - dismiss(); - return; - } - listAdapter.add(SensorType.NONE.getPreferenceValue(), getContext().getString(DEVICE_NONE_RESOURCEID)); selectedEntryIndex = 0; @@ -228,6 +208,28 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference { selectedEntryIndex = !includeInternalSensor ? 1 : 2; } + BluetoothAdapter bluetoothAdapter = BluetoothUtils.getAdapter(getContext()); + if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { + Log.w(TAG, "Bluetooth adapter is present or not enabled. Skipping BLE scan."); + Toast.makeText(getContext(), R.string.bluetooth_disabled, Toast.LENGTH_SHORT).show(); + if (!includeInternalSensor) { + dismiss(); + } + return; + } + + if (bluetoothAdapter.isDiscovering()) { + Log.i(TAG, "Cancelling ongoing Bluetooth discovery."); + bluetoothAdapter.cancelDiscovery(); + } + + scanner = bluetoothAdapter.getBluetoothLeScanner(); + if (scanner == null) { + Log.e(TAG, "BluetoothLeScanner is null."); + dismiss(); + return; + } + List scanFilter = null; if (PreferencesUtils.getBluetoothFilterEnabled()) { scanFilter = serviceUUIDs.stream() From 9b7e858d1d823ab60af5495d056b1e9555fa89b1 Mon Sep 17 00:00:00 2001 From: stickflowerfightclub Date: Sun, 12 Apr 2026 13:22:35 +0200 Subject: [PATCH 2/2] Sensors: Fix excessive altitude gain by enforcing SAMPLING_PERIOD on internal barometer. On some modern devices like Pixel 8 Pro, the internal pressure sensor ignores the requested sampling period in registerListener and sends data at high frequency (~50Hz). This floods the AltitudeChangeHandler with noise, causing absurdly high altitude gain (e.g., 38km for a flat run). This commit adds a manual throttle in BarometerInternal to strictly respect the SAMPLING_PERIOD (5s), allowing the exponential smoothing to work as intended. --- .../sensors/driver/BarometerInternal.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java b/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java index b200d1f09..c19997e41 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java @@ -9,6 +9,8 @@ import android.util.Log; import androidx.annotation.NonNull; +import java.time.Duration; +import java.time.Instant; import java.util.concurrent.TimeUnit; import de.dennisguse.opentracks.data.models.AtmosphericPressure; @@ -17,12 +19,14 @@ public class BarometerInternal implements Driver { private static final String TAG = BarometerInternal.class.getSimpleName(); - private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5); + private static final Duration SAMPLING_PERIOD = Duration.ofSeconds(5); private final DriverObserver observer; private android.hardware.SensorManager sensorService; + private Instant lastEventTime = Instant.EPOCH; + private final SensorEventListener sensorEventListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { @@ -31,6 +35,13 @@ public class BarometerInternal implements Driver { return; } + Instant currentTime = Instant.now(); + + if (lastEventTime.plus(SAMPLING_PERIOD).isAfter(currentTime)) { + return; + } + + lastEventTime = currentTime; observer.onDataReceived(AtmosphericPressure.ofHPA(event.values[0])); } @@ -48,8 +59,9 @@ public class BarometerInternal implements Driver { public void connect(Context context, Handler handler, String addressIgnored) { sensorService = (android.hardware.SensorManager) context.getSystemService(Context.SENSOR_SERVICE); Sensor pressureSensor = sensorService.getDefaultSensor(Sensor.TYPE_PRESSURE); + int samplingPeriodUs = (int) TimeUnit.MICROSECONDS.convert(SAMPLING_PERIOD); - if (pressureSensor != null && sensorService.registerListener(sensorEventListener, pressureSensor, SAMPLING_PERIOD, handler)) { + if (pressureSensor != null && sensorService.registerListener(sensorEventListener, pressureSensor, samplingPeriodUs, handler)) { observer.onConnected(null, null); return; }