From f9a4c1ad35beff5baf533511191f2a0a477da5e3 Mon Sep 17 00:00:00 2001 From: Daniel Dakhno Date: Sun, 16 Feb 2020 01:17:45 +0100 Subject: [PATCH 01/49] added call notification support (doesnt work on all phones) --- .../qhybrid/NotificationHRConfiguration.java | 27 +++++++-- .../fossil_hr/FossilHRWatchAdapter.java | 56 ++++++------------- .../PlayCallNotificationRequest.java | 7 ++- .../notification/PlayNotificationRequest.java | 7 ++- .../NotificationFilterPutHRRequest.java | 17 ++---- .../receivers/GBCallControlReceiver.java | 2 +- 6 files changed, 57 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationHRConfiguration.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationHRConfiguration.java index ad62c548f..03fe551a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationHRConfiguration.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationHRConfiguration.java @@ -1,18 +1,33 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; -import android.util.Log; - import java.io.Serializable; - -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.zip.CRC32; public class NotificationHRConfiguration implements Serializable { private String packageName; private long id = -1; + private byte[] packageCrc; public NotificationHRConfiguration(String packageName, long id) { this.packageName = packageName; this.id = id; + + CRC32 crc = new CRC32(); + crc.update(packageName.getBytes()); + + this.packageCrc = ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt((int) crc.getValue()) + .array(); + } + + public NotificationHRConfiguration(String packageName, byte[] packageCrc, long id) { + this.id = id; + this.packageCrc = packageCrc; + this.packageName = packageName; } public String getPackageName() { @@ -22,4 +37,8 @@ public class NotificationHRConfiguration implements Serializable { public long getId() { return id; } + + public byte[] getPackageCrc() { + return packageCrc; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 963769dc1..4d30bfca7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -26,6 +26,7 @@ import java.util.Iterator; import java.util.TimeZone; import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HRConfigActivity; @@ -37,9 +38,11 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; 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.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.configuration.ConfigurationPutRequest.TimeConfigItem; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayCallNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest; @@ -99,46 +102,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZING)); - // icons - loadNotificationConfigurations(); queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations, this)); - // queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations,this)); - - /*try { - final String[] appNames = {"instagram", "snapchat", "line", "whatsapp"}; - final String[] paths = { - "/storage/emulated/0/Q/images/icInstagram.icon", - "/storage/emulated/0/Q/images/icSnapchat.icon", - "/storage/emulated/0/Q/images/icLine.icon", - "/storage/emulated/0/Q/images/icWhatsapp.icon" - }; - - NotificationHRConfiguration[] configs = new NotificationHRConfiguration[4]; - NotificationImage[] images = new NotificationImage[4]; - for(int i = 0; i < 4; i++){ - FileInputStream fis = new FileInputStream(paths[i]); - byte[] imageData = new byte[fis.available()]; - fis.read(imageData); - fis.close(); - configs[i] = new NotificationHRConfiguration(appNames[i], i); - images[i] = new NotificationImage(appNames[i], imageData); - } - queueWrite(new NotificationImagePutRequest(images, this)); - queueWrite(new NotificationFilterPutHRRequest(configs, this)); - - for(String appName : appNames){ - queueWrite(new PlayNotificationHRRequest( - appName, - appName.toUpperCase(), - "this is some strange message", - this - )); - } - } catch (Exception e) { - e.printStackTrace(); - }*/ - setVibrationStrength((short) 75); syncSettings(); @@ -165,6 +130,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { private void loadNotificationConfigurations(){ this.notificationConfigurations = new NotificationHRConfiguration[]{ new NotificationHRConfiguration("generic", 0), + new NotificationHRConfiguration("call", new byte[]{(byte)0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}, 0) }; } @@ -539,7 +505,9 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { byte requestType = value[1]; - if (requestType == (byte) 0x05) { + if(requestType == (byte) 0x04){ + handleCallRequest(value); + }else if (requestType == (byte) 0x05) { handleMusicRequest(value); } else if (requestType == (byte) 0x01) { int eventId = value[2]; @@ -608,6 +576,16 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { } } + private void handleCallRequest(byte[] value) { + boolean acceptCall = value[7] == (byte) 0x00; + queueWrite(new PlayCallNotificationRequest("", false, this)); + + GBDeviceEventCallControl callControlEvent = new GBDeviceEventCallControl(); + callControlEvent.event = acceptCall ? GBDeviceEventCallControl.Event.START : GBDeviceEventCallControl.Event.REJECT; + + getDeviceSupport().evaluateGBDeviceEvent(callControlEvent); + } + private void handleMusicRequest(byte[] value) { byte command = value[3]; logger.info("got music command: " + command); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java index e4b8c9aa2..52dda71be 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java @@ -1,9 +1,14 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; public class PlayCallNotificationRequest extends PlayNotificationRequest { public PlayCallNotificationRequest(String number, boolean callStart, FossilWatchAdapter adapter) { - super(callStart ? 1 : 7, callStart ? 8 : 2, "generic", number, "Incoming Call", adapter); + super(callStart ? 1 : 7, callStart ? 8 : 2, + ByteBuffer.wrap(new byte[]{(byte) 0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}).order(ByteOrder.LITTLE_ENDIAN).getInt(), + number, "Incoming Call", adapter); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayNotificationRequest.java index 61434dba4..977c6e0d2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayNotificationRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayNotificationRequest.java @@ -26,8 +26,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public abstract class PlayNotificationRequest extends FilePutRequest { - static int id = 0; - public PlayNotificationRequest(int notificationType, int flags, String packageName, FossilWatchAdapter adapter) { super((short) 0x0900, createFile(notificationType, flags, packageName, packageName, packageName), adapter); } @@ -36,6 +34,9 @@ public abstract class PlayNotificationRequest extends FilePutRequest { super((short) 0x0900, createFile(notificationType, flags, packageName, sender, message), adapter); } + public PlayNotificationRequest(int notificationType, int flags, int packageCRC, String sender, String message, FossilWatchAdapter adapter) { + super((short) 0x0900, createFile(notificationType, flags, "whatever", sender, message, packageCRC), adapter); + } private static byte[] createFile(int notificationType, int flags, String packageName, String sender, String message){ CRC32 crc = new CRC32(); @@ -73,7 +74,7 @@ public abstract class PlayNotificationRequest extends FilePutRequest { mainBuffer.put((byte) senderBytes.length); mainBuffer.put((byte) messageBytes.length); - mainBuffer.putInt(id++); // messageId + mainBuffer.putInt(0); // messageId mainBuffer.putInt(packageCrc); mainBuffer.put(titleBytes); mainBuffer.put(senderBytes); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationFilterPutHRRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationFilterPutHRRequest.java index 5b6bc25d3..1d6cacb12 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationFilterPutHRRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationFilterPutHRRequest.java @@ -3,7 +3,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fo import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.zip.CRC32; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; @@ -21,20 +20,16 @@ public class NotificationFilterPutHRRequest extends FilePutRequest { } private static byte[] createFile(NotificationHRConfiguration[] configs) { - ByteBuffer buffer = ByteBuffer.allocate(configs.length * 28); + int payloadLength = configs.length * 28; + ByteBuffer buffer = ByteBuffer.allocate(payloadLength); buffer.order(ByteOrder.LITTLE_ENDIAN); for (NotificationHRConfiguration config : configs) { - buffer.putShort((short) 28); //packet length + payloadLength = 26; - CRC32 crc = new CRC32(); - crc.update(config.getPackageName().getBytes()); + buffer.putShort((short) payloadLength); //packet length - byte[] crcBytes = ByteBuffer - .allocate(4) - .order(ByteOrder.LITTLE_ENDIAN) - .putInt((int) crc.getValue()) - .array(); + byte[] crcBytes = config.getPackageCrc(); // 6 bytes buffer.put(PacketID.PACKAGE_NAME_CRC.id) @@ -44,7 +39,7 @@ public class NotificationFilterPutHRRequest extends FilePutRequest { // 3 bytes buffer.put(PacketID.GROUP_ID.id) .put((byte) 1) - .put((byte) 2); + .put((byte) 0); // 3 bytes buffer.put(PacketID.PRIORITY.id) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java index f26a2d5da..569b6c95e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java @@ -53,7 +53,7 @@ public class GBCallControlReceiver extends BroadcastReceiver { telephonyService.answerRingingCall(); } } catch (Exception e) { - LOG.warn("could not start or hangup call"); + LOG.warn("could not start or hangup call", e); } break; default: From c57d5d36596f4c25febb6fdc69a88a0a8dce3e2e Mon Sep 17 00:00:00 2001 From: Daniel Dakhno Date: Sun, 16 Feb 2020 01:41:14 +0100 Subject: [PATCH 02/49] added find my device support --- .../devices/qhybrid/QHybridSupport.java | 32 ++---------------- .../devices/qhybrid/adapter/WatchAdapter.java | 3 ++ .../adapter/fossil/FossilWatchAdapter.java | 33 +++++++++++++++++++ .../fossil_hr/FossilHRWatchAdapter.java | 22 +++++++++++++ 4 files changed, 60 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java index ab74a8b6b..040ccdea9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java @@ -115,7 +115,7 @@ public class QHybridSupport extends QHybridBaseSupport { private PackageConfigHelper helper; - private volatile boolean searchDevice = false; + public volatile boolean searchDevice = false; private long timeOffset; @@ -511,35 +511,7 @@ public class QHybridSupport extends QHybridBaseSupport { @Override public void onFindDevice(boolean start) { - try { - if (watchAdapter.supportsExtendedVibration()) { - GB.toast("Device does not support brr brr", Toast.LENGTH_SHORT, GB.INFO); - } - } catch (UnsupportedOperationException e) { - notifiyException(e); - GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.INFO); - } - - if (start && searchDevice) return; - - searchDevice = start; - - if (start) { - new Thread(new Runnable() { - @Override - public void run() { - int i = 0; - while (searchDevice) { - QHybridSupport.this.watchAdapter.vibrateFindMyDevicePattern(); - try { - Thread.sleep(2500); - } catch (InterruptedException e) { - GB.log("error", GB.ERROR, e); - } - } - } - }).start(); - } + watchAdapter.onFindDevice(start); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java index 87776e5ec..383c0ffd8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java @@ -121,4 +121,7 @@ public abstract class WatchAdapter { public void onSetCallState(CallSpec callSpec) { } + + public void onFindDevice(boolean start) { + } } 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 4f8ff123b..c9fc9ea25 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 @@ -516,6 +516,39 @@ public class FossilWatchAdapter extends WatchAdapter { public void handleHeartRateCharacteristic(BluetoothGattCharacteristic characteristic) { } + @Override + public void onFindDevice(boolean start) { + try { + if (this.supportsExtendedVibration()) { + GB.toast("Device does not support brr brr", Toast.LENGTH_SHORT, GB.INFO); + } + } catch (UnsupportedOperationException e) { + getDeviceSupport().notifiyException(e); + GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.INFO); + } + + if (start && getDeviceSupport().searchDevice) return; + + getDeviceSupport().searchDevice = start; + + if (start) { + new Thread(new Runnable() { + @Override + public void run() { + int i = 0; + while (getDeviceSupport().searchDevice) { + vibrateFindMyDevicePattern(); + try { + Thread.sleep(2500); + } catch (InterruptedException e) { + GB.log("error", GB.ERROR, e); + } + } + } + }).start(); + } + } + protected void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic) { byte[] value = characteristic.getValue(); switch (value[1]) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 4d30bfca7..636b74c7f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -24,6 +24,7 @@ import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Iterator; import java.util.TimeZone; +import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; @@ -36,6 +37,8 @@ import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.service.btle.Transaction; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; 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.requests.fossil.FossilRequest; @@ -429,6 +432,25 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { return true; } + @Override + public void onFindDevice(boolean start) { + if(start){ + new TransactionBuilder("vibrate find") + .write( + getDeviceSupport().getCharacteristic(UUID.fromString("3dda0005-957f-7d4a-34a6-74696673696d")), + new byte[]{(byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0x75, (byte) 0x00, (byte) 0x00} + ) + .queue(getDeviceSupport().getQueue()); + }else{ + new TransactionBuilder("vibrate find") + .write( + getDeviceSupport().getCharacteristic(UUID.fromString("3dda0005-957f-7d4a-34a6-74696673696d")), + new byte[]{(byte) 0x02, (byte) 0x05, (byte) 0x04} + ) + .queue(getDeviceSupport().getQueue()); + } + } + @Override public void onSetCallState(CallSpec callSpec) { super.onSetCallState(callSpec); From 977e94b359c2724bdfb012f2044353e613c2e6aa Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 16 Feb 2020 02:19:48 +0100 Subject: [PATCH 03/49] Fossil Hybrid HR: experimetn with weather, does not work yet I could change the widget icon but it always shows -- for temperature.. --- .../fossil_hr/FossilHRWatchAdapter.java | 34 +++++++++++++++---- .../requests/fossil_hr/widget/Widget.java | 1 + app/src/main/res/values/strings.xml | 1 + 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 636b74c7f..b8abbc272 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -9,7 +9,6 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Build; -import android.os.CpuUsageInfo; import org.json.JSONArray; import org.json.JSONException; @@ -37,17 +36,15 @@ import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; -import nodomain.freeyourgadget.gadgetbridge.service.btle.Transaction; +import nodomain.freeyourgadget.gadgetbridge.model.Weather; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; 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.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.configuration.ConfigurationPutRequest.TimeConfigItem; -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayCallNotificationRequest; -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfigurationPutRequest; @@ -574,7 +571,30 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { .put("result", "off"); queueWrite(new JsonPutRequest(responseObject, this)); } - } else { + } else if (requestJson.getJSONObject("req").has("weatherInfo")) { + logger.info("Got weatherInfo request"); + WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec(); + if (weatherSpec != null) { + long ts = System.currentTimeMillis(); + ts /= 1000; + JSONObject responseObject = new JSONObject() + .put("res", new JSONObject() + .put("id", requestId) + .put("set", new JSONObject() + .put("weatherInfo", new JSONObject() + .put("alive", ts + 60 * 60) + .put("unit", "C") // FIXME: do not hardcode + .put("temp", weatherSpec.currentTemp - 273) + .put("cond_id", 2) // FIXME do not hardcode 2=cloudy + ) + ) + ); + + queueWrite(new JsonPutRequest(responseObject, this)); + } else { + logger.info("no weather data available - ignoring request"); + } + } else if (requestJson.getJSONObject("req").has("commuteApp._.config.commute_info")) { String action = requestJson.getJSONObject("req").getJSONObject("commuteApp._.config.commute_info") .getString("dest"); @@ -591,6 +611,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { Intent menuIntent = new Intent(QHybridSupport.QHYBRID_EVENT_COMMUTE_MENU); menuIntent.putExtra("EXTRA_ACTION", action); getContext().sendBroadcast(menuIntent); + } else { + logger.warn("Unhandled request from watch: " + requestJson.toString()); } } catch (JSONException e) { e.printStackTrace(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java index 148815de0..ee52c013a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java @@ -56,6 +56,7 @@ public class Widget implements Serializable { ACTIVE_MINUTES("activeMinutesSSE", R.string.hr_widget_active_minutes), CALORIES("caloriesSSE", R.string.hr_widget_calories), BATTERY("batterySSE", R.string.hr_widget_battery), + WEATHER("weatherSSE", R.string.hr_widget_weather), NOTHING(null, R.string.hr_widget_nothing); private String identifier; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 778a70c97..93fb1c9a3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -782,6 +782,7 @@ Active minutes Calories Battery + Weather Nothing Event 1 action From 23cbc2e7f11c517e652357392f396fafe3492c9a Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 16 Feb 2020 13:09:08 +0100 Subject: [PATCH 04/49] Fossil Hybrid HR: Fix weather (unit must be lower case) --- .../gadgetbridge/devices/qhybrid/QHybridCoordinator.java | 2 +- .../devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java index ea1c8ed49..4b8aa316c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java @@ -167,7 +167,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { @Override public boolean supportsWeather() { - return false; + return true; // FIXME: not for old Q? } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index b8abbc272..5237a03f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -583,7 +583,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { .put("set", new JSONObject() .put("weatherInfo", new JSONObject() .put("alive", ts + 60 * 60) - .put("unit", "C") // FIXME: do not hardcode + .put("unit", "c") // FIXME: do not hardcode .put("temp", weatherSpec.currentTemp - 273) .put("cond_id", 2) // FIXME do not hardcode 2=cloudy ) From 6a30c2fa6f182b59a2a7bd4441e8da87c6d9170a Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 16 Feb 2020 22:56:43 +0100 Subject: [PATCH 05/49] Fossil Hybrid HR: send weather as soon as it comes in, map correct icons --- .../devices/qhybrid/QHybridSupport.java | 7 +- .../devices/qhybrid/adapter/WatchAdapter.java | 4 + .../adapter/fossil/FossilWatchAdapter.java | 3 - .../fossil_hr/FossilHRWatchAdapter.java | 121 +++++++++++++++--- 4 files changed, 115 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java index 040ccdea9..7d71f4a9b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java @@ -46,7 +46,6 @@ import java.util.Iterator; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration; @@ -61,6 +60,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; @@ -514,6 +514,11 @@ public class QHybridSupport extends QHybridBaseSupport { watchAdapter.onFindDevice(start); } + @Override + public void onSendWeather(WeatherSpec weatherSpec) { + watchAdapter.onSendWeather(weatherSpec); + } + @Override public void onTestNewFunction() { watchAdapter.onTestNewFunction(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java index 383c0ffd8..e6e39b050 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java @@ -27,6 +27,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; @@ -124,4 +125,7 @@ public abstract class WatchAdapter { public void onFindDevice(boolean start) { } + + public void onSendWeather(WeatherSpec weatherSpec) { + } } 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 c9fc9ea25..e3b0c481d 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 @@ -35,7 +35,6 @@ import java.util.GregorianCalendar; import java.util.TimeZone; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; @@ -54,9 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos 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.notification.NotificationFilterPutRequest; -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest; -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.MoveHandsRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ReleaseHandsControlRequest; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 5237a03f1..9342f5565 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -454,6 +454,110 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { queueWrite(new PlayCallNotificationRequest(callSpec.number, callSpec.command == CallSpec.CALL_INCOMING, this)); } + // this method is based on the one from AppMessageHandlerYWeather.java + private int getIconForConditionCode(int conditionCode, boolean isNight) { + final int CLEAR_DAY = 0; + final int CLEAR_NIGHT = 1; + final int CLOUDY = 2; + final int PARTLY_CLOUDY_DAY = 3; + final int PARTLY_CLOUDY_NIGHT = 4; + final int RAIN = 5; + final int SNOW = 6; + final int SNOW_2 = 7; // same as 6? + final int THUNDERSTORM = 8; + final int CLOUDY_2 = 9; // same as 2? + final int WINDY = 10; + + if (conditionCode == 800 || conditionCode == 951) { + return isNight ? CLEAR_NIGHT : CLEAR_DAY; + } else if (conditionCode > 800 && conditionCode < 900) { + return isNight ? PARTLY_CLOUDY_NIGHT : PARTLY_CLOUDY_DAY; + } else if (conditionCode >= 300 && conditionCode < 400) { + return RAIN; // drizzle mapped to rain + } else if (conditionCode >= 500 && conditionCode < 600) { + return RAIN; + } else if (conditionCode >= 700 && conditionCode < 732) { + return CLOUDY; + } else if (conditionCode == 741 || conditionCode == 751 || conditionCode == 761 || conditionCode == 762) { + return CLOUDY; // fog mapped to cloudy + } else if (conditionCode == 771) { + return CLOUDY; // squalls mapped to cloudy + } else if (conditionCode == 781) { + return WINDY; // tornato mapped to windy + } else if (conditionCode >= 200 && conditionCode < 300) { + return THUNDERSTORM; + } else if (conditionCode >= 600 && conditionCode <= 602) { + return SNOW; + } else if (conditionCode >= 611 && conditionCode <= 622) { + return RAIN; + } else if (conditionCode == 906) { + return RAIN; // hail mapped to rain + } else if (conditionCode >= 907 && conditionCode < 957) { + return WINDY; + } else if (conditionCode == 905) { + return WINDY; + } else if (conditionCode == 900) { + return WINDY; + } else if (conditionCode == 901 || conditionCode == 902 || conditionCode == 962) { + return WINDY; + } + return isNight ? CLEAR_NIGHT : CLEAR_DAY; + } + + @Override + public void onSendWeather(WeatherSpec weatherSpec) { + long ts = System.currentTimeMillis(); + ts /= 1000; + try { + JSONObject responseObject = new JSONObject() + .put("res", new JSONObject() + .put("id", 0) // seems the id does not matter? + .put("set", new JSONObject() + .put("weatherInfo", new JSONObject() + .put("alive", ts + 60 * 60) + .put("unit", "c") // FIXME: do not hardcode + .put("temp", weatherSpec.currentTemp - 273) + .put("cond_id", getIconForConditionCode(weatherSpec.currentConditionCode, false)) // FIXME do not hardcode 2=cloudy + ) + ) + ); + + queueWrite(new JsonPutRequest(responseObject, this)); + + } catch (JSONException e) { + logger.error("JSON exception: ", e); + } + } + + + // this was used to enumerate the weather icons :) + /* + static int i = 0; + + @Override + public void onTestNewFunction() { + long ts = System.currentTimeMillis(); + ts /= 1000; + try { + JSONObject responseObject = new JSONObject() + .put("res", new JSONObject() + .put("id", 0) // seems the id does not matter? + .put("set", new JSONObject() + .put("weatherInfo", new JSONObject() + .put("alive", ts + 60 * 60) + .put("unit", "c") + .put("temp", i) + .put("cond_id", i++) + ) + )); + + queueWrite(new JsonPutRequest(responseObject, this)); + + } catch (JSONException e) { + logger.error(" JSON exception: ", e); + } + } +*/ public byte[] getSecretKey() { byte[] authKeyBytes = new byte[16]; @@ -575,22 +679,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { logger.info("Got weatherInfo request"); WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec(); if (weatherSpec != null) { - long ts = System.currentTimeMillis(); - ts /= 1000; - JSONObject responseObject = new JSONObject() - .put("res", new JSONObject() - .put("id", requestId) - .put("set", new JSONObject() - .put("weatherInfo", new JSONObject() - .put("alive", ts + 60 * 60) - .put("unit", "c") // FIXME: do not hardcode - .put("temp", weatherSpec.currentTemp - 273) - .put("cond_id", 2) // FIXME do not hardcode 2=cloudy - ) - ) - ); - - queueWrite(new JsonPutRequest(responseObject, this)); + onSendWeather(weatherSpec); } else { logger.info("no weather data available - ignoring request"); } From a90e8de040aa50c3395debb2eb3d063e54eb7f1b Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 16 Feb 2020 23:05:21 +0100 Subject: [PATCH 06/49] Fossil Hybrid HR: Display caller name instead of number, when known --- .../devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 9342f5565..4a8a72aa6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -451,7 +451,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { @Override public void onSetCallState(CallSpec callSpec) { super.onSetCallState(callSpec); - queueWrite(new PlayCallNotificationRequest(callSpec.number, callSpec.command == CallSpec.CALL_INCOMING, this)); + queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), callSpec.command == CallSpec.CALL_INCOMING, this)); } // this method is based on the one from AppMessageHandlerYWeather.java From fe7c4d52907bd0060fc7bdaaf0342340294dedda Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 18 Feb 2020 00:31:43 +0100 Subject: [PATCH 07/49] Fossil Hybrid HR: Play around with the weather app --- .../fossil_hr/FossilHRWatchAdapter.java | 70 ++++++++++++++++--- .../ButtonConfigurationPutRequest.java | 2 +- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 4a8a72aa6..d3c56d3c6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -18,6 +18,7 @@ import java.io.File; import java.io.IOException; import java.nio.BufferOverflowException; import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; @@ -517,13 +518,65 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { .put("alive", ts + 60 * 60) .put("unit", "c") // FIXME: do not hardcode .put("temp", weatherSpec.currentTemp - 273) - .put("cond_id", getIconForConditionCode(weatherSpec.currentConditionCode, false)) // FIXME do not hardcode 2=cloudy + .put("cond_id", getIconForConditionCode(weatherSpec.currentConditionCode, false)) // FIXME do not assume daylight ) ) ); queueWrite(new JsonPutRequest(responseObject, this)); + JSONArray forecastWeekArray = new JSONArray(); + final String[] weekdays = {"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(weatherSpec.timestamp * 1000L); + int i = 0; + for (WeatherSpec.Forecast forecast : weatherSpec.forecasts) { + cal.add(Calendar.DATE, 1); + int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); + forecastWeekArray.put(new JSONObject() + .put("day", weekdays[dayOfWeek]) + .put("cond_id", getIconForConditionCode(forecast.conditionCode, false)) // FIXME do not assume daylight + .put("high", forecast.maxTemp - 273) + .put("low", forecast.minTemp - 273) + ); + if (++i == 3) break; // max 3 + } + + JSONArray forecastDayArray = new JSONArray(); + final int[] hours = {0, 0, 0}; + + for (int hour : hours) { + forecastDayArray.put(new JSONObject() + .put("hour", hour) + .put("cond_id", 0) + .put("temp", 0) + ); + } + + + JSONObject forecastResponseObject = new JSONObject() + .put("res", new JSONObject() + .put("id", 0) + .put("set", new JSONObject() + .put("weatherApp._.config.locations", new JSONArray() + .put(new JSONObject() + .put("alive", ts + 60 * 60) + .put("city", weatherSpec.location) + .put("unit", "c") // FIXME: do not hardcode + .put("temp", weatherSpec.currentTemp - 273) + .put("high", weatherSpec.todayMaxTemp - 273) + .put("low", weatherSpec.todayMinTemp - 273) + .put("rain", 0) + .put("cond_id", getIconForConditionCode(weatherSpec.currentConditionCode, false)) // FIXME do not assume daylight + .put("forecast_day", forecastDayArray) + .put("forecast_week", forecastWeekArray) + ) + ) + ) + ); + + queueWrite(new JsonPutRequest(forecastResponseObject, this)); + } catch (JSONException e) { logger.error("JSON exception: ", e); } @@ -640,10 +693,11 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { logger.info(jsonString); JSONObject requestJson = new JSONObject(jsonString); - int requestId = requestJson.getJSONObject("req").getInt("id"); + JSONObject request = requestJson.getJSONObject("req"); + int requestId = request.getInt("id"); - if (requestJson.getJSONObject("req").has("ringMyPhone")) { - String action = requestJson.getJSONObject("req").getJSONObject("ringMyPhone").getString("action"); + if (request.has("ringMyPhone")) { + String action = request.getJSONObject("ringMyPhone").getString("action"); logger.info("got ringMyPhone request; " + action); GBDeviceEventFindPhone findPhoneEvent = new GBDeviceEventFindPhone(); @@ -675,7 +729,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { .put("result", "off"); queueWrite(new JsonPutRequest(responseObject, this)); } - } else if (requestJson.getJSONObject("req").has("weatherInfo")) { + } else if (request.has("weatherInfo") || request.has("weatherApp._.config.locations")) { logger.info("Got weatherInfo request"); WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec(); if (weatherSpec != null) { @@ -683,11 +737,11 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { } else { logger.info("no weather data available - ignoring request"); } - } else if (requestJson.getJSONObject("req").has("commuteApp._.config.commute_info")) { - String action = requestJson.getJSONObject("req").getJSONObject("commuteApp._.config.commute_info") + } else if (request.has("commuteApp._.config.commute_info")) { + String action = request.getJSONObject("commuteApp._.config.commute_info") .getString("dest"); - String startStop = requestJson.getJSONObject("req").getJSONObject("commuteApp._.config.commute_info") + String startStop = request.getJSONObject("commuteApp._.config.commute_info") .getString("action"); if (startStop.equals("stop")) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/buttons/ButtonConfigurationPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/buttons/ButtonConfigurationPutRequest.java index 8e6f77b85..ebea27b27 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/buttons/ButtonConfigurationPutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/buttons/ButtonConfigurationPutRequest.java @@ -24,7 +24,7 @@ public class ButtonConfigurationPutRequest extends JsonPutRequest { .put("commuteApp._.config.destinations", new JSONArray(menuItems)) .put("master._.config.buttons", new JSONArray() .put(new JSONObject() - .put("name", "commuteApp") + .put("name", "weatherApp") .put("button_evt", "top_short_press_release") ) .put(new JSONObject() From 71b76c8e8f378214b9f0116c8c07734ff01736f0 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 18 Feb 2020 22:20:57 +0100 Subject: [PATCH 08/49] Huami: add unused and untested co to send upcoming calender events as notifications --- .../service/devices/huami/HuamiSupport.java | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index cee8549e9..7835b392e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -818,7 +818,6 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } - private void sendMusicStateToDevice() { if (characteristicChunked == null) { return; @@ -1323,8 +1322,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { if ((currentButtonPressTime == 0) || (timeSinceLastPress < buttonPressMaxDelay)) { currentButtonPressCount++; - } - else { + } else { currentButtonPressCount = 1; currentButtonActionId = 0; } @@ -1352,8 +1350,6 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } - - @Override public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { @@ -1703,6 +1699,45 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } + private HuamiSupport sendCalendarEventsAsReminder(TransactionBuilder builder) { + CalendarEvents upcomingEvents = new CalendarEvents(); + List calendarEvents = upcomingEvents.getCalendarEventList(getContext()); + Calendar calendar = Calendar.getInstance(); + + int iteration = 0; + + for (CalendarEvents.CalendarEvent calendarEvent : calendarEvents) { + if (iteration > 8) { // limit ? + break; + } + calendar.setTimeInMillis(calendarEvent.getBegin()); + byte[] title = calendarEvent.getTitle().getBytes(); + byte[] body = calendarEvent.getDescription().getBytes(); + + int length = 18 + title.length + 1 + body.length + 1; + ByteBuffer buf = ByteBuffer.allocate(length); + + buf.order(ByteOrder.LITTLE_ENDIAN); + buf.put((byte) 0x0b); // always 0x0b? + buf.put((byte) 0); // îd + buf.putInt(0x08 | 0x04 | 0x01); // flags 0x01 = enable, 0x04 = end date present, 0x08 = has text + calendar.setTimeInMillis(calendarEvent.getBegin()); + buf.put(BLETypeConversions.shortCalendarToRawBytes(calendar)); + calendar.setTimeInMillis(calendarEvent.getEnd()); + buf.put(BLETypeConversions.shortCalendarToRawBytes(calendar)); + buf.put(title); + buf.put((byte) 0); // 0 Terminated + buf.put(body); + buf.put((byte) 0); // 0 Terminated + writeToChunked(builder, 2, buf.array()); + builder.queue(getQueue()); + + iteration++; + } + + return this; + } + @Override public void onSendConfiguration(String config) { TransactionBuilder builder; From bffb8e8f876186fe61e7ce73da2b40d89c948e91 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Wed, 19 Feb 2020 09:41:50 +0100 Subject: [PATCH 09/49] Huami: send upcoming calendar events as reminder TODO: make this optional, fix title not being displayed, do it proberly like we do on pebble --- .../service/devices/huami/HuamiSupport.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 7835b392e..8c6a6e745 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -737,7 +737,14 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { TransactionBuilder builder = performInitialized("Set date and time"); setCurrentTimeWithService(builder); //TODO: once we have a common strategy for sending events (e.g. EventHandler), remove this call from here. Meanwhile it does no harm. - sendCalendarEvents(builder); + // = we should genaralize the pebble calender code + if (characteristicChunked == null) { + sendCalendarEvents(builder); + } + else { + // TODO: make this configurable + sendCalendarEventsAsReminder(builder); + } builder.queue(getQueue()); } catch (IOException ex) { LOG.error("Unable to set time on Huami device", ex); @@ -1719,7 +1726,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { buf.order(ByteOrder.LITTLE_ENDIAN); buf.put((byte) 0x0b); // always 0x0b? - buf.put((byte) 0); // îd + buf.put((byte) iteration); // îd buf.putInt(0x08 | 0x04 | 0x01); // flags 0x01 = enable, 0x04 = end date present, 0x08 = has text calendar.setTimeInMillis(calendarEvent.getBegin()); buf.put(BLETypeConversions.shortCalendarToRawBytes(calendar)); @@ -1730,7 +1737,6 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { buf.put(body); buf.put((byte) 0); // 0 Terminated writeToChunked(builder, 2, buf.array()); - builder.queue(getQueue()); iteration++; } From ded225e6a208b9a61e0f1ec632aecd13733f84ca Mon Sep 17 00:00:00 2001 From: Nikolai Sinyov Date: Mon, 10 Feb 2020 14:44:42 +0000 Subject: [PATCH 10/49] Translated using Weblate (Russian) Currently translated at 100.0% (751 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 233 ++++++++++++++++++++++--- 1 file changed, 204 insertions(+), 29 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 608bdb9ad..4f4896975 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -23,7 +23,7 @@ Управление приложением Приложения в памяти Установленные приложения - Установленный циферблаты + Установленные циферблаты Удалить Удалить и очистить кеш Переустановка @@ -306,7 +306,7 @@ Формат даты Время Время и дата - Активировать экран при подъёме + Активировать экран поднятием руки Готов к передаче данных с %1$s Ожидание переподключения Ваши данные @@ -332,11 +332,9 @@ Если флажок установлен, данные сохраняются как есть. В дальнейшем их можно будет обрабатывать. Обратите внимание: в этом случае база данных будет занимать больше места. Управление базой данных Управление базой данных - "Операции с базой данных используют этот путь на устройстве. -\n -\nОн доступен для других приложений Android и. компьютера. -\n -\nВы можете найти экспортированную базу данных (или разместить базу данных, которую вы хотите импортировать) здесь:" + Операции с базой данных используют этот путь на устройстве. +\nОн доступен для других приложений Android и компьютера. +\nВы можете найти экспортированную базу данных (или разместить базу данных, которую вы хотите импортировать) здесь: Удаление устаревшей базы данных Нет доступа к пути экспорта. Обратитесь, пожалуйста, к разработчикам. Экспортировано в: %1$s @@ -403,12 +401,12 @@ \nОбратите внимание: если файлы .gps и .res такие же, как в текущей версии, их не нужно переустанавливать. \n \nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! - Вы собираетесь установить прошивку %s на ваш Amazfit Cor. -\n -\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. -\n -\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. -\n + Вы собираетесь установить прошивку %s на ваш Amazfit Cor. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw устройство перезагрузится. +\n +\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\n \nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! Включить жесты \"провести направо и налево\" в графиках активности Заблокировать Календари @@ -430,14 +428,14 @@ Заряд батарейки Действия кнопки Настройте действия при нажатии на кнопку - Нажатий на кнопку + Кол-во нажатий на кнопку Количество нажатий, необходимое для генерации События 1. Ещё столько же нажатий потребуется для генерации События 2 и т.д. Сообщение для трансляции Сообщение транслируемое при наступлении события. Параметр `button_id` добавляется к каждому сообщению автоматически. - Включить действия при нажатии на кнопку - Включить действия для заданного количества нажатий на кнопку - Включить вибрацию - Включить вибрацию браслета в ответ на исполняющееся при нажатии действие + Включить действия для кнопки + Включить действия на заданное кол-во нажатий кнопки + Включить вибро-отклик браслета + Включить вибро-отклик браслета в ответ на исполнение действия при нажатии Максимальная задержка между нажатиями Максимальная задержка между нажатиями в миллисекундах Задержка после действия при нажатии @@ -446,7 +444,7 @@ Браслет завибрирует, когда будет выполнена дневная норма шагов Что показывать на экране Выберите, что показывать на экране браслета - Поверните запястье, чтобы переключиться на другую информацию + Переключать информацию поворотом запястья Не беспокоить Браслет не будет получать уведомления, даже если включён Напоминания о низкой активности @@ -479,23 +477,23 @@ Погода Компас Настройки - Заблокировать все уведомления - Разблокировать все уведомления + Черный список уведомлений + Белый список уведомлений Вы собираетесь установить прошивку %s на ваш Mi Band 3. \n -\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. -\n -\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. -\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. +\n +\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\n \nНЕ ПРОВЕРЯЛОСЬ, ЕСТЬ ВЕРОЯТНОСТЬ СЛОМАТЬ ВАШЕ УСТРОЙСТВО. ВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! Местоположение для погоды (CM/LOS) Подключаться только в режиме GATT-клиента Экспериментальные настройки только для Pebble 2. Попробуйте, если связь не очень Автоматический экспорт данных - Включить автоматический экспорт - Путь экспорта + Автоматический экспорт включён + Путь для экспорта данных Интервал экспорта - Экспортировать каждые %d часов + Экспортировать каждые %d часа(ов) Испанский Русский Не измерялось @@ -640,7 +638,7 @@ В среднем: %1$s Разрешает другим приложениям доступ к датчику сердцебиения при активном соединении через Gadgetbridge Доступ к пульсометру - Кнопка подключения новых устройств + Кнопка подключения нового устройства Всегда отображать Когда нет добавленных устройств Реакция на Событие 1 @@ -648,4 +646,181 @@ Реакция на Событие 3 Детальная настройка реакции на нажатие кнопки Реакция на долгое нажатие + Приложение не должно находиться в черном списке для дальнейшей настройки + Введите нужные слова, где каждому новому слову соответствует своя строка + Фильтр уведомлений сохранён + Не фильтровать + Показывать, когда слова находятся в списке + Блокировать, когда слова находятся в списке + Режим конфигурации + Настройки ZeTime + Настройки пульса + Продолжительность отображения в секундах + Пульсовой сигнал + Часы предупредят вас, когда частота пульса превысит допустимые значения. + Включить пульсовой сигнал + Максимальный пульс + Минимальный пульс + Аналоговый режим + Только руки + Руки и шаги + Отслеживание активности + Включение отслеживания активности, будет считать ваши шаги и так далее. + Движение руки + Поверните запястье, чтобы активировать или деактивировать дисплей. + Тип калорий + Только активные сжигаемые калории + Активные и неактивные сжигаемые калории + Формат даты + Повторения + Установить тип сигнализации для будильника + Тишина + Непрерывная вибрация + Непрерывный звуковой сигнал + Непрерывная вибрация и звуковой сигнал + Вибрировать единожды + Вибрировать дважды + Сигнализировать единожды + Сигнализировать дважды + Вибрировать и сигнализировать единожды + Предупреждение о потерях + каждые 15 минут + каждые 45 минут + Ежедневная цель: сожженные калории + Ежедневная цель: дистанция в метрах + Ежедневная цель: время активности в минутах + Mi Scale 2 + Активировать VoIP звонки внутри приложения + Специфичные настройки устройства + Ключ авторизации + Измените ключ авторизации на общий ключ на всех ваших Android-устройствах, с которых вы хотели бы подключиться. Предыдущий ключ по умолчанию для всех устройств 0123456789@ABCDE + BFH-16 + Вы собираетесь установить прошивку %s на ваш Amazfit Cor 2. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. +\n +\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\n +\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! +\n +\nПОЛНОСТЬЮ НЕ ПРОТЕСТИРОВАНО, ВОЗМОЖНО НУЖНО ПРОШИТЬ ПРОШИВКУ BEATS_W, ЕСЛИ ИМЯ ВАШЕГО УСТРОЙСТВА \"Amazfit Band 2\" + Голландский язык + Турецкий язык + Украинский язык + Арабский язык + Индонезийский язык + Тайский язык + Вьетнамский язык + Португальский язык + Amazfit Cor 2 + Mi Band 4 + Вы собираетесь установить прошивку %s на ваш Mi Band 4. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. +\n +\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\n +\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! + Сигнал пульсометра в течение занятия спортом + Нижний предел + Верхний предел + Настройки Графиков + Показывать средние значения на графиках + Диапазон графиков + Диапазон графиков в рамках месяца + Диапазон графиков в рамках недели + Шаги за месяц + Сон за месяц + Mijia Smart Clock + NFC + Использовать пользовательский шрифт + Активируйте это для поддержки emoji, если ваше устройство имеет установленный пользовательский шрифт + Местоположение авто-экспорта базы данных установлено: + Авто-экспорт + Экспорт базы данных + Импорт базы данных + Запустить Авто-экспорт сейчас + Экспортирование базы данных… + Удалить старую базу данных + Пустая база данных + Пустая база данных + Экспорт и Импорт + Внимание! Нажав эту кнопку, вы сотрете вашу базу данных и начнете с нуля. + Сигнализация сна + Шаги: %1$02d + Сон: %1$s + Статус и будильники + Установить сигнал после: + 5 минут + 10 минут + 20 минут + 1 час + + час + часа + часов + + Для просмотра трассировки активности установите приложение, которое может работать с GPX файлами. + Настройки Makibes HR3 + Makibes HR3 + Amazfit Bip Lite + Найти телефон + Включить \\\'Найти телефон\\\' + Использовать ваш браслет для проигрывания рингтонов. + Продолжительность звонка в секундах + Продолжительность + Это устройство нуждается в ключе авторизации, используйте длительное нажатие на устройство, чтобы войти в него. Читайте Wiki. + Вы собираетесь установить прошивку %s на ваш Amazfit Bip Lite. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res, и затем .gps. После установки файла .fw часы перезагрузятся. +\n +\nОбратите внимание: если файлы .gps и .res такие же, как в текущей версии, их не нужно переустанавливать. +\n +\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! + Amazfit GTR + Вы собираетесь установить прошивку %s на ваш Amazfit GTR. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. +\n +\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\n +\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! + Красный + Оранжевый + Цвет пульса + Диапазон сна + Последние 24 часа + С полудня до полудня + Amazfit GTS + Вы собираетесь установить прошивку %s на ваш Amazfit GTS. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. +\n +\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\n +\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! + Fossil Q Hybrid + Настройки Q Hybrid + Часы не подсоединены + сила вибрации: + Цель в шагах + сдвиг по времени + смещение второго часового пояса относительно UTC + кнопки перезаписи + использовать активную руку в качестве счетчика уведомлений + Пожалуйста, установите счетчик шагов на миллион, чтобы активировать это. + Кнопки перезаписаны + Ошибка перезаписи кнопок + смещение часового пояса на + изменения могут занять несколько секунд… + смещение часового пояса на + Отключить новое BLE сканирование + Установите этот флажок, если устройство не может быть найдено во время обнаружения + Bangle.js + Y5 + Короткий сон + Доступ к местоположению должен быть разрешен и включен для корректной работы поиска + iTag + Разрешить высокий MTU + Увеличивает скорость передачи данных, но может не работать на некоторых Android-устройствах. \ No newline at end of file From e232a43c3c46dcce817b04595b8ecdcc3c324339 Mon Sep 17 00:00:00 2001 From: Deixondit Date: Tue, 11 Feb 2020 15:59:50 +0000 Subject: [PATCH 11/49] Translated using Weblate (Catalan) Currently translated at 95.9% (720 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ca/ --- app/src/main/res/values-ca/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 7f9e230a5..144d7a464 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -792,4 +792,5 @@ Per a veure la traça d\'activitat, instal·leu una app que pugui manejar fitxers GPX. Fes servir la teva banda per a reproduir el to del telèfon. Aquest aparell requereix una clau d\'autenticació secreta, mantingueu premut sobre l\'aparell per a introduir-la. Consulteu la wiki. + Augmenta la velocitat de transferència, però pot ser que no funcioni en alguns aparells Android. \ No newline at end of file From bf9e983ba7d45bf8ee65b1f9e133c80bd749b7e2 Mon Sep 17 00:00:00 2001 From: Pander Date: Tue, 11 Feb 2020 16:48:53 +0000 Subject: [PATCH 12/49] Translated using Weblate (Dutch) Currently translated at 100.0% (751 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nl/ --- app/src/main/res/values-nl/strings.xml | 50 +++++++++++++------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 303a33a25..23cd8e658 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -6,19 +6,19 @@ Debug Sluit af Doneer - Synchroniseren - Zoek verloren Toestel + Synchroniseer + Zoek verloren toestel Screenshot maken - Loskoppelen - Apparaat Verwijderen + Ontkoppel + Verwijder apparaat Verwijder %1$s Dit zal het apparaat en alle bijbehorende gegevens verwijderen! - Druk lang op de kaart om los te koppelen - Loskoppelen + Druk lang op de kaart om te ontkoppelen + Ontkoppelen Verbinden… Een screenshot maken van het apparaat Debug - App Beheerder + App-beheerder Apps in de cache Geïnstalleerde apps Geïnstalleerde wijzerplaten @@ -26,13 +26,13 @@ Verwijder en verwijder uit cache Herinstalleer Zoek in Pebble appstore - Activeren - Deactiveren + Activeer + Deactiveer Activeer HRM Deactiveer HRM Activeer de systeem weer app Installeer de app voor weer meldingen - Configureren + Configureer Verplaats naar de top Melding zwarte lijst U staat op het punt om firmware %s te installeren. @@ -54,7 +54,7 @@ Verbind met Gadgetbridge apparaat wanneer Bluetooth is ingeschakeld Start automatisch Verbind automatisch opnieuw - Gewenste Audiospeler + Gewenste audiospeler Standaard Datum en tijd Sync tijd @@ -166,7 +166,7 @@ Wanneer ingeschakeld, kunnen horloges het weer, batterij-informatie enz. weergeven. Pogingen tot opnieuw verbinden Eenheden - Tijd weergave + Tijdsformaat Tijd dat scherm aan is "De hele dag hartslag meten" HPlus/Makibes instellingen @@ -343,7 +343,7 @@ Alarmen gereserveerd voor toekomstige gebeurtenissen Gebruik hartslag sensor om slaap detectie te verbeteren Toestel tijdsverschuiving in uren (voor het detecteren van slaap van ploegarbeiders) - Datum formaat + Datumformaat Tijd Tijd & datum Knoppen acties @@ -426,7 +426,7 @@ Oude activiteitsdatabase verwijderen mislukt. Overschrijven Annuleren - Verwijderen + Verwijder Vibratie Pebble koppelen Er zal een koppelingsdialoogvenster verschijnen op uw Android-apparaat. Als dat niet gebeurt, kijk dan tussen uw meldingen en accepteer het koppelingsverzoek. Accepteer het daarna ook op uw Pebble. @@ -519,7 +519,7 @@ Activiteiten Fietsen Loopband - Alles selecteren + Selecteer alles Delen Mi Band 3 Q8 @@ -554,10 +554,10 @@ Herstel ophaal datum MyKronoz ZeTime Meldingen - Wijzig LED kleur + Wijzig ledkleur Wijzig FM frequentie Weet U zeker dat u de fabrieksinstellingen wilt terugzetten\? - Het terugzetten van de fabrieksinstellingen zal alle data van het verbonden toestel verwijderen (indien ondersteund). Xiaomi/Huami toestellen veranderen ook van Bluetooth MAC address, zodat deze zullen verschijnen als nieuwe toestellen in Gadgetbridge. + Het terugzetten van de fabrieksinstellingen zal alle data van het verbonden toestel verwijderen (indien ondersteund). Xiaomi/Huami toestellen veranderen ook van Bluetooth MAC-adres, zodat deze zullen verschijnen als nieuwe toestellen in Gadgetbridge. Minimum tijd tussen meldingen Van rechts naar links Schakel dit in als uw toestel geen talen van rechts naar links kan weergeven @@ -606,8 +606,8 @@ Hou er alsjeblieft rekening mee dat Gadgetbridge bestanden logt die veel persoonlijke informatie kunnen bevatten, inclusief maar niet gelimiteerd tot gezondheidsgegevens, unieke identificatiegegevens (zoals het MAC adres van een toestel), muziek voorkeuren, enz. Overweeg deze handmatig verwijderen van deze gegevens uit dit bestand alvorens deze te verzenden naar een publiek foutrapport. Waarschuwing! Geen data - LED Kleur - FM frequentie + Ledkleur + FM-frequentie Ongeldige frequentie Voer een frequentie in tussen 87,5 en 108,0 Taal en regio instellingen @@ -646,7 +646,7 @@ Soort calorieën Alleen calorieën verbrand gedurende activiteiten Verbrande calorieën actief en inactief - Datum formaat + Datumformaat YY/MM/DD DD/MM/YY MM/DD/YY @@ -723,8 +723,8 @@ Slaap per maand Mijia Smart Clock NFC - Sta toe dat andere apps HR data in realtime benaderen terwijl Gadgetbridge verbonden is - Derde partij realtime HR toegang + Sta andere apps toe HR-data te benaderen in realtime terwijl Gadgetbridge verbonden is + realtime HR-toegang door derden Gebruik aangepast lettertype Selecteer dit als je device aangepaste font software bevat met emoji ondersteuning Database autoexport locatie is ingesteld op: @@ -738,10 +738,10 @@ Leeg Database Exporteer en importeer Waarschuwing! Als je op deze knop drukt wis je je database en start je met een schone lei. - Slaap Alarm + Slaapalarm Stappen: %1$02d Slaap: %1$s - Status en Alarmen + Status en alarmen Zet alarm na: 5 minuten 10 minuten @@ -795,7 +795,7 @@ \nGA VERDER OP EIGEN RISICO! nodomain.freeyourgadget.gadgetbridge.ButtonPressed Fossil Q Hybrid - Q Hybrid Instellingen + Q Hybrid instellingen Horloge niet verbonden trillingssterkte: Doel in stappen From a574b1efd5436ad7e0483ce9d66510d3923b1554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Deparis?= Date: Tue, 11 Feb 2020 12:45:02 +0000 Subject: [PATCH 13/49] Translated using Weblate (French) Currently translated at 100.0% (751 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fr/ --- app/src/main/res/values-fr/strings.xml | 31 ++++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index e9b0ebc42..2c2603a9e 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -415,9 +415,9 @@ Temps de sommeil préféré en heures Actions du bouton Spécifier les actions par pression du bouton Nombre de pressions du bouton - Nombre de pressions pour envoyer message + Nombre d\'appuis sur le boutton pour envoyer l’Évènement 1. Appuyer de nouveau autant de fois créera l\'Évènement 2, etc. Message à envoyer - Envoyer message après nombre défini de pressions du bouton + Message de diffusion envoyé avec l\'évènement. Le paramètre `button_id` est automatiquement ajouté à chaque message. Activer action du bouton Activer action après nombre spécifié de pressions Activer la vibration du bracelet @@ -601,8 +601,8 @@ Temps de sommeil préféré en heures Roidmi 3 Arabe contextuel A cocher pour activer le support \"Arabe contextuel\" - Confirmer la réinitialisation usine \? - Une réinitialisation d\'usine effacera toutes les données de l\'appareil connecté (si supporté). Les appareils Xiaomi/Huami modifient également l\'adresse MAC Bluetooth, de sorte qu\'ils apparaissent comme de nouveaux appareils dans Gadgetbrige. + Confirmer la réinitialisation \? + Une réinitialisation effacera toutes les données de l\'appareil connecté (si supporté). Les appareils Xiaomi/Huami modifient également l\'adresse MAC Bluetooth, de sorte qu\'ils apparaissent comme de nouveaux appareils dans Gadgetbridge. Déverrouillage de l\'écran du Band Activité physique Casio GB-6900 @@ -788,15 +788,32 @@ Temps de sommeil préféré en heures \n \nÀ VOS RISQUES ET PÉRILS ! Fossil Q Hybrid - Paramètres du Q Hybrid + Paramètres hybrides Q Montre non connectée Puissance de vibration : Objectif de pas décalage horaire décalage du deuxième fuseau horaire par rapport à UTC Veuillez régler le compteur de pas à un million pour l\'activer. - les changements peuvent prendre quelques secondes… - Désactiver le nouveau scan BLE + le changement peut prendre quelques secondes… + Désactiver la nouvelle détection BLE Cochez cette option si votre appareil ne peut être découvert Bangle.js + modifier les boutons + utilise l\'activité de la main comme compteur de notification + Boutons modifiés + Une erreur est survenue lors de la modification des boutons + décale le fuseau horaire de + décale l\'heure de + Y5 + Action de l\'évènement 1 + Action de l\'évènement 2 + Action de l\'évènement 3 + Paramètres détaillés des appuis de bouton + Action d\'appui long de bouton + Reporter + L\'accès à la localisation doit être autorisé et activé pour permettre à la détection de fonctionner correctement + iTag + Autoriser une grande MTU + Augmente la vitesse de transfert, mais peut ne pas fonctionner avec quelques appareils Android. \ No newline at end of file From 850edf402303bf6be3bead950e941b1ded62508b Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Feb 2020 10:59:40 +0000 Subject: [PATCH 14/49] Translated using Weblate (Polish) Currently translated at 100.0% (751 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/pl/ --- app/src/main/res/values-pl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 8b18744e8..4f14cd194 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -825,4 +825,5 @@ iTag Dostęp do lokalizacji musi zostać przyznany i włączony, aby skanowanie działało poprawnie Zwiększa szybkość transferu, ale może nie działać na niektórych urządzeniach z Androidem. + Zezwól na wysoki MTU \ No newline at end of file From 3d953b041fd395098aece0ec87017455fc51a348 Mon Sep 17 00:00:00 2001 From: homocomputeris Date: Fri, 14 Feb 2020 23:32:42 +0000 Subject: [PATCH 15/49] Translated using Weblate (Russian) Currently translated at 100.0% (751 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 142 ++++++++++++------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4f4896975..de90c736f 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -4,7 +4,7 @@ Gadgetbridge Настройки Отладка - Выход + Выйти Синхронизировать Найти устройство Сделать снимок экрана @@ -14,26 +14,26 @@ Устройство и вся связанная с ним информация будут удалены! Открыть панель навигации Закрыть панель навигации - Чтобы разъединиться, нажмите на карточку устройства и удержите - Разъединение - Соединение… - Сделать снимок устройства + Долгое нажатие отключит устройство + Отключается + Подключается… + Делается снимок устройства Отладка Управление приложением - Приложения в памяти + Приложения в кеше Установленные приложения Установленные циферблаты Удалить Удалить и очистить кеш - Переустановка + Переустановить Искать в магазине Pebble Активировать Деактивировать - Включить монитор сердечного ритма - Выключить монитор сердечного ритма - Включить системное приложение прогноза погоды - Выключить системное приложение прогноза погоды + Включить пульсометр + Выключить пульсометр + Включить системный прогноз погоды + Выключить системный прогноз погоды Установить уведомления для прогноза погоды Настроить Переместить наверх @@ -41,58 +41,58 @@ Заблокированные уведомления - Установщик прошивки/приложений + Установка прошивки и приложений Вы собираетесь установить прошивку %s. Вы собираетесь установить прошивки %1$s и %2$s вместо текущей на вашем Mi Band. - Эта прошивка была проверена и совместима с Gadgetbridge. + Эта прошивка была проверена: она совместима с Gadgetbridge. Эта прошивка не протестирована и может быть несовместима с Gadgetbridge. \n \nНЕ РЕКОМЕНДУЕТСЯ устанавливать её! Если вы установите эту прошивку и убедитесь, что всё работает без сбоев, пожалуйста, сообщите об этом разработчикам Gadgetbridge. Они пометят эту версию прошивки (%s) как совместимую. Настройки - Общие настройки - Подключение к зарегистрированному устройству при активации Bluetooth + Общие + Подключаться к добавленному устройству при включении Bluetooth Запускать автоматически Переподключаться автоматически Предпочтительный музыкальный плеер По умолчанию Дата и время - Синхронизировать время при подключении - Синхронизировать время при подключении к зарегистрированному устройству, а также при изменении времени или временной зоны в системных настройках + Синхронизировать время + Синхронизировать время на добавленном устройстве при подключении, установке времени или часового пояса Тема Светлая - Темная + Тёмная Язык - Прятать уведомление Gadgetbridge - Показывать значок в строке состояния и уведомление на экране блокировки - Не показывать значок в строке состояния и уведомление на экране блокировки + Скрывать уведомление Gadgetbridge + Показывает значок в строке состояния и уведомление на экране блокировки + Не показывает значок в строке состояния и уведомление на экране блокировки Уведомления Повторы - Вызовы - СМС-сообщения + Телефонные звонки + SMS-сообщения Сообщения Pebble - Поддержка приложений, которые отправляют уведомления на Pebble с помощью PebbleKit. - Поддержка обычных уведомлений - … даже когда экран включён + Для приложений, которые отправляют уведомления на Pebble с помощью PebbleKit. + Доступ к уведомлениям + Уведомления при включённом экране Не беспокоить - Предотвращать отправку нежелательных уведомлений в режиме \"Не беспокоить\" + Не показывать нежелательные уведомления в этом режиме Транслитерация Всегда - Включите эту функцию, если ваше устройство не имеет поддержки шрифта на вашем языке + Включите, если на устройстве нет шрифта для вашего языка Когда экран выключен Никогда Конфиденциальность Конфиденциальность вызовов - Отображать имя и номер - Скрывать имя, но отображать номер - Скрывать номер, но отображать имя + Показывать имя и номер + Скрывать имя, но показывать номер + Скрывать номер, но показывать имя Скрывать имя и номер Заблокированные приложения Сохранённые сообщения Ответы Общий суффикс - Пропущенные вызовы + Отклонённые звонки Обновить на Pebble Настройки для разработчиков Адрес Mi Band @@ -122,7 +122,7 @@ Долгота Обновлять местоположение Попробуйте получить текущее местоположение во время выполнения, используйте сохраненное местоположение в качестве резервного - Пожалуйста, включите сетевое расположение + Включите местоположение по сети Месторасположение определено Принудительный протокол уведомлений Эта настройка принудительно использует самый новый протокол уведомлений (зависит от версии прошивки). ВКЛЮЧАЙТЕ, ЕСЛИ ТОЧНО ЗНАЕТЕ, ЗАЧЕМ ВЫ ЭТО ДЕЛАЕТЕ! @@ -198,7 +198,7 @@ Анализ фаз сна Сохранять файлы журнала Запускается - Получение данных активности + Передаёт данные активности От %1$s до %2$s Носите на левой или правой руке? Профиль настроек вибрации @@ -394,22 +394,22 @@ Пожертвовать Подключить… Заблокированные календари - Вы собираетесь установить прошивку %s на ваш Amazfit Bip. -\n -\nСоблюдайте последовательность: вначале установите файл .fw, затем .res, и затем .gps. После установки файла .fw часы перезагрузятся. -\n -\nОбратите внимание: если файлы .gps и .res такие же, как в текущей версии, их не нужно переустанавливать. -\n -\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! + Вы собираетесь установить прошивку %s на ваш Amazfit Bip. +\n +\nБудьте внимательны: сначала установите файл .fw, затем .res, и затем .gps. После установки файла .fw часы перезагрузятся. +\n +\nЕсли файлы .gps и .res такие же, как в текущей версии, их не нужно переустанавливать. +\n +\nВы действуете на свой страх и риск! Вы собираетесь установить прошивку %s на ваш Amazfit Cor. \n -\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw устройство перезагрузится. +\nБудьте внимательны: сначала установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. \n -\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\nЕсли файл и .res такой же, как в текущей версии, его не нужно переустанавливать. \n -\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! +\nВы действуете на свой страх и риск! Включить жесты \"провести направо и налево\" в графиках активности - Заблокировать Календари + Заблокированные календари Временной график Pebble Включить JS в фоновом режиме Включают, чтобы видеть погоду, заряд батарейки и т.д. на циферблате. @@ -431,7 +431,7 @@ Кол-во нажатий на кнопку Количество нажатий, необходимое для генерации События 1. Ещё столько же нажатий потребуется для генерации События 2 и т.д. Сообщение для трансляции - Сообщение транслируемое при наступлении события. Параметр `button_id` добавляется к каждому сообщению автоматически. + Отправлять сообщение при наступлении события. Параметр `button_id` добавляется к каждому сообщению автоматически. Включить действия для кнопки Включить действия на заданное кол-во нажатий кнопки Включить вибро-отклик браслета @@ -477,8 +477,8 @@ Погода Компас Настройки - Черный список уведомлений - Белый список уведомлений + Заблокировать все + Разблокировать все Вы собираетесь установить прошивку %s на ваш Mi Band 3. \n \nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. @@ -493,7 +493,7 @@ Автоматический экспорт включён Путь для экспорта данных Интервал экспорта - Экспортировать каждые %d часа(ов) + Экспортировать раз в %d ч. Испанский Русский Не измерялось @@ -530,15 +530,15 @@ XWatch MyKronoz ZeTime Ориентация экрана - Автозагрузка данных об активности - Загрузка данных при каждой разблокировке экрана. Это работает только при включенной блокировке экрана! - Минимальный интервал между загрузками - Загружать каждые %d минут(ы) + Автоматически получать данные + Получать данные активности при разблокировке. Работает только при настроенной блокировке экрана! + Минимальный интервал + Получать раз в %d мин. Горизонтально Вертикально Отслеживание активности Статистика активности - Сбросить дату загрузки + Сбросить дату получения Недопустимый формат данных Данные GPS Поправка ошибки GPS @@ -550,7 +550,7 @@ Уведомления Ещё Музыка - Калибровать устройство + Откалибровать устройство Когда устройство завибрирует, встряхните его или нажмите на кнопку. Watch 9 Минут: @@ -587,8 +587,8 @@ Автоматически снижать яркость экрана устройства по ночам На закате Принято - Изменить цвет излучения светодиода - Изменить частоту УКВ + Изменить цвет светодиода + Изменить FM-частоту Roidmi Roidmi 3 Цвет излучения светодиода @@ -602,11 +602,11 @@ Максимальный пульс Минимальный пульс Справа налево - Включите, если ваше устройство поддерживает ввод справа налево - Максимальная длина строки при вводе справа налево - Изменяет длину строк, на которые разбит текст при вводе справа налево + Включите, если устройство не отображает письмо справа налево + Длина строки при вводе справа налево + Изменить длину строк в тексте с письмом справа налево Контекстные формы для арабского языка - Включает поддержку контекстных форм арабского языка + Включить поддержку контекстных форм арабского языка Поддержка ввода справа налево Уведомление об отключении Упражнения @@ -615,12 +615,12 @@ Минимум одно из слов Все слова Введите хотя бы одно слово - Точно сбросить до заводских настроек\? + Сбросить до заводских настроек\? Режим фильтрации Сохранить конфигурацию Не подключено, будильник не установлено. nodomain.freeyourgadget.gadgetbridge.ButtonPressed - Сброс настроек приведёт к удалению всех данных с подключённого устройства (если поддерживается). Устройства Xiaomi / Huami также меняют MAC-адрес Bluetooth, поэтому для Gadgetbridge они отображаются как новые устройства. + Сброс настроек удалит все данные с этого устройства (если поддерживается). Устройства Xiaomi и Huami поменяют MAC-адрес Bluetooth, поэтому в Gadgetbridge они отображаются как новые устройства. ГГ/ММ/ДД ДД/ММ/ГГ ММ/ДД/ГГ @@ -646,12 +646,12 @@ Реакция на Событие 3 Детальная настройка реакции на нажатие кнопки Реакция на долгое нажатие - Приложение не должно находиться в черном списке для дальнейшей настройки - Введите нужные слова, где каждому новому слову соответствует своя строка + Чтобы настроить приложение, разблокируйте его + Введите нужные слова по одному в строке Фильтр уведомлений сохранён Не фильтровать Показывать, когда слова находятся в списке - Блокировать, когда слова находятся в списке + Блокировать, когда из списка списке Режим конфигурации Настройки ZeTime Настройки пульса @@ -690,7 +690,7 @@ Ежедневная цель: дистанция в метрах Ежедневная цель: время активности в минутах Mi Scale 2 - Активировать VoIP звонки внутри приложения + Включить VoIP-звонки Специфичные настройки устройства Ключ авторизации Измените ключ авторизации на общий ключ на всех ваших Android-устройствах, с которых вы хотели бы подключиться. Предыдущий ключ по умолчанию для всех устройств 0123456789@ABCDE @@ -772,11 +772,11 @@ Это устройство нуждается в ключе авторизации, используйте длительное нажатие на устройство, чтобы войти в него. Читайте Wiki. Вы собираетесь установить прошивку %s на ваш Amazfit Bip Lite. \n -\nСоблюдайте последовательность: вначале установите файл .fw, затем .res, и затем .gps. После установки файла .fw часы перезагрузятся. +\nБудьте внимательны: сначала установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. \n -\nОбратите внимание: если файлы .gps и .res такие же, как в текущей версии, их не нужно переустанавливать. +\nЕсли файл и .res такой же, как в текущей версии, его не нужно переустанавливать. \n -\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! +\nВы действуете на свой страх и риск! Amazfit GTR Вы собираетесь установить прошивку %s на ваш Amazfit GTR. \n @@ -815,7 +815,7 @@ изменения могут занять несколько секунд… смещение часового пояса на Отключить новое BLE сканирование - Установите этот флажок, если устройство не может быть найдено во время обнаружения + Включите, если устройство не видно как доступное Bangle.js Y5 Короткий сон From bb6f78467e5dec14d01c56900252ea167e6e13c1 Mon Sep 17 00:00:00 2001 From: Nee Sorry Date: Sat, 15 Feb 2020 14:43:31 +0000 Subject: [PATCH 16/49] Added translation using Weblate (Georgian) --- app/src/main/res/values-ka/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-ka/strings.xml diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-ka/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From b93c5c363161090e2ec5ea6e8f22a8890a7d9465 Mon Sep 17 00:00:00 2001 From: Vytenis Date: Sun, 16 Feb 2020 08:19:45 +0000 Subject: [PATCH 17/49] Translated using Weblate (Lithuanian) Currently translated at 35.5% (267 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/lt/ --- app/src/main/res/values-lt/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 2145cee33..1ba57eb79 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -9,7 +9,7 @@ Sinchronizuoti Surasti pamestą įrenginį Padaryti ekrano nuotrauką - Prijungti + Prijungti… Atjungti Ištrinti įrenginį Ištrinti %1$s @@ -26,7 +26,7 @@ Užverti programos meniu Norėdami atjungti ilgai spauskite kortelę Atjungiama - Jungiama + Jungiama… Derinti Programų tvarkyklė Programos talpykloje From 57d9d88986b4733b663408a9b686383f9e5018f1 Mon Sep 17 00:00:00 2001 From: Nee Sorry Date: Sat, 15 Feb 2020 14:51:55 +0000 Subject: [PATCH 18/49] Translated using Weblate (Georgian) Currently translated at 4.2% (32 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ka/ --- app/src/main/res/values-ka/strings.xml | 33 +++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index a6b3daec9..6d833162d 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -1,2 +1,33 @@ - \ No newline at end of file + + გაჯეტბრიჯი + გაჯეტბრიდჯი + პარამეტრები + შეწყვეტა + დონაცია + სინქრონიზაცია + დაკარგული მოწყობილობის პოვნა + LED ფერის შეცვლა + FM სიხშირის შეცვლა + დაკავშირება… + გათიშვა + მოწყობილობის წაშლა + წაშლა %1$s + ეს წაშლის ხელსაწყოს და მასთან დაკავშირებულ ყველა მონაცემს! + დააჭირეთ ბარათს გათიშვისთვის + გათიშავს + აკავშირებს… + მოწყობილობის დაკალიბრება + გსურთ რეალურად მოწყობილობის გადატვირთვა\? + აპლიკაციას მენეჭერი + აპლიკაციები ქეშიში + დაინსტალირებული აპლიკაციები + დაინსტალირებული ციფერბლატები + წაშლა + წაშლა და ქეშიდან ამოღება + ისევ ინსტალაცია + ფებლის მაღაზიაში ძებნა + გააქტიურება + გამორტვა + კონფიგურაცია + \ No newline at end of file From 01ab7bcb54cad446bd149f7bb01c50ec30c7f97a Mon Sep 17 00:00:00 2001 From: Andrzej Surowiec Date: Fri, 21 Feb 2020 21:57:18 +0100 Subject: [PATCH 19/49] Fix answering/rejecting calls on Android 9 --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 1 + .../activities/ControlCenterv2.java | 2 + .../receivers/GBCallControlReceiver.java | 50 +++++++++++++++---- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 65c329204..a1b545e45 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,7 +22,7 @@ android { defaultConfig { applicationId "nodomain.freeyourgadget.gadgetbridge" minSdkVersion 19 - targetSdkVersion 27 + targetSdkVersion 28 // Note: always bump BOTH versionCode and versionName! versionName "0.42.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 788b6b740..6cce9aac7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java index 5ec41ba3a..1b61b4791 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java @@ -343,6 +343,8 @@ public class ControlCenterv2 extends AppCompatActivity wantedPermissions.add(Manifest.permission.READ_CONTACTS); if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_DENIED) wantedPermissions.add(Manifest.permission.CALL_PHONE); + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_DENIED) + wantedPermissions.add(Manifest.permission.ANSWER_PHONE_CALLS); if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_DENIED) wantedPermissions.add(Manifest.permission.READ_CALL_LOG); if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java index f26a2d5da..42a3d4620 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java @@ -16,9 +16,12 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.receivers; +import android.annotation.TargetApi; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.os.Build; +import android.telecom.TelecomManager; import android.telephony.TelephonyManager; import com.android.internal.telephony.ITelephony; @@ -28,20 +31,26 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.Method; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; public class GBCallControlReceiver extends BroadcastReceiver { public static final String ACTION_CALLCONTROL = "nodomain.freeyourgadget.gadgetbridge.callcontrol"; private static final Logger LOG = LoggerFactory.getLogger(GBCallControlReceiver.class); + private Context mContext = GBApplication.getContext(); @Override public void onReceive(Context context, Intent intent) { GBDeviceEventCallControl.Event callCmd = GBDeviceEventCallControl.Event.values()[intent.getIntExtra("event", 0)]; - switch (callCmd) { - case END: - case REJECT: - case START: - try { + + if (Build.VERSION.SDK_INT >= 28){ + handleCallCmdTelecomManager(callCmd); + }else { + switch (callCmd) { + case END: + case REJECT: + case START: + try { TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); Class clazz = Class.forName(telephonyManager.getClass().getName()); Method method = clazz.getDeclaredMethod("getITelephony"); @@ -52,11 +61,32 @@ public class GBCallControlReceiver extends BroadcastReceiver { } else { telephonyService.answerRingingCall(); } - } catch (Exception e) { - LOG.warn("could not start or hangup call"); - } - break; - default: + } catch (Exception e) { + LOG.warn("could not start or hangup call"); + } + break; + default: + } + } + } + + @TargetApi(28) + public void handleCallCmdTelecomManager(GBDeviceEventCallControl.Event callCmd){ + try { + TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); + + if (callCmd == GBDeviceEventCallControl.Event.END || callCmd == GBDeviceEventCallControl.Event.REJECT) { + tm.endCall(); + } + else if (callCmd == GBDeviceEventCallControl.Event.START || callCmd == GBDeviceEventCallControl.Event.ACCEPT) { + tm.acceptRingingCall(); + } + + }catch (SecurityException e){ + LOG.warn("no permission to start or hangup call"); + } + catch (Exception e) { + LOG.warn("could not start or hangup call"); } } } From 1b416e18b92617f04f64fd70cadbc71443493b40 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sat, 22 Feb 2020 10:12:33 +0100 Subject: [PATCH 20/49] introduce GBApplication.isRunningPieOrLater() and fix indent of last commit --- .../gadgetbridge/GBApplication.java | 4 ++ .../receivers/GBCallControlReceiver.java | 39 +++++++++---------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index a8b2446ab..451a7c435 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -344,6 +344,10 @@ public class GBApplication extends Application { return VERSION.SDK_INT >= Build.VERSION_CODES.O; } + public static boolean isRunningPieOrLater() { + return VERSION.SDK_INT >= Build.VERSION_CODES.P; + } + private static boolean isPrioritySender(int prioritySenders, String number) { if (prioritySenders == Policy.PRIORITY_SENDERS_ANY) { return true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java index 42a3d4620..e2bd99d4b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java @@ -16,7 +16,6 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.receivers; -import android.annotation.TargetApi; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -24,6 +23,8 @@ import android.os.Build; import android.telecom.TelecomManager; import android.telephony.TelephonyManager; +import androidx.annotation.RequiresApi; + import com.android.internal.telephony.ITelephony; import org.slf4j.Logger; @@ -43,24 +44,24 @@ public class GBCallControlReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { GBDeviceEventCallControl.Event callCmd = GBDeviceEventCallControl.Event.values()[intent.getIntExtra("event", 0)]; - if (Build.VERSION.SDK_INT >= 28){ + if (GBApplication.isRunningPieOrLater()) { handleCallCmdTelecomManager(callCmd); - }else { + } else { switch (callCmd) { case END: case REJECT: case START: try { - TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - Class clazz = Class.forName(telephonyManager.getClass().getName()); - Method method = clazz.getDeclaredMethod("getITelephony"); - method.setAccessible(true); - ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager); - if (callCmd == GBDeviceEventCallControl.Event.END || callCmd == GBDeviceEventCallControl.Event.REJECT) { - telephonyService.endCall(); - } else { - telephonyService.answerRingingCall(); - } + TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + Class clazz = Class.forName(telephonyManager.getClass().getName()); + Method method = clazz.getDeclaredMethod("getITelephony"); + method.setAccessible(true); + ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager); + if (callCmd == GBDeviceEventCallControl.Event.END || callCmd == GBDeviceEventCallControl.Event.REJECT) { + telephonyService.endCall(); + } else { + telephonyService.answerRingingCall(); + } } catch (Exception e) { LOG.warn("could not start or hangup call"); } @@ -70,22 +71,20 @@ public class GBCallControlReceiver extends BroadcastReceiver { } } - @TargetApi(28) - public void handleCallCmdTelecomManager(GBDeviceEventCallControl.Event callCmd){ + @RequiresApi(api = Build.VERSION_CODES.P) + public void handleCallCmdTelecomManager(GBDeviceEventCallControl.Event callCmd) { try { TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); if (callCmd == GBDeviceEventCallControl.Event.END || callCmd == GBDeviceEventCallControl.Event.REJECT) { tm.endCall(); - } - else if (callCmd == GBDeviceEventCallControl.Event.START || callCmd == GBDeviceEventCallControl.Event.ACCEPT) { + } else if (callCmd == GBDeviceEventCallControl.Event.START || callCmd == GBDeviceEventCallControl.Event.ACCEPT) { tm.acceptRingingCall(); } - }catch (SecurityException e){ + } catch (SecurityException e) { LOG.warn("no permission to start or hangup call"); - } - catch (Exception e) { + } catch (Exception e) { LOG.warn("could not start or hangup call"); } } From 9a114f640bb977c113a40ef8ce45ca63f653fd21 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 24 Feb 2020 14:19:06 +0100 Subject: [PATCH 21/49] Huami: Make experimental calendar sync feature optional --- .../devicesettings/DeviceSettingsPreferenceConst.java | 1 + .../devices/huami/amazfitbip/AmazfitBipCoordinator.java | 1 + .../devices/huami/amazfitcor/AmazfitCorCoordinator.java | 1 + .../huami/amazfitcor2/AmazfitCor2Coordinator.java | 1 + .../devices/huami/amazfitgtr/AmazfitGTRCoordinator.java | 1 + .../devices/huami/amazfitgts/AmazfitGTSCoordinator.java | 1 + .../devices/huami/miband3/MiBand3Coordinator.java | 1 + .../devices/huami/miband4/MiBand4Coordinator.java | 1 + .../gadgetbridge/service/devices/huami/HuamiSupport.java | 9 +++++++-- app/src/main/res/values/strings.xml | 2 ++ 10 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 8963da73a..027ecca5d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -23,4 +23,5 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_SCREEN_ORIENTATION = "screen_orientation"; public static final String PREF_RESERVER_ALARMS_CALENDAR = "reserve_alarms_calendar"; public static final String PREF_ALLOW_HIGH_MTU = "allow_high_mtu"; + public static final String PREF_SYNC_CALENDAR = "sync_calendar"; } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java index e6988a13d..c462a6cbf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java @@ -86,6 +86,7 @@ public class AmazfitBipCoordinator extends HuamiCoordinator { R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_buttonactions_with_longpress, R.xml.devicesettings_pairingkey diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java index 8c334c33d..6c5b7e839 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java @@ -89,6 +89,7 @@ public class AmazfitCorCoordinator extends HuamiCoordinator { R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java index ea7f55431..56209f6be 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java @@ -91,6 +91,7 @@ public class AmazfitCor2Coordinator extends HuamiCoordinator { R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java index f253838e1..b4bfdcafe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java @@ -93,6 +93,7 @@ public class AmazfitGTRCoordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java index 77fa1d61c..1c244bd6a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java @@ -93,6 +93,7 @@ public class AmazfitGTSCoordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java index 30c3a9ffb..3dc835b4a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java @@ -110,6 +110,7 @@ public class MiBand3Coordinator extends HuamiCoordinator { R.xml.devicesettings_donotdisturb_withauto, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_swipeunlock, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java index b1e22b125..883322d0d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java @@ -96,6 +96,7 @@ public class MiBand4Coordinator extends HuamiCoordinator { R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_swipeunlock, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey, R.xml.devicesettings_high_mtu diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 8c6a6e745..5d7ddbb20 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -137,6 +137,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.Version; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ALLOW_HIGH_MTU; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DATEFORMAT; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_RESERVER_ALARMS_CALENDAR; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SYNC_CALENDAR; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TIMEFORMAT; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_WEARLOCATION; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; @@ -738,11 +739,10 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { setCurrentTimeWithService(builder); //TODO: once we have a common strategy for sending events (e.g. EventHandler), remove this call from here. Meanwhile it does no harm. // = we should genaralize the pebble calender code - if (characteristicChunked == null) { + if (characteristicChunked == null) { // all except Mi Band 2 sendCalendarEvents(builder); } else { - // TODO: make this configurable sendCalendarEventsAsReminder(builder); } builder.queue(getQueue()); @@ -1707,6 +1707,11 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } private HuamiSupport sendCalendarEventsAsReminder(TransactionBuilder builder) { + boolean syncCalendar = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getBoolean(PREF_SYNC_CALENDAR, false); + if (!syncCalendar) { + return this; + } + CalendarEvents upcomingEvents = new CalendarEvents(); List calendarEvents = upcomingEvents.getCalendarEventList(getContext()); Calendar calendar = Calendar.getInstance(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8adcb7e08..970e55ae5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -182,6 +182,8 @@ Enable this if your device has a custom font firmware for emoji support Allow high MTU Increases transfer speed, but might not work on some Android devices. + Enables calendar alerts, even when disconnected + Sync calendar events Connect new device button Always visible Visible only if no device is added From 2580a0b818dc0cc217d8db0cd8f5cd0d74d9cede Mon Sep 17 00:00:00 2001 From: Fabio Parri Date: Fri, 21 Feb 2020 07:59:28 +0000 Subject: [PATCH 22/49] Translated using Weblate (Italian) Currently translated at 96.4% (724 of 751 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/it/ --- app/src/main/res/values-it/strings.xml | 106 ++++++++++++++++++++----- 1 file changed, 87 insertions(+), 19 deletions(-) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 7c48102b8..a297aa0ee 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -140,9 +140,9 @@ Tentativi di riconessione Unità - Formato dell\'orario + Formato orario Durata dell\'accensione dello schermo - Misura il battito cardiaco continuativamente + Misurazione della frequenza cardiaca per tutto il giorno Impostazioni HPlus/Makibes Non connesso In collegamento @@ -225,7 +225,7 @@ Passi al minuto Trova dispositivo smarrito Annulla per fermare la vibrazione. - Le tue attività + Attività e Sonno Configurazione sveglia Configurazione sveglia Sveglia @@ -253,11 +253,11 @@ %1$s batteria rimanente: %2$s%% Ultima ricarica: %s \n Numero di ricariche: %s - Il tuo sonno + Sonno Sonno settimanale Sonno di oggi, obiettivo: %1$s Passi della settimana - Attività e sonno + Attività Aggiornamento del Firmware… Il file non può essere installato, il dispositivo non è pronto. %1$s: %2$s %3$s @@ -430,11 +430,11 @@ ogni ora Esportazione del database fallita! Per favore controlla le impostazioni. Azioni tasto - Specifica le azioni alla pressione del pulsante del Mi Band 2 + Specifica le azioni alla pressione del pulsante Conteggio pressione tasto - Numero di volte che il tasto deve essere premuto per inviare un messaggio in broadcast + Numero di volte che il tasto deve essere premuto per generare un Evento 1. Successivo medesimo numero di volte che il tasto deve essere premuto per un Evento 2 e così via. Messaggio da inviare in broadcast - Numero di pressioni del tasto per il messaggio in broadcast raggiunto + Messaggio inviato con l\'evento. Il parametro `button_id` è aggiunto automaticamente al ogni messaggio. Abilita azioni tasto Abilita azioni selezionando un numero specifico di pressioni del tasto Abilita vibrazione band @@ -484,7 +484,7 @@ Notifiche Gadgetbridge XWatch Acceso - Blocca le notifiche da tutte le applicazioni + Blocca tutte le notifiche Consenti le notifiche da tutte le applicazioni Si sta per installare il firmware %s sul Mi Band 3. \n @@ -602,7 +602,7 @@ Passi mancanti: %1$d Passi eccedenti: %1$d Vuoi ripristinare alle impostazioni di fabbrica\? - Effettuare il ripristino delle impostazioni di fabbrica cancellerà tutti i dati presenti sul dispositivo connesso (se supportato). I dispositivi Xiaomi/Huami cambieranno anche il proprio MAC Address Bluetooth, in modo da risultare dispositivi nuovi per Gadgetbrige. + Effettuare il ripristino delle impostazioni di fabbrica cancellerà tutti i dati presenti sul dispositivo connesso (se supportato). I dispositivi Xiaomi/Huami cambiano anche MAC Address Bluetooth, e in modo risultano dispositivi nuovi per Gadgetbrige. Casio GB-6900 Filtro Notifiche L\'app non deve trovarsi nella blacklist per essere configurata @@ -676,15 +676,15 @@ Obiettivo giornaliero: tempo di attività in minuti Mi Scale 2 BFH-16 - Stai per installare il firmware %s sul tuo Amazfit Cor 2. -\n -\nAssicurati di installare il file .fw e successivamente il file .res. L\' Amazfit Cor 2 si riavvierà dopo aver installato il file .fw. -\n -\nNota: non è necessario installare .res se è esattamente lo stesso di quello precedentemente installato. -\n -\nPROCEDI A TUO RISCHIO! -\n -\nNON COMPLETAMENTE TESTATO, PROBABILMENTE DOVRAI FLASHARE IL FIRMWARE BEATS_W SE IL NOME DEL TUO DISPOSITIVO è \"Amazfit Band 2\" + Stai per installare il firmware %s sul tuo Amazfit Cor 2. +\n +\nAssicurati di installare il file .fw e successivamente il file .res. La band si riavvierà dopo aver installato il file .fw. +\n +\nNota: non è necessario installare .res se è esattamente lo stesso di quello installato in precedenza. +\n +\nPROCEDI A TUO RISCHIO! +\n +\nCOMPLETAMENTE NON TESTATO, PROBABILMENTE DOVRAI FLASHARE IL FIRMWARE BEATS_W SE IL NOME DEL TUO DISPOSITIVO è \"Amazfit Band 2\" Olandese Turco Ucraino @@ -706,4 +706,72 @@ Limite inferiore Limite Superiore nodomain.freeyourgadget.gadgetbridge.ButtonPressed + Impostazioni dei grafici + Mostra le medie nei grafici + Intervallo dei grafici + L\'intervallo dei grafici è impostato su di un mese + L\'intervallo dei grafici è impostato su di una settimana + Passi al mese + Sonno per mese + NFC + Consente ad altre applicazioni di accedere ai dati cardiaci in tempo reale mentre Gadgetbridge è collegato + Accesso ai dati cardiaci in tempo reale a terze parti + Utilizza un font personalizzato + Abilita questa opzione se il tuo dispositivo ha un firmware dei caratteri personalizzato per il supporto emoji + Il percorso di esportazione automatica del database è stato impostato su: + Esportazione automatica + Esporta DB + Importa DB + Esegui esportazione automatica ora + Esportazione database in corso… + Elimina db precedente + DB vuoto + Database vuoto + Esportazione e importazione + Attenzione! Premendo questo pulsante si cancella il database e si riparte da zero. + Passi: %1$02d + Riposo:% 1 $ s + Imposta sveglia dopo: + 5 minuti + 10 minuti + 20 minuti + 1 ora + Sempre visibile + Visibile solo se non viene aggiunto alcun dispositivo + Per visualizzare la traccia delle attività, installare un\'applicazione in grado di gestire i file GPX. + Impostazioni Makibes HR3 + Makibes HR3 + Amazfit Bip Lite + Trova telefono + Attivare \'\'Trova telefono\' + Usa la tua band per riprodurre la suoneria del tuo telefono. + Durata dello squillo in secondi + Durata + Questo dispositivo ha bisogno di una chiave di autenticazione segreta, premere a lungo sul dispositivo per inserirla. Leggi il wiki. + Amazfit GTR + Rosso + Arancione + Colore della frequenza cardiaca + Intervallo di sonno + Ultime 24 ore + Da mezzogiorno a mezzogiorno + Amazfit GTS + Fossil Q Hybrid + Orologio non connesso + forza della vibrazione: + Obiettivo in passi + Il cambiamento potrebbe richiedere qualche secondo… + Disattivare nuove scansioni BLE + Selezionare questa opzione se il dispositivo non può essere trovato durante il rilevamento + Bangle.js + Y5 + Evento 1 azione + Evento 2 azione + Evento 3 azione + Azione di pressione prolungata del pulsante + Snooze + Per il corretto funzionamento della scansione dei dispositivi occorre concedere e abilitare l\'accesso alla posizione + iTag + Consenti MTU elevato + Aumenta la velocità di trasferimento, ma potrebbe non funzionare su alcuni dispositivi Android. \ No newline at end of file From 8f0a407db9e54514535d55f3d49216574acc2b29 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 24 Feb 2020 14:29:11 +0100 Subject: [PATCH 23/49] bump version, add changelog, commit missing file --- CHANGELOG.md | 4 ++++ app/build.gradle | 4 ++-- app/src/main/res/xml/changelog_master.xml | 4 ++++ app/src/main/res/xml/devicesettings_sync_calendar.xml | 8 ++++++++ fastlane/metadata/android/en-US/changelogs/168.txt | 2 ++ 5 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/xml/devicesettings_sync_calendar.xml create mode 100644 fastlane/metadata/android/en-US/changelogs/168.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e2e9014d..99c2ca323 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ### Changelog +#### Version 0.42.1 +* Fix accepting/rejecting calls on Android 9 +* Mi Band 3/4, Amazfit Bip/Cor/GTS/GTR: Option to sync calender events as reminder + #### Version 0.42.0 * Initial iTag support * Fix indefinitely lasting bluetooth scans when location permission has not been granted diff --git a/app/build.gradle b/app/build.gradle index a1b545e45..cb0ec42ec 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,8 +25,8 @@ android { targetSdkVersion 28 // Note: always bump BOTH versionCode and versionName! - versionName "0.42.0" - versionCode 167 + versionName "0.42.1" + versionCode 168 vectorDrawables.useSupportLibrary = true } buildTypes { diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index c9deff023..5f6349d9b 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,5 +1,9 @@ + + Fix accepting/rejecting calls on Android 9 + Mi Band 3/4, Amazfit Bip/Cor/GTS/GTR: Option to sync calender events as reminder + Initial iTag support Fix indefinitely lasting bluetooth scans when location permission has not been granted diff --git a/app/src/main/res/xml/devicesettings_sync_calendar.xml b/app/src/main/res/xml/devicesettings_sync_calendar.xml new file mode 100644 index 000000000..58c66b1b9 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_sync_calendar.xml @@ -0,0 +1,8 @@ + + + + diff --git a/fastlane/metadata/android/en-US/changelogs/168.txt b/fastlane/metadata/android/en-US/changelogs/168.txt new file mode 100644 index 000000000..087149a1b --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/168.txt @@ -0,0 +1,2 @@ +* Fix accepting/rejecting calls on Android 9 +* Mi Band 3/4, Amazfit Bip/Cor/GTS/GTR: Option to sync calender events as reminder From 136825fa9d3e53a82bc5dc365e89f46a926e8a6e Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 26 Feb 2020 21:15:30 +0100 Subject: [PATCH 24/49] Do not connect to random (first) device on start --- .../gadgetbridge/activities/ControlCenterv2.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java index f278cad5d..1b61b4791 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java @@ -218,12 +218,6 @@ public class ControlCenterv2 extends AppCompatActivity } else { GBApplication.deviceService().requestDeviceInfo(); } - - List devices = deviceManager.getDevices(); - - if(devices.size() > 0){ - GBApplication.deviceService().connect(devices.get(0)); - } } @Override From c766b1d1b7874d27233c1a1fa81ad8e01c57ae64 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 26 Feb 2020 21:31:04 +0100 Subject: [PATCH 25/49] Make exception notification only visible in debug builds --- .../service/devices/qhybrid/QHybridSupport.java | 11 ++++++++--- .../qhybrid/adapter/fossil/FossilWatchAdapter.java | 1 - 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java index 7d71f4a9b..98c71b37b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java @@ -45,6 +45,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.BuildConfig; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; @@ -560,7 +561,13 @@ public class QHybridSupport extends QHybridBaseSupport { notifiyException("", e); } - public void notifiyException(String requestName, Exception e){ + public void notifiyException(String requestName, Exception e) { + if (!BuildConfig.DEBUG) { + logger.error("Error: " + requestName, e); + return; + } + GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.ERROR, e); + StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); @@ -593,7 +600,6 @@ public class QHybridSupport extends QHybridBaseSupport { } ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify((int) System.currentTimeMillis(), notificationBuilder.build()); - } @Override @@ -623,7 +629,6 @@ public class QHybridSupport extends QHybridBaseSupport { gbDevice.addDeviceInfo(new GenericItem(ITEM_HAS_ACTIVITY_HAND, String.valueOf(watchAdapter.supportsActivityHand()))); } catch (UnsupportedOperationException e) { notifiyException(e); - GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.INFO); gbDevice.addDeviceInfo(new GenericItem(ITEM_EXTENDED_VIBRATION_SUPPORT, "false")); } break; 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 e3b0c481d..ab030c145 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 @@ -521,7 +521,6 @@ public class FossilWatchAdapter extends WatchAdapter { } } catch (UnsupportedOperationException e) { getDeviceSupport().notifiyException(e); - GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.INFO); } if (start && getDeviceSupport().searchDevice) return; From c68182fd42b3ea8659d057ca4cce9634c887b26e Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 26 Feb 2020 21:50:37 +0100 Subject: [PATCH 26/49] Fossil support does not support activity data fetching yet. --- .../gadgetbridge/devices/qhybrid/QHybridCoordinator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java index 4b8aa316c..3a4d9784a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java @@ -85,7 +85,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { @Override public boolean supportsActivityDataFetching() { - return true; + return false; } @Override From d3f6b115eed56ddcaadd59899acbeb2d2f536ad0 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 26 Feb 2020 21:59:48 +0100 Subject: [PATCH 27/49] Alarm Details configuration: set scale factor back to 1 --- app/src/main/res/layout/activity_alarm_details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/activity_alarm_details.xml b/app/src/main/res/layout/activity_alarm_details.xml index 8a449e905..f3ab4f7dd 100644 --- a/app/src/main/res/layout/activity_alarm_details.xml +++ b/app/src/main/res/layout/activity_alarm_details.xml @@ -47,8 +47,8 @@ android:id="@+id/alarm_time_picker" android:layout_width="match_parent" android:layout_height="wrap_content" - android:scaleX="0.7" - android:scaleY="0.7" + android:scaleX="1" + android:scaleY="1" android:layout_marginBottom="20dp" /> Date: Wed, 26 Feb 2020 22:25:03 +0100 Subject: [PATCH 28/49] Sanity check for alarms index to avoid AIOOBE --- .../gadgetbridge/service/devices/huami/HuamiSupport.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 5d7ddbb20..4aa1ccf10 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -1501,12 +1501,17 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { private void decodeAndUpdateAlarmStatus(byte[] response) { List alarms = DBHelper.getAlarms(gbDevice); - boolean[] alarmsInUse = new boolean[10]; - boolean[] alarmsEnabled = new boolean[10]; + int maxAlarms = 10; + boolean[] alarmsInUse = new boolean[maxAlarms]; + boolean[] alarmsEnabled = new boolean[maxAlarms]; int nr_alarms = response[8]; for (int i = 0; i < nr_alarms; i++) { byte alarm_data = response[9 + i]; int index = alarm_data & 0xf; + if (index >= maxAlarms) { + GB.toast("Unexpected alarm index from device, ignoring: " + index, Toast.LENGTH_SHORT, GB.ERROR); + return; + } alarmsInUse[index] = true; boolean enabled = (alarm_data & 0x10) == 0x10; alarmsEnabled[index] = enabled; From ce574ea5dbd1fb389f4c8175cc31d9f6037571b5 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 26 Feb 2020 22:37:18 +0100 Subject: [PATCH 29/49] Use long instead of int for daily totals calculation --- .../freeyourgadget/gadgetbridge/Widget.java | 10 +++--- .../gadgetbridge/model/DailyTotals.java | 32 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java index 5ade766fc..9cb178955 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java @@ -66,12 +66,12 @@ public class Widget extends AppWidgetProvider { return gbApp.getDeviceManager().getSelectedDevice(); } - private int[] getSteps() { + private long[] getSteps() { Context context = GBApplication.getContext(); Calendar day = GregorianCalendar.getInstance(); if (!(context instanceof GBApplication)) { - return new int[]{0, 0, 0}; + return new long[]{0, 0, 0}; } DailyTotals ds = new DailyTotals(); return ds.getDailyTotalsForAllDevices(day); @@ -114,10 +114,10 @@ public class Widget extends AppWidgetProvider { } - int[] DailyTotals = getSteps(); + long[] dailyTotals = getSteps(); - views.setTextViewText(R.id.todaywidget_steps, context.getString(R.string.widget_steps_label, (int) DailyTotals[0])); - views.setTextViewText(R.id.todaywidget_sleep, context.getString(R.string.widget_sleep_label, getHM((long) DailyTotals[1]))); + views.setTextViewText(R.id.todaywidget_steps, context.getString(R.string.widget_steps_label, dailyTotals[0])); + views.setTextViewText(R.id.todaywidget_sleep, context.getString(R.string.widget_sleep_label, getHM((dailyTotals[1]))); if (device != null) { String status = String.format("%1s", device.getStateString()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DailyTotals.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DailyTotals.java index 59647d35d..2b35eabb4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DailyTotals.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DailyTotals.java @@ -40,11 +40,11 @@ public class DailyTotals { private static final Logger LOG = LoggerFactory.getLogger(DailyTotals.class); - public int[] getDailyTotalsForAllDevices(Calendar day) { + public long[] getDailyTotalsForAllDevices(Calendar day) { Context context = GBApplication.getContext(); //get today's steps for all devices in GB - int all_steps = 0; - int all_sleep = 0; + long all_steps = 0; + long all_sleep = 0; if (context instanceof GBApplication) { @@ -55,18 +55,18 @@ public class DailyTotals { if (!coordinator.supportsActivityDataFetching()) { continue; } - int[] all_daily = getDailyTotalsForDevice(device, day); + long[] all_daily = getDailyTotalsForDevice(device, day); all_steps += all_daily[0]; all_sleep += all_daily[1] + all_daily[2]; } } LOG.debug("gbwidget daily totals, all steps:" + all_steps); LOG.debug("gbwidget daily totals, all sleep:" + all_sleep); - return new int[]{all_steps, all_sleep}; + return new long[]{all_steps, all_sleep}; } - public int[] getDailyTotalsForDevice(GBDevice device, Calendar day) { + public long[] getDailyTotalsForDevice(GBDevice device, Calendar day) { try (DBHandler handler = GBApplication.acquireDB()) { ActivityAnalysis analysis = new ActivityAnalysis(); @@ -76,19 +76,19 @@ public class DailyTotals { amountsSteps = analysis.calculateActivityAmounts(getSamplesOfDay(handler, day, 0, device)); amountsSleep = analysis.calculateActivityAmounts(getSamplesOfDay(handler, day, -12, device)); - int[] Sleep = getTotalsSleepForActivityAmounts(amountsSleep); - int Steps = getTotalsStepsForActivityAmounts(amountsSteps); + long[] sleep = getTotalsSleepForActivityAmounts(amountsSleep); + long steps = getTotalsStepsForActivityAmounts(amountsSteps); - return new int[]{Steps, Sleep[0], Sleep[1]}; + return new long[]{steps, sleep[0], sleep[1]}; } catch (Exception e) { GB.toast("Error loading activity summaries.", Toast.LENGTH_SHORT, GB.ERROR, e); - return new int[]{0, 0, 0}; + return new long[]{0, 0, 0}; } } - private int[] getTotalsSleepForActivityAmounts(ActivityAmounts activityAmounts) { + private long[] getTotalsSleepForActivityAmounts(ActivityAmounts activityAmounts) { long totalSecondsDeepSleep = 0; long totalSecondsLightSleep = 0; for (ActivityAmount amount : activityAmounts.getAmounts()) { @@ -98,14 +98,14 @@ public class DailyTotals { totalSecondsLightSleep += amount.getTotalSeconds(); } } - int totalMinutesDeepSleep = (int) (totalSecondsDeepSleep / 60); - int totalMinutesLightSleep = (int) (totalSecondsLightSleep / 60); - return new int[]{totalMinutesDeepSleep, totalMinutesLightSleep}; + long totalMinutesDeepSleep = (totalSecondsDeepSleep / 60); + long totalMinutesLightSleep = (totalSecondsLightSleep / 60); + return new long[]{totalMinutesDeepSleep, totalMinutesLightSleep}; } - private int getTotalsStepsForActivityAmounts(ActivityAmounts activityAmounts) { - int totalSteps = 0; + private long getTotalsStepsForActivityAmounts(ActivityAmounts activityAmounts) { + long totalSteps = 0; for (ActivityAmount amount : activityAmounts.getAmounts()) { totalSteps += amount.getTotalSteps(); From 18ebd766c7f35c20ea1948dd930ef63b206c41b9 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 26 Feb 2020 22:42:43 +0100 Subject: [PATCH 30/49] Make the constant static final --- .../service/devices/casiogb6900/CasioHandlerThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioHandlerThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioHandlerThread.java index dfa5e90ff..379db068b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioHandlerThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioHandlerThread.java @@ -30,11 +30,11 @@ import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread; public class CasioHandlerThread extends GBDeviceIoThread { private static final Logger LOG = LoggerFactory.getLogger(CasioHandlerThread.class); + private static final int TX_PERIOD = 60; private boolean mQuit = false; private CasioGB6900DeviceSupport mDeviceSupport; private final Object waitObject = new Object(); - private int TX_PERIOD = 60; private Calendar mTxTime = GregorianCalendar.getInstance(); From 07818d1f79caf59a10aa3ec94750c17eaae568cd Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 26 Feb 2020 23:16:34 +0100 Subject: [PATCH 31/49] Remove extraneous bracket --- .../main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java index 9cb178955..c59ad39e0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java @@ -117,7 +117,7 @@ public class Widget extends AppWidgetProvider { long[] dailyTotals = getSteps(); views.setTextViewText(R.id.todaywidget_steps, context.getString(R.string.widget_steps_label, dailyTotals[0])); - views.setTextViewText(R.id.todaywidget_sleep, context.getString(R.string.widget_sleep_label, getHM((dailyTotals[1]))); + views.setTextViewText(R.id.todaywidget_sleep, context.getString(R.string.widget_sleep_label, getHM(dailyTotals[1]))); if (device != null) { String status = String.format("%1s", device.getStateString()); From f0afa0e291dab5fe6ff6d7e31db7e239d5a3162a Mon Sep 17 00:00:00 2001 From: fparri Date: Thu, 27 Feb 2020 09:22:11 +0100 Subject: [PATCH 32/49] WIP - Added a localization string for the find lost device feature (#1809) Added a new string to localize the Found it! message shown when using the find lost device feature --- .../freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java | 2 +- app/src/main/res/values-it/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index 9bfe5b148..f76924e14 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -292,7 +292,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.AdapterAM/PM Sveglia Trovato! + Trovato! Mi2: Formato dell\'orario E\' necessario installare la verione %1$s prima di installare questo firmware! Notifiche diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ec5d2edd3..ad1fa5c8c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -610,6 +610,7 @@ Web View Activity (%1$s) You found it! + Found it! Mi2: Time format You need to install version %1$s before installing this firmware! Text notifications From 003dd943eadabb32c36947ae5d813b02c15b7dd5 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Mon, 24 Feb 2020 13:50:38 +0000 Subject: [PATCH 33/49] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (753 of 753 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/pt_BR/ --- app/src/main/res/values-pt-rBR/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 57d594b81..b8fe693b9 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -835,4 +835,6 @@ iTag Permitir MTU alto Aumenta velocidade de transferência, mas pode não funcionar em alguns dispositivos Android. + Possibilita alertas de calendário, mesmo quando desconectado + Sincronizar eventos de calendário \ No newline at end of file From 584766e9beec673fdcc8d58da683f97ce0bc3023 Mon Sep 17 00:00:00 2001 From: nautilusx Date: Mon, 24 Feb 2020 17:33:31 +0000 Subject: [PATCH 34/49] Translated using Weblate (German) Currently translated at 100.0% (753 of 753 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/de/ --- app/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 17eae1d01..ed3e37cd7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -832,4 +832,6 @@ Aktion bei 2 Tastendrücken Aktion bei 3 Tastendrücken Hohe MTU erlauben + Aktiviert Kalendererinnerungen, auch wenn die Verbindung getrennt ist + Kalenderereignisse synchronisieren \ No newline at end of file From 3366150bdb0ca18fcb69bd33f44192427e133422 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 24 Feb 2020 17:58:16 +0000 Subject: [PATCH 35/49] Translated using Weblate (Hebrew) Currently translated at 100.0% (753 of 753 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index b8f6296dd..a33004e66 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -825,4 +825,6 @@ iTag לאפשר MTU גבוה מגביר את קצב ההעברה, יש מכשירי Android שלא תומכים בזה. + הפעלת התראות לוח שנה, אפילו ללא חיבור + סנכרון אירועי לוח שנה \ No newline at end of file From 2ca5674f55dc3dc2aef54fc27ec5c93586977251 Mon Sep 17 00:00:00 2001 From: Fabio Parri Date: Tue, 25 Feb 2020 11:17:34 +0000 Subject: [PATCH 36/49] Translated using Weblate (Italian) Currently translated at 96.0% (723 of 753 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/it/ --- app/src/main/res/values-it/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index a1897716e..83bb9f337 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -775,4 +775,5 @@ iTag Consenti MTU elevato Aumenta la velocità di trasferimento, ma potrebbe non funzionare su alcuni dispositivi Android. + Sincronizza gli eventi del calendario \ No newline at end of file From 9878a999cb83e36a7eb5432aaf92863119147e42 Mon Sep 17 00:00:00 2001 From: FransM Date: Tue, 25 Feb 2020 17:28:45 +0000 Subject: [PATCH 37/49] Translated using Weblate (Dutch) Currently translated at 100.0% (753 of 753 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nl/ --- app/src/main/res/values-nl/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 23cd8e658..724cfac10 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -823,4 +823,6 @@ iTag Hoge MTU toestaan Verhoogt de overdrachtssnelheid, maar werkt mogelijk niet op sommige Android-apparaten. + Schakelt agendameldingen in, zelfs wanneer U niet verbonden bent + Agenda-afspraken synchroniseren \ No newline at end of file From 60d5284c65ffbe7f4e868bc383cb792a347a8791 Mon Sep 17 00:00:00 2001 From: Marco Alberto Diosdado Nava Date: Wed, 26 Feb 2020 06:13:58 +0000 Subject: [PATCH 38/49] Translated using Weblate (Spanish) Currently translated at 97.4% (734 of 753 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/es/ --- app/src/main/res/values-es/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 84c1795c3..8c9c3db23 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -799,4 +799,7 @@ El cambio puede demorar varios segundos… tiempo compensado por Marque esta opción si su dispositivo no es encontrado durante el descubrimiento + Incrementa la velocidad de transferencia, pero puede no trabajar en algunos dispositivos Android. + Habilita las alertas del calendario, incluso cuando se encuentre desconectado + Sincronizar eventos del calendario \ No newline at end of file From f0c28f37681d123eb3bd3cf49901aba67a10d582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Tue, 25 Feb 2020 02:03:47 +0000 Subject: [PATCH 39/49] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (753 of 753 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index aab68a7e6..0565535ec 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -823,4 +823,6 @@ iTag 允许高 MTU 增加传输速度,但是在某些 Android 设备上可能不会工作。 + 即使已经断开连接,也启用日历提醒 + 同步日历事件 \ No newline at end of file From 1c473f8ecdecbc1291d2d0bf0dd0700a5ee54ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Tue, 25 Feb 2020 23:04:20 +0000 Subject: [PATCH 40/49] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 96.1% (724 of 753 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nb_NO/ --- app/src/main/res/values-nb-rNO/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index c3dedb461..056169831 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -826,4 +826,6 @@ iTag Tillat høy MTU Øker overføringshastighet, men kan forårsake problemer på noen Android-enheter. + Skru på kalendervarsler, selv når frakoblet. + Synkroniser kalenderhendelser \ No newline at end of file From 98dfe929a5e6d61db5be0cf08dc26a8620360b5a Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Thu, 27 Feb 2020 07:16:04 +0000 Subject: [PATCH 41/49] Translated using Weblate (Hebrew) Currently translated at 100.0% (761 of 761 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index a33004e66..5368fe090 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -827,4 +827,12 @@ מגביר את קצב ההעברה, יש מכשירי Android שלא תומכים בזה. הפעלת התראות לוח שנה, אפילו ללא חיבור סנכרון אירועי לוח שנה + דופק + צעדים + תאריך + דקות פעילות + קלוריות + סוללה + מזג אוויר + כלום \ No newline at end of file From 0e9cc6b7f37209f5f5a6b2a9e3ebefee8abc43cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Thu, 27 Feb 2020 02:00:06 +0000 Subject: [PATCH 42/49] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (761 of 761 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0565535ec..9dc31c2aa 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -825,4 +825,12 @@ 增加传输速度,但是在某些 Android 设备上可能不会工作。 即使已经断开连接,也启用日历提醒 同步日历事件 + 心率 + 步数 + 日期 + 活动分钟 + 卡路里 + 电池 + 天气 + \ No newline at end of file From 23c8b973a0c2522efd0e5ab73bd01e3145733e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Thu, 27 Feb 2020 03:41:32 +0000 Subject: [PATCH 43/49] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 96.5% (735 of 761 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nb_NO/ --- app/src/main/res/values-nb-rNO/strings.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 056169831..6bdc7b816 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -327,7 +327,7 @@ Knappevalg Angi knappetrykkshandlinger Antall trykk på knapp - Antall trykk på knapp for å utløse meldingskringkasting + Antall knappetrykk for å utløse hendelse 1. Etterfølgende likt antall trykk utløser hendelse 2, osv. Kringkastingsmelding å sende Målmerknad Båndet vil vibrere når daglig stegmål nås @@ -445,7 +445,7 @@ Meldinger sendt til eksterne tredjepartsprogrammer vil alltid bli anerkjent umiddelbart Demp skjerm etter Tidsjustering i timer (for oppdagelse av søvn for skiftarbeidere) - Kringkast melding ved et gitt antall knappetrykk + Kringkastingsmelding sendt sammen med hendelsen. Parameter `button_id` legges til automatisk for hver melding. Skru på knappehandling Skru på handling ved gitt antall knappetrykk Skru på båndvibrasjon @@ -828,4 +828,12 @@ Øker overføringshastighet, men kan forårsake problemer på noen Android-enheter. Skru på kalendervarsler, selv når frakoblet. Synkroniser kalenderhendelser + Puls + Steg + Dato + Aktive minutter + Kalorier + Batteri + Vær + Ingenting \ No newline at end of file From c7dc343b45524807ef8e68841186ada20b47d45e Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 27 Feb 2020 12:19:16 +0100 Subject: [PATCH 44/49] bump version (to mark the merge of Fossil Hybrid HR) --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index cb0ec42ec..76f180b5f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,8 +25,8 @@ android { targetSdkVersion 28 // Note: always bump BOTH versionCode and versionName! - versionName "0.42.1" - versionCode 168 + versionName "0.43.0" + versionCode 169 vectorDrawables.useSupportLibrary = true } buildTypes { From 335c37795c4dcc6234d17b31105b609a12f3383d Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 27 Feb 2020 12:32:30 +0100 Subject: [PATCH 45/49] bump gradle and com.google.android.material --- app/build.gradle | 2 +- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 76f180b5f..0054e1289 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,7 +73,7 @@ dependencies { implementation "androidx.recyclerview:recyclerview:1.1.0" implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.gridlayout:gridlayout:1.0.0" - implementation "com.google.android.material:material:1.0.0" + implementation "com.google.android.material:material:1.1.0" implementation "androidx.palette:palette:1.0.0" implementation("com.github.tony19:logback-android-classic:1.1.1-6") { exclude group: "com.google.android", module: "android" diff --git a/build.gradle b/build.gradle index 210271ac2..d56213d37 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:3.6.0' classpath "gradle.plugin.com.github.spotbugs:spotbugs-gradle-plugin:2.0.0" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6f49f14f8..a7a1cb798 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Sep 16 21:26:43 CEST 2019 +#Thu Feb 27 12:28:03 CET 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip From ddd70f93fc60e5ab0d9280a33025bb4bd566ac5c Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 27 Feb 2020 13:36:53 +0100 Subject: [PATCH 46/49] Fossil Hybrid HR: option to force white background Currently needs reconnect and one change to the widget configuration to be effective. This might improve visiblity of the hands when using a model with gray hands --- .../devices/AbstractDeviceCoordinator.java | 8 ++-- .../devices/qhybrid/HRConfigActivity.java | 2 +- .../devices/qhybrid/QHybridCoordinator.java | 43 +++++++++++------- .../qhybrid/WidgetSettingsActivity.java | 16 +++---- .../fossil_hr/FossilHRWatchAdapter.java | 45 ++++++++++++------- .../fossil_hr/widget/CustomWidget.java | 4 +- .../requests/fossil_hr/widget/Widget.java | 8 ++-- app/src/main/res/values/strings.xml | 2 + .../res/xml/devicesettings_fossilhybridhr.xml | 8 ++++ 9 files changed, 83 insertions(+), 53 deletions(-) create mode 100644 app/src/main/res/xml/devicesettings_fossilhybridhr.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java index 6d94ef2f7..eea9dd67f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java @@ -21,17 +21,17 @@ import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.ScanFilter; +import androidx.annotation.NonNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collection; import java.util.Collections; -import androidx.annotation.NonNull; import de.greenrobot.dao.query.QueryBuilder; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBException; -import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; @@ -41,6 +41,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributesDao; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; + import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getPrefs; public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { @@ -177,7 +178,6 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { - return new int[] {R.xml.devicesettings_pairingkey }; + return null; } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java index b22b30bb6..640e58f98 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java @@ -205,7 +205,7 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick for (int i = 0; i < customWidgets.length(); i++) { JSONObject customWidgetObject = customWidgets.getJSONObject(i); CustomWidget widget = new CustomWidget( - customWidgetObject.getString("name"), 0, 0 + customWidgetObject.getString("name"), 0, 0, "default" // FIXME: handle force white background ); JSONArray elements = customWidgetObject.getJSONArray("elements"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java index 3a4d9784a..81affe9ca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java @@ -19,26 +19,22 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; import android.annotation.TargetApi; import android.app.Activity; -import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.content.Context; import android.net.Uri; import android.os.Build; import android.os.ParcelUuid; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import java.util.Collection; +import java.util.Collections; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; @@ -48,9 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; -import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; public class QHybridCoordinator extends AbstractDeviceCoordinator { @NonNull @@ -113,7 +107,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { return false; } - public boolean supportsAlarmConfiguration() { + private boolean supportsAlarmConfiguration() { GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice(); if(connectedDevice == null || connectedDevice.getType() != DeviceType.FOSSILQHYBRID || connectedDevice.getState() != GBDevice.State.INITIALIZED){ return false; @@ -136,8 +130,6 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { return false; } - - @Override public String getManufacturer() { return "Fossil"; @@ -150,9 +142,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { @Override public Class getAppsManagementActivity() { - GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice(); - boolean isHR = connectedDevice.getFirmwareVersion().charAt(2) == '1'; - return isHR ? HRConfigActivity.class : ConfigActivity.class; + return isHybridHR() ? HRConfigActivity.class : ConfigActivity.class; } @Override @@ -167,7 +157,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { @Override public boolean supportsWeather() { - return true; // FIXME: not for old Q? + return isHybridHR(); } @Override @@ -188,5 +178,24 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { } + @Override + public int[] getSupportedDeviceSpecificSettings(GBDevice device) { + if (isHybridHR()) { + return new int[]{ + R.xml.devicesettings_fossilhybridhr, + R.xml.devicesettings_pairingkey + }; + } + return new int[]{ + R.xml.devicesettings_pairingkey + }; + } + private boolean isHybridHR() { + GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice(); + if (connectedDevice != null) { + return connectedDevice.getName().startsWith("Hybrid HR"); + } + return false; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/WidgetSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/WidgetSettingsActivity.java index 6746ae6c9..6662a1133 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/WidgetSettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/WidgetSettingsActivity.java @@ -1,32 +1,26 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; - -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.graphics.Paint; import android.os.Bundle; -import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; -import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; + import java.util.List; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.Widget; import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement; @@ -56,7 +50,7 @@ public class WidgetSettingsActivity extends AbstractGBActivity { ((EditText) findViewById(R.id.qhybrid_widget_name)).setText(subject.getName()); resultCode = RESULT_CODE_WIDGET_UPDATED; }else{ - subject = new CustomWidget("", 0, 63); + subject = new CustomWidget("", 0, 63, "default"); // FIXME: handle force white background resultCode = RESULT_CODE_WIDGET_CREATED; findViewById(R.id.qhybrid_widget_delete).setEnabled(false); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index d3c56d3c6..78c06aea4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -67,6 +67,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.Widget; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.WidgetsPutRequest; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_PHONE_REQUEST; @@ -76,9 +77,9 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { private byte[] phoneRandomNumber; private byte[] watchRandomNumber; - ArrayList widgets = new ArrayList<>(); + private ArrayList widgets = new ArrayList<>(); - NotificationHRConfiguration[] notificationConfigurations; + private NotificationHRConfiguration[] notificationConfigurations; private MusicSpec currentSpec = null; @@ -136,18 +137,29 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { } private void loadBackground(){ - /*Bitmap backgroundBitmap = BitmapFactory - .decodeFile("/sdcard/DCIM/Camera/IMG_20191129_200726.jpg"); + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress())); + boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false); + if (forceWhiteBackground) { + byte[] whiteGIF = new byte[]{ + 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x01, 0x00, 0x01, 0x00, (byte) 0x80, 0x01, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3B + }; - try { - this.backGroundImage = AssetImageFactory.createAssetImage(backgroundBitmap, false, 0,:wq - 0, 0); - } catch (IOException e) { - GB.log("Backgroundimage error", GB.ERROR, e); - }*/ + Bitmap backgroundBitmap = BitmapFactory.decodeByteArray(whiteGIF, 0, whiteGIF.length); + //Bitmap backgroundBitmap = BitmapFactory.decodeFile("/sdcard/DCIM/Camera/IMG_20191129_200726.jpg"); + + try { + this.backGroundImage = AssetImageFactory.createAssetImage(backgroundBitmap, false, 0, 0, 0); + } catch (IOException e) { + logger.error("Backgroundimage error", e); + } + } } private void loadWidgets() { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress())); + boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false); + String fontColor = forceWhiteBackground ? "black" : "default"; + this.widgets.clear(); String widgetJson = GBApplication.getPrefs().getPreferences().getString("FOSSIL_HR_WIDGETS", "{}"); String customWidgetJson = GBApplication.getPrefs().getString("QHYBRID_CUSTOM_WIDGETS", "[]"); @@ -170,7 +182,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { Widget widget = null; if(type != null) { - widget = new Widget(type, positionMap.get(position), 63); + widget = new Widget(type, positionMap.get(position), 63, fontColor); }else{ identifier = identifier.substring(7); for(int i = 0; i < customWidgets.length(); i++){ @@ -179,7 +191,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { CustomWidget newWidget = new CustomWidget( customWidget.getString("name"), positionMap.get(position), - 63 + 63, + fontColor ); JSONArray elements = customWidget.getJSONArray("elements"); @@ -224,6 +237,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { } private void renderWidgets() { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress())); + boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false); try { ArrayList widgetImages = new ArrayList<>(); @@ -245,12 +260,12 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { Paint circlePaint = new Paint(); if(!backgroundDrawn){ - circlePaint.setColor(Color.BLACK); + circlePaint.setColor(forceWhiteBackground ? Color.WHITE : Color.BLACK); circlePaint.setStyle(Paint.Style.FILL); circlePaint.setStrokeWidth(3); widgetCanvas.drawCircle(38, 38, 37, circlePaint); - circlePaint.setColor(Color.WHITE); + circlePaint.setColor(forceWhiteBackground ? Color.BLACK : Color.WHITE); circlePaint.setStyle(Paint.Style.STROKE); circlePaint.setStrokeWidth(3); widgetCanvas.drawCircle(38, 38, 37, circlePaint); @@ -287,7 +302,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { textPaint.setStrokeWidth(4); textPaint.setTextSize(17f); textPaint.setStyle(Paint.Style.FILL); - textPaint.setColor(Color.WHITE); + textPaint.setColor(forceWhiteBackground ? Color.BLACK : Color.WHITE); textPaint.setTextAlign(Paint.Align.CENTER); widgetCanvas.drawText(element.getValue(), element.getX(), element.getY() - (textPaint.descent() + textPaint.ascent()) / 2f, textPaint); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidget.java index e10bdcee3..d6f1f0af3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidget.java @@ -10,8 +10,8 @@ public class CustomWidget extends Widget { private int angle, distance; private String name; - public CustomWidget(String name, int angle, int distance) { - super(null, angle, distance); + public CustomWidget(String name, int angle, int distance, String fontColor) { + super(null, angle, distance, fontColor); this.angle = angle; this.distance = distance; this.name = name; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java index ee52c013a..19de46906 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java @@ -11,12 +11,14 @@ import nodomain.freeyourgadget.gadgetbridge.R; public class Widget implements Serializable { private WidgetType widgetType; - int angle, distance; + private int angle, distance; + private String fontColor; - public Widget(WidgetType type, int angle, int distance) { + public Widget(WidgetType type, int angle, int distance, String fontColor) { this.widgetType = type; this.angle = angle; this.distance = distance; + this.fontColor = fontColor; } @NonNull @@ -39,7 +41,7 @@ public class Widget implements Serializable { .put("data", new JSONObject()) .put("theme", new JSONObject() - .put("font_color", "default") + .put("font_color", fontColor) ); } catch (JSONException e) { e.printStackTrace(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ad1fa5c8c..f2028fb8b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -496,6 +496,8 @@ Swipe up to unlock the band\'s screen Night mode Lower band screen brightness automatically at night + Force black on white color scheme + Useful if you your watch has dark hands Automatic Simplified Chinese Traditional Chinese diff --git a/app/src/main/res/xml/devicesettings_fossilhybridhr.xml b/app/src/main/res/xml/devicesettings_fossilhybridhr.xml new file mode 100644 index 000000000..028fa1fe5 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_fossilhybridhr.xml @@ -0,0 +1,8 @@ + + + + From fdc57aed677452d8dc1f4865ea33b06462db05d8 Mon Sep 17 00:00:00 2001 From: fparri Date: Fri, 28 Feb 2020 10:35:12 +0100 Subject: [PATCH 47/49] Aggiornare 'app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java' Removed a comment not needed anymore and added a missing bracket --- .../freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index f76924e14..d873c792f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -291,8 +291,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter Date: Sun, 1 Mar 2020 21:41:15 +0100 Subject: [PATCH 48/49] Remove bracket (compile fix) --- .../freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index d873c792f..bae852524 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -291,7 +291,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter Date: Sun, 1 Mar 2020 22:20:00 +0100 Subject: [PATCH 49/49] Fossil HR: actions now movable in list --- .../devices/qhybrid/HRConfigActivity.java | 76 +++++++++++++++++-- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java index 640e58f98..d782cd135 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java @@ -11,9 +11,12 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; +import android.widget.RelativeLayout; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -375,7 +378,8 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick public void onItemClick(AdapterView parent, View view, final int position, long id) { final EditText input = new EditText(this); input.setId(0); - input.setText(((TextView) view).getText()); + TextView subject = findViewById(0); + input.setText(subject.getText()); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); @@ -407,6 +411,22 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick .show(); } + private void moveActionUp(int position){ + this.menuActions.add(position - 1, this.menuActions.remove(position)); + this.actionListAdapter.notifyDataSetChanged(); + putActionItems(menuActions); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS)); + } + + private void moveActionDown(int position){ + this.menuActions.add(position + 1, this.menuActions.remove(position)); + this.actionListAdapter.notifyDataSetChanged(); + putActionItems(menuActions); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS)); + } + private void putActionItems(List actions) { JSONArray array = new JSONArray(); for (MenuAction action : actions) array.put(action.getAction()); @@ -456,15 +476,57 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick @NonNull @Override - public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { - if (convertView == null) convertView = new TextView(getContext()); - TextView view = (TextView) convertView; + public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) { + RelativeLayout layout = new RelativeLayout(getContext()); - view.setText(getItem(position).getAction()); + TextView text = new TextView(getContext()); + text.setId(0); + + text.setText(getItem(position).getAction()); // view.setTextColor(Color.WHITE); - view.setTextSize(25); + text.setTextSize(25); + RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + textParams.addRule(RelativeLayout.ALIGN_PARENT_START, RelativeLayout.TRUE); + layout.addView(text); - return view; + try { + getItem(position + 1); + ImageView downView = new ImageView(getContext()); + downView.setImageResource(R.drawable.ic_arrow_upward); + downView.setRotation(180); + RelativeLayout.LayoutParams downParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); + downParams.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE); + downView.setLayoutParams(downParams); + downView.setId(2); + downView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + moveActionDown(position); + } + }); + layout.addView(downView); + }catch (IndexOutOfBoundsException e){ + // no following item + } + + if (position != 0) { + ImageView upView = new ImageView(getContext()); + upView.setImageResource(R.drawable.ic_arrow_upward); + RelativeLayout.LayoutParams upParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); + upParams.setMarginEnd(100); + upParams.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE); + upView.setLayoutParams(upParams); + upView.setId(1); + upView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + moveActionUp(position); + } + }); + layout.addView(upView); + } + + return layout; } } }