mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-01 06:22:55 +01:00
Fossil Hybrid HR: Dismiss incoming call with a quick SMS reply (#2264)
Merge branch 'master' into fossil_hr_quick_replies Fossil Hybrid HR: Allow between 1 and 16 quick replies to be configured Fossil Hybrid HR: Dismiss incoming call with a quick SMS reply Co-authored-by: Arjan Schrijver <a_gadgetbridge@anymore.nl> Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2264 Co-Authored-By: Arjan Schrijver <arjan5@noreply.codeberg.org> Co-Committed-By: Arjan Schrijver <arjan5@noreply.codeberg.org>
This commit is contained in:
parent
830197168b
commit
2f37d4c839
@ -196,6 +196,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
||||
return new int[]{
|
||||
R.xml.devicesettings_fossilhybridhr,
|
||||
R.xml.devicesettings_autoremove_notifications,
|
||||
R.xml.devicesettings_canned_dismisscall_16,
|
||||
R.xml.devicesettings_pairingkey,
|
||||
R.xml.devicesettings_custom_deviceicon
|
||||
};
|
||||
|
@ -58,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||
@ -767,4 +768,10 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
return watchAdapter.onCharacteristicChanged(gatt, characteristic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) {
|
||||
if(this.watchAdapter instanceof FossilHRWatchAdapter){
|
||||
((FossilHRWatchAdapter) watchAdapter).setQuickRepliesConfiguration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
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.HRConfigActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HybridHRActivitySampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration;
|
||||
@ -114,6 +115,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification.NotificationFilterPutHRRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification.NotificationImage;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification.NotificationImagePutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.quickreply.QuickReplyConfigurationPutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.quickreply.QuickReplyConfirmationPutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomWidget;
|
||||
@ -139,6 +142,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
|
||||
private NotificationHRConfiguration[] notificationConfigurations;
|
||||
|
||||
private CallSpec currentCallSpec = null;
|
||||
private MusicSpec currentSpec = null;
|
||||
|
||||
int imageNameIndex = 0;
|
||||
@ -201,6 +205,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
GB.toast(getContext().getString(R.string.fossil_hr_auth_failed), Toast.LENGTH_LONG, GB.ERROR);
|
||||
|
||||
setNotificationConfigurations();
|
||||
setQuickRepliesConfiguration();
|
||||
|
||||
if (authenticated) {
|
||||
setVibrationStrength();
|
||||
@ -290,6 +295,27 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations, this));
|
||||
}
|
||||
|
||||
private String[] getQuickReplies() {
|
||||
ArrayList<String> configuredReplies = new ArrayList<>();
|
||||
Prefs prefs = new Prefs(getDeviceSpecificPreferences());
|
||||
for (int i=1; i<=16; i++) {
|
||||
String quickReply = prefs.getString("canned_message_dismisscall_" + i, null);
|
||||
if (quickReply != null) {
|
||||
configuredReplies.add(quickReply);
|
||||
}
|
||||
}
|
||||
return configuredReplies.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public void setQuickRepliesConfiguration() {
|
||||
String[] quickReplies = getQuickReplies();
|
||||
if (quickReplies.length > 0) {
|
||||
NotificationImage quickReplyIcon = new NotificationImage("icMessage.icon", NotificationImage.getEncodedIconFromDrawable(getContext().getResources().getDrawable(R.drawable.ic_message_outline)), 24, 24);
|
||||
queueWrite(new NotificationImagePutRequest(quickReplyIcon, this));
|
||||
queueWrite(new QuickReplyConfigurationPutRequest(quickReplies, this));
|
||||
}
|
||||
}
|
||||
|
||||
private File getBackgroundFile() {
|
||||
return new File(getContext().getExternalFilesDir(null), "hr_background.bin");
|
||||
}
|
||||
@ -994,7 +1020,15 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
@Override
|
||||
public void onSetCallState(CallSpec callSpec) {
|
||||
super.onSetCallState(callSpec);
|
||||
queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), callSpec.command == CallSpec.CALL_INCOMING, this));
|
||||
String[] quickReplies = getQuickReplies();
|
||||
boolean quickRepliesEnabled = quickReplies.length > 0 && callSpec.number != null && callSpec.number.matches("^\\+(?:[0-9] ?){6,14}[0-9]$");
|
||||
if (callSpec.command == CallSpec.CALL_INCOMING) {
|
||||
currentCallSpec = callSpec;
|
||||
queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), true, quickRepliesEnabled, this));
|
||||
} else {
|
||||
currentCallSpec = null;
|
||||
queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), false, quickRepliesEnabled, this));
|
||||
}
|
||||
}
|
||||
|
||||
// this method is based on the one from AppMessageHandlerYWeather.java
|
||||
@ -1314,6 +1348,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
handleCallRequest(value);
|
||||
} else if (value[7] == 0x02) {
|
||||
handleDeleteNotification(value);
|
||||
} else if (value[7] == 0x03) {
|
||||
handleQuickReplyRequest(value);
|
||||
}
|
||||
} else if (requestType == (byte) 0x05) {
|
||||
handleMusicRequest(value);
|
||||
@ -1410,7 +1446,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
|
||||
private void handleCallRequest(byte[] value) {
|
||||
boolean acceptCall = value[7] == (byte) 0x00;
|
||||
queueWrite(new PlayCallNotificationRequest("", false, this));
|
||||
queueWrite(new PlayCallNotificationRequest("", false, false, this));
|
||||
|
||||
GBDeviceEventCallControl callControlEvent = new GBDeviceEventCallControl();
|
||||
callControlEvent.event = acceptCall ? GBDeviceEventCallControl.Event.START : GBDeviceEventCallControl.Event.REJECT;
|
||||
@ -1418,6 +1454,25 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
getDeviceSupport().evaluateGBDeviceEvent(callControlEvent);
|
||||
}
|
||||
|
||||
private void handleQuickReplyRequest(byte[] value) {
|
||||
if (currentCallSpec == null) {
|
||||
return;
|
||||
}
|
||||
String[] quickReplies = getQuickReplies();
|
||||
byte callId = value[3];
|
||||
byte replyChoice = value[8];
|
||||
if (replyChoice >= quickReplies.length) {
|
||||
return;
|
||||
}
|
||||
GBDeviceEventNotificationControl devEvtNotificationControl = new GBDeviceEventNotificationControl();
|
||||
devEvtNotificationControl.handle = callId;
|
||||
devEvtNotificationControl.phoneNumber = currentCallSpec.number;
|
||||
devEvtNotificationControl.reply = quickReplies[replyChoice];
|
||||
devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.REPLY;
|
||||
getDeviceSupport().evaluateGBDeviceEvent(devEvtNotificationControl);
|
||||
queueWrite(new QuickReplyConfirmationPutRequest(callId));
|
||||
}
|
||||
|
||||
private void handleMusicRequest(byte[] value) {
|
||||
byte command = value[3];
|
||||
LOG.info("got music command: " + command);
|
||||
|
@ -36,6 +36,9 @@ public class SupportedFileVersionsInfo implements DeviceInfo {
|
||||
supportedFileVersions.put(handle, version);
|
||||
}
|
||||
|
||||
// Add quick replies packet type
|
||||
supportedFileVersions.put((byte) 0x13, (short) 0x0002);
|
||||
// Add phone app packet type
|
||||
supportedFileVersions.put((byte) 0x15, (short) 0x0003);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,11 @@ public class FilePutRequest extends FilePutRawRequest {
|
||||
|
||||
buffer.putShort(fileHandle.getHandle());
|
||||
buffer.putShort(fileVersion);
|
||||
buffer.putInt(0);
|
||||
if (fileHandle == FileHandle.REPLY_MESSAGES) {
|
||||
buffer.put(new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x0d, (byte) 0x00});
|
||||
} else {
|
||||
buffer.putInt(0);
|
||||
}
|
||||
buffer.putInt(file.length);
|
||||
|
||||
buffer.put(file);
|
||||
|
@ -20,6 +20,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.foss
|
||||
|
||||
public class DismissTextNotificationRequest extends PlayNotificationRequest {
|
||||
public DismissTextNotificationRequest(int messageId, FossilWatchAdapter adapter) {
|
||||
super(7, 2, "", "", "", messageId, adapter);
|
||||
super(NotificationType.DISMISS_NOTIFICATION, 2, "", "", "", messageId, adapter);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
/* Copyright (C) 2020-2021 Arjan Schrijver
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification;
|
||||
|
||||
public enum NotificationType {
|
||||
INCOMING_CALL(1),
|
||||
TEXT(2),
|
||||
NOTIFICATION(3),
|
||||
EMAIL(4),
|
||||
CALENDAR(5),
|
||||
MISSED_CALL(6),
|
||||
DISMISS_NOTIFICATION(7);
|
||||
|
||||
private int type;
|
||||
|
||||
NotificationType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
@ -24,8 +24,18 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.foss
|
||||
public class PlayCallNotificationRequest extends PlayNotificationRequest {
|
||||
private final static int MESSAGE_ID_CALL = 1;
|
||||
|
||||
public PlayCallNotificationRequest(String number, boolean callStart, FossilWatchAdapter adapter) {
|
||||
super(callStart ? 1 : 7, callStart ? 0b00011000 : 2,
|
||||
private static int notificationFlags(boolean callStart, boolean quickReplies) {
|
||||
if (callStart && quickReplies) {
|
||||
return 0b00111000;
|
||||
} else if (callStart) {
|
||||
return 0b00011000;
|
||||
} else {
|
||||
return 0b00000010;
|
||||
}
|
||||
}
|
||||
|
||||
public PlayCallNotificationRequest(String number, boolean callStart, boolean quickReplies, FossilWatchAdapter adapter) {
|
||||
super(callStart ? NotificationType.INCOMING_CALL : NotificationType.DISMISS_NOTIFICATION, notificationFlags(callStart, quickReplies),
|
||||
ByteBuffer.wrap(new byte[]{(byte) 0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}).order(ByteOrder.LITTLE_ENDIAN).getInt(),
|
||||
number, "Incoming Call", MESSAGE_ID_CALL, adapter);
|
||||
}
|
||||
|
@ -28,15 +28,15 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
|
||||
public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
public PlayNotificationRequest(int notificationType, int flags, String packageName, FossilWatchAdapter adapter) {
|
||||
public PlayNotificationRequest(NotificationType notificationType, int flags, String packageName, FossilWatchAdapter adapter) {
|
||||
super(FileHandle.NOTIFICATION_PLAY, createFile(notificationType, flags, packageName, packageName, packageName, getCurrentMessageId()), adapter);
|
||||
}
|
||||
|
||||
public PlayNotificationRequest(int notificationType, int flags, String packageName, String sender, String message, int notificationId, FossilWatchAdapter adapter) {
|
||||
public PlayNotificationRequest(NotificationType notificationType, int flags, String packageName, String sender, String message, int notificationId, FossilWatchAdapter adapter) {
|
||||
super(FileHandle.NOTIFICATION_PLAY, createFile(notificationType, flags, packageName, sender, message, notificationId), adapter);
|
||||
}
|
||||
|
||||
public PlayNotificationRequest(int notificationType, int flags, int packageCRC, String sender, String message, int messageId, FossilWatchAdapter adapter) {
|
||||
public PlayNotificationRequest(NotificationType notificationType, int flags, int packageCRC, String sender, String message, int messageId, FossilWatchAdapter adapter) {
|
||||
super(FileHandle.NOTIFICATION_PLAY, createFile(notificationType, flags, "whatever", sender, message, packageCRC, messageId), adapter);
|
||||
}
|
||||
|
||||
@ -44,13 +44,13 @@ public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
return (int) System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private static byte[] createFile(int notificationType, int flags, String packageName, String sender, String message, int messageId){
|
||||
private static byte[] createFile(NotificationType notificationType, int flags, String packageName, String sender, String message, int messageId){
|
||||
CRC32 crc = new CRC32();
|
||||
crc.update(packageName.getBytes());
|
||||
return createFile(notificationType, flags, packageName, sender, message, (int)crc.getValue(), messageId);
|
||||
}
|
||||
|
||||
private static byte[] createFile(int notificationType, int flags, String title, String sender, String message, int packageCrc, int messageId) {
|
||||
private static byte[] createFile(NotificationType notificationType, int flags, String title, String sender, String message, int packageCrc, int messageId) {
|
||||
byte lengthBufferLength = (byte) 10;
|
||||
byte uidLength = (byte) 4;
|
||||
byte appBundleCRCLength = (byte) 4;
|
||||
@ -74,7 +74,7 @@ public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
mainBuffer.putShort(mainBufferLength);
|
||||
|
||||
mainBuffer.put(lengthBufferLength);
|
||||
mainBuffer.put((byte) notificationType);
|
||||
mainBuffer.put((byte) notificationType.getType());
|
||||
mainBuffer.put((byte) flags);
|
||||
mainBuffer.put(uidLength);
|
||||
mainBuffer.put(appBundleCRCLength);
|
||||
|
@ -20,10 +20,10 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.foss
|
||||
|
||||
public class PlayTextNotificationRequest extends PlayNotificationRequest {
|
||||
public PlayTextNotificationRequest(String packageName, String sender, String message, int messageId, FossilWatchAdapter adapter) {
|
||||
super(3, 2, packageName, sender, message, messageId, adapter);
|
||||
super(NotificationType.NOTIFICATION, 2, packageName, sender, message, messageId, adapter);
|
||||
}
|
||||
|
||||
public PlayTextNotificationRequest(String packageName, FossilWatchAdapter adapter) {
|
||||
super(3, 2, packageName, adapter);
|
||||
super(NotificationType.NOTIFICATION, 2, packageName, adapter);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,8 @@ public class NotificationImage extends AssetFile {
|
||||
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
|
||||
paint.setColorFilter(f);
|
||||
c.drawBitmap(bitmap, 0, 0, paint);
|
||||
// Increase brightness
|
||||
// bitmap = changeBitmapContrastBrightness(bitmap, 1, -50);
|
||||
// Return result
|
||||
return bitmap;
|
||||
}
|
||||
|
@ -30,6 +30,10 @@ public class NotificationImagePutRequest extends FilePutRequest {
|
||||
super(FileHandle.ASSET_NOTIFICATION_IMAGES, prepareFileData(images), adapter);
|
||||
}
|
||||
|
||||
public NotificationImagePutRequest(NotificationImage image, FossilWatchAdapter adapter) {
|
||||
super(FileHandle.ASSET_REPLY_IMAGES, prepareFileData(image), adapter);
|
||||
}
|
||||
|
||||
private static byte[] prepareFileData(NotificationImage[] images) throws IOException {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
/* Copyright (C) 2019-2021 Arjan Schrijver
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.quickreply;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
|
||||
public class QuickReplyConfigurationPutRequest extends FilePutRequest {
|
||||
public QuickReplyConfigurationPutRequest(String[] replies, FossilHRWatchAdapter adapter) {
|
||||
super(FileHandle.REPLY_MESSAGES, createFile(replies), adapter);
|
||||
}
|
||||
|
||||
private static byte[] createFile(String[] replies) {
|
||||
String[] processedReplies = new String[replies.length];
|
||||
int fileLength = 0;
|
||||
|
||||
byte[] mysteryHeader = new byte[]{(byte) 0x02, (byte) 0x0b, (byte) 0x46, (byte) 0x00, (byte) 0x03, (byte) 0x19, (byte) 0x00, (byte) 0x00, (byte) 0x00};
|
||||
|
||||
Charset charsetUTF8 = Charset.forName("UTF-8");
|
||||
String iconName = StringUtils.terminateNull("icMessage.icon");
|
||||
byte[] iconNameBytes = iconName.getBytes(charsetUTF8);
|
||||
|
||||
for (int index=0; index< replies.length; index++) {
|
||||
String reply = replies[index];
|
||||
if (reply.length() > 50) {
|
||||
reply = reply.substring(0, 50);
|
||||
}
|
||||
processedReplies[index] = StringUtils.terminateNull(reply);
|
||||
fileLength += 8 + processedReplies[index].length() + iconNameBytes.length;
|
||||
}
|
||||
|
||||
ByteBuffer mainBuffer = ByteBuffer.allocate(mysteryHeader.length + 4 + fileLength);
|
||||
mainBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
mainBuffer.put(mysteryHeader);
|
||||
mainBuffer.putInt(fileLength);
|
||||
|
||||
for (int index=0; index < processedReplies.length; index++) {
|
||||
byte[] msgBytes = processedReplies[index].getBytes(charsetUTF8);
|
||||
mainBuffer.putShort((short) (8 + msgBytes.length + iconNameBytes.length));
|
||||
mainBuffer.put((byte) 0x08);
|
||||
mainBuffer.put((byte) index);
|
||||
mainBuffer.putShort((short) msgBytes.length);
|
||||
mainBuffer.putShort((short) iconNameBytes.length);
|
||||
mainBuffer.put(msgBytes);
|
||||
mainBuffer.put(iconNameBytes);
|
||||
}
|
||||
|
||||
return mainBuffer.array();
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 2019-2021 Arjan Schrijver
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.quickreply;
|
||||
|
||||
import java.util.UUID;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
||||
|
||||
|
||||
public class QuickReplyConfirmationPutRequest extends FossilRequest {
|
||||
/**
|
||||
* Contains the bytes to confirm to the watch that a quick reply SMS has been sent.
|
||||
* @param callId
|
||||
*/
|
||||
public QuickReplyConfirmationPutRequest(byte callId) {
|
||||
this.data = new byte[]{
|
||||
(byte) 0x02,
|
||||
(byte) 0x04,
|
||||
callId,
|
||||
(byte) 0x00,
|
||||
(byte) 0x00,
|
||||
(byte) 0x00,
|
||||
(byte) 0x03,
|
||||
(byte) 0x00
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getStartSequence() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getRequestUUID() {
|
||||
return UUID.fromString("3dda0006-957f-7d4a-34a6-74696673696d");
|
||||
}
|
||||
}
|
@ -150,7 +150,7 @@
|
||||
<string name="pref_title_canned_replies">Replies</string>
|
||||
<string name="pref_title_canned_reply_suffix">Common suffix</string>
|
||||
<string name="pref_title_canned_messages_dismisscall">Call Dismissal</string>
|
||||
<string name="pref_title_canned_messages_set">Update on Pebble</string>
|
||||
<string name="pref_title_canned_messages_set">Update on device</string>
|
||||
<string name="pref_header_development">Developer options</string>
|
||||
<string name="pref_title_development_miaddr">Mi Band address</string>
|
||||
<string name="pref_title_pebble_settings">Pebble settings</string>
|
||||
|
Loading…
Reference in New Issue
Block a user