From e04cd474dce8658bd723ebb1e3ff5fed3bfc3271 Mon Sep 17 00:00:00 2001 From: Daniel Dakhno Date: Sun, 17 Nov 2019 04:55:12 +0100 Subject: [PATCH] user can now assign a few more functions to buttons --- .../devices/qhybrid/ConfigActivity.java | 68 ++++++++++++++- .../adapter/fossil/FossilWatchAdapter.java | 76 ++++++++++++----- .../buttonconfig/ConfigFileBuilder.java | 82 +++++++++++++++++++ .../qhybrid/buttonconfig/ConfigPayload.java | 58 +++++++++++++ .../ButtonConfigurationGetRequest.java | 47 +++++++++++ .../res/layout/activity_qhybrid_settings.xml | 6 ++ 6 files changed, 313 insertions(+), 24 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/buttons/ButtonConfigurationGetRequest.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ConfigActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ConfigActivity.java index 6ff7eed29..7a5a21f48 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ConfigActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ConfigActivity.java @@ -46,6 +46,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; 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.GBException; 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.GenericItem; 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; public class ConfigActivity extends AbstractGBActivity { @@ -305,7 +312,7 @@ public class ConfigActivity extends AbstractGBActivity { activityHandCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override 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) .setMessage("Please set the step count to a million to activate that.") .setPositiveButton("ok", null) @@ -326,10 +333,67 @@ public class ConfigActivity extends AbstractGBActivity { @Override public void onClick(View v) { 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); + } + } } }); } 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 69a5d8817..7f5588f4d 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 @@ -7,6 +7,10 @@ import android.os.Build; import android.util.Log; import android.widget.Toast; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.text.DateFormat; import java.util.ArrayList; 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.devices.qhybrid.QHybridSupport; 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.fossil.FossilRequest; 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.buttons.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.file.FilePutRequest; @@ -46,6 +53,7 @@ public class FossilWatchAdapter extends WatchAdapter { private int MTU = 23; private String ITEM_MTU = "MTU"; + static public final String ITEM_BUTTONS = "BUTTONS"; private int lastButtonIndex = -1; @@ -64,6 +72,18 @@ public class FossilWatchAdapter extends WatchAdapter { 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); } @@ -105,24 +125,33 @@ public class FossilWatchAdapter extends WatchAdapter { @Override public void overwriteButtons() { - FilePutRequest fileUploadRequets = new FilePutRequest((short) 0x0600, 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) 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) 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, - (byte) 0x00, - (byte) 0x4F, (byte) 0x79, (byte) 0x97, (byte) 0x78, - }, 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); + try { + JSONArray buttonConfigJson = new JSONArray(getDeviceSupport().getDevice().getDeviceInfo(ITEM_BUTTONS).getDetails()); + + ConfigPayload[] payloads = new ConfigPayload[buttonConfigJson.length()]; + + for(int i = 0; i < buttonConfigJson.length(); i++){ + try { + payloads[i] = ConfigPayload.valueOf(buttonConfigJson.getString(i)); + }catch (IllegalArgumentException e){ + payloads[i] = ConfigPayload.FORWARD_TO_PHONE; + } } - }; - 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 @@ -161,10 +190,11 @@ public class FossilWatchAdapter extends WatchAdapter { @Override public void setStepGoal(int stepGoal) { - queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.DailyStepGoalConfigItem(stepGoal), this){ + queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.DailyStepGoalConfigItem(stepGoal), this) { @Override 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); } }, false); @@ -176,11 +206,13 @@ public class FossilWatchAdapter extends WatchAdapter { queueWrite( - new ConfigurationPutRequest(new ConfigurationPutRequest.ConfigItem[]{vibrationItem}, this){ + new ConfigurationPutRequest(new ConfigurationPutRequest.ConfigItem[]{vibrationItem}, this) { @Override public void onFilePut(boolean success) { - if(success) GB.toast("successfully updated vibration strength", Toast.LENGTH_SHORT, GB.INFO); - else GB.toast("error updating vibration strength", Toast.LENGTH_SHORT, GB.INFO); + if (success) + GB.toast("successfully updated vibration strength", Toast.LENGTH_SHORT, GB.INFO); + else + GB.toast("error updating vibration strength", Toast.LENGTH_SHORT, GB.INFO); } }, false ); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java new file mode 100644 index 000000000..af28bc65a --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java @@ -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 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(); + } +} 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 new file mode 100644 index 000000000..45fd450a8 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java @@ -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; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/buttons/ButtonConfigurationGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/buttons/ButtonConfigurationGetRequest.java new file mode 100644 index 000000000..ecb58222a --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/buttons/ButtonConfigurationGetRequest.java @@ -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){} +} diff --git a/app/src/main/res/layout/activity_qhybrid_settings.xml b/app/src/main/res/layout/activity_qhybrid_settings.xml index 2007dbfd5..bd9a45223 100644 --- a/app/src/main/res/layout/activity_qhybrid_settings.xml +++ b/app/src/main/res/layout/activity_qhybrid_settings.xml @@ -77,6 +77,12 @@ android:layout_height="wrap_content" android:text="use activity hand as notification counter" /> + +