diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java
index d06defdf37..16962d180e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java
@@ -82,5 +82,11 @@ public abstract class AbstractEarCoordinator extends AbstractBLClassicDeviceCoor
public abstract boolean incrementCounter();
- public abstract boolean supportsLightAncAndTransparency();
+ public boolean supportsInEarDetection() {
+ return true;
+ }
+
+ public abstract boolean supportsLightAnc();
+
+ public abstract boolean supportsTransparency();
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2Coordinator.java
index 1285c25ad7..3298a78eaf 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2Coordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2Coordinator.java
@@ -37,7 +37,12 @@ public class CmfBuds2Coordinator extends AbstractEarCoordinator {
}
@Override
- public boolean supportsLightAncAndTransparency() {
+ public boolean supportsLightAnc() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsTransparency() {
return true;
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2aCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2aCoordinator.java
new file mode 100644
index 0000000000..24ea61bc64
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2aCoordinator.java
@@ -0,0 +1,58 @@
+/* Copyright (C) 2026 José Rebelo
+
+ 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.devices.nothing;
+
+import java.util.regex.Pattern;
+
+import nodomain.freeyourgadget.gadgetbridge.R;
+
+public class CmfBuds2aCoordinator extends AbstractEarCoordinator {
+ @Override
+ public boolean isExperimental() {
+ return true;
+ }
+
+ @Override
+ protected Pattern getSupportedDeviceName() {
+ return Pattern.compile("^CMF Buds 2a$");
+ }
+
+ @Override
+ public int getDeviceNameResource() {
+ return R.string.devicetype_nothing_cmf_buds_2a;
+ }
+
+ @Override
+ public boolean incrementCounter() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsInEarDetection() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsLightAnc() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsTransparency() {
+ return true;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBudsPro2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBudsPro2Coordinator.java
index 6f2f3e4d9b..969afbac51 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBudsPro2Coordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBudsPro2Coordinator.java
@@ -37,7 +37,12 @@ public class CmfBudsPro2Coordinator extends AbstractEarCoordinator {
}
@Override
- public boolean supportsLightAncAndTransparency() {
+ public boolean supportsLightAnc() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsTransparency() {
return true;
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear1Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear1Coordinator.java
index 6707d891cf..1c096dc199 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear1Coordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear1Coordinator.java
@@ -38,7 +38,12 @@ public class Ear1Coordinator extends AbstractEarCoordinator {
}
@Override
- public boolean supportsLightAncAndTransparency() {
+ public boolean supportsLightAnc() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsTransparency() {
return true;
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear2Coordinator.java
index e5b1a0e602..7306a280f3 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear2Coordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear2Coordinator.java
@@ -37,7 +37,12 @@ public class Ear2Coordinator extends AbstractEarCoordinator {
}
@Override
- public boolean supportsLightAncAndTransparency() {
+ public boolean supportsLightAnc() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsTransparency() {
return true;
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarACoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarACoordinator.java
index 6bc59099f0..538f704e8d 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarACoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarACoordinator.java
@@ -37,7 +37,12 @@ public class EarACoordinator extends AbstractEarCoordinator {
}
@Override
- public boolean supportsLightAncAndTransparency() {
+ public boolean supportsLightAnc() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsTransparency() {
return false;
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java
index 0d5564b58d..e57e69f283 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java
@@ -52,7 +52,14 @@ public class EarSettingsCustomizer implements DeviceSpecificSettingsCustomizer {
public void customizeSettings(final DeviceSpecificSettingsHandler handler, final Prefs prefs, final String rootKey) {
final AbstractEarCoordinator earCoordinator = (AbstractEarCoordinator) handler.getDevice().getDeviceCoordinator();
- if (!earCoordinator.supportsLightAncAndTransparency()) {
+ if (!earCoordinator.supportsInEarDetection()) {
+ final Preference inEarPreference = handler.findPreference(DeviceSettingsPreferenceConst.PREF_NOTHING_EAR1_INEAR);
+ if (inEarPreference != null) {
+ inEarPreference.setVisible(false);
+ }
+ }
+
+ if (!earCoordinator.supportsLightAnc() || !earCoordinator.supportsTransparency()) {
// If light anc and transparency is not supported, remove the values from the preference
final Preference audioModePref = handler.findPreference(DeviceSettingsPreferenceConst.PREF_NOTHING_EAR1_AUDIOMODE);
@@ -64,10 +71,14 @@ public class EarSettingsCustomizer implements DeviceSpecificSettingsCustomizer {
final List entryValues = new ArrayList<>();
for (int i = 0; i < originalEntries.length; i++) {
- if ("anc".equals(originalEntryValues[i].toString()) || "off".equals(originalEntryValues[i].toString())) {
- entries.add(originalEntries[i]);
- entryValues.add(originalEntryValues[i]);
+ if ("anclight".equals(originalEntryValues[i].toString()) && !earCoordinator.supportsLightAnc()) {
+ continue;
}
+ if ("transparency".equals(originalEntryValues[i].toString()) && !earCoordinator.supportsTransparency()) {
+ continue;
+ }
+ entries.add(originalEntries[i]);
+ entryValues.add(originalEntryValues[i]);
}
((ListPreference) audioModePref).setEntries(entries.toArray(new CharSequence[0]));
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java
index 1200ec4044..324fc541c7 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java
@@ -37,7 +37,12 @@ public class EarStickCoordinator extends AbstractEarCoordinator {
}
@Override
- public boolean supportsLightAncAndTransparency() {
+ public boolean supportsLightAnc() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsTransparency() {
return false;
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
index a3f615166b..124d23ea9d 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
@@ -353,6 +353,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.ViranC29Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.ZL02DCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nothing.CmfBuds2Coordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.nothing.CmfBuds2aCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nothing.CmfBudsPro2Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear1Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear2Coordinator;
@@ -761,6 +762,7 @@ public enum DeviceType {
NOTHING_EAR_A(EarACoordinator.class),
NOTHING_EAR_STICK(EarStickCoordinator.class),
NOTHING_CMF_BUDS_2(CmfBuds2Coordinator.class),
+ NOTHING_CMF_BUDS_2A(CmfBuds2aCoordinator.class),
NOTHING_CMF_BUDS_PRO_2(CmfBudsPro2Coordinator.class),
NOTHING_CMF_WATCH_PRO(CmfWatchProCoordinator.class),
NOTHING_CMF_WATCH_PRO_2(CmfWatchPro2Coordinator.class),
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 302289411d..5362882baa 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -3150,6 +3150,7 @@
Nothing Ear (a)
Nothing Ear (Stick)
CMF Buds 2
+ CMF Buds 2a
CMF Buds Pro 2
CMF Watch Pro
CMF Watch Pro 2
diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinatorTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinatorTest.java
index 5fe33e96a9..234f693fb8 100644
--- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinatorTest.java
+++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinatorTest.java
@@ -30,6 +30,7 @@ public class AbstractDeviceCoordinatorTest extends TestBase {
put("Xiaomi Band 9 Active AB01", DeviceType.MIBAND9ACTIVE);
put("vĂvoactive 6", DeviceType.GARMIN_VIVOACTIVE_6);
put("CMF Buds 2", DeviceType.NOTHING_CMF_BUDS_2); // #5579
+ put("CMF Buds 2a", DeviceType.NOTHING_CMF_BUDS_2A); // #6028
put("HC96", DeviceType.HC96);
put("P8", DeviceType.WASPOS); // from wasp-os source
put("P8DFU", DeviceType.WASPOS); // from wasp-os source