mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-01-27 18:17:33 +01:00
user can now assign a few more functions to buttons
This commit is contained in:
parent
3bac26457b
commit
e04cd474dc
@ -46,6 +46,10 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
@ -54,6 +58,9 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
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.buttonconfig.ConfigPayload;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
public class ConfigActivity extends AbstractGBActivity {
|
public class ConfigActivity extends AbstractGBActivity {
|
||||||
@ -305,7 +312,7 @@ public class ConfigActivity extends AbstractGBActivity {
|
|||||||
activityHandCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
activityHandCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
|
public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
|
||||||
if(!device.getDeviceInfo(QHybridSupport.ITEM_STEP_GOAL).getDetails().equals("1000000")){
|
if (!device.getDeviceInfo(QHybridSupport.ITEM_STEP_GOAL).getDetails().equals("1000000")) {
|
||||||
new AlertDialog.Builder(ConfigActivity.this)
|
new AlertDialog.Builder(ConfigActivity.this)
|
||||||
.setMessage("Please set the step count to a million to activate that.")
|
.setMessage("Please set the step count to a million to activate that.")
|
||||||
.setPositiveButton("ok", null)
|
.setPositiveButton("ok", null)
|
||||||
@ -326,10 +333,67 @@ public class ConfigActivity extends AbstractGBActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
GB.toast("nah.", Toast.LENGTH_SHORT, GB.INFO);
|
GB.toast("nah.", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
((CheckBox)v).setChecked(false);
|
((CheckBox) v).setChecked(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String buttonJson = device.getDeviceInfo(FossilWatchAdapter.ITEM_BUTTONS).getDetails();
|
||||||
|
if (buttonJson != null && !buttonJson.isEmpty()) {
|
||||||
|
try {
|
||||||
|
final JSONArray buttonConfig = new JSONArray(buttonJson);
|
||||||
|
LinearLayout buttonLayout = findViewById(R.id.buttonConfigLayout);
|
||||||
|
buttonLayout.removeAllViews();
|
||||||
|
findViewById(R.id.buttonOverwriteButtons).setVisibility(View.GONE);
|
||||||
|
final ConfigPayload[] payloads = ConfigPayload.values();
|
||||||
|
final String[] names = new String[payloads.length];
|
||||||
|
for (int i = 0; i < payloads.length; i++)
|
||||||
|
names[i] = payloads[i].getDescription();
|
||||||
|
for (int i = 0; i < buttonConfig.length(); i++) {
|
||||||
|
final int currentIndex = i;
|
||||||
|
String configName = buttonConfig.getString(i);
|
||||||
|
TextView buttonTextView = new TextView(ConfigActivity.this);
|
||||||
|
try {
|
||||||
|
ConfigPayload payload = ConfigPayload.valueOf(configName);
|
||||||
|
buttonTextView.setTextColor(Color.WHITE);
|
||||||
|
buttonTextView.setTextSize(20);
|
||||||
|
buttonTextView.setText("Button " + (i + 1) + ": " + payload.getDescription());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
buttonTextView.setText("Button " + (i + 1) + ": Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonTextView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
AlertDialog dialog = new AlertDialog.Builder(ConfigActivity.this)
|
||||||
|
.setItems(names, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.cancel();
|
||||||
|
ConfigPayload selected = payloads[which];
|
||||||
|
|
||||||
|
try {
|
||||||
|
buttonConfig.put(currentIndex, selected.toString());
|
||||||
|
device.addDeviceInfo(new GenericItem(FossilWatchAdapter.ITEM_BUTTONS, buttonConfig.toString()));
|
||||||
|
updateSettings();
|
||||||
|
LocalBroadcastManager.getInstance(ConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
buttonLayout.addView(buttonTextView);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
GB.toast("error parsing button config", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,10 @@ import android.os.Build;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -21,10 +25,13 @@ import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||||
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.buttonconfig.ConfigFileBuilder;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigPayload;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||||
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.buttons.ButtonConfigurationGetRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationGetRequest;
|
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;
|
||||||
@ -46,6 +53,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
private int MTU = 23;
|
private int MTU = 23;
|
||||||
|
|
||||||
private String ITEM_MTU = "MTU";
|
private String ITEM_MTU = "MTU";
|
||||||
|
static public final String ITEM_BUTTONS = "BUTTONS";
|
||||||
|
|
||||||
private int lastButtonIndex = -1;
|
private int lastButtonIndex = -1;
|
||||||
|
|
||||||
@ -64,6 +72,18 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
syncNotificationSettings();
|
syncNotificationSettings();
|
||||||
|
|
||||||
|
queueWrite(new ButtonConfigurationGetRequest(this) {
|
||||||
|
@Override
|
||||||
|
public void onConfigurationsGet(ConfigPayload[] configs) {
|
||||||
|
super.onConfigurationsGet(configs);
|
||||||
|
|
||||||
|
JSONArray buttons = new JSONArray();
|
||||||
|
for (ConfigPayload payload : configs) buttons.put(payload.toString());
|
||||||
|
String json = buttons.toString();
|
||||||
|
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_BUTTONS, json));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED), false);
|
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,24 +125,33 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void overwriteButtons() {
|
public void overwriteButtons() {
|
||||||
FilePutRequest fileUploadRequets = new FilePutRequest((short) 0x0600, new byte[]{
|
try {
|
||||||
(byte) 0x01, (byte) 0x00, (byte) 0x00,
|
JSONArray buttonConfigJson = new JSONArray(getDeviceSupport().getDevice().getDeviceInfo(ITEM_BUTTONS).getDetails());
|
||||||
(byte) 0x03,
|
|
||||||
(byte) 0x10, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00,
|
ConfigPayload[] payloads = new ConfigPayload[buttonConfigJson.length()];
|
||||||
(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,
|
for(int i = 0; i < buttonConfigJson.length(); i++){
|
||||||
(byte) 0x01,
|
try {
|
||||||
(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,
|
payloads[i] = ConfigPayload.valueOf(buttonConfigJson.getString(i));
|
||||||
(byte) 0x00,
|
}catch (IllegalArgumentException e){
|
||||||
(byte) 0x4F, (byte) 0x79, (byte) 0x97, (byte) 0x78,
|
payloads[i] = ConfigPayload.FORWARD_TO_PHONE;
|
||||||
}, this){
|
}
|
||||||
@Override
|
|
||||||
public void onFilePut(boolean success) {
|
|
||||||
if(success) GB.toast("successfully overwritten button settings", Toast.LENGTH_SHORT, GB.INFO);
|
|
||||||
else GB.toast("error overwriting button settings", Toast.LENGTH_SHORT, GB.INFO);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
queueWrite(fileUploadRequets);
|
ConfigFileBuilder builder = new ConfigFileBuilder(payloads);
|
||||||
|
|
||||||
|
FilePutRequest fileUploadRequets = new FilePutRequest((short) 0x0600, builder.build(true), this) {
|
||||||
|
@Override
|
||||||
|
public void onFilePut(boolean success) {
|
||||||
|
if (success)
|
||||||
|
GB.toast("successfully overwritten button settings", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
|
else GB.toast("error overwriting button settings", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
queueWrite(fileUploadRequets);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -161,10 +190,11 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStepGoal(int stepGoal) {
|
public void setStepGoal(int stepGoal) {
|
||||||
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) {
|
||||||
if(success) GB.toast("successfully updated step goal", Toast.LENGTH_SHORT, GB.INFO);
|
if (success)
|
||||||
|
GB.toast("successfully updated step goal", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
else GB.toast("error updating step goal", Toast.LENGTH_SHORT, GB.INFO);
|
else GB.toast("error updating step goal", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
@ -176,11 +206,13 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
|
|
||||||
queueWrite(
|
queueWrite(
|
||||||
new ConfigurationPutRequest(new ConfigurationPutRequest.ConfigItem[]{vibrationItem}, this){
|
new ConfigurationPutRequest(new ConfigurationPutRequest.ConfigItem[]{vibrationItem}, this) {
|
||||||
@Override
|
@Override
|
||||||
public void onFilePut(boolean success) {
|
public void onFilePut(boolean success) {
|
||||||
if(success) GB.toast("successfully updated vibration strength", Toast.LENGTH_SHORT, GB.INFO);
|
if (success)
|
||||||
else GB.toast("error updating vibration strength", Toast.LENGTH_SHORT, GB.INFO);
|
GB.toast("successfully updated vibration strength", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
|
else
|
||||||
|
GB.toast("error updating vibration strength", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
}
|
}
|
||||||
}, false
|
}, false
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
|
public class ConfigFileBuilder {
|
||||||
|
private ConfigPayload[] configs;
|
||||||
|
|
||||||
|
public ConfigFileBuilder(ConfigPayload[] configs) {
|
||||||
|
this.configs = configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] build(boolean appendChecksum) {
|
||||||
|
int payloadSize = 0;
|
||||||
|
for (ConfigPayload payload : this.configs) {
|
||||||
|
payloadSize += payload.getData().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int headerSize = 0;
|
||||||
|
for (ConfigPayload payload : this.configs) {
|
||||||
|
headerSize += payload.getHeader().length + 3; // button + version + null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(
|
||||||
|
3 // version bytes
|
||||||
|
+ 1 // header count byte
|
||||||
|
+ headerSize
|
||||||
|
+ 1 // payload count byte
|
||||||
|
+ payloadSize
|
||||||
|
+ 1 // customization count byte
|
||||||
|
+ (appendChecksum ? 4 : 0) // checksum
|
||||||
|
);
|
||||||
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
buffer.put(new byte[]{(byte) 0x01, (byte) 0x00, (byte) 0x00}); // version
|
||||||
|
buffer.put((byte) this.configs.length);
|
||||||
|
int buttonIndex = 0x00;
|
||||||
|
for (ConfigPayload payload : configs) {
|
||||||
|
buffer.put((byte) (buttonIndex += 0x10));
|
||||||
|
buffer.put((byte) 0x01);
|
||||||
|
buffer.put(payload.getHeader());
|
||||||
|
buffer.put((byte) 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<ConfigPayload> distinctPayloads = new ArrayList<>(3);
|
||||||
|
|
||||||
|
// distinctPayloads.add(configs[0].getData());
|
||||||
|
|
||||||
|
compareLoop:
|
||||||
|
for (int payloadIndex = 0; payloadIndex < configs.length; payloadIndex++) {
|
||||||
|
for (int compareTo = 0; compareTo < distinctPayloads.size(); compareTo++) {
|
||||||
|
if (configs[payloadIndex].equals(distinctPayloads.get(compareTo))) {
|
||||||
|
continue compareLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
distinctPayloads.add(configs[payloadIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.put((byte) distinctPayloads.size());
|
||||||
|
for (ConfigPayload payload : distinctPayloads) {
|
||||||
|
buffer.put(payload.getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.put((byte) 0x00);
|
||||||
|
|
||||||
|
ByteBuffer buffer2 = ByteBuffer.allocate(buffer.position() + (appendChecksum ? 4 : 0));
|
||||||
|
buffer2.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
buffer2.put(buffer.array(), 0, buffer.position());
|
||||||
|
|
||||||
|
if (!appendChecksum) return buffer2.array();
|
||||||
|
|
||||||
|
CRC32 crc = new CRC32();
|
||||||
|
crc.update(buffer.array(), 0, buffer.position());
|
||||||
|
|
||||||
|
buffer2.putInt((int) crc.getValue());
|
||||||
|
|
||||||
|
return buffer2.array();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public enum ConfigPayload {
|
||||||
|
FORWARD_TO_PHONE(
|
||||||
|
"forward to phone",
|
||||||
|
new byte[]{(byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00},
|
||||||
|
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,}
|
||||||
|
),
|
||||||
|
STOPWATCH(
|
||||||
|
"stopwatch",
|
||||||
|
new byte[]{(byte) 0x02, (byte) 0x01, (byte) 0x20, (byte) 0x01},
|
||||||
|
new byte[]{(byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x20, (byte) 0x20, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x07, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x92, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x0F, (byte) 0xC0, (byte) 0x5F, (byte) 0x2A}
|
||||||
|
),
|
||||||
|
DATE(
|
||||||
|
"show date",
|
||||||
|
new byte[]{(byte) 0x01, (byte) 0x01, (byte) 0x14, (byte) 0x00},
|
||||||
|
new byte[]{(byte) 0x01 , (byte) 0x00 , (byte) 0x01 , (byte) 0x01 , (byte) 0x14 , (byte) 0x2D , (byte) 0x00 , (byte) 0x00 , (byte) 0x00 , (byte) 0x01 , (byte) 0x00 , (byte) 0x06 , (byte) 0x00 , (byte) 0x02 , (byte) 0x00 , (byte) 0x00 , (byte) 0x07 , (byte) 0x00 , (byte) 0x01 , (byte) 0x01 , (byte) 0x16 , (byte) 0x00 , (byte) 0x89 , (byte) 0x05 , (byte) 0x01 , (byte) 0x07 , (byte) 0xB0 , (byte) 0x00 , (byte) 0x00 , (byte) 0xB0 , (byte) 0x00 , (byte) 0x00 , (byte) 0xB0 , (byte) 0x00 , (byte) 0x00 , (byte) 0x08 , (byte) 0x01 , (byte) 0x50 , (byte) 0x00 , (byte) 0x01 , (byte) 0x00 , (byte) 0xD0 , (byte) 0x89 , (byte) 0xDE , (byte) 0x6E}
|
||||||
|
);
|
||||||
|
private byte[] header, data;
|
||||||
|
|
||||||
|
static public ConfigPayload fromId(short id) throws RuntimeException{
|
||||||
|
for(ConfigPayload payload : ConfigPayload.values()){
|
||||||
|
ByteBuffer buffer = ByteBuffer.wrap(payload.header);
|
||||||
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
if(id == buffer.getShort(1)) return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("app " + id + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(ConfigPayload p1, ConfigPayload p2){
|
||||||
|
return Arrays.equals(p1.getData(), p2.getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
ConfigPayload(String description, byte[] header, byte[] data) {
|
||||||
|
this.description = description;
|
||||||
|
this.header = header;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.buttons;
|
||||||
|
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigPayload;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
|
||||||
|
|
||||||
|
public class ButtonConfigurationGetRequest extends FileGetRequest {
|
||||||
|
public ButtonConfigurationGetRequest(FossilWatchAdapter adapter) {
|
||||||
|
super((short) 0x0600, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFileData(byte[] fileData) {
|
||||||
|
log("fileData");
|
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.wrap(fileData);
|
||||||
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
short fileHandle = buffer.getShort(0);
|
||||||
|
// TODO check file handle
|
||||||
|
// if(fileData != )
|
||||||
|
|
||||||
|
byte count = buffer.get(15);
|
||||||
|
|
||||||
|
ConfigPayload[] configs = new ConfigPayload[count];
|
||||||
|
|
||||||
|
for(int i = 0; i < count; i++){
|
||||||
|
byte buttonIndex = (byte) (buffer.get(16 + i * 7) >> 4);
|
||||||
|
short appId = buffer.getShort(19 + i * 7);
|
||||||
|
|
||||||
|
try {
|
||||||
|
configs[buttonIndex - 1] = ConfigPayload.fromId(appId);
|
||||||
|
}catch (RuntimeException e){
|
||||||
|
configs[buttonIndex - 1] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onConfigurationsGet(configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onConfigurationsGet(ConfigPayload[] configs){}
|
||||||
|
}
|
@ -77,6 +77,12 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="use activity hand as notification counter" />
|
android:text="use activity hand as notification counter" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/buttonConfigLayout"
|
||||||
|
android:orientation="vertical"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- <ProgressBar
|
<!-- <ProgressBar
|
||||||
|
Loading…
x
Reference in New Issue
Block a user