mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-06-05 21:49:48 +02:00
Merge branch 'fossil-q-hybrid' of github.com:dakhnod/Gadgetbridge into q-hybrid-hr
This commit is contained in:
@@ -396,18 +396,17 @@ public class ConfigActivity extends AbstractGBActivity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemWithDetails buttonInfo = device.getDeviceInfo(FossilWatchAdapter.ITEM_BUTTONS);
|
final String buttonJson = device.getDeviceInfo(FossilWatchAdapter.ITEM_BUTTONS).getDetails();
|
||||||
try {
|
try {
|
||||||
JSONArray buttonConfig = new JSONArray(new String[]{"Unknown", "Unknown", "Unknown"});
|
JSONArray buttonConfig_;
|
||||||
String buttonJson = null;
|
if (buttonJson == null || buttonJson.isEmpty()) {
|
||||||
if (buttonInfo != null) {
|
buttonConfig_ = new JSONArray(new String[]{"", "", ""});
|
||||||
buttonJson = buttonInfo.getDetails();
|
}else{
|
||||||
}
|
buttonConfig_ = new JSONArray(buttonJson);
|
||||||
if (buttonJson != null && !buttonJson.isEmpty()) {
|
|
||||||
buttonConfig = new JSONArray(buttonJson);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final JSONArray finalButtonConfig = buttonConfig;
|
final JSONArray buttonConfig = buttonConfig_;
|
||||||
|
|
||||||
LinearLayout buttonLayout = findViewById(R.id.buttonConfigLayout);
|
LinearLayout buttonLayout = findViewById(R.id.buttonConfigLayout);
|
||||||
buttonLayout.removeAllViews();
|
buttonLayout.removeAllViews();
|
||||||
findViewById(R.id.buttonOverwriteButtons).setVisibility(View.GONE);
|
findViewById(R.id.buttonOverwriteButtons).setVisibility(View.GONE);
|
||||||
@@ -437,11 +436,14 @@ public class ConfigActivity extends AbstractGBActivity {
|
|||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
dialog.cancel();
|
dialog.cancel();
|
||||||
ConfigPayload selected = payloads[which];
|
ConfigPayload selected = payloads[which];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
finalButtonConfig.put(currentIndex, selected.toString());
|
buttonConfig.put(currentIndex, selected.toString());
|
||||||
device.addDeviceInfo(new GenericItem(FossilWatchAdapter.ITEM_BUTTONS, finalButtonConfig.toString()));
|
device.addDeviceInfo(new GenericItem(FossilWatchAdapter.ITEM_BUTTONS, buttonConfig.toString()));
|
||||||
updateSettings();
|
updateSettings();
|
||||||
LocalBroadcastManager.getInstance(ConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS));
|
Intent buttonIntent = new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS);
|
||||||
|
buttonIntent.putExtra(FossilWatchAdapter.ITEM_BUTTONS, buttonConfig.toString());
|
||||||
|
LocalBroadcastManager.getInstance(ConfigActivity.this).sendBroadcast(buttonIntent);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -455,9 +457,9 @@ public class ConfigActivity extends AbstractGBActivity {
|
|||||||
|
|
||||||
buttonLayout.addView(buttonTextView);
|
buttonLayout.addView(buttonTextView);
|
||||||
}
|
}
|
||||||
} catch (
|
} catch (JSONException e) {
|
||||||
JSONException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
GB.toast("error parsing button config", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -93,7 +93,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
|||||||
|
|
||||||
public boolean supportsAlarmConfiguration() {
|
public boolean supportsAlarmConfiguration() {
|
||||||
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
||||||
if(connectedDevice == null || connectedDevice.getType() != DeviceType.FOSSILQHYBRID){
|
if(connectedDevice == null || connectedDevice.getType() != DeviceType.FOSSILQHYBRID || connectedDevice.getState() != GBDevice.State.INITIALIZED){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@@ -51,6 +51,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapterFactory;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapterFactory;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.DownloadFileRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.DownloadFileRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
@@ -178,7 +179,8 @@ public class QHybridSupport extends QHybridBaseSupport {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QHYBRID_COMMAND_OVERWRITE_BUTTONS: {
|
case QHYBRID_COMMAND_OVERWRITE_BUTTONS: {
|
||||||
watchAdapter.overwriteButtons();
|
String buttonConfig = intent.getStringExtra(FossilWatchAdapter.ITEM_BUTTONS);
|
||||||
|
watchAdapter.overwriteButtons(buttonConfig);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QHYBRID_COMMAND_NOTIFICATION_CONFIG_CHANGED: {
|
case QHYBRID_COMMAND_NOTIFICATION_CONFIG_CHANGED: {
|
||||||
|
@@ -31,7 +31,7 @@ public abstract class WatchAdapter {
|
|||||||
public abstract void playPairingAnimation();
|
public abstract void playPairingAnimation();
|
||||||
public abstract void playNotification(NotificationConfiguration config);
|
public abstract void playNotification(NotificationConfiguration config);
|
||||||
public abstract void setTime();
|
public abstract void setTime();
|
||||||
public abstract void overwriteButtons();
|
public abstract void overwriteButtons(String buttonConfigJson);
|
||||||
public abstract void setActivityHand(double progress);
|
public abstract void setActivityHand(double progress);
|
||||||
public abstract void setHands(short hour, short minute);
|
public abstract void setHands(short hour, short minute);
|
||||||
public abstract void vibrate(PlayNotificationRequest.VibrationType vibration);
|
public abstract void vibrate(PlayNotificationRequest.VibrationType vibration);
|
||||||
|
@@ -3,6 +3,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fos
|
|||||||
import android.bluetooth.BluetoothGatt;
|
import android.bluetooth.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@@ -19,6 +20,7 @@ import java.util.Date;
|
|||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
|
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper;
|
||||||
@@ -34,10 +36,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Req
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.AlarmsGetRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.AlarmsSetRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.AlarmsSetRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.button.ButtonConfigurationGetRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationGetRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.NotificationFilterPutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.NotificationFilterPutRequest;
|
||||||
@@ -48,6 +47,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.mis
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.RequestHandControlRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.RequestHandControlRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.ITEM_STEP_GOAL;
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.ITEM_TIMEZONE_OFFSET;
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.ITEM_VIBRATION_STRENGTH;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_EVENT_BUTTON_PRESS;
|
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_EVENT_BUTTON_PRESS;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_EVENT_MULTI_BUTTON_PRESS;
|
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_EVENT_MULTI_BUTTON_PRESS;
|
||||||
|
|
||||||
@@ -58,9 +60,14 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
private int MTU = 23;
|
private int MTU = 23;
|
||||||
|
|
||||||
private String ITEM_MTU = "MTU";
|
private final String ITEM_MTU = "MTU";
|
||||||
static public final String ITEM_BUTTONS = "BUTTONS";
|
static public final String ITEM_BUTTONS = "BUTTONS";
|
||||||
|
|
||||||
|
private final String CONFIG_ITEM_STEP_GOAL = "step_goal";
|
||||||
|
private final String CONFIG_ITEM_VIBRATION_STRENGTH = "vibration_strength";
|
||||||
|
private final String CONFIG_ITEM_TIMEZONE_OFFSET = "timezone_offset";
|
||||||
|
public final String CONFIG_ITEM_BUTTONS = "buttons";
|
||||||
|
|
||||||
private int lastButtonIndex = -1;
|
private int lastButtonIndex = -1;
|
||||||
|
|
||||||
Logger logger = LoggerFactory.getLogger(getClass());
|
Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
@@ -76,11 +83,16 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
queueWrite(new RequestMtuRequest(512), false);
|
queueWrite(new RequestMtuRequest(512), false);
|
||||||
}
|
}
|
||||||
queueWrite(new ConfigurationGetRequest(this), false);
|
// queueWrite(new FileCloseRequest((short) 0xFFFF));
|
||||||
|
// queueWrite(new ConfigurationGetRequest(this), false);
|
||||||
|
|
||||||
|
syncConfiguration();
|
||||||
|
|
||||||
syncNotificationSettings();
|
syncNotificationSettings();
|
||||||
|
|
||||||
queueWrite(new ButtonConfigurationGetRequest(this) {
|
syncButtonSettings();
|
||||||
|
|
||||||
|
/* queueWrite(new ButtonConfigurationGetRequest(this) {
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationsGet(ConfigPayload[] configs) {
|
public void onConfigurationsGet(ConfigPayload[] configs) {
|
||||||
super.onConfigurationsGet(configs);
|
super.onConfigurationsGet(configs);
|
||||||
@@ -90,11 +102,43 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
String json = buttons.toString();
|
String json = buttons.toString();
|
||||||
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_BUTTONS, json));
|
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_BUTTONS, json));
|
||||||
}
|
}
|
||||||
});
|
}); */
|
||||||
|
|
||||||
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED), false);
|
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void syncButtonSettings(){
|
||||||
|
String buttonConfig = getDeviceSpecificPreferences().getString(CONFIG_ITEM_BUTTONS, null);
|
||||||
|
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_BUTTONS, buttonConfig));
|
||||||
|
overwriteButtons(buttonConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SharedPreferences getDeviceSpecificPreferences(){
|
||||||
|
return GBApplication.getDeviceSpecificSharedPrefs(
|
||||||
|
getDeviceSupport().getDevice().getAddress()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncConfiguration(){
|
||||||
|
SharedPreferences preferences = getDeviceSpecificPreferences();
|
||||||
|
|
||||||
|
int stepGoal = preferences.getInt(CONFIG_ITEM_STEP_GOAL, 1000000);
|
||||||
|
byte vibrationStrength = (byte) preferences.getInt(CONFIG_ITEM_VIBRATION_STRENGTH, 100);
|
||||||
|
int timezoneOffset = preferences.getInt(CONFIG_ITEM_TIMEZONE_OFFSET, 0);
|
||||||
|
|
||||||
|
GBDevice device = getDeviceSupport().getDevice();
|
||||||
|
|
||||||
|
device.addDeviceInfo(new GenericItem(ITEM_STEP_GOAL, String.valueOf(stepGoal)));
|
||||||
|
device.addDeviceInfo(new GenericItem(ITEM_VIBRATION_STRENGTH, String.valueOf(vibrationStrength)));
|
||||||
|
device.addDeviceInfo(new GenericItem(ITEM_TIMEZONE_OFFSET, String.valueOf(timezoneOffset)));
|
||||||
|
|
||||||
|
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.ConfigItem[]{
|
||||||
|
new ConfigurationPutRequest.DailyStepGoalConfigItem(stepGoal),
|
||||||
|
new ConfigurationPutRequest.VibrationStrengthConfigItem(vibrationStrength),
|
||||||
|
new ConfigurationPutRequest.TimezoneOffsetConfigItem((short) timezoneOffset)
|
||||||
|
}, this));
|
||||||
|
}
|
||||||
|
|
||||||
public int getMTU() {
|
public int getMTU() {
|
||||||
if (this.MTU < 0) throw new RuntimeException("MTU not configured");
|
if (this.MTU < 0) throw new RuntimeException("MTU not configured");
|
||||||
|
|
||||||
@@ -132,9 +176,15 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void overwriteButtons() {
|
public void overwriteButtons(String jsonConfigString) {
|
||||||
try {
|
try {
|
||||||
JSONArray buttonConfigJson = new JSONArray(getDeviceSupport().getDevice().getDeviceInfo(ITEM_BUTTONS).getDetails());
|
if(jsonConfigString == null) return;
|
||||||
|
getDeviceSpecificPreferences()
|
||||||
|
.edit()
|
||||||
|
.putString(CONFIG_ITEM_BUTTONS, jsonConfigString)
|
||||||
|
.apply();
|
||||||
|
JSONArray buttonConfigJson = new JSONArray(jsonConfigString);
|
||||||
|
// JSONArray buttonConfigJson = new JSONArray(getDeviceSupport().getDevice().getDeviceInfo(ITEM_BUTTONS).getDetails());
|
||||||
|
|
||||||
ConfigPayload[] payloads = new ConfigPayload[buttonConfigJson.length()];
|
ConfigPayload[] payloads = new ConfigPayload[buttonConfigJson.length()];
|
||||||
|
|
||||||
@@ -198,6 +248,11 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStepGoal(int stepGoal) {
|
public void setStepGoal(int stepGoal) {
|
||||||
|
getDeviceSpecificPreferences()
|
||||||
|
.edit()
|
||||||
|
.putInt(CONFIG_ITEM_STEP_GOAL, stepGoal)
|
||||||
|
.apply();
|
||||||
|
|
||||||
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.DailyStepGoalConfigItem(stepGoal), this) {
|
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.DailyStepGoalConfigItem(stepGoal), this) {
|
||||||
@Override
|
@Override
|
||||||
public void onFilePut(boolean success) {
|
public void onFilePut(boolean success) {
|
||||||
@@ -210,6 +265,11 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVibrationStrength(short strength) {
|
public void setVibrationStrength(short strength) {
|
||||||
|
getDeviceSpecificPreferences()
|
||||||
|
.edit()
|
||||||
|
.putInt(CONFIG_ITEM_VIBRATION_STRENGTH, (byte) strength)
|
||||||
|
.apply();
|
||||||
|
|
||||||
ConfigurationPutRequest.ConfigItem vibrationItem = new ConfigurationPutRequest.VibrationStrengthConfigItem((byte) strength);
|
ConfigurationPutRequest.ConfigItem vibrationItem = new ConfigurationPutRequest.VibrationStrengthConfigItem((byte) strength);
|
||||||
|
|
||||||
|
|
||||||
@@ -268,6 +328,11 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTimezoneOffsetMinutes(short offset) {
|
public void setTimezoneOffsetMinutes(short offset) {
|
||||||
|
getDeviceSpecificPreferences()
|
||||||
|
.edit()
|
||||||
|
.putInt(CONFIG_ITEM_TIMEZONE_OFFSET, offset)
|
||||||
|
.apply();
|
||||||
|
|
||||||
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.TimezoneOffsetConfigItem(offset), this){
|
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.TimezoneOffsetConfigItem(offset), this){
|
||||||
@Override
|
@Override
|
||||||
public void onFilePut(boolean success) {
|
public void onFilePut(boolean success) {
|
||||||
|
@@ -458,7 +458,7 @@ public class MisfitWatchAdapter extends WatchAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void overwriteButtons() {
|
public void overwriteButtons(String jsonConfigString) {
|
||||||
uploadFileRequest = new UploadFileRequest((short) 0x0800, new byte[]{
|
uploadFileRequest = new UploadFileRequest((short) 0x0800, new byte[]{
|
||||||
(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x10, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00,
|
(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x10, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00,
|
||||||
(byte) 0x30, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x2E, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01,
|
(byte) 0x30, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x2E, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01,
|
||||||
|
@@ -0,0 +1,160 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.microapp;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
public interface MicroAppCommand {
|
||||||
|
byte[] getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
class StartCriticalCommand implements MicroAppCommand{
|
||||||
|
@Override
|
||||||
|
public byte[] getData() {
|
||||||
|
return new byte[]{(byte) 0x03, (byte) 0x00};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CloseCommand implements MicroAppCommand{
|
||||||
|
@Override
|
||||||
|
public byte[] getData() {
|
||||||
|
return new byte[]{(byte) 0x01, (byte) 0x00};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DelayCommand implements MicroAppCommand{
|
||||||
|
private double delayInSeconds;
|
||||||
|
|
||||||
|
public DelayCommand(double delayInSeconds) {
|
||||||
|
this.delayInSeconds = delayInSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getData() {
|
||||||
|
return ByteBuffer.wrap(new byte[]{0x08, 0x01, 0x00, 0x00})
|
||||||
|
.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
.putShort(2, (short)(delayInSeconds * 10f))
|
||||||
|
.array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum VibrationType{
|
||||||
|
NORMAL((byte) 0x04);
|
||||||
|
|
||||||
|
private byte value;
|
||||||
|
|
||||||
|
VibrationType(byte value){
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getValue(){ return this.value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class VibrateCommand implements MicroAppCommand{
|
||||||
|
private VibrationType vibrationType;
|
||||||
|
|
||||||
|
public VibrateCommand(VibrationType vibrationType) {
|
||||||
|
this.vibrationType = vibrationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getData() {
|
||||||
|
return ByteBuffer.wrap(new byte[]{(byte) 0x93, 0x00, 0x00})
|
||||||
|
.put(2, vibrationType.getValue())
|
||||||
|
.array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MovingDirection{
|
||||||
|
CLOCKWISE((byte) 0x00),
|
||||||
|
COUNTER_CLOCKWISE((byte) 0x01),
|
||||||
|
SHORTEST((byte) 0x02),
|
||||||
|
;
|
||||||
|
private byte value;
|
||||||
|
|
||||||
|
MovingDirection(byte value){ this.value = value; }
|
||||||
|
|
||||||
|
public byte getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MovingSpeed{
|
||||||
|
MAX((byte) 0x00),
|
||||||
|
HALF((byte) 0x01),
|
||||||
|
QUARTER((byte) 0x02),
|
||||||
|
EIGHTH((byte) 0x03),
|
||||||
|
SIXTEENTH((byte) 0x04),
|
||||||
|
;
|
||||||
|
private byte value;
|
||||||
|
|
||||||
|
MovingSpeed(byte value){ this.value = value; }
|
||||||
|
|
||||||
|
public byte getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StreamCommand implements MicroAppCommand{
|
||||||
|
private byte type;
|
||||||
|
|
||||||
|
public StreamCommand(byte type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getData() {
|
||||||
|
return new byte[]{(byte) 0x8B, (byte) 0x00, this.type};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RepeatStartCommand implements MicroAppCommand{
|
||||||
|
private byte count;
|
||||||
|
|
||||||
|
public RepeatStartCommand(byte count) {
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getData() {
|
||||||
|
return new byte[]{(byte) 0x86, (byte) 0x00, this.count};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RepeatStopCommand implements MicroAppCommand{
|
||||||
|
@Override
|
||||||
|
public byte[] getData() {
|
||||||
|
return new byte[]{(byte) 0x07, (byte) 0x00};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AnimationCommand implements MicroAppCommand{
|
||||||
|
private short hour, minute;
|
||||||
|
private MovingDirection direction;
|
||||||
|
private MovingSpeed speed;
|
||||||
|
private byte absoluteMovementFlag;
|
||||||
|
|
||||||
|
public AnimationCommand(short hour, short minute) {
|
||||||
|
this.hour = hour;
|
||||||
|
this.minute = minute;
|
||||||
|
this.speed = MovingSpeed.MAX;
|
||||||
|
this.direction = MovingDirection.SHORTEST;
|
||||||
|
this.absoluteMovementFlag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getData() {
|
||||||
|
return ByteBuffer.allocate(10)
|
||||||
|
.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
.put((byte) 0x09)
|
||||||
|
.put((byte) 0x04)
|
||||||
|
.put((byte) 0x01)
|
||||||
|
.put((byte) 0x03)
|
||||||
|
.put((byte) ((direction.getValue() << 6) | (byte)(absoluteMovementFlag << 5) | this.speed.getValue()))
|
||||||
|
.putShort(this.hour)
|
||||||
|
.put((byte) ((direction.getValue() << 6) | (byte)(absoluteMovementFlag << 5) | this.speed.getValue()))
|
||||||
|
.putShort(this.minute)
|
||||||
|
.array();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.microapp;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
|
||||||
|
|
||||||
|
public class PlayCrazyShitRequest extends FilePutRequest {
|
||||||
|
public PlayCrazyShitRequest(byte[] appData, FossilWatchAdapter adapter) {
|
||||||
|
super((short) 0x0600, createPayload(appData), adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] createPayload(byte[] appData) {
|
||||||
|
List<MicroAppCommand> commands = new ArrayList<>();
|
||||||
|
|
||||||
|
commands.add(new StartCriticalCommand());
|
||||||
|
// commands.add(new RepeatStartCommand((byte) 10));
|
||||||
|
commands.add(new VibrateCommand(VibrationType.NORMAL));
|
||||||
|
commands.add(new DelayCommand(1));
|
||||||
|
// commands.add(new RepeatStopCommand());
|
||||||
|
// commands.add(new StreamCommand((byte) 0b11111111));
|
||||||
|
// commands.add(new AnimationCommand((short) 300, (short) 60));
|
||||||
|
// commands.add(new DelayCommand(2));
|
||||||
|
commands.add(new CloseCommand());
|
||||||
|
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
for (MicroAppCommand command : commands) length += command.getData().length;
|
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(
|
||||||
|
3 /* magic bytes */
|
||||||
|
+ 8 /* button header copy */
|
||||||
|
+ 1 /* 0xFF */
|
||||||
|
+ 2 /* payload length */
|
||||||
|
+ length
|
||||||
|
+ 4 /* crc */
|
||||||
|
);
|
||||||
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
buffer.put((byte) 0x01);
|
||||||
|
buffer.put((byte) 0x00);
|
||||||
|
buffer.put((byte) 0x08);
|
||||||
|
buffer.put(appData, 3, 8);
|
||||||
|
buffer.put((byte) 0xFF);
|
||||||
|
buffer.putShort((short)(length + 3));
|
||||||
|
|
||||||
|
for(MicroAppCommand command : commands) buffer.put(command.getData());
|
||||||
|
|
||||||
|
CRC32 crc = new CRC32();
|
||||||
|
crc.update(buffer.array(), 0, buffer.position());
|
||||||
|
|
||||||
|
buffer.putInt((int) crc.getValue());
|
||||||
|
|
||||||
|
return buffer.array();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user