diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java
index 6341d0365c..43f9707f3e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java
@@ -55,6 +55,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
+import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HybridHRActivitySampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper;
@@ -88,6 +89,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FirmwareFilePutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.NotificationFilterPutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.MoveHandsRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ReleaseHandsControlRequest;
@@ -801,13 +803,15 @@ public class FossilWatchAdapter extends WatchAdapter {
}
protected void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value) {
- switch (value[1]) {
- case 2: {
+ byte requestType = value[1];
+
+ switch (requestType) {
+ case 0x02: {
byte syncId = value[2];
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(QHybridSupport.ITEM_LAST_HEARTBEAT, DateFormat.getTimeInstance().format(new Date())));
break;
}
- case 8: {
+ case 0x08: { // FORWARD_TO_PHONE
if (value.length != 12) {
throw new RuntimeException("wrong button message");
}
@@ -819,34 +823,93 @@ public class FossilWatchAdapter extends WatchAdapter {
log("Button press on button " + button);
Intent i = new Intent(QHYBRID_EVENT_BUTTON_PRESS);
- i.setPackage(BuildConfig.APPLICATION_ID);
i.putExtra("BUTTON", button);
getContext().sendBroadcast(i);
+
+ LOG.debug("Sent broadcast intent: ACTION={} EXTRA=BUTTON={}", QHYBRID_EVENT_BUTTON_PRESS, button);
}
break;
}
- case 5: {
+ case 0x05: { // FORWARD_TO_PHONE_MULTI / VOLUME_UP / VOLUME_DOWN / MUSIC_CONTROL
if (value.length != 4) {
throw new RuntimeException("wrong button message");
}
int action = value[3];
- String actionString = "SINGLE";
- if (action == 3) actionString = "DOUBLE";
- else if (action == 4) actionString = "LONG";
+ String upperButtonFunction = getDeviceSpecificPreferences().getString("top_button_function", "");
+ String middleButtonFunction = getDeviceSpecificPreferences().getString("middle_button_function", "");
+ String bottomButtonFunction = getDeviceSpecificPreferences().getString("bottom_button_function", "");
+ boolean musicControlEnabled = upperButtonFunction.equals("MUSIC_CONTROL") || middleButtonFunction.equals("MUSIC_CONTROL") || bottomButtonFunction.equals("MUSIC_CONTROL");
+ MusicControlRequest.MUSIC_WATCH_REQUEST request = MusicControlRequest.MUSIC_WATCH_REQUEST.fromCommandByte((byte)action);
+ GBDevice currentDevice = getDeviceSupport().getDevice();
+ if (((QHybridCoordinator) currentDevice.getDeviceCoordinator()).isHybridHR(currentDevice)
+ || request == MusicControlRequest.MUSIC_WATCH_REQUEST.MUSIC_REQUEST_LOUDER
+ || request == MusicControlRequest.MUSIC_WATCH_REQUEST.MUSIC_REQUEST_QUITER
+ || (musicControlEnabled && request == MusicControlRequest.MUSIC_WATCH_REQUEST.MUSIC_REQUEST_PLAY_PAUSE)
+ || (musicControlEnabled && request == MusicControlRequest.MUSIC_WATCH_REQUEST.MUSIC_REQUEST_NEXT)
+ || (musicControlEnabled && request == MusicControlRequest.MUSIC_WATCH_REQUEST.MUSIC_REQUEST_PREVIOUS)
+ ) {
+ handleMusicRequest(value);
+ } else {
+ String actionString = "SINGLE";
+ if (action == 3) actionString = "DOUBLE";
+ else if (action == 4) actionString = "LONG";
- // lastButtonIndex = index;
- log(actionString + " button press");
+ // lastButtonIndex = index;
+ log(actionString + " button press");
- Intent i = new Intent(QHYBRID_EVENT_MULTI_BUTTON_PRESS);
- i.putExtra("ACTION", actionString);
- getContext().sendBroadcast(i);
+ Intent i = new Intent(QHYBRID_EVENT_MULTI_BUTTON_PRESS);
+ i.putExtra("ACTION", actionString);
+ getContext().sendBroadcast(i);
+
+ LOG.debug("Sent broadcast intent: ACTION={} EXTRA=ACTION={}", QHYBRID_EVENT_MULTI_BUTTON_PRESS, actionString);
+ }
break;
}
}
}
+ private void handleMusicRequest(byte[] value) {
+ byte command = value[3];
+ LOG.info("got music command: " + command);
+ MusicControlRequest.MUSIC_WATCH_REQUEST request = MusicControlRequest.MUSIC_WATCH_REQUEST.fromCommandByte(command);
+
+ GBDeviceEventMusicControl deviceEventMusicControl = new GBDeviceEventMusicControl();
+ deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PLAY;
+
+ // TODO add skipping/seeking
+
+ switch (request) {
+ case MUSIC_REQUEST_PLAY_PAUSE: {
+ queueWrite(new MusicControlRequest(MusicControlRequest.MUSIC_PHONE_REQUEST.MUSIC_REQUEST_PLAY_PAUSE));
+ deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PLAYPAUSE;
+ break;
+ }
+ case MUSIC_REQUEST_NEXT: {
+ queueWrite(new MusicControlRequest(MusicControlRequest.MUSIC_PHONE_REQUEST.MUSIC_REQUEST_NEXT));
+ deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.NEXT;
+ break;
+ }
+ case MUSIC_REQUEST_PREVIOUS: {
+ queueWrite(new MusicControlRequest(MusicControlRequest.MUSIC_PHONE_REQUEST.MUSIC_REQUEST_PREVIOUS));
+ deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PREVIOUS;
+ break;
+ }
+ case MUSIC_REQUEST_LOUDER: {
+ queueWrite(new MusicControlRequest(MusicControlRequest.MUSIC_PHONE_REQUEST.MUSIC_REQUEST_LOUDER));
+ deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEUP;
+ break;
+ }
+ case MUSIC_REQUEST_QUITER: {
+ queueWrite(new MusicControlRequest(MusicControlRequest.MUSIC_PHONE_REQUEST.MUSIC_REQUEST_QUITER));
+ deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEDOWN;
+ break;
+ }
+ }
+
+ getDeviceSupport().evaluateGBDeviceEvent(deviceEventMusicControl);
+ }
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java
index 1f9f3b6d60..f645a40f38 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java
@@ -27,7 +27,6 @@ import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.reque
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.UnitsConfigItem;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.VibrationStrengthConfigItem;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_PHONE_REQUEST;
-import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_WATCH_REQUEST;
import static nodomain.freeyourgadget.gadgetbridge.util.BitmapUtil.convertDrawableToBitmap;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_ID;
import static nodomain.freeyourgadget.gadgetbridge.util.StringUtils.shortenPackageName;
@@ -103,7 +102,6 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
-import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventNotificationControl;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.CommuteActionsActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.FossilFileReader;
@@ -130,9 +128,8 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NavigationInfoSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
-import nodomain.freeyourgadget.gadgetbridge.model.weather.Weather;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
-import nodomain.freeyourgadget.gadgetbridge.webview.CurrentPosition;
+import nodomain.freeyourgadget.gadgetbridge.model.weather.Weather;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
@@ -196,6 +193,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
import nodomain.freeyourgadget.gadgetbridge.util.Version;
import nodomain.freeyourgadget.gadgetbridge.util.calendar.CalendarEvent;
import nodomain.freeyourgadget.gadgetbridge.util.calendar.CalendarManager;
+import nodomain.freeyourgadget.gadgetbridge.webview.CurrentPosition;
public class FossilHRWatchAdapter extends FossilWatchAdapter {
public static final int MESSAGE_WHAT_VOICE_DATA_RECEIVED = 0;
@@ -1964,8 +1962,6 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
} else if (value[7] == 0x03) {
handleQuickReplyRequest(value);
}
- } else if (requestType == (byte) 0x05) {
- handleMusicRequest(value);
} else if (requestType == (byte) 0x01) {
int eventId = value[2];
LOG.info("got event id " + eventId);
@@ -2143,47 +2139,6 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
queueWrite(new QuickReplyConfirmationPutRequest(callId));
}
- private void handleMusicRequest(byte[] value) {
- byte command = value[3];
- LOG.info("got music command: " + command);
- MUSIC_WATCH_REQUEST request = MUSIC_WATCH_REQUEST.fromCommandByte(command);
-
- GBDeviceEventMusicControl deviceEventMusicControl = new GBDeviceEventMusicControl();
- deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PLAY;
-
- // TODO add skipping/seeking
-
- switch (request) {
- case MUSIC_REQUEST_PLAY_PAUSE: {
- queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_PLAY_PAUSE));
- deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PLAYPAUSE;
- break;
- }
- case MUSIC_REQUEST_NEXT: {
- queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_NEXT));
- deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.NEXT;
- break;
- }
- case MUSIC_REQUEST_PREVIOUS: {
- queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_PREVIOUS));
- deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PREVIOUS;
- break;
- }
- case MUSIC_REQUEST_LOUDER: {
- queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_LOUDER));
- deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEUP;
- break;
- }
- case MUSIC_REQUEST_QUITER: {
- queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_QUITER));
- deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEDOWN;
- break;
- }
- }
-
- getDeviceSupport().evaluateGBDeviceEvent(deviceEventMusicControl);
- }
-
@Override
public void setCommuteMenuMessage(String message, boolean finished) {
queueWrite(new SetCommuteMenuMessage(message, finished, this));
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java
index d86adca2df..b1d936be12 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java
@@ -27,7 +27,12 @@ public enum ConfigPayload {
new byte[]{(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x2E, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x0F, (byte) 0x00, (byte) 0x8B, (byte) 0x00, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x01, (byte) 0x08, (byte) 0x01, (byte) 0x14, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0xFE, (byte) 0x08, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0xBF, (byte) 0xD5, (byte) 0x54, (byte) 0xD1}
),
FORWARD_TO_PHONE_MULTI(
- "forward to phone (multifunction)", // This is "play/pause music" in the official app
+ "forward to phone (multifunction)", // Identical to MUSIC_CONTROL, but handled differently in FossilWatchAdapter
+ new byte[]{(byte) 0x01, (byte) 0x06, (byte) 0x12, (byte) 0x00},
+ new byte[]{(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x06, (byte) 0x12, (byte) 0x63, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x1D, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0xF6, (byte) 0x00, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0x42, (byte) 0x02, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0x43, (byte) 0x03, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0x44, (byte) 0x04, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x1E, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x0D, (byte) 0x00, (byte) 0x8C, (byte) 0x01, (byte) 0xCD, (byte) 0x00, (byte) 0x01, (byte) 0x93, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x03, (byte) 0x0D, (byte) 0x00, (byte) 0x8C, (byte) 0x01, (byte) 0xB6, (byte) 0x00, (byte) 0x01, (byte) 0x93, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x04, (byte) 0x0D, (byte) 0x00, (byte) 0x8C, (byte) 0x01, (byte) 0xB5, (byte) 0x00, (byte) 0x01, (byte) 0x93, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0xFE, (byte) 0x08, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x7B, (byte) 0x56, (byte) 0x4E, (byte) 0x97}
+ ),
+ MUSIC_CONTROL(
+ "control music (play/pause/prev/next", // Identical to FORWARD_TO_PHONE_MULTI, but handled differently in FossilWatchAdapter
new byte[]{(byte) 0x01, (byte) 0x06, (byte) 0x12, (byte) 0x00},
new byte[]{(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x06, (byte) 0x12, (byte) 0x63, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x1D, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0xF6, (byte) 0x00, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0x42, (byte) 0x02, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0x43, (byte) 0x03, (byte) 0x00, (byte) 0x85, (byte) 0x01, (byte) 0x44, (byte) 0x04, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x1E, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x0D, (byte) 0x00, (byte) 0x8C, (byte) 0x01, (byte) 0xCD, (byte) 0x00, (byte) 0x01, (byte) 0x93, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x03, (byte) 0x0D, (byte) 0x00, (byte) 0x8C, (byte) 0x01, (byte) 0xB6, (byte) 0x00, (byte) 0x01, (byte) 0x93, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x04, (byte) 0x0D, (byte) 0x00, (byte) 0x8C, (byte) 0x01, (byte) 0xB5, (byte) 0x00, (byte) 0x01, (byte) 0x93, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0xFE, (byte) 0x08, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x7B, (byte) 0x56, (byte) 0x4E, (byte) 0x97}
),
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index 8f6651d078..d77245d6d8 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -5439,15 +5439,16 @@
- - Forward to phone
- - Forward to phone (multifunction)
- - Stopwatch
- - Date
- - Last notification
- - Second timezone
- - Volume up
- - Volume down
- - Step goal progress
+ - @string/qhybrid_button_function_forward
+ - @string/qhybrid_button_function_forward_multi
+ - @string/qhybrid_button_function_stopwatch
+ - @string/qhybrid_button_function_date
+ - @string/qhybrid_button_function_last_notif
+ - @string/qhybrid_button_function_2nd_tz
+ - @string/qhybrid_button_function_volume_up
+ - @string/qhybrid_button_function_volume_down
+ - @string/qhybrid_button_function_step_goal
+ - @string/qhybrid_button_function_control_music
@@ -5461,6 +5462,7 @@
- VOLUME_UP
- VOLUME_DOWN
- STEP_GOAL_COMPLETION
+ - MUSIC_CONTROL
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ddcae88e0b..cb6384a728 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -4714,4 +4714,14 @@
Top button function
Middle button function
Bottom button function
+ Forward to phone
+ Forward to phone (multifunction)
+ Stopwatch
+ Date
+ Last notification
+ Second timezone
+ Volume up
+ Volume down
+ Step goal progress
+ Control music player