mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-01-26 17:47:34 +01:00
Soundcore Q30: Initial Support
This commit is contained in:
parent
725c477ebd
commit
991461a8d8
@ -411,6 +411,7 @@ public class DeviceSettingsPreferenceConst {
|
||||
public static final String PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING = "pref_adaptive_noise_cancelling";
|
||||
public static final String PREF_SOUNDCORE_WIND_NOISE_REDUCTION= "pref_soundcore_wind_noise_reduction";
|
||||
public static final String PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE = "pref_soundcore_transparency_vocal_mode";
|
||||
public static final String PREF_SOUNDCORE_ANC_MODE = "pref_soundcore_anc_mode";
|
||||
public static final String PREF_SOUNDCORE_WEARING_DETECTION = "pref_soundcore_wearing_detection";
|
||||
public static final String PREF_SOUNDCORE_WEARING_TONE = "pref_soundcore_wearing_tone";
|
||||
public static final String PREF_SOUNDCORE_TOUCH_TONE = "pref_soundcore_touch_tone";
|
||||
|
@ -747,6 +747,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_WIND_NOISE_REDUCTION);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_ANC_MODE);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_TOUCH_TONE);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_WEARING_TONE);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_WEARING_DETECTION);
|
||||
|
@ -0,0 +1,71 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.soundcore.q30;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.q30.SoundcoreQ30DeviceSupport;
|
||||
|
||||
public class SoundcoreQ30Coordinator extends AbstractDeviceCoordinator {
|
||||
@Override
|
||||
public int getDeviceNameResource() {
|
||||
return R.string.devicetype_soundcore_q30;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultIconResource() {
|
||||
return R.drawable.ic_device_headphones;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisabledIconResource() {
|
||||
return R.drawable.ic_device_headphones_disabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManufacturer() {
|
||||
return "Anker";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern getSupportedDeviceName() {
|
||||
return Pattern.compile("Soundcore Q30");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBondingStyle(){
|
||||
return BONDING_STYLE_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BatteryConfig[] getBatteryConfig(final GBDevice device) {
|
||||
BatteryConfig battery = new BatteryConfig(0, R.drawable.ic_battery, R.string.battery);
|
||||
return new BatteryConfig[]{battery};
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) {
|
||||
final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings();
|
||||
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_soundcore_q30);
|
||||
return deviceSpecificSettings;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Class<? extends DeviceSupport> getDeviceSupportClass() {
|
||||
return SoundcoreQ30DeviceSupport.class;
|
||||
}
|
||||
}
|
@ -268,6 +268,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12.SonySWR12DeviceCoo
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.soundcore.liberty3_pro.SoundcoreLiberty3ProCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.soundcore.liberty4_nc.SoundcoreLiberty4NCCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.soundcore.motion300.SoundcoreMotion300Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.soundcore.q30.SoundcoreQ30Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.supercars.SuperCarsCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.test.TestDeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.tlw64.TLW64Coordinator;
|
||||
@ -536,6 +537,7 @@ public enum DeviceType {
|
||||
SOUNDCORE_LIBERTY3_PRO(SoundcoreLiberty3ProCoordinator.class),
|
||||
SOUNDCORE_LIBERTY4_NC(SoundcoreLiberty4NCCoordinator.class),
|
||||
SOUNDCORE_MOTION300(SoundcoreMotion300Coordinator.class),
|
||||
SOUNDCORE_Q30(SoundcoreQ30Coordinator.class),
|
||||
MOONDROP_SPACE_TRAVEL(MoondropSpaceTravelCoordinator.class),
|
||||
BOSE_QC35(QC35Coordinator.class),
|
||||
HONORBAND3(HonorBand3Coordinator.class),
|
||||
|
@ -76,15 +76,15 @@ public class SoundcoreLibertyProtocol extends AbstractSoundcoreProtocol {
|
||||
private void decodeAudioMode(byte[] payload) {
|
||||
SharedPreferences prefs = getDevicePrefs().getPreferences();
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
String soundmode = "off";
|
||||
String ambient_sound_mode = "off";
|
||||
int anc_strength = 0;
|
||||
|
||||
if (payload[0] == 0x00) {
|
||||
soundmode = "noise_cancelling";
|
||||
ambient_sound_mode = "noise_cancelling";
|
||||
} else if (payload[0] == 0x01) {
|
||||
soundmode = "ambient_sound";
|
||||
ambient_sound_mode = "ambient_sound";
|
||||
} else if (payload[0] == 0x02) {
|
||||
soundmode = "off";
|
||||
ambient_sound_mode = "off";
|
||||
}
|
||||
|
||||
if (payload[1] == 0x10) {
|
||||
@ -99,7 +99,7 @@ public class SoundcoreLibertyProtocol extends AbstractSoundcoreProtocol {
|
||||
boolean adaptive_anc = (payload[3] == 0x01);
|
||||
boolean windnoiseReduction = (payload[4] == 0x01);
|
||||
|
||||
editor.putString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL, soundmode);
|
||||
editor.putString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL, ambient_sound_mode);
|
||||
editor.putInt(DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_LEVEL, anc_strength);
|
||||
editor.putBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE, vocal_mode);
|
||||
editor.putBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING, adaptive_anc);
|
||||
@ -210,19 +210,19 @@ public class SoundcoreLibertyProtocol extends AbstractSoundcoreProtocol {
|
||||
private byte[] encodeAudioMode() {
|
||||
Prefs prefs = getDevicePrefs();
|
||||
|
||||
byte anc_mode;
|
||||
byte ambient_sound_mode;
|
||||
switch (prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL, "off")) {
|
||||
case "noise_cancelling":
|
||||
anc_mode = 0x00;
|
||||
ambient_sound_mode = 0x00;
|
||||
break;
|
||||
case "ambient_sound":
|
||||
anc_mode = 0x01;
|
||||
ambient_sound_mode = 0x01;
|
||||
break;
|
||||
case "off":
|
||||
anc_mode = 0x02;
|
||||
ambient_sound_mode = 0x02;
|
||||
break;
|
||||
default:
|
||||
LOG.error("Invalid Audio Mode selected");
|
||||
LOG.error("Invalid Ambient Mode selected");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ public class SoundcoreLibertyProtocol extends AbstractSoundcoreProtocol {
|
||||
byte vocal_mode = encodeBoolean(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE, false));
|
||||
byte windnoise_reduction = encodeBoolean(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_WIND_NOISE_REDUCTION, false));
|
||||
|
||||
byte[] payload = new byte[]{anc_mode, anc_strength, vocal_mode, adaptive_anc, windnoise_reduction, 0x01};
|
||||
byte[] payload = new byte[]{ambient_sound_mode, anc_strength, vocal_mode, adaptive_anc, windnoise_reduction, 0x01};
|
||||
return new SoundcorePacket((short) 0x8106, payload).encode();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.q30;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
|
||||
public class SoundcoreQ30DeviceSupport extends AbstractSerialDeviceSupport {
|
||||
|
||||
@Override
|
||||
protected GBDeviceProtocol createDeviceProtocol() {
|
||||
return new SoundcoreQ30Protocol(getDevice());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GBDeviceIoThread createDeviceIOThread() {
|
||||
return new SoundcoreQ30IOThread(getDevice(), getContext(), (SoundcoreQ30Protocol) getDeviceProtocol(),this, getBluetoothAdapter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect() {
|
||||
getDeviceIOThread().start();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAutoConnect() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.q30;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.hexdump;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
import android.os.ParcelUuid;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.liberty.SoundcoreLibertyProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
|
||||
public class SoundcoreQ30IOThread extends BtClassicIoThread {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SoundcoreQ30IOThread.class);
|
||||
private final SoundcoreQ30Protocol mSoundcoreProtocol;
|
||||
|
||||
public SoundcoreQ30IOThread(GBDevice gbDevice, Context context, SoundcoreQ30Protocol deviceProtocol, AbstractSerialDeviceSupport deviceSupport, BluetoothAdapter btAdapter) {
|
||||
super(gbDevice, context, deviceProtocol, deviceSupport, btAdapter);
|
||||
mSoundcoreProtocol = deviceProtocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] parseIncoming(InputStream inStream) throws IOException {
|
||||
byte[] buffer = new byte[1048576]; //HUGE read
|
||||
int bytes = inStream.read(buffer);
|
||||
LOG.debug("read {} bytes. {}", bytes, hexdump(buffer, 0, bytes));
|
||||
return Arrays.copyOf(buffer, bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
write(mSoundcoreProtocol.encodeDeviceInfoRequest());
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected UUID getUuidToConnect(@NonNull ParcelUuid[] uuids) {
|
||||
return UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.q30;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.hexdump;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.AbstractSoundcoreProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.SoundcorePacket;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
public class SoundcoreQ30Protocol extends AbstractSoundcoreProtocol {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SoundcoreQ30Protocol.class);
|
||||
|
||||
protected SoundcoreQ30Protocol(GBDevice device) {
|
||||
super(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GBDeviceEvent[] decodeResponse(byte[] responseData) {
|
||||
ByteBuffer buf = ByteBuffer.wrap(responseData);
|
||||
SoundcorePacket packet = SoundcorePacket.decode(buf);
|
||||
|
||||
if (packet == null)
|
||||
return null;
|
||||
|
||||
List<GBDeviceEvent> devEvts = new ArrayList<>();
|
||||
short cmd = packet.getCommand();
|
||||
byte[] payload = packet.getPayload();
|
||||
|
||||
if (cmd == (short) 0x0101) {
|
||||
// a lot of other data is in here, anything interesting?
|
||||
String firmware1 = readString(payload, 39, 5);
|
||||
String firmware2 = "";
|
||||
String serialNumber = readString(payload, 44, 16);
|
||||
devEvts.add(buildVersionInfo(firmware1, firmware2, serialNumber));
|
||||
} else if (cmd == (short) 0x0106) { // ANC Mode Updated by Button
|
||||
decodeAudioMode(payload);
|
||||
} else if (cmd == (short) 0x0301) { // Battery Update
|
||||
int battery = payload[0] * 20; // untested
|
||||
devEvts.add(buildBatteryInfo(0, battery));
|
||||
} else if (cmd == (short) 0x8106) {
|
||||
// Acknowledgement for changed Ambient Mode
|
||||
// empty payload
|
||||
} else {
|
||||
LOG.debug("Unknown incoming message - command: " + cmd + ", dump: " + hexdump(responseData));
|
||||
}
|
||||
return devEvts.toArray(new GBDeviceEvent[devEvts.size()]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] encodeSendConfiguration(String config) {
|
||||
switch (config) {
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL:
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_ANC_MODE:
|
||||
return encodeAudioMode();
|
||||
|
||||
default:
|
||||
LOG.debug("Unsupported CONFIG: " + config);
|
||||
}
|
||||
|
||||
return super.encodeSendConfiguration(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the following settings to a payload to set the audio-mode on the headphones:
|
||||
* PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL If ANC, Transparent or neither should be active
|
||||
* PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING If the strenght of the ANC should be set manual or adaptively according to ambient noise
|
||||
* PREF_SONY_AMBIENT_SOUND_LEVEL How strong the ANC should be in manual mode
|
||||
* PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE If the Transparency should focus on vocals or should be fully transparent
|
||||
* PREF_SOUNDCORE_WIND_NOISE_REDUCTION If Transparency or ANC should reduce Wind Noise
|
||||
* @return The payload
|
||||
*/
|
||||
private byte[] encodeAudioMode() {
|
||||
Prefs prefs = getDevicePrefs();
|
||||
|
||||
byte ambient_sound_mode;
|
||||
switch (prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL, "off")) {
|
||||
case "noise_cancelling":
|
||||
ambient_sound_mode = 0x00;
|
||||
break;
|
||||
case "ambient_sound":
|
||||
ambient_sound_mode = 0x01;
|
||||
break;
|
||||
case "off":
|
||||
ambient_sound_mode = 0x02;
|
||||
break;
|
||||
default:
|
||||
LOG.error("Invalid Ambient Mode selected");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte anc_mode;
|
||||
switch (prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_ANC_MODE, "transport")) {
|
||||
case "transport":
|
||||
anc_mode = 0x00;
|
||||
break;
|
||||
case "outdoor":
|
||||
anc_mode = 0x01;
|
||||
break;
|
||||
case "indoor":
|
||||
anc_mode = 0x02;
|
||||
break;
|
||||
default:
|
||||
LOG.error("Invalid ANC Mode selected");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] payload = new byte[]{ambient_sound_mode, anc_mode, 0x01};
|
||||
return new SoundcorePacket((short) 0x8106, payload).encode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets triggered when the button on the device is pressed or transparency toggled with the right palm.
|
||||
*/
|
||||
private void decodeAudioMode(byte[] payload) {
|
||||
SharedPreferences prefs = getDevicePrefs().getPreferences();
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
String ambient_sound_mode = "off";
|
||||
String anc_mode = "transport";
|
||||
|
||||
if (payload[0] == 0x00) {
|
||||
ambient_sound_mode = "noise_cancelling";
|
||||
} else if (payload[0] == 0x01) {
|
||||
ambient_sound_mode = "ambient_sound";
|
||||
} else if (payload[0] == 0x02) {
|
||||
ambient_sound_mode = "off";
|
||||
}
|
||||
|
||||
if (payload[1] == 0x00) {
|
||||
anc_mode = "transport";
|
||||
} else if (payload[1] == 0x01) {
|
||||
anc_mode = "outdoor";
|
||||
} else if (payload[1] == 0x02) {
|
||||
anc_mode = "indoor";
|
||||
}
|
||||
|
||||
// payload has two more bytes
|
||||
// payload[2] always 1 ?
|
||||
// payload[3] checksum ?
|
||||
|
||||
editor.putString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL, ambient_sound_mode);
|
||||
editor.putString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_ANC_MODE, anc_mode);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
@ -3762,6 +3762,18 @@
|
||||
<item>game_mode</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="soundcore_anc_mode_names">
|
||||
<item>@string/prefs_active_noise_cancelling_transport</item>
|
||||
<item>@string/prefs_active_noise_cancelling_indoor</item>
|
||||
<item>@string/prefs_active_noise_cancelling_outdoor</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="soundcore_anc_mode_values">
|
||||
<item>transport</item>
|
||||
<item>indoor</item>
|
||||
<item>outdoor</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="soundcore_button_function_names">
|
||||
<item>@string/pref_media_volumedown</item>
|
||||
<item>@string/pref_media_volumeup</item>
|
||||
|
@ -1860,6 +1860,7 @@
|
||||
<string name="devicetype_soundcore_liberty3_pro">Soundcore Liberty 3 Pro</string>
|
||||
<string name="devicetype_soundcore_liberty4_nc">Soundcore Liberty 4 NC</string>
|
||||
<string name="devicetype_soundcore_motion300">Soundcore Motion 300</string>
|
||||
<string name="devicetype_soundcore_q30">Soundcore Q30</string>
|
||||
<string name="devicetype_moondrop_space_travel">Moondrop Space Travel</string>
|
||||
<string name="devicetype_binary_sensor">Binary sensor</string>
|
||||
<string name="devicetype_honor_band3">Honor Band 3</string>
|
||||
@ -2580,6 +2581,9 @@
|
||||
<string name="prefs_active_noise_cancelling_level_high">High</string>
|
||||
<string name="prefs_active_noise_cancelling_level_low">Low</string>
|
||||
<string name="prefs_active_noise_cancelling_summary">Block noises of the surroundings</string>
|
||||
<string name="prefs_active_noise_cancelling_transport">Transport</string>
|
||||
<string name="prefs_active_noise_cancelling_indoor">Indoor</string>
|
||||
<string name="prefs_active_noise_cancelling_outdoor">Outdoor</string>
|
||||
<string name="prefs_pressure_relief">Pressure relief with ambient sound</string>
|
||||
<string name="pressure_relief_summary">Prevent feeling of pressure in ears when not using Active Noise Cancelling</string>
|
||||
<string name="prefs_left">Left</string>
|
||||
|
@ -48,8 +48,6 @@
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_header_soundcore_other"
|
||||
android:title="@string/pref_header_other">
|
||||
|
26
app/src/main/res/xml/devicesettings_soundcore_q30.xml
Normal file
26
app/src/main/res/xml/devicesettings_soundcore_q30.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_header_soundcore_ambient_sound_control"
|
||||
android:title="@string/pref_header_sony_ambient_sound_control">
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="noise_cancelling"
|
||||
android:entries="@array/sony_ambient_sound_control_names"
|
||||
android:entryValues="@array/sony_ambient_sound_control_values"
|
||||
android:icon="@drawable/ic_hearing"
|
||||
android:key="pref_soundcore_ambient_sound_control"
|
||||
android:summary="%s"
|
||||
android:title="@string/sony_ambient_sound" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="transport"
|
||||
android:entries="@array/soundcore_anc_mode_names"
|
||||
android:entryValues="@array/soundcore_anc_mode_values"
|
||||
android:icon="@drawable/ic_hearing"
|
||||
android:key="pref_soundcore_anc_mode"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_active_noise_cancelling_level" />
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
Loading…
x
Reference in New Issue
Block a user