mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-28 12:56:49 +01:00
Generalize auto-pickup and read-notifications-aloud features
This commit is contained in:
parent
717789dc48
commit
523d02ae7f
@ -19,6 +19,23 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_CONTROL_CENTER_SORTABLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ITEMS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_EXPOSE_HR_THIRDPARTY;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS_SORTABLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_END;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_OFF;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_SCHEDULED;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_START;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_SWIPE_UNLOCK;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
@ -43,10 +60,10 @@ import java.util.Set;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.CalBlacklistActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureContacts;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureWorldClocks;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.app_specific_notifications.AppSpecificNotificationSettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst;
|
||||
@ -61,30 +78,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_CONTROL_CENTER_SORTABLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_FELL_SLEEP_BROADCAST;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_FELL_SLEEP_SELECTIONS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_SELECTION_BROADCAST;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_START_NON_WEAR_BROADCAST;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_START_NON_WEAR_SELECTIONS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_WOKE_UP_BROADCAST;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_WOKE_UP_SELECTIONS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ITEMS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_EXPOSE_HR_THIRDPARTY;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS_SORTABLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_END;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_OFF;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_SCHEDULED;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_START;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_SWIPE_UNLOCK;
|
||||
|
||||
public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment implements DeviceSpecificSettingsHandler {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DeviceSpecificSettingsFragment.class);
|
||||
@ -928,6 +921,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i
|
||||
setInputTypeFor(DeviceSettingsPreferenceConst.PREF_INACTIVITY_THRESHOLD, InputType.TYPE_CLASS_NUMBER);
|
||||
setInputTypeFor(DeviceSettingsPreferenceConst.PREF_DEVICE_GPS_UPDATE_INTERVAL, InputType.TYPE_CLASS_NUMBER);
|
||||
setInputTypeFor(DeviceSettingsPreferenceConst.PREF_BANGLEJS_TEXT_BITMAP_SIZE, InputType.TYPE_CLASS_NUMBER);
|
||||
setInputTypeFor(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, InputType.TYPE_CLASS_NUMBER);
|
||||
|
||||
new PasswordCapabilityImpl().registerPreferences(getContext(), coordinator.getPasswordCapability(), this);
|
||||
new HeartRateCapability().registerPreferences(getContext(), coordinator.getHeartRateMeasurementIntervals(), this);
|
||||
|
@ -25,6 +25,7 @@ public enum DeviceSpecificSettingsScreen {
|
||||
AUDIO("pref_screen_audio", R.xml.devicesettings_root_audio),
|
||||
AUTHENTICATION("pref_screen_authentication", R.xml.devicesettings_root_authentication),
|
||||
CALENDAR("pref_screen_calendar", R.xml.devicesettings_root_calendar),
|
||||
CALLS_AND_NOTIFICATIONS("pref_screen_calls_and_notifications", R.xml.devicesettings_root_calls_and_notifications),
|
||||
CONNECTION("pref_screen_connection", R.xml.devicesettings_root_connection),
|
||||
DEVELOPER("pref_screen_developer", R.xml.devicesettings_root_developer),
|
||||
DISPLAY("pref_screen_display", R.xml.devicesettings_root_display),
|
||||
|
@ -49,6 +49,8 @@ public class GalaxyBudsLiveDeviceCoordinator extends GalaxyBudsGenericCoordinato
|
||||
final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings();
|
||||
final List<Integer> audio = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.AUDIO);
|
||||
audio.add(R.xml.devicesettings_galaxy_buds_live);
|
||||
final List<Integer> callsAndNotif = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.CALLS_AND_NOTIFICATIONS);
|
||||
callsAndNotif.add(R.xml.devicesettings_headphones);
|
||||
return deviceSpecificSettings;
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,11 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_2_NOISE_CONTROL;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_ANC_LEVEL;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_BALANCE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_NOISE_CONTROL;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_2_NOISE_CONTROL;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT;
|
||||
|
@ -23,6 +23,7 @@ import androidx.annotation.NonNull;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLClassicDeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
@ -74,10 +75,11 @@ public abstract class AbstractEarCoordinator extends AbstractBLClassicDeviceCoor
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
||||
return new int[]{
|
||||
R.xml.devicesettings_nothing_ear1
|
||||
};
|
||||
public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) {
|
||||
final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings();
|
||||
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_nothing_ear1);
|
||||
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_headphones);
|
||||
return deviceSpecificSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -17,9 +17,7 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.nothing;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.text.InputType;
|
||||
|
||||
import androidx.preference.EditTextPreference;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
@ -76,22 +74,6 @@ public class EarSettingsCustomizer implements DeviceSpecificSettingsCustomizer {
|
||||
((ListPreference) audioModePref).setEntryValues(entryValues.toArray(new CharSequence[0]));
|
||||
}
|
||||
}
|
||||
final Preference autoReplyPref = handler.findPreference(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL);
|
||||
final Preference autoReplyDelay = handler.findPreference(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY);
|
||||
|
||||
if (autoReplyPref != null && autoReplyDelay != null) {
|
||||
|
||||
autoReplyDelay.setEnabled(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL, false));
|
||||
|
||||
autoReplyPref.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
autoReplyDelay.setEnabled((Boolean) newValue);
|
||||
return true;
|
||||
});
|
||||
|
||||
((EditTextPreference) autoReplyDelay).setOnBindEditTextListener(editText -> editText.setInputType(InputType.TYPE_CLASS_NUMBER));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,135 @@
|
||||
/* Copyright (C) 2024 Arjan Schrijver, Daniele Gobbetti
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBTextToSpeech;
|
||||
|
||||
public abstract class AbstractHeadphoneDeviceSupport extends AbstractSerialDeviceSupport {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractHeadphoneDeviceSupport.class);
|
||||
private GBTextToSpeech gbTextToSpeech;
|
||||
|
||||
@Override
|
||||
public void onSetCallState(CallSpec callSpec) {
|
||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
|
||||
|
||||
if (!prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL, false))
|
||||
return;
|
||||
|
||||
final int delayMillis = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, "15")) * 1000;
|
||||
|
||||
if (CallSpec.CALL_INCOMING != callSpec.command)
|
||||
return;
|
||||
|
||||
if (!gbTextToSpeech.isConnected()) { // schedule the automatic reply here, if the speech to text is not connected. Else it's done by the callback, and the timeout starts after the name or number have been spoken
|
||||
Looper mainLooper = Looper.getMainLooper();
|
||||
LOG.debug("Incoming call, scheduling auto answer in {} seconds.", delayMillis / 1000);
|
||||
|
||||
new Handler(mainLooper).postDelayed(() -> {
|
||||
GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl();
|
||||
callCmd.event = GBDeviceEventCallControl.Event.ACCEPT;
|
||||
evaluateGBDeviceEvent(callCmd);
|
||||
}, delayMillis); //15s
|
||||
|
||||
return;
|
||||
}
|
||||
String speechText = callSpec.name;
|
||||
if (callSpec.name.equals(callSpec.number)) {
|
||||
StringBuilder numberSpeller = new StringBuilder();
|
||||
for (char c : callSpec.number.toCharArray()) {
|
||||
numberSpeller.append(c).append(" ");
|
||||
}
|
||||
speechText = numberSpeller.toString();
|
||||
}
|
||||
gbTextToSpeech.speak(speechText);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotification(NotificationSpec notificationSpec) {
|
||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
|
||||
|
||||
if (!prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SPEAK_NOTIFICATIONS_ALOUD, false))
|
||||
return;
|
||||
|
||||
if (gbTextToSpeech.isConnected()) {
|
||||
|
||||
String notificationSpeller = new StringBuilder()
|
||||
.append(notificationSpec.sourceName == null ? "" : notificationSpec.sourceName).append(". ")
|
||||
.append(notificationSpec.title == null ? "" : notificationSpec.title).append(": ")
|
||||
.append(notificationSpec.body == null ? "" : notificationSpec.body).toString();
|
||||
|
||||
|
||||
gbTextToSpeech.speakNotification(notificationSpeller);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect() {
|
||||
getDeviceIOThread().start();
|
||||
gbTextToSpeech = new GBTextToSpeech(getContext(), new UtteranceProgressListener());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
gbTextToSpeech.shutdown();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private class UtteranceProgressListener extends android.speech.tts.UtteranceProgressListener {
|
||||
@Override
|
||||
public void onStart(String utteranceId) {
|
||||
// LOG.debug("UtteranceProgressListener onStart.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDone(String utteranceId) {
|
||||
// LOG.debug("UtteranceProgressListener onDone.");
|
||||
if (utteranceId.equals("call")) {
|
||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
|
||||
final int delayMillis = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, "15")) * 1000;
|
||||
|
||||
|
||||
Looper mainLooper = Looper.getMainLooper();
|
||||
new Handler(mainLooper).postDelayed(() -> {
|
||||
GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl();
|
||||
callCmd.event = GBDeviceEventCallControl.Event.ACCEPT;
|
||||
evaluateGBDeviceEvent(callCmd);
|
||||
}, delayMillis); //15s
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String utteranceId) {
|
||||
LOG.error("UtteranceProgressListener returned error.");
|
||||
}
|
||||
}
|
||||
}
|
@ -16,23 +16,16 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.galaxy_buds;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.AbstractHeadphoneDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
|
||||
public class GalaxyBudsDeviceSupport extends AbstractSerialDeviceSupport {
|
||||
public class GalaxyBudsDeviceSupport extends AbstractHeadphoneDeviceSupport {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GalaxyBudsDeviceSupport.class);
|
||||
|
||||
|
||||
@Override
|
||||
public void onSendConfiguration(String config) {
|
||||
super.onSendConfiguration(config);
|
||||
@ -43,12 +36,6 @@ public class GalaxyBudsDeviceSupport extends AbstractSerialDeviceSupport {
|
||||
super.onTestNewFunction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect() {
|
||||
getDeviceIOThread().start();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized GalaxyBudsIOThread getDeviceIOThread() {
|
||||
return (GalaxyBudsIOThread) super.getDeviceIOThread();
|
||||
|
@ -16,82 +16,15 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.nothing;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.AbstractHeadphoneDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBTextToSpeech;
|
||||
|
||||
public class Ear1Support extends AbstractSerialDeviceSupport {
|
||||
public class Ear1Support extends AbstractHeadphoneDeviceSupport {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Ear1Support.class);
|
||||
private GBTextToSpeech gbTextToSpeech;
|
||||
|
||||
@Override
|
||||
public void onSetCallState(CallSpec callSpec) {
|
||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
|
||||
|
||||
if (!prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL, false))
|
||||
return;
|
||||
|
||||
final int delayMillis = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, "15")) * 1000;
|
||||
|
||||
if (CallSpec.CALL_INCOMING != callSpec.command)
|
||||
return;
|
||||
|
||||
if (!gbTextToSpeech.isConnected()) { // schedule the automatic reply here, if the speech to text is not connected. Else it's done by the callback, and the timeout starts after the name or number have been spoken
|
||||
Looper mainLooper = Looper.getMainLooper();
|
||||
LOG.debug("Incoming call, scheduling auto answer in {} seconds.", delayMillis / 1000);
|
||||
|
||||
new Handler(mainLooper).postDelayed(() -> {
|
||||
GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl();
|
||||
callCmd.event = GBDeviceEventCallControl.Event.ACCEPT;
|
||||
evaluateGBDeviceEvent(callCmd);
|
||||
}, delayMillis); //15s
|
||||
|
||||
return;
|
||||
}
|
||||
String speechText = callSpec.name;
|
||||
if (callSpec.name.equals(callSpec.number)) {
|
||||
StringBuilder numberSpeller = new StringBuilder();
|
||||
for (char c : callSpec.number.toCharArray()) {
|
||||
numberSpeller.append(c).append(" ");
|
||||
}
|
||||
speechText = numberSpeller.toString();
|
||||
}
|
||||
gbTextToSpeech.speak(speechText);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotification(NotificationSpec notificationSpec) {
|
||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
|
||||
|
||||
if (!prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SPEAK_NOTIFICATIONS_ALOUD, false))
|
||||
return;
|
||||
|
||||
if (gbTextToSpeech.isConnected()) {
|
||||
|
||||
String notificationSpeller = new StringBuilder()
|
||||
.append(notificationSpec.sourceName == null ? "" : notificationSpec.sourceName).append(". ")
|
||||
.append(notificationSpec.title == null ? "" : notificationSpec.title).append(": ")
|
||||
.append(notificationSpec.body == null ? "" : notificationSpec.body).toString();
|
||||
|
||||
|
||||
gbTextToSpeech.speakNotification(notificationSpeller);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendConfiguration(String config) {
|
||||
@ -103,13 +36,6 @@ public class Ear1Support extends AbstractSerialDeviceSupport {
|
||||
//getDeviceIOThread().write(((NothingProtocol) getDeviceProtocol()).encodeBatteryStatusReq());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect() {
|
||||
getDeviceIOThread().start();
|
||||
gbTextToSpeech = new GBTextToSpeech(getContext(), new UtteranceProgressListener());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized NothingIOThread getDeviceIOThread() {
|
||||
return (NothingIOThread) super.getDeviceIOThread();
|
||||
@ -129,39 +55,4 @@ public class Ear1Support extends AbstractSerialDeviceSupport {
|
||||
return new NothingIOThread(getDevice(), getContext(), (NothingProtocol) getDeviceProtocol(),
|
||||
Ear1Support.this, getBluetoothAdapter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
gbTextToSpeech.shutdown();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private class UtteranceProgressListener extends android.speech.tts.UtteranceProgressListener {
|
||||
@Override
|
||||
public void onStart(String utteranceId) {
|
||||
// LOG.debug("UtteranceProgressListener onStart.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDone(String utteranceId) {
|
||||
// LOG.debug("UtteranceProgressListener onDone.");
|
||||
if (utteranceId.equals("call")) {
|
||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
|
||||
final int delayMillis = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, "15")) * 1000;
|
||||
|
||||
|
||||
Looper mainLooper = Looper.getMainLooper();
|
||||
new Handler(mainLooper).postDelayed(() -> {
|
||||
GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl();
|
||||
callCmd.event = GBDeviceEventCallControl.Event.ACCEPT;
|
||||
evaluateGBDeviceEvent(callCmd);
|
||||
}, delayMillis); //15s
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String utteranceId) {
|
||||
LOG.error("UtteranceProgressListener returned error.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2789,4 +2789,5 @@
|
||||
<string name="pref_auto_reply_calls_delay_title">Automatic Answer Delay</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">Notifications will be read aloud through the headphones</string>
|
||||
<string name="pref_speak_notifications_aloud_title">Speak Notifications Aloud</string>
|
||||
<string name="pref_header_calls_and_notifications">Calls and notifications</string>
|
||||
</resources>
|
||||
|
25
app/src/main/res/xml/devicesettings_headphones.xml
Normal file
25
app/src/main/res/xml/devicesettings_headphones.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_phone"
|
||||
android:key="pref_auto_reply_phonecall"
|
||||
android:summary="@string/pref_auto_reply_calls_summary"
|
||||
android:title="@string/pref_auto_reply_calls_title"/>
|
||||
<EditTextPreference
|
||||
android:icon="@drawable/ic_timer"
|
||||
android:digits="123"
|
||||
android:dependency="pref_auto_reply_phonecall"
|
||||
android:inputType="numberDecimal"
|
||||
android:key="pref_auto_reply_phonecall_delay"
|
||||
android:summary="@string/pref_auto_reply_calls_delay_summary"
|
||||
android:title="@string/pref_auto_reply_calls_delay_title"
|
||||
app:defaultValue="15" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_voice"
|
||||
android:key="pref_speak_notifications_aloud"
|
||||
android:summary="@string/pref_speak_notifications_aloud_summary"
|
||||
android:title="@string/pref_speak_notifications_aloud_title" />
|
||||
</androidx.preference.PreferenceScreen>
|
@ -15,24 +15,4 @@
|
||||
android:key="pref_nothing_audiomode"
|
||||
android:summary="%s"
|
||||
android:title="@string/nothing_prefs_audiomode_title" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_phone"
|
||||
android:key="pref_auto_reply_phonecall"
|
||||
android:summary="@string/pref_auto_reply_calls_summary"
|
||||
android:title="@string/pref_auto_reply_calls_title"/>
|
||||
<EditTextPreference
|
||||
android:digits="123"
|
||||
android:enabled="false"
|
||||
android:inputType="numberDecimal"
|
||||
android:key="pref_auto_reply_phonecall_delay"
|
||||
android:summary="@string/pref_auto_reply_calls_delay_summary"
|
||||
android:title="@string/pref_auto_reply_calls_delay_title"
|
||||
app:defaultValue="15" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_voice"
|
||||
android:key="pref_speak_notifications_aloud"
|
||||
android:summary="@string/pref_speak_notifications_aloud_summary"
|
||||
android:title="@string/pref_speak_notifications_aloud_title" />
|
||||
</androidx.preference.PreferenceScreen>
|
||||
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:key="pref_screen_calls_and_notifications"
|
||||
android:persistent="false"
|
||||
android:title="@string/pref_header_calls_and_notifications">
|
||||
</PreferenceScreen>
|
||||
</androidx.preference.PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user