From 8af6515df886878a55be4d343e27b6e68a9ff32d Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Mon, 16 Jul 2018 11:49:42 +0200 Subject: [PATCH 0001/1017] Add what is working for the ZeTime to the changelog. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 166e3292a..65a2286b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ### Changelog #### Version 0.28.0 (WIP) -* Inital support for ZeTime +* Inital support for ZeTime: time,weather and activity data sync, notification support and music playback control is working * Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme * Mi Band 3: support setting language (english and spanish tested) From c30ec7d407def59ad74103608bb760597fae9f03 Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Mon, 16 Jul 2018 13:41:59 +0200 Subject: [PATCH 0002/1017] BUGFIX: use newer weather icons, if firmware build is B41 or higher. The new firmware supports 24 icons, older ones have only 6. --- .../gadgetbridge/model/Weather.java | 172 +++++++++++++++++- .../devices/zetime/ZeTimeDeviceSupport.java | 10 +- 2 files changed, 180 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java index f2c5a9cf6..5ff768946 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java @@ -600,7 +600,7 @@ public class Weather { } } - public static byte mapToZeTimeCondition(int openWeatherMapCondition) { + public static byte mapToZeTimeConditionOld(int openWeatherMapCondition) { /* deducted values: 0 = partly cloudy 1 = cloudy @@ -709,4 +709,174 @@ public class Weather { return 3; } } + + public static byte mapToZeTimeCondition(int openWeatherMapCondition) { +/* deducted values: + 0 = tornado + 1 = typhoon + 2 = hurricane + 3 = thunderstorm + 4 = rain and snow + 5 = unavailable + 6 = freezing rain + 7 = drizzle + 8 = showers + 9 = snow flurries + 10 = blowing snow + 11 = snow + 12 = sleet + 13 = foggy + 14 = windy + 15 = cloudy + 16 = partly cloudy (night) + 17 = partly cloudy (day) + 18 = clear night + 19 = sunny + 20 = thundershower + 21 = hot + 22 = scattered thunders + 23 = snow showers + 24 = heavy snow + */ + switch (openWeatherMapCondition) { +//Group 2xx: Thunderstorm + case 210: //light thunderstorm:: //11d + return 22; + +//Group 2xx: Thunderstorm + case 200: //thunderstorm with light rain: //11d + case 201: //thunderstorm with rain: //11d + case 202: //thunderstorm with heavy rain: //11d + case 230: //thunderstorm with light drizzle: //11d + case 231: //thunderstorm with drizzle: //11d + case 232: //thunderstorm with heavy drizzle: //11d + return 20; + +//Group 2xx: Thunderstorm + case 211: //thunderstorm: //11d + case 212: //heavy thunderstorm: //11d + case 221: //ragged thunderstorm: //11d + return 3; + +//Group 7xx: Atmosphere + case 781: //tornado: //[[file:50d.png]] +//Group 90x: Extreme + case 900: //tornado + return 0; + +//Group 90x: Extreme + case 901: //tropical storm + return 1; + +// Group 7xx: Atmosphere + case 771: //squalls: //[[file:50d.png]] +//Group 9xx: Additional + case 960: //storm + case 961: //violent storm + case 902: //hurricane + case 962: //hurricane + return 2; + +//Group 3xx: Drizzle + case 300: //light intensity drizzle: //09d + case 301: //drizzle: //09d + case 302: //heavy intensity drizzle: //09d + case 310: //light intensity drizzle rain: //09d + case 311: //drizzle rain: //09d + case 312: //heavy intensity drizzle rain: //09d + case 313: //shower rain and drizzle: //09d + case 314: //heavy shower rain and drizzle: //09d + case 321: //shower drizzle: //09d + return 7; + +//Group 5xx: Rain + case 500: //light rain: //10d + case 501: //moderate rain: //10d + case 502: //heavy intensity rain: //10d + case 503: //very heavy rain: //10d + case 504: //extreme rain: //10d + case 520: //light intensity shower rain: //09d + case 521: //shower rain: //09d + case 522: //heavy intensity shower rain: //09d + case 531: //ragged shower rain: //09d +//Group 90x: Extreme + case 906: //hail + return 8; + +//Group 5xx: Rain + case 511: //freezing rain: //13d + return 6; + +//Group 6xx: Snow + case 620: //light shower snow: //[[file:13d.png]] + case 621: //shower snow: //[[file:13d.png]] + case 622: //heavy shower snow: //[[file:13d.png]] + return 23; + +//Group 6xx: Snow + case 615: //light rain and snow: //[[file:13d.png]] + case 616: //rain and snow: //[[file:13d.png]] + return 4; + +//Group 6xx: Snow + case 611: //sleet: //[[file:13d.png]] + case 612: //shower sleet: //[[file:13d.png]] + return 12; + +//Group 6xx: Snow + case 600: //light snow: //[[file:13d.png]] + case 601: //snow: //[[file:13d.png]] + return 11; +//Group 6xx: Snow + case 602: //heavy snow: //[[file:13d.png]] + return 24; + +//Group 7xx: Atmosphere + case 701: //mist: //[[file:50d.png]] + case 711: //smoke: //[[file:50d.png]] + case 721: //haze: //[[file:50d.png]] + case 731: //sandcase dust whirls: //[[file:50d.png]] + case 741: //fog: //[[file:50d.png]] + case 751: //sand: //[[file:50d.png]] + case 761: //dust: //[[file:50d.png]] + case 762: //volcanic ash: //[[file:50d.png]] + return 13; + +//Group 800: Clear + case 800: //clear sky: //[[file:01d.png]] [[file:01n.png]] + return 19; + +//Group 90x: Extreme + case 904: //hot + return 21; + +//Group 80x: Clouds + case 801: //few clouds: //[[file:02d.png]] [[file:02n.png]] + case 802: //scattered clouds: //[[file:03d.png]] [[file:03d.png]] + case 803: //broken clouds: //[[file:04d.png]] [[file:03d.png]] + return 17; + +//Group 80x: Clouds + case 804: //overcast clouds: //[[file:04d.png]] [[file:04d.png]] + return 15; + +//Group 9xx: Additional + case 905: //windy + case 951: //calm + case 952: //light breeze + case 953: //gentle breeze + case 954: //moderate breeze + case 955: //fresh breeze + case 956: //strong breeze + case 957: //high windcase near gale + case 958: //gale + case 959: //severe gale + return 14; + + default: +//Group 90x: Extreme + case 903: //cold + return 5; + } + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index 902bc5b31..d309c8f96 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -412,6 +412,7 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { @Override public void onSendWeather(WeatherSpec weatherSpec) { + String buildnumber = versionCmd.fwVersion.substring(versionCmd.fwVersion.length() - 4); byte[] weather = new byte[weatherSpec.location.getBytes(StandardCharsets.UTF_8).length + 26]; // 26 bytes for weatherdata and overhead weather[0] = ZeTimeConstants.CMD_PREAMBLE; weather[1] = ZeTimeConstants.CMD_PUSH_WEATHER_DATA; @@ -422,7 +423,14 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { weather[6] = (byte)(weatherSpec.currentTemp - 273); weather[7] = (byte)(weatherSpec.todayMinTemp - 273); weather[8] = (byte)(weatherSpec.todayMaxTemp - 273); - weather[9] = Weather.mapToZeTimeCondition(weatherSpec.currentConditionCode); + + if (buildnumber.compareTo("B4.1") >= 0) // if using firmware 1.7 Build 41 and above use newer icons + { + weather[9] = Weather.mapToZeTimeCondition(weatherSpec.currentConditionCode); + } else + { + weather[9] = Weather.mapToZeTimeConditionOld(weatherSpec.currentConditionCode); + } for(int forecast = 0; forecast < 3; forecast++) { weather[10+(forecast*5)] = 0; // celsius weather[11+(forecast*5)] = (byte) 0xff; From ca7108c1533c5584bf2b76c8114878538bdab517 Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Thu, 6 Sep 2018 14:51:29 +0200 Subject: [PATCH 0003/1017] Add ZeTime settings: choose on which wrist you wear the watch and set screen on duration. --- .../devices/zetime/ZeTimeConstants.java | 9 ++++ .../devices/zetime/ZeTimeDeviceSupport.java | 43 +++++++++++++++++++ app/src/main/res/values-de/strings.xml | 4 ++ app/src/main/res/values/strings.xml | 4 ++ app/src/main/res/xml/preferences.xml | 23 ++++++++++ 5 files changed, 83 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index bfba33c43..02c479775 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -55,6 +55,7 @@ public class ZeTimeConstants { public static final byte CMD_SCREEN_ON_TIME = (byte) 0x13; public static final byte CMD_SNOOZE = (byte) 0x14; public static final byte CMD_DO_NOT_DISTURB = (byte) 0x15; + public static final byte CMD_DISPLAY_TIMEOUT = (byte) 0x25; public static final byte CMD_USER_INFO = (byte) 0x30; public static final byte CMD_USAGE_HABITS = (byte) 0x31; public static final byte CMD_USER_NAME = (byte) 0x32; @@ -105,4 +106,12 @@ public class ZeTimeConstants { public static final byte NOTIFICATION_UBER = (byte) 0x13; public static final byte NOTIFICATION_LINE = (byte) 0x14; public static final byte NOTIFICATION_SKYPE = (byte) 0x15; + // watch settings + public static final String PREF_WRIST = "zetime_wrist"; + public static final byte WEAR_ON_LEFT_WRIST = (byte) 0x00; + public static final byte WEAR_ON_RIGHT_WRIST = (byte) 0x01; + + public static final String PREF_SCREENTIME = "zetime_screentime"; + public static final int MAX_SCREEN_ON_TIME = 0xffff; + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index fcd65f586..663a8fa9c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -120,6 +120,8 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { builder.notify(notifyCharacteristic, true); requestDeviceInfo(builder); requestBatteryInfo(builder); + setWrist(builder); + setScreenTime(builder); requestActivityInfo(builder); synchronizeTime(builder); @@ -1153,4 +1155,45 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { ZeTimeConstants.CMD_END}; sendMsgToWatch(builder, timeSync); } + + // function serving the settings + private void setWrist(TransactionBuilder builder) + { + String value = GBApplication.getPrefs().getString(ZeTimeConstants.PREF_WRIST,"left"); + + byte[] wrist = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_USAGE_HABITS, + ZeTimeConstants.CMD_SEND, + (byte)0x1, + (byte)0x0, + ZeTimeConstants.WEAR_ON_LEFT_WRIST, + ZeTimeConstants.CMD_END}; + if (value.equals("right")) { + wrist[5] = ZeTimeConstants.WEAR_ON_RIGHT_WRIST; + } + + LOG.warn("Wrist: " + wrist[5]); + sendMsgToWatch(builder, wrist); + } + + private void setScreenTime(TransactionBuilder builder) + { + int value = GBApplication.getPrefs().getInt(ZeTimeConstants.PREF_SCREENTIME, 30); + if(value > ZeTimeConstants.MAX_SCREEN_ON_TIME) + { + GB.toast(getContext(), "Value for screen on time is greater than 18h! ", Toast.LENGTH_LONG, GB.ERROR); + value = ZeTimeConstants.MAX_SCREEN_ON_TIME; + } + + byte[] screentime = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_DISPLAY_TIMEOUT, + ZeTimeConstants.CMD_SEND, + (byte)0x2, + (byte)0x0, + (byte)(value & 0xff), + (byte)(value >> 8), + ZeTimeConstants.CMD_END}; + + sendMsgToWatch(builder, screentime); + } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 620b4618f..a00e52989 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -571,4 +571,8 @@ Koreanisch Japanisch + + ZeTime Einstellungen + Bildschirm-An-Dauer in Sekunden + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d67d8feb6..6efaa9808 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -205,6 +205,10 @@ ID115 settings Screen orientation + + ZeTime settings + Screen on duration in seconds + Auto export Auto export enabled diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 934195805..69d433078 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -701,6 +701,29 @@ android:summary="%s" /> + + + + + + + Date: Fri, 7 Sep 2018 10:53:33 +0200 Subject: [PATCH 0004/1017] Send user info to the watch, add more daily targets (goals) and send them to the watch. --- .../devices/zetime/ZeTimeConstants.java | 1 + .../gadgetbridge/model/ActivityUser.java | 36 ++++++++ .../devices/zetime/ZeTimeDeviceSupport.java | 87 +++++++++++++++++++ app/src/main/res/values-de/strings.xml | 4 + app/src/main/res/values/strings.xml | 4 + app/src/main/res/xml/preferences.xml | 21 +++++ 6 files changed, 153 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index 02c479775..cb1f0a36f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -113,5 +113,6 @@ public class ZeTimeConstants { public static final String PREF_SCREENTIME = "zetime_screentime"; public static final int MAX_SCREEN_ON_TIME = 0xffff; + public static final int MIN_SCREEN_ON_TIME = 0x000a; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java index 9f94f5ea4..4bc88656f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java @@ -41,6 +41,9 @@ public class ActivityUser { private int activityUserWeightKg; private int activityUserSleepDuration; private int activityUserStepsGoal; + private int activityUserCaloriesBurnt; + private int activityUserDistanceKMeters; + private int activityUserActiveTimeMinutes; private static final String defaultUserName = "gadgetbridge-user"; public static final int defaultUserGender = GENDER_FEMALE; @@ -50,6 +53,9 @@ public class ActivityUser { public static final int defaultUserWeightKg = 70; public static final int defaultUserSleepDuration = 7; public static final int defaultUserStepsGoal = 8000; + public static final int defaultUserCaloriesBurnt = 2000; + public static final int defaultUserDistanceKMeters = 5; + public static final int defaultUserActiveTimeMinutes = 60; public static final String PREF_USER_NAME = "mi_user_alias"; public static final String PREF_USER_YEAR_OF_BIRTH = "activity_user_year_of_birth"; @@ -58,6 +64,9 @@ public class ActivityUser { public static final String PREF_USER_WEIGHT_KG = "activity_user_weight_kg"; public static final String PREF_USER_SLEEP_DURATION = "activity_user_sleep_duration"; public static final String PREF_USER_STEPS_GOAL = "mi_fitness_goal"; // FIXME: for compatibility + public static final String PREF_USER_CALORIES_BURNT = "activity_user_calories_burnt"; + public static final String PREF_USER_DISTANCE_KMETERS = "activity_user_distance_kmeters"; + public static final String PREF_USER_ACTIVETIME_MINUTES = "activity_user_activetime_minutes"; public ActivityUser() { fetchPreferences(); @@ -127,6 +136,9 @@ public class ActivityUser { activityUserYearOfBirth = prefs.getInt(PREF_USER_YEAR_OF_BIRTH, defaultUserYearOfBirth); activityUserSleepDuration = prefs.getInt(PREF_USER_SLEEP_DURATION, defaultUserSleepDuration); activityUserStepsGoal = prefs.getInt(PREF_USER_STEPS_GOAL, defaultUserStepsGoal); + activityUserCaloriesBurnt = prefs.getInt(PREF_USER_CALORIES_BURNT, defaultUserCaloriesBurnt); + activityUserDistanceKMeters = prefs.getInt(PREF_USER_DISTANCE_KMETERS, defaultUserDistanceKMeters); + activityUserActiveTimeMinutes = prefs.getInt(PREF_USER_ACTIVETIME_MINUTES, defaultUserActiveTimeMinutes); } public Date getUserBirthday() { @@ -134,4 +146,28 @@ public class ActivityUser { cal.set(GregorianCalendar.YEAR, getYearOfBirth()); return cal.getTime(); } + + public int getCaloriesBurnt() + { + if (activityUserCaloriesBurnt < 0) { + activityUserCaloriesBurnt = defaultUserCaloriesBurnt; + } + return activityUserCaloriesBurnt; + } + + public int getDistanceKMeters() + { + if (activityUserDistanceKMeters < 0) { + activityUserDistanceKMeters = defaultUserDistanceKMeters; + } + return activityUserDistanceKMeters; + } + + public int getActiveTimeMinutes() + { + if (activityUserActiveTimeMinutes < 0) { + activityUserActiveTimeMinutes = defaultUserActiveTimeMinutes; + } + return activityUserActiveTimeMinutes; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index 663a8fa9c..83780eecf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -45,6 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.zetime.ZeTimeSampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.ZeTimeActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; +import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; @@ -120,8 +121,10 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { builder.notify(notifyCharacteristic, true); requestDeviceInfo(builder); requestBatteryInfo(builder); + setUserInfo(builder); setWrist(builder); setScreenTime(builder); + setUserGoals(builder); requestActivityInfo(builder); synchronizeTime(builder); @@ -1183,6 +1186,10 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { { GB.toast(getContext(), "Value for screen on time is greater than 18h! ", Toast.LENGTH_LONG, GB.ERROR); value = ZeTimeConstants.MAX_SCREEN_ON_TIME; + } else if(value < ZeTimeConstants.MIN_SCREEN_ON_TIME) + { + GB.toast(getContext(), "Value for screen on time is lesser than 10s! ", Toast.LENGTH_LONG, GB.ERROR); + value = ZeTimeConstants.MIN_SCREEN_ON_TIME; } byte[] screentime = {ZeTimeConstants.CMD_PREAMBLE, @@ -1196,4 +1203,84 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { sendMsgToWatch(builder, screentime); } + + private void setUserInfo(TransactionBuilder builder) + { + ActivityUser activityUser = new ActivityUser(); + byte gender = (byte)activityUser.getGender(); + int age = activityUser.getAge(); + int height = activityUser.getHeightCm(); + int weight = activityUser.getWeightKg()*10; // weight is set and get in 100g granularity + + if(gender == ActivityUser.GENDER_MALE) // translate gender for zetime + { + gender = 0; + } else if(gender == ActivityUser.GENDER_FEMALE) + { + gender = 1; + } else + { + gender = 2; + } + + byte[] userinfo = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_USER_INFO, + ZeTimeConstants.CMD_SEND, + (byte)0x5, + (byte)0x0, + gender, + (byte)age, + (byte)height, + (byte)(weight & 0xff), + (byte)(weight >> 8), + ZeTimeConstants.CMD_END}; + sendMsgToWatch(builder, userinfo); + } + + private void setUserGoals(TransactionBuilder builder) + { + ActivityUser activityUser = new ActivityUser(); + int steps = activityUser.getStepsGoal() / 100; // ZeTime expect the steps in 100 increment + int calories = activityUser.getCaloriesBurnt(); + int distance = activityUser.getDistanceKMeters(); + int sleep = activityUser.getSleepDuration(); + int activeTime = activityUser.getActiveTimeMinutes(); + + // set steps goal + byte[] goal = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_GOALS, + ZeTimeConstants.CMD_SEND, + (byte)0x4, + (byte)0x0, + (byte)0x0, + (byte)(steps & 0xff), + (byte)(steps >> 8), + (byte)0x1, + ZeTimeConstants.CMD_END}; + sendMsgToWatch(builder, goal); + + // set calories goal + goal[5] = (byte)0x1; + goal[6] = (byte)(calories & 0xff); + goal[7] = (byte)(calories >> 8); + sendMsgToWatch(builder, goal); + + // set distance goal + goal[5] = (byte)0x2; + goal[6] = (byte)(distance & 0xff); + goal[7] = (byte)(distance >> 8); + sendMsgToWatch(builder, goal); + + // set sleep goal + goal[5] = (byte)0x3; + goal[6] = (byte)(sleep & 0xff); + goal[7] = (byte)(sleep >> 8); + sendMsgToWatch(builder, goal); + + // set active time goal + goal[5] = (byte)0x4; + goal[6] = (byte)(activeTime & 0xff); + goal[7] = (byte)(activeTime >> 8); + sendMsgToWatch(builder, goal); + } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a00e52989..e7fae6e7f 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -571,6 +571,10 @@ Koreanisch Japanisch + Tägliches Ziel: verbrannte Kalorien + Tägliches Ziel: zurückgelegte Strecke in km + Tägliches Ziel: aktive Zeit in Minuten + ZeTime Einstellungen Bildschirm-An-Dauer in Sekunden diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6efaa9808..86c8e15b6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -500,6 +500,10 @@ Heart rate Heart rate + Daily target: calories burnt + Daily target: distance in km + Daily target: active time in minutes + Store raw record in the database Stores the data \"as is\", increasing the database usage to allow for later interpretation. Database management diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 69d433078..f8a2f467c 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -100,6 +100,27 @@ android:key="activity_user_sleep_duration" android:maxLength="2" android:title="@string/activity_prefs_sleep_duration" /> + + + + + + Date: Fri, 7 Sep 2018 13:24:54 +0200 Subject: [PATCH 0005/1017] Add icons for ZeTime. --- .../gadgetbridge/model/DeviceType.java | 2 +- .../main/res/drawable-hdpi/ic_device_zetime.png | Bin 0 -> 2729 bytes .../drawable-hdpi/ic_device_zetime_disabled.png | Bin 0 -> 2694 bytes .../main/res/drawable-mdpi/ic_device_zetime.png | Bin 0 -> 1829 bytes .../drawable-mdpi/ic_device_zetime_disabled.png | Bin 0 -> 1806 bytes .../main/res/drawable-xhdpi/ic_device_zetime.png | Bin 0 -> 3532 bytes .../drawable-xhdpi/ic_device_zetime_disabled.png | Bin 0 -> 3383 bytes .../res/drawable-xxhdpi/ic_device_zetime.png | Bin 0 -> 4949 bytes .../ic_device_zetime_disabled.png | Bin 0 -> 4447 bytes app/src/main/res/xml/preferences.xml | 2 +- 10 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_device_zetime.png create mode 100644 app/src/main/res/drawable-hdpi/ic_device_zetime_disabled.png create mode 100644 app/src/main/res/drawable-mdpi/ic_device_zetime.png create mode 100644 app/src/main/res/drawable-mdpi/ic_device_zetime_disabled.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_device_zetime.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_device_zetime_disabled.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_device_zetime.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_device_zetime_disabled.png diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index de073474b..ac6779292 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -46,7 +46,7 @@ public enum DeviceType { NO1F1(50, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_no1_f1), TECLASTH30(60, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_teclast_h30), XWATCH(70, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_xwatch), - ZETIME(80, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_mykronoz_zetime), + ZETIME(80, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_mykronoz_zetime), ID115(90, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_id115), WATCH9(100, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_watch9), ROIDMI(110, R.drawable.ic_device_roidmi, R.drawable.ic_device_roidmi_disabled, R.string.devicetype_roidmi), diff --git a/app/src/main/res/drawable-hdpi/ic_device_zetime.png b/app/src/main/res/drawable-hdpi/ic_device_zetime.png new file mode 100644 index 0000000000000000000000000000000000000000..579dadcb09dcb1b2dac028c606817165ff3dffce GIT binary patch literal 2729 zcmV;a3Rd-rP)UjpngzDNF+gx z;bPF3m=GhV@e;fs1%v>C#1BwFDkKC!!PY`4mEE?qgZWx(k4JOS&}H$p;6(2*gUTy~L6eSZ-%_@3z6*Wd?4Mp^jsQ!?{#+Nsn0urW~nL zWzw1|loEWvnHe9oXXZ~S*kJl*Gc?l7@G!lc({pppdz>90!elqCmBUge`MgdE+H0wx0Z@g{qdRO4J29eNU8JR6qcZjz& zqb@OG!={26h?M@?*yA=Z!mRcbFgZ2en$Q}fN@AuZb7TwC1Rft5kW$90hp zI@LlE0(AoUy0jJx_=A;s*?*VqGd%yLHcsv`#D0J|S?`R8!GiJ5M zgMu_quE4ackhLQNTHTZIbdTemKF=#V>dnf)z^ry*#hic@a}8IWJaY0{I^7bQ7}a#! znW=e@0DCH)pPio@wy$TO!>#V36K^N83`l{_9NfGj+wl1-I})yVtb!3a>;$U{i;uHh^F)=$ zHpIjBFPvui@~I(Sk0L-`;p&q^j>}8K=w9|ng}~I?onuwvxd3i?p~lwY@Nm2Olz>7g zM-QNkfn`IKvj8`)uA(AihSQkS;7{v@&sa}A&N90osf1Z7faZ1>E?shRkoKJQ5dPK^)$k)>3~%0`DduTS5~U-$P=k5OwSu0exorLJ=2?T{~Iy= zHJV=0nhq%PaOUjB(?0O8h=Hmn_Kdnk4hk8e=0@J{{0AZtp55FSW*2k^^nJU7r>-=V zqoYD79vH^h!Olb}CvfZ88KP0*pq9W_PYb!{^_W6-_}R720Dq=qYsiqcnAZaVAGz33mEn;r4}^Xpo|q36)X#;c!Hk{j9SIw2!8#=9N&DrLZ*GVPRa+uac%X_yQdn$A#kcm zJ+zQW1*#s>&bMHrCtw zF3B?(>A2IU0#=lJFUb$v_kP*)+WUUoD!t`^4Dh#23B{-p$CFp)$Mx7*_J`o@pUyIK zgvZZMZgLFN(wVKM0!Reb?(*EfzERMvoELEC=W+z5o@)+kqN)cbq}QFEX?W1rUsKla z^8E0{S}NX?YDaNuR`|gSRaVZmESqs)9KLpX$ovlBp8v!=za=3sLSX6>T(5PwPU`|Q z_VCH$4c}jx<^1m96S?c3s`Bsm9X7?rajGrXY#`kEa*g{wk~c0~7;yHyfVDdvzj`g^ zjopq{w>Uc54aJIM&J@dM76e>>VS;E+MS+(TJy5$bG-?z zT78>3AOW@){kRuSjbuOlXG~i-NdN)lLt()$O03zM&^J!S8#!3F%dz6#GE;N3%vu7- zE1WppaQUMZe)oDju5+y4<+$L%L3WgsRxWOD*=n|WJ3|=nbkzf)l~h%8%Z1`d`DieK zy%l9Fi(N&a6n#7|8MPFUHSoatm`C1>$K*${f6^M7w1@970EsB50S$Ej%W_S%$T2QW zl$Q4>iijxG_GcV_2tZ~LumOXi+3Td!zS;4$W<;xE$r!JSVoVko96d=pSJWV!sV0s* z)=uJ=p*~cy-X=+66la5s55kQ9;606z0fiN`qY4^0v4NlTfC8I%SBjjmPF>A!YbygM z>F7ziQqaVAxeo4^)E3=LBn$J2b%m;lRfC|ARMrLcwSYQ`2MMd#yxwXr|8qo7fdW>@RuRee1?&rL*%KtO+J&9U6OK2LYEP+Sk9P_l_kOz^w+R09zIA)-hMy z?pxmYike`Fs#B6$Na6y#8a`~vOyn>WFer#(#1RCE*sM3szuoiWQ|@bmBzacgd=_w? zb=mpZq@z7+)n(M?E#8a6%S3k=Ypf!%_lZwLeT{v^Y9-i_^d(Dxd)yIDH8w%+E~$2l z_;`orUB*S$M9!-)&5)l5B3Sn64et zR_Yc%uTSVmCU*Myz>}O{dZtj59`(TtU)ehYqMs|Q(8Nr7uvE4P00000NkvXXu0mjfO%*y6 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_device_zetime_disabled.png b/app/src/main/res/drawable-hdpi/ic_device_zetime_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..884e93a5f50dabc53b88854a6dad4fef170a5611 GIT binary patch literal 2694 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 A0ssI2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_device_zetime.png b/app/src/main/res/drawable-mdpi/ic_device_zetime.png new file mode 100644 index 0000000000000000000000000000000000000000..7b7b50388b4a9549cfe070d6a789da311c19bc8d GIT binary patch literal 1829 zcmV+=2io|FP)>V(9R(+@&uQ?)^WAQG*p5N$z-hl+@ghYAR& zAEH79wW>f00yPf>DIy>d`T|ue=u4G{7SUEEO(lpFp(d2(ySAIePW-iA@7jCs-g}0J z^=BMsy}RiqLLKQyd+*+JH2<0T&zU&~K9Y~5A(7?(+9>dp#6R6Hz2z)rJ1J3Exbl>% zB&s2)bdR1bo+X#>RQmTTybYi$2Jp@OrBz{2@}@?HO;8MsRV$a7|DoAc#Aqz;YI0Ru zqrIN^)MWP zz~Y`baz54Cq4Ct}ha8xaB>+B|U2B317u-fN!b(P+ZjjQzu~af_i)XU8IPhZt7Aaep z7&1|z;Fvny+@G_RA6Jl=XZTn~>R^-#g?!Q)8_Tv>GelYdT>#*hVxtg^tf_FMHd}Qj zg;P6QajT&J&v3+-|1w?myUP+fG)@$j-SSl4!2Q7Pg&{Nubf8gCmxrf97@e+e*V8#A zwDm=iQ7bBOMT~-fDT!q^1J}6eKzCaB-qsi$$?9`Ix6a|g%`VPW%24jrNY%Tx$N9pB zl`Ykg6n=eAf{D^Juk}T>htj29X%s-(6MC|>FZ0D7w;JD@17LltVQr@NWwvw~lCf(X zLRMiz7Q9OWdZ?%j6)dN7$_*{T+Kg~xT1dL{9O=#&vTc`hXHE2TRu_3KZ0`J@{(0f zPAK}r)S@uZ8EgB|d}uiao`1K@6L0twg2icPV@Hy>Tda9=s|$b;D1{ZR+T(`LbUVnd ziN*0^;k(;B{&2vD^n5#=N*Y!rgiSNVjTBCfE6*Ly6GTqUrA1u;;tre`i+~vINuj&d zu(8uw67R2`iRj(nF3ItIdCNn$S2CC*@Y1n>7mnArGuOod$H04|N@OeE_{vQ#IbUac z@VVidnas1`UD?6|y)jm&=HX72sr0bT%0dDh8;Llbs|5YGx5W7V?J-JW^?7Lz_I@cb z_ij3bw?2r7nI@)DfawT+{+2)Y{Il%|?%q%-ie||?dm>{M0t@X4VfWn$y3-YFzn`=0 zJsj|UuKumK?pi2j;I+Px-~T&c=N%pi2cEkx$vYP<&mIbRy|2vZ6jGGlq=k-wKXI&7B|gH5YOQ!(LR=OcFBQF-GZ;pz)5T;f7|gXc@@YuE@c&5q`+E2QU@DgkL)e zcO49fIoAPzxC@`%SLEfBWrC>s_h%=S?SC$kj$fUF`i23hLhovaC*KUn`_)6~&4G|p z<63tIcGZtnX6t-M;Lu=1##`R5u7UoXHh7dG%K<2Z8Zd@>&R`2=US#AkBB>4w$xrDN%bL8zu`mUsB1!XoCI)uDF;k8r6$`RHsc9@7DCTb4_rL8SFLYKL{V73uRjds1)?Y< z;ZEkt7yRL=V+v2{<;W_4_WbnSN2ROl2?Q5Z(7DT%Cg1c)g}AC^9T|P5?^m1mz_S96 zFL%ke;LP)}gB^@cq@#(^7MTt_wQ5vt6Wmfc%P@|y>PRTr_9>^eZL)vgJ;T+L>YO|# z@y?s2wPVCfmhq-VT-W-JM@*Y!cP5QhPrcA{!myZM}4 zjL}SpYV&v@fndi9ikG!xgQu0?kGAHWczismjNcl;fe5@NGdG$U-vG8M|F7~t3sk8! TE;VoJ00000NkvXXu0mjf=Bj;l literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_device_zetime_disabled.png b/app/src/main/res/drawable-mdpi/ic_device_zetime_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..8a22d521b7ca83ab4e465edf0bea932524bed763 GIT binary patch literal 1806 zcmV+p2l4ocP)d&&++Db68CL%s69@ z!`MRn%k#MR|Nh7K|K}XwNBL3KB-CJz1_uWzo6W+qEOK49B}yr!pzFHwJP)N(NsWz- zsoANeYx!~?IePSHXAlH>I-O?KYLzLaNGa7Cs}g~Tl&J?H0liv4dqtsfg?wb zJdw?2pHWKj4G|_pK_ZcOZqJ@QFI>`DEeC)O9XiyRPNz=^A^M1DL&UjK3Y_zc@pyb- z|Ni~9ZQF8ojxAicWy=;yrBb?-l5Z5{XG2O#$xod+747NiF_OuoHf#Jv04&R5>2#WZ zKb+8L_R1oqq*N*u6+#%6WodPjxKJptN~NMT}0c7b+}PuP&`x z*39z(81B070SsKQ_^#3(`KsUljba$?L-yQuX#8oKl zYX;ESVWHcMta@Lpw;wDNUf&R6N`PCv(3eC(ZpJ}%W(F5?CG ze|z>Rd_FQU_v0rX9l~!P`vU^G4mrS#2zKw9XP!U*^$W!R{Z<5zhn5@ z?A-YE$rw7ilC1`y5VJbb9;qeoUyh$e%$)=gYgjW#NxXOLUvpz&&ama09w;eV2S7@N zO`Ce5hd4Y1@To80vB+}Ob8+r4hWyxBy!DL(0H_AQ>2s5)Rx4s4@#wSt8d zh-%7~0u7ZwVaJXgSa@cZQlh`VAETqA(6o7;&15pL^EsR^NZhgDi}6GPO49)ZEdW3o zw4i3$cpF1UyNP4(zFXtg1#;rV32@FYJDe~jaZR!t03Z}_F7}Q0m*a- z`yzmT=;1c#RuX!-1hwSI5(5t9IhSMSqn!3{{Q(fCQg3caWb};>UcgFEiEEGX(Z5{oZb}M4=b18UU{g!w+!WkJE3F>-a zcz9U(zVApWgN^n=BZLSz=OxE++)AY~7v@ywyrK5(+xKK5kvKp^9JMQL!ji|eRw-WN z7UgF$ndc53JlOD&Z%+2^-J7s&+bkA~5yx?Kr4+jaq$R=_lZ>&Tqobo@nr7+n;lt_r zCyZslcXf49B9YL2-`4?fDW%33Q!NY`MMMGTJSY?j?)3Duz$zZPRVI^BLI^Jwiv^D3 wu=R+2#+Wh;L)x~zEVVZZiH(xU3O`i&4p!U5xkh#t^#A|>07*qoM6N<$f{oKd(f|Me literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_device_zetime.png b/app/src/main/res/drawable-xhdpi/ic_device_zetime.png new file mode 100644 index 0000000000000000000000000000000000000000..bd837d4645db8ca9d5609cba63a2c64307b451ce GIT binary patch literal 3532 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_device_zetime_disabled.png b/app/src/main/res/drawable-xhdpi/ic_device_zetime_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..8906792d1aa2d6de0406eca13dc82f062c44f268 GIT binary patch literal 3383 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 TICE&i00000NkvXXu0mjfX-7x- literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_zetime_disabled.png b/app/src/main/res/drawable-xxhdpi/ic_device_zetime_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..39e832e04d1651760639cc9049d26efd699040c5 GIT binary patch literal 4447 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index f8a2f467c..5e988c876 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -723,7 +723,7 @@ Date: Wed, 12 Sep 2018 13:59:45 +0200 Subject: [PATCH 0006/1017] BUGFIX: setting goals now correct! Add automatic heart rate measurement settings - but the function got not called. Add option to leave activity data on the watch or delete them. --- .../devices/zetime/ZeTimeConstants.java | 2 + .../devices/zetime/ZeTimeCoordinator.java | 2 +- .../devices/zetime/ZeTimeDeviceSupport.java | 166 +++++++++++++++--- app/src/main/res/values/arrays.xml | 16 ++ app/src/main/res/xml/preferences.xml | 12 ++ 5 files changed, 174 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index cb1f0a36f..8a0d8e4c8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -115,4 +115,6 @@ public class ZeTimeConstants { public static final int MAX_SCREEN_ON_TIME = 0xffff; public static final int MIN_SCREEN_ON_TIME = 0x000a; + public static final String PREF_ZETIME_DONT_DEL_ACTDATA = "zetime_dont_del_actdata"; + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeCoordinator.java index d0c77dc6b..1f88e4faa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeCoordinator.java @@ -146,7 +146,7 @@ public class ZeTimeCoordinator extends AbstractDeviceCoordinator { @Override public boolean supportsRealtimeData() { - return false; + return true; } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index 83780eecf..a905533bb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -61,6 +61,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; /** * Created by Kranz on 08.02.2018. @@ -144,7 +145,15 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { @Override public void onSendConfiguration(String config) { - + switch(config) + { + case ZeTimeConstants.PREF_WRIST: + break; + case ZeTimeConstants.PREF_SCREENTIME: + break; + case "heartrate_measurement_interval": + break; + } } @Override @@ -174,7 +183,24 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { @Override public void onSetHeartRateMeasurementInterval(int seconds) { + int heartRateMeasurementIntervall = 0; // 0 means off + heartRateMeasurementIntervall = seconds/60; // zetime accepts only minutes + byte[] heartrate = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_AUTO_HEARTRATE, + ZeTimeConstants.CMD_SEND, + (byte)0x1, + (byte)0x0, + (byte)heartRateMeasurementIntervall, + ZeTimeConstants.CMD_END}; + + try { + TransactionBuilder builder = performInitialized("enableAutoHeartRate"); + sendMsgToWatch(builder, heartrate); + builder.queue(getQueue()); + } catch (IOException e) { + GB.toast(getContext(), "Error enable auto heart rate measurement: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } } @Override @@ -870,10 +896,27 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { } } + private void deleteStepData() + { + try { + TransactionBuilder builder = performInitialized("deleteStepData"); + sendMsgToWatch(builder, new byte[]{ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_DELETE_STEP_COUNT, + ZeTimeConstants.CMD_SEND, + 0x01, + 0x00, + 0x00, + ZeTimeConstants.CMD_END}); + builder.queue(getQueue()); + } catch (IOException e) { + GB.toast(getContext(), "Error deleting activity data: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } + } + private void getHeartRateData() { try { - TransactionBuilder builder = performInitialized("fetchStepData"); + TransactionBuilder builder = performInitialized("fetchHeartRateData"); builder.write(writeCharacteristic, new byte[]{ZeTimeConstants.CMD_PREAMBLE, ZeTimeConstants.CMD_GET_HEARTRATE_EXDATA, ZeTimeConstants.CMD_REQUEST, @@ -884,14 +927,31 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { builder.write(ackCharacteristic, new byte[]{ZeTimeConstants.CMD_ACK_WRITE}); builder.queue(getQueue()); } catch (IOException e) { - GB.toast(getContext(), "Error fetching activity data: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + GB.toast(getContext(), "Error fetching heart rate data: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } + } + + private void deleteHeartRateData() + { + try { + TransactionBuilder builder = performInitialized("deleteHeartRateData"); + sendMsgToWatch(builder, new byte[]{ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_DELETE_HEARTRATE_DATA, + ZeTimeConstants.CMD_SEND, + 0x01, + 0x00, + 0x00, + ZeTimeConstants.CMD_END}); + builder.queue(getQueue()); + } catch (IOException e) { + GB.toast(getContext(), "Error deleting heart rate data: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); } } private void getSleepData() { try { - TransactionBuilder builder = performInitialized("fetchStepData"); + TransactionBuilder builder = performInitialized("fetchSleepData"); builder.write(writeCharacteristic, new byte[]{ZeTimeConstants.CMD_PREAMBLE, ZeTimeConstants.CMD_GET_SLEEP_DATA, ZeTimeConstants.CMD_REQUEST, @@ -903,7 +963,24 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { builder.write(ackCharacteristic, new byte[]{ZeTimeConstants.CMD_ACK_WRITE}); builder.queue(getQueue()); } catch (IOException e) { - GB.toast(getContext(), "Error fetching activity data: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + GB.toast(getContext(), "Error fetching sleep data: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } + } + + private void deleteSleepData() + { + try { + TransactionBuilder builder = performInitialized("deleteSleepData"); + sendMsgToWatch(builder, new byte[]{ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_DELETE_SLEEP_DATA, + ZeTimeConstants.CMD_SEND, + 0x01, + 0x00, + 0x00, + ZeTimeConstants.CMD_END}); + builder.queue(getQueue()); + } catch (IOException e) { + GB.toast(getContext(), "Error deleting sleep data: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); } } @@ -933,6 +1010,7 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { progressSteps = (msg[5]&0xff) | ((msg[6] << 8)&0xff00); GB.updateTransferNotification(null, getContext().getString(R.string.busy_task_fetch_activity_data), true, (int) (progressSteps *100 / availableStepsData), getContext()); if (progressSteps == availableStepsData) { + Prefs prefs = GBApplication.getPrefs(); progressSteps = 0; availableStepsData = 0; GB.updateTransferNotification(null,"", false, 100, getContext()); @@ -940,6 +1018,9 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { getDevice().unsetBusyTask(); getDevice().sendDeviceUpdateIntent(getContext()); } + if (!prefs.getBoolean(ZeTimeConstants.PREF_ZETIME_DONT_DEL_ACTDATA, false)) { + deleteStepData(); + } if(availableHeartRateData > 0) { getHeartRateData(); } else if(availableSleepData > 0) @@ -978,6 +1059,7 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { progressSleep = (msg[5]&0xff) | (msg[6] << 8)&0xff00; GB.updateTransferNotification(null, getContext().getString(R.string.busy_task_fetch_activity_data), true, (int) (progressSleep *100 / availableSleepData), getContext()); if (progressSleep == availableSleepData) { + Prefs prefs = GBApplication.getPrefs(); progressSleep = 0; availableSleepData = 0; GB.updateTransferNotification(null,"", false, 100, getContext()); @@ -985,6 +1067,9 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { getDevice().unsetBusyTask(); getDevice().sendDeviceUpdateIntent(getContext()); } + if (!prefs.getBoolean(ZeTimeConstants.PREF_ZETIME_DONT_DEL_ACTDATA, false)) { + deleteSleepData(); + } } } @@ -1008,7 +1093,30 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { progressHeartRate = (msg[5]&0xff) | ((msg[6] << 8)&0xff00); GB.updateTransferNotification(null, getContext().getString(R.string.busy_task_fetch_activity_data), true, (int) (progressHeartRate *100 / availableHeartRateData), getContext()); + + if(((msg[4] << 8)&0xff00 | (msg[3]&0xff)) == 0xe) // if the message is longer than 0x7, than it has to measurements (payload = 0xe) + { + timestamp = (msg[17] << 24)&0xff000000 | (msg[16] << 16)&0xff0000 | (msg[15] << 8)&0xff00 | (msg[14]&0xff); + timestamp += sixHourOffset; // the timestamp from the watch has an offset of six hours, do not know why... + sample.setHeartRate(msg[18]); + sample.setTimestamp(timestamp); + + try (DBHandler dbHandler = GBApplication.acquireDB()) { + sample.setUserId(DBHelper.getUser(dbHandler.getDaoSession()).getId()); + sample.setDeviceId(DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId()); + ZeTimeSampleProvider provider = new ZeTimeSampleProvider(getDevice(), dbHandler.getDaoSession()); + provider.addGBActivitySample(sample); + } catch (Exception ex) { + GB.toast(getContext(), "Error saving steps data: " + ex.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + GB.updateTransferNotification(null,"Data transfer failed", false, 0, getContext()); + } + + progressHeartRate = (msg[12]&0xff) | ((msg[13] << 8)&0xff00); + GB.updateTransferNotification(null, getContext().getString(R.string.busy_task_fetch_activity_data), true, (int) (progressHeartRate *100 / availableHeartRateData), getContext()); + } + if (progressHeartRate == availableHeartRateData) { + Prefs prefs = GBApplication.getPrefs(); progressHeartRate = 0; availableHeartRateData = 0; GB.updateTransferNotification(null,"", false, 100, getContext()); @@ -1016,6 +1124,9 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { getDevice().unsetBusyTask(); getDevice().sendDeviceUpdateIntent(getContext()); } + if (!prefs.getBoolean(ZeTimeConstants.PREF_ZETIME_DONT_DEL_ACTDATA, false)) { + deleteHeartRateData(); + } if(availableSleepData > 0) { getSleepData(); @@ -1247,7 +1358,7 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { int activeTime = activityUser.getActiveTimeMinutes(); // set steps goal - byte[] goal = {ZeTimeConstants.CMD_PREAMBLE, + byte[] goal_steps = {ZeTimeConstants.CMD_PREAMBLE, ZeTimeConstants.CMD_GOALS, ZeTimeConstants.CMD_SEND, (byte)0x4, @@ -1257,30 +1368,39 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { (byte)(steps >> 8), (byte)0x1, ZeTimeConstants.CMD_END}; - sendMsgToWatch(builder, goal); + sendMsgToWatch(builder, goal_steps); + byte[] goal_calories = new byte[goal_steps.length]; + System.arraycopy(goal_steps, 0, goal_calories, 0, goal_steps.length); // set calories goal - goal[5] = (byte)0x1; - goal[6] = (byte)(calories & 0xff); - goal[7] = (byte)(calories >> 8); - sendMsgToWatch(builder, goal); + goal_calories[5] = (byte)0x1; + goal_calories[6] = (byte)(calories & 0xff); + goal_calories[7] = (byte)(calories >> 8); + sendMsgToWatch(builder, goal_calories); + byte[] goal_distance = new byte[goal_steps.length]; + System.arraycopy(goal_steps, 0, goal_distance, 0, goal_steps.length); // set distance goal - goal[5] = (byte)0x2; - goal[6] = (byte)(distance & 0xff); - goal[7] = (byte)(distance >> 8); - sendMsgToWatch(builder, goal); + goal_distance[5] = (byte)0x2; + goal_distance[6] = (byte)(distance & 0xff); + goal_distance[7] = (byte)(distance >> 8); + sendMsgToWatch(builder, goal_distance); + byte[] goal_sleep = new byte[goal_steps.length]; + System.arraycopy(goal_steps, 0, goal_sleep, 0, goal_steps.length); // set sleep goal - goal[5] = (byte)0x3; - goal[6] = (byte)(sleep & 0xff); - goal[7] = (byte)(sleep >> 8); - sendMsgToWatch(builder, goal); + goal_sleep[5] = (byte)0x3; + goal_sleep[6] = (byte)(sleep & 0xff); + goal_sleep[7] = (byte)(sleep >> 8); + sendMsgToWatch(builder, goal_sleep); + byte[] goal_activeTime = new byte[goal_steps.length]; + System.arraycopy(goal_steps, 0, goal_activeTime, 0, goal_steps.length); // set active time goal - goal[5] = (byte)0x4; - goal[6] = (byte)(activeTime & 0xff); - goal[7] = (byte)(activeTime >> 8); - sendMsgToWatch(builder, goal); + goal_activeTime[5] = (byte)0x4; + goal_activeTime[6] = (byte)(activeTime & 0xff); + goal_activeTime[7] = (byte)(activeTime >> 8); + sendMsgToWatch(builder, goal_activeTime); } + } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index c31318900..c21121fdf 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -403,6 +403,22 @@ 3600 + + @string/off + @string/interval_five_minutes + @string/interval_ten_minutes + @string/interval_thirty_minutes + @string/interval_one_hour + + + + 0 + 300 + 600 + 1800 + 3600 + + @string/no_limit @string/seconds_5 diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 5e988c876..ab2b7fa8d 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -743,6 +743,18 @@ android:defaultValue="30" android:key="zetime_screentime" android:title="@string/zetime_title_screentime"/> + + From 6617c45fec00c157a11223c1a6b7059f9d707df4 Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Thu, 13 Sep 2018 14:55:38 +0200 Subject: [PATCH 0007/1017] Add setting heart rate alarm values. Make the settings of the wearside and screen on duration interactive - give them their own activity. Also make the auto heart rate measurement work. --- app/src/main/AndroidManifest.xml | 4 + .../activities/SettingsActivity.java | 10 +++ .../devices/zetime/ZeTimeConstants.java | 3 + .../zetime/ZeTimePreferenceActivity.java | 77 +++++++++++++++++++ .../devices/zetime/ZeTimeDeviceSupport.java | 64 +++++++++++---- app/src/main/res/values-de/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/preferences.xml | 13 ++++ 8 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9ecb863a..bce238e18 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -61,6 +61,10 @@ android:name=".devices.miband.MiBandPreferencesActivity" android:label="@string/preferences_miband_settings" android:parentActivityName=".activities.SettingsActivity" /> + ZeTime Einstellungen Bildschirm-An-Dauer in Sekunden + Max Puls Alarm + Min Puls Alarm diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 86c8e15b6..51de96138 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -208,6 +208,8 @@ ZeTime settings Screen on duration in seconds + Max heart rate alarm + Min heart rate alarm Auto export diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index ab2b7fa8d..e588ab5cf 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -750,6 +750,19 @@ android:key="heartrate_measurement_interval" android:summary="%s" android:title="@string/prefs_title_heartrate_measurement_interval" /> + + + Date: Fri, 14 Sep 2018 11:26:10 +0100 Subject: [PATCH 0008/1017] Add LGTM.com code quality badges --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ca18a09b2..feb582a0a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ vendor's servers. [![Build](https://travis-ci.org/Freeyourgadget/Gadgetbridge.svg?branch=master)](https://travis-ci.org/Freeyourgadget/Gadgetbridge) +[![Code Quality: Java](https://img.shields.io/lgtm/grade/java/g/Freeyourgadget/Gadgetbridge.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Freeyourgadget/Gadgetbridge/context:java) +[![Total Alerts](https://img.shields.io/lgtm/alerts/g/Freeyourgadget/Gadgetbridge.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Freeyourgadget/Gadgetbridge/alerts) ## Download From 6be181047a38edb34689bdf2d676d0afd358d2eb Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Fri, 14 Sep 2018 13:32:18 +0200 Subject: [PATCH 0009/1017] Add more preference settings for ZeTime: time and date format, activity tracking, do-not-disturb scheduling, wrist-flick, analog mode and calories type. --- .../devices/zetime/ZeTimeConstants.java | 13 ++ .../zetime/ZeTimePreferenceActivity.java | 83 +++++++- .../devices/zetime/ZeTimeDeviceSupport.java | 185 +++++++++++++++++- app/src/main/res/values/arrays.xml | 49 +++++ app/src/main/res/values/strings.xml | 20 ++ app/src/main/res/xml/preferences.xml | 48 +---- app/src/main/res/xml/zetime_preferences.xml | 126 ++++++++++++ 7 files changed, 475 insertions(+), 49 deletions(-) create mode 100644 app/src/main/res/xml/zetime_preferences.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index 514829a06..3339dd0e4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -55,6 +55,8 @@ public class ZeTimeConstants { public static final byte CMD_SCREEN_ON_TIME = (byte) 0x13; public static final byte CMD_SNOOZE = (byte) 0x14; public static final byte CMD_DO_NOT_DISTURB = (byte) 0x15; + public static final byte CMD_ANALOG_MODE = (byte) 0x17; + public static final byte CMD_CONTROL_DEVICE = (byte) 0x1A; public static final byte CMD_DISPLAY_TIMEOUT = (byte) 0x25; public static final byte CMD_USER_INFO = (byte) 0x30; public static final byte CMD_USAGE_HABITS = (byte) 0x31; @@ -74,6 +76,7 @@ public class ZeTimeConstants { public static final byte CMD_GET_HEARTRATE_EXDATA = (byte) 0x61; public static final byte CMD_PUSH_EX_MSG = (byte) 0x76; public static final byte CMD_PUSH_WEATHER_DATA = (byte) 0x77; + public static final byte CMD_SWITCH_SETTINGS = (byte) 0x90; public static final byte CMD_PUSH_CALENDAR_DAY = (byte) 0x99; public static final byte CMD_MUSIC_CONTROL = (byte) 0xD0; // here are the action commands @@ -120,4 +123,14 @@ public class ZeTimeConstants { public static final String PREF_ZETIME_MAX_HEARTRATE = "alarm_max_heart_rate"; public static final String PREF_ZETIME_MIN_HEARTRATE = "alarm_min_heart_rate"; + public static final String PREF_DO_NOT_DISTURB = "zetime_do_not_disturb"; + public static final String PREF_DO_NOT_DISTURB_START = "zetime_do_not_disturb_start"; + public static final String PREF_DO_NOT_DISTURB_END = "zetime_do_not_disturb_end"; + + public static final String PREF_ANALOG_MODE = "zetime_analog_mode"; + public static final String PREF_ACTIVITY_TRACKING = "zetime_activity_tracking"; + public static final String PREF_HANDMOVE_DISPLAY = "zetime_handmove_display"; + public static final String PREF_CALORIES_TYPE = "zetime_calories_type"; + public static final String PREF_TIME_FORMAT = "zetime_time_format"; + public static final String PREF_DATE_FORMAT = "zetime_date_format"; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java index e3b9520ba..9d97eccc5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java @@ -17,7 +17,7 @@ public class ZeTimePreferenceActivity extends AbstractSettingsActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.preferences); + addPreferencesFromResource(R.xml.zetime_preferences); //addTryListeners(); @@ -49,6 +49,87 @@ public class ZeTimePreferenceActivity extends AbstractSettingsActivity { return true; } }); + + final Preference analogMode = findPreference(ZeTimeConstants.PREF_ANALOG_MODE); + analogMode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_ANALOG_MODE); + return true; + } + }); + + final Preference activity = findPreference(ZeTimeConstants.PREF_ACTIVITY_TRACKING); + activity.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_ACTIVITY_TRACKING); + return true; + } + }); + + final Preference handmove = findPreference(ZeTimeConstants.PREF_HANDMOVE_DISPLAY); + handmove.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_HANDMOVE_DISPLAY); + return true; + } + }); + + final Preference dnd = findPreference(ZeTimeConstants.PREF_DO_NOT_DISTURB); + dnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_DO_NOT_DISTURB); + return true; + } + }); + + final Preference dnd_start = findPreference(ZeTimeConstants.PREF_DO_NOT_DISTURB_START); + dnd_start.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_DO_NOT_DISTURB); + return true; + } + }); + + final Preference dnd_end = findPreference(ZeTimeConstants.PREF_DO_NOT_DISTURB_END); + dnd_end.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_DO_NOT_DISTURB); + return true; + } + }); + + final Preference caloriesType = findPreference(ZeTimeConstants.PREF_CALORIES_TYPE); + caloriesType.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_CALORIES_TYPE); + return true; + } + }); + + final Preference timeFormat = findPreference(ZeTimeConstants.PREF_TIME_FORMAT); + timeFormat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_TIME_FORMAT); + return true; + } + }); + + final Preference dateFormat = findPreference(ZeTimeConstants.PREF_DATE_FORMAT); + dateFormat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_DATE_FORMAT); + return true; + } + }); } // private void addTryListeners() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index 23f34f7bf..46ec21fe5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -27,6 +27,8 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -124,8 +126,6 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { requestDeviceInfo(builder); requestBatteryInfo(builder); setUserInfo(builder); - setWrist(builder); - setScreenTime(builder); setUserGoals(builder); setHeartRateLimits(builder); requestActivityInfo(builder); @@ -149,6 +149,27 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { case ZeTimeConstants.PREF_SCREENTIME: setScreenTime(builder); break; + case ZeTimeConstants.PREF_ANALOG_MODE: + setAnalogMode(builder); + break; + case ZeTimeConstants.PREF_ACTIVITY_TRACKING: + setActivityTracking(builder); + break; + case ZeTimeConstants.PREF_HANDMOVE_DISPLAY: + setDisplayOnMovement(builder); + break; + case ZeTimeConstants.PREF_DO_NOT_DISTURB: + setDoNotDisturb(builder); + break; + case ZeTimeConstants.PREF_CALORIES_TYPE: + setCaloriesType(builder); + break; + case ZeTimeConstants.PREF_TIME_FORMAT: + setTimeFormate(builder); + break; + case ZeTimeConstants.PREF_DATE_FORMAT: + setDateFormate(builder); + break; } builder.queue(getQueue()); } catch (IOException e) { @@ -1433,4 +1454,164 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { volume, ZeTimeConstants.CMD_END}); } + + private void setAnalogMode(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + int mode = prefs.getInt(ZeTimeConstants.PREF_ANALOG_MODE, 0); + + byte[] analog = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_ANALOG_MODE, + ZeTimeConstants.CMD_SEND, + (byte)0x1, + (byte)0x0, + (byte)mode, + ZeTimeConstants.CMD_END}; + + sendMsgToWatch(builder, analog); + } + + private void setActivityTracking(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + boolean tracking = prefs.getBoolean(ZeTimeConstants.PREF_ACTIVITY_TRACKING, false); + + byte[] activity = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_CONTROL_DEVICE, + ZeTimeConstants.CMD_SEND, + (byte)0x1, + (byte)0x0, + (byte)0x9, + ZeTimeConstants.CMD_END}; + if(tracking) + { + activity[5] = (byte)0xa; + } + sendMsgToWatch(builder, activity); + } + + private void setDisplayOnMovement(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + boolean movement = prefs.getBoolean(ZeTimeConstants.PREF_ACTIVITY_TRACKING, false); + + byte[] handmove = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_SWITCH_SETTINGS, + ZeTimeConstants.CMD_SEND, + (byte)0x3, + (byte)0x0, + (byte)0x1, + (byte)0xe, + (byte)0x0, + ZeTimeConstants.CMD_END}; + if(movement) + { + handmove[7] = (byte)0x1; + } + sendMsgToWatch(builder, handmove); + } + + private void setDoNotDisturb(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + String scheduled = prefs.getString(ZeTimeConstants.PREF_DO_NOT_DISTURB, "off"); + String dndScheduled = getContext().getString(R.string.p_scheduled); + String start = prefs.getString(ZeTimeConstants.PREF_DO_NOT_DISTURB_START, "22:00"); + String end = prefs.getString(ZeTimeConstants.PREF_DO_NOT_DISTURB_END, "07:00"); + DateFormat df_start = new SimpleDateFormat("HH:mm"); + DateFormat df_end = new SimpleDateFormat("HH:mm"); + Calendar calendar = GregorianCalendar.getInstance(); + Calendar calendar_end = GregorianCalendar.getInstance(); + + try { + calendar.setTime(df_start.parse(start)); + try { + calendar_end.setTime(df_end.parse(end)); + + byte[] doNotDisturb = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_DO_NOT_DISTURB, + ZeTimeConstants.CMD_SEND, + (byte)0x5, + (byte)0x0, + (byte)0x0, + (byte)calendar.get(Calendar.HOUR_OF_DAY), + (byte)calendar.get(Calendar.MINUTE), + (byte)calendar_end.get(Calendar.HOUR_OF_DAY), + (byte)calendar_end.get(Calendar.MINUTE), + ZeTimeConstants.CMD_END}; + + if(scheduled.equals(dndScheduled)) + { + doNotDisturb[5] = (byte)0x1; + } + sendMsgToWatch(builder, doNotDisturb); + } catch(Exception e) { + LOG.error("Unexpected exception in ZeTimeDeviceSupport.setDoNotDisturb: " + e.getMessage()); + } + } catch(Exception e) { + LOG.error("Unexpected exception in ZeTimeDeviceSupport.setDoNotDisturb: " + e.getMessage()); + } + } + + private void setCaloriesType(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + int type = prefs.getInt(ZeTimeConstants.PREF_CALORIES_TYPE, 0); + + byte[] calories = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_CALORIES_TYPE, + ZeTimeConstants.CMD_SEND, + (byte)0x1, + (byte)0x0, + (byte)type, + ZeTimeConstants.CMD_END}; + + sendMsgToWatch(builder, calories); + } + + private void setTimeFormate(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + int type = prefs.getInt(ZeTimeConstants.PREF_TIME_FORMAT, 0); + + byte[] timeformat = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_TIME_SURFACE_SETTINGS, + ZeTimeConstants.CMD_SEND, + (byte)0x8, + (byte)0x0, + (byte)0xff, // set to ff to not change anything on the watch + (byte)type, + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + ZeTimeConstants.CMD_END}; + + sendMsgToWatch(builder, timeformat); + } + + private void setDateFormate(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + int type = prefs.getInt(ZeTimeConstants.PREF_TIME_FORMAT, 0); + + byte[] dateformat = {ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_TIME_SURFACE_SETTINGS, + ZeTimeConstants.CMD_SEND, + (byte)0x8, + (byte)0x0, + (byte)type, + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + (byte)0xff, // set to ff to not change anything on the watch + ZeTimeConstants.CMD_END}; + + sendMsgToWatch(builder, dateformat); + } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index c21121fdf..99403968d 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -159,6 +159,15 @@ @string/p_scheduled + + @string/mi2_dnd_off + @string/mi2_dnd_scheduled + + + @string/p_off + @string/p_scheduled + + @string/off @string/on @@ -407,7 +416,9 @@ @string/off @string/interval_five_minutes @string/interval_ten_minutes + @string/interval_fifteen_minutes @string/interval_thirty_minutes + @string/interval_forty_five_minutes @string/interval_one_hour @@ -415,7 +426,9 @@ 0 300 600 + 900 1800 + 2700 3600 @@ -442,4 +455,40 @@ 1800 + + + @string/zetime_analog_mode_hands + @string/zetime_analog_mode_handsandsteps + + + 0 + 1 + + + @string/zetime_calories_type_active + @string/zetime_calories_type_all + + + 0 + 1 + + + @string/zetime_time_format_24h + @string/zetime_time_format_12h + + + 1 + 2 + + + @string/zetime_date_format_1 + @string/zetime_date_format_2 + @string/zetime_date_format_3 + + + 1 + 2 + 3 + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 51de96138..1d48124c8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -207,9 +207,27 @@ ZeTime settings + Heart rate settings Screen on duration in seconds Max heart rate alarm Min heart rate alarm + Analog mode + Only hands + Hands and steps + Activity tracking + Switching the activity tracking on, will count your steps and so on. + Hand movement + Rotate your wrist to activate or deactivate the display. + Calories type + Only active burnt calories + Active and inactive burnt calories + Time format + 24h + 12h + Date format + YY/MM/DD + DD/MM/YY + MM/DD/YY Auto export @@ -317,7 +335,9 @@ once a minute every 5 minutes every 10 minutes + every 15 minutes every 30 minutes + every 45 minutes once an hour Speed zones diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index e588ab5cf..178a11102 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -722,54 +722,10 @@ android:summary="%s" /> - - - - - - - - - - - - + android:title="@string/zetime_title_settings"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 87c09b038b485d23382f3857680f17df91cbc72b Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 10 Sep 2018 22:38:51 +0000 Subject: [PATCH 0010/1017] Translated using Weblate (Hebrew) Currently translated at 100.0% (577 of 577 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, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 3329538b2..be7550450 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -641,4 +641,10 @@ יש להפעיל אפשרות זו כדי לתמוך בערבית מחוברת תמיכה בטקסט מימין לשמאל הגדרות שפה ואיזור - +מחסור בשינה: %1$s + עודף שינה: %1$s + מחסור בצעדים: %1$d + עודף צעדים: %1$d + אין נתונים + + From 1fe8842743afb1f27277bf3f493de2221f5ef486 Mon Sep 17 00:00:00 2001 From: postsorino Date: Fri, 14 Sep 2018 05:02:49 +0000 Subject: [PATCH 0011/1017] Translated using Weblate (Greek) Currently translated at 97.2% (561 of 577 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/el/ --- app/src/main/res/values-el/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 741a297ee..11db0ccb0 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -683,4 +683,6 @@ Συχνότητα FM Μη έγκυρη συχνότητα Παρακαλώ εισάγετε συχνότητα από 87.5 έως 108.0 - +"Από δεξιά προς αριστερά " + "Ενεργοποιήστε αυτή την επιλογή αν η συσκευή σας δεν έχει υποστήριξη για γλώσσες που γράφονται από δεξιά " + From b9944ec0282eb0abd03be5e4e4b5c78dbc951ade Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 17 Sep 2018 00:11:32 +0200 Subject: [PATCH 0012/1017] Changelog for 0.30.0 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 958a74253..15353a0cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ ### Changelog +#### Version 0.30.0 +* Amazfit Bip + Mi Band 3: Support for right to left display (configurable) (#976) +* Add Arabic, Bengali Farsi, Persian, Scandinavian transliteration +* Add support for some Roidmi FM receivers +* Mi Band 3: Allow enabling the "Workout" menu item +* Mi Band 3: Support for night mode configuration +* Huami devices: fix seldom activity/sports synchronization problem (#1264) +* Preferences: Make minimum heart rate configurable (lower values will be disregarded) +* Preferences: Group language settings +* Preferences: Configure minimum time between notifications +* Attempt to fix BLE connection issues on Samsung S devices +* Week sleep and steps charts: display balance (actual value vs. desired value) +* Live Activity: show current/maximum heart rate, display minute steps and total steps and more improvements +* Live Activity: fix discrepancy between number of steps in Gadgetbridge and wearable device +* Fix missing caller ID for incoming calls on Android 9 +* Support for easy sharing of log files via the Debug screen +* Misc small bugfixes + #### Version 0.29.1 * Mi Band 3: Support setting language to to German, Italian, French, Polish, Japanese, Korean (read wiki) * Mi Band 3: Support flashing latest RES files From 46aec12aa6ab141949bf6ee31eda70cbe34e51f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Mon, 17 Sep 2018 01:15:18 +0200 Subject: [PATCH 0013/1017] News strings reworked --- app/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7942f6cf4..91dec54a0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -107,9 +107,9 @@ Enable this if your device has no support for your language\'s font Right-To-Left - Enable this if your device has no support in right-to-left languages + Enable this if your device can not show right-to-left languages Right-To-Left Max Line Length - When Right-To-Left is enable, the text is separated to lines. Change this value if the lines are to long/short. + Lengthens or shortens the lines Right-To-Left text is seperated into Always When screen is off From 828df4898f8a7e652f49228aaf9e9d79aad839fb Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Mon, 17 Sep 2018 05:53:24 +0200 Subject: [PATCH 0014/1017] First part: Add inactivity alert. --- .../devices/zetime/ZeTimeConstants.java | 12 ++++ .../devices/zetime/ZeTimeDeviceSupport.java | 46 ++++++++++++ app/src/main/res/values/strings.xml | 8 +++ app/src/main/res/xml/zetime_preferences.xml | 71 +++++++++++++++++++ 4 files changed, 137 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index 3339dd0e4..444a42aec 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -127,6 +127,18 @@ public class ZeTimeConstants { public static final String PREF_DO_NOT_DISTURB_START = "zetime_do_not_disturb_start"; public static final String PREF_DO_NOT_DISTURB_END = "zetime_do_not_disturb_end"; + public static final String PREF_INACTIVITY_ENABLE = "zetime_inactivity_warnings"; + public static final String PREF_INACTIVITY_START = "zetime_inactivity_warnings_start"; + public static final String PREF_INACTIVITY_END = "zetime_inactivity_warnings_end"; + public static final String PREF_INACTIVITY_THRESHOLD = "zetime_inactivity_warnings_threshold"; + public static final String PREF_INACTIVITY_MO = "zetime_prefs_inactivity_repetitions_mo"; + public static final String PREF_INACTIVITY_TU = "zetime_prefs_inactivity_repetitions_tu"; + public static final String PREF_INACTIVITY_WE = "zetime_prefs_inactivity_repetitions_we"; + public static final String PREF_INACTIVITY_TH = "zetime_prefs_inactivity_repetitions_th"; + public static final String PREF_INACTIVITY_FR = "zetime_prefs_inactivity_repetitions_fr"; + public static final String PREF_INACTIVITY_SA = "zetime_prefs_inactivity_repetitions_sa"; + public static final String PREF_INACTIVITY_SU = "zetime_prefs_inactivity_repetitions_su"; + public static final String PREF_ANALOG_MODE = "zetime_analog_mode"; public static final String PREF_ACTIVITY_TRACKING = "zetime_activity_tracking"; public static final String PREF_HANDMOVE_DISPLAY = "zetime_handmove_display"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index 46ec21fe5..50787b246 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -1614,4 +1614,50 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { sendMsgToWatch(builder, dateformat); } + + private void setInactivityAlert(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + boolean enabled = prefs.getBoolean(ZeTimeConstants.PREF_INACTIVITY_ENABLE, false); + int threshold = prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_THRESHOLD, 60); + + if(threshold > 0xff) + { + threshold = 0xff; + GB.toast(getContext(), "Value for inactivity threshold is greater than 255min! ", Toast.LENGTH_LONG, GB.ERROR); + } + + byte[] inactivity = { + ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_INACTIVITY_ALERT, + ZeTimeConstants.CMD_SEND, + (byte)0x8, + (byte)0x0, + (byte)0x0, + (byte)threshold, + (byte)0x0, + (byte)0x0, + (byte)0x0, + (byte)0x0, + (byte)0x64, + (byte)0x0, + ZeTimeConstants.CMD_END + }; + + if(enabled) + { + int reps = (1 << 7); // set inactivity active: set bit 7 + reps |= prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_MO, 0); + reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_TU, 0) << 1); + reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_WE, 0) << 2); + reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_TH, 0) << 3); + reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_FR, 0) << 4); + reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_SA, 0) << 5); + reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_SU, 0) << 6); + + inactivity[5] = (byte)reps; + } + + sendMsgToWatch(builder, inactivity); + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1d48124c8..e86ca3de9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -228,6 +228,14 @@ YY/MM/DD DD/MM/YY MM/DD/YY + Repetitions + Monday + Tuesday + Wednesday + Thursday + Friday + Saturday + Sunday Auto export diff --git a/app/src/main/res/xml/zetime_preferences.xml b/app/src/main/res/xml/zetime_preferences.xml index 92af75e18..0b0bcf818 100644 --- a/app/src/main/res/xml/zetime_preferences.xml +++ b/app/src/main/res/xml/zetime_preferences.xml @@ -24,6 +24,77 @@ android:title="@string/zetime_activity_tracking" android:summary="@string/zetime_activity_tracking_summary" /> + + + + + + + + + + + + + + + + + + + + + + + + + Date: Mon, 17 Sep 2018 08:10:49 +0200 Subject: [PATCH 0015/1017] Part 2: Add inactivity alert - complete now. Add checkbox to en-/disable the heart rate alarm and group this with the limits in its own screen. --- .../devices/zetime/ZeTimeConstants.java | 2 + .../zetime/ZeTimePreferenceActivity.java | 161 ++++++++++++++++++ .../devices/zetime/ZeTimeDeviceSupport.java | 43 ++++- app/src/main/res/values/strings.xml | 7 +- app/src/main/res/xml/zetime_preferences.xml | 44 +++-- 5 files changed, 235 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index 444a42aec..a0d8deda1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -120,6 +120,7 @@ public class ZeTimeConstants { public static final String PREF_ZETIME_DONT_DEL_ACTDATA = "zetime_dont_del_actdata"; + public static final String PREF_ZETIME_HEARTRATE_ALARM = "zetime_heartrate_alarm_enable"; public static final String PREF_ZETIME_MAX_HEARTRATE = "alarm_max_heart_rate"; public static final String PREF_ZETIME_MIN_HEARTRATE = "alarm_min_heart_rate"; @@ -127,6 +128,7 @@ public class ZeTimeConstants { public static final String PREF_DO_NOT_DISTURB_START = "zetime_do_not_disturb_start"; public static final String PREF_DO_NOT_DISTURB_END = "zetime_do_not_disturb_end"; + public static final String PREF_INACTIVITY_KEY = "zetime_inactivity_warning_key"; public static final String PREF_INACTIVITY_ENABLE = "zetime_inactivity_warnings"; public static final String PREF_INACTIVITY_START = "zetime_inactivity_warnings_start"; public static final String PREF_INACTIVITY_END = "zetime_inactivity_warnings_end"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java index 9d97eccc5..8eabbc36f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java @@ -130,6 +130,167 @@ public class ZeTimePreferenceActivity extends AbstractSettingsActivity { return true; } }); + + final Preference inactivityAlert = findPreference(ZeTimeConstants.PREF_INACTIVITY_ENABLE); + inactivityAlert.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertStart = findPreference(ZeTimeConstants.PREF_INACTIVITY_START); + inactivityAlertStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertEnd = findPreference(ZeTimeConstants.PREF_INACTIVITY_END); + inactivityAlertEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertThreshold = findPreference(ZeTimeConstants.PREF_INACTIVITY_THRESHOLD); + inactivityAlertThreshold.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertMo = findPreference(ZeTimeConstants.PREF_INACTIVITY_MO); + inactivityAlertMo.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertTu = findPreference(ZeTimeConstants.PREF_INACTIVITY_TU); + inactivityAlertTu.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertWe = findPreference(ZeTimeConstants.PREF_INACTIVITY_WE); + inactivityAlertWe.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertTh = findPreference(ZeTimeConstants.PREF_INACTIVITY_TH); + inactivityAlertTh.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertFr = findPreference(ZeTimeConstants.PREF_INACTIVITY_FR); + inactivityAlertFr.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertSa = findPreference(ZeTimeConstants.PREF_INACTIVITY_SA); + inactivityAlertSa.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + + final Preference inactivityAlertSu = findPreference(ZeTimeConstants.PREF_INACTIVITY_SU); + inactivityAlertSu.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_KEY); + } + }); + return true; + } + }); + } + + /** + * delayed execution so that the preferences are applied first + */ + private void invokeLater(Runnable runnable) { + getListView().post(runnable); } // private void addTryListeners() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index 50787b246..51eaea75a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -170,6 +170,9 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { case ZeTimeConstants.PREF_DATE_FORMAT: setDateFormate(builder); break; + case ZeTimeConstants.PREF_INACTIVITY_KEY: + setInactivityAlert(builder); + break; } builder.queue(getQueue()); } catch (IOException e) { @@ -1428,6 +1431,7 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { { Prefs prefs = GBApplication.getPrefs(); + boolean alarmEnabled = prefs.getBoolean(ZeTimeConstants.PREF_ZETIME_HEARTRATE_ALARM, false); int maxHR = prefs.getInt(ZeTimeConstants.PREF_ZETIME_MAX_HEARTRATE, 180); int minHR = prefs.getInt(ZeTimeConstants.PREF_ZETIME_MIN_HEARTRATE, 60); @@ -1438,7 +1442,7 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { (byte)0x0, (byte)(maxHR & 0xff), (byte)(minHR & 0xff), - (byte)0x1, // activate alarm + (byte)(alarmEnabled ? 1 : 0), // activate alarm ZeTimeConstants.CMD_END}; sendMsgToWatch(builder, heartrateAlarm); } @@ -1646,16 +1650,39 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { if(enabled) { + String start = prefs.getString(ZeTimeConstants.PREF_INACTIVITY_START, "06:00"); + String end = prefs.getString(ZeTimeConstants.PREF_INACTIVITY_END, "22:00"); + DateFormat df_start = new SimpleDateFormat("HH:mm"); + DateFormat df_end = new SimpleDateFormat("HH:mm"); + Calendar calendar = GregorianCalendar.getInstance(); + Calendar calendar_end = GregorianCalendar.getInstance(); + int reps = (1 << 7); // set inactivity active: set bit 7 - reps |= prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_MO, 0); - reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_TU, 0) << 1); - reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_WE, 0) << 2); - reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_TH, 0) << 3); - reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_FR, 0) << 4); - reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_SA, 0) << 5); - reps |= (prefs.getInt(ZeTimeConstants.PREF_INACTIVITY_SU, 0) << 6); + reps |= (prefs.getBoolean(ZeTimeConstants.PREF_INACTIVITY_MO, false) ? 1 : 0); + reps |= ((prefs.getBoolean(ZeTimeConstants.PREF_INACTIVITY_TU, false) ? 1 : 0) << 1); + reps |= ((prefs.getBoolean(ZeTimeConstants.PREF_INACTIVITY_WE, false) ? 1 : 0) << 2); + reps |= ((prefs.getBoolean(ZeTimeConstants.PREF_INACTIVITY_TH, false) ? 1 : 0) << 3); + reps |= ((prefs.getBoolean(ZeTimeConstants.PREF_INACTIVITY_FR, false) ? 1 : 0) << 4); + reps |= ((prefs.getBoolean(ZeTimeConstants.PREF_INACTIVITY_SA, false) ? 1 : 0) << 5); + reps |= ((prefs.getBoolean(ZeTimeConstants.PREF_INACTIVITY_SU, false) ? 1 : 0) << 6); inactivity[5] = (byte)reps; + + try { + calendar.setTime(df_start.parse(start)); + try { + calendar_end.setTime(df_end.parse(end)); + + inactivity[7] = (byte)calendar.get(Calendar.HOUR_OF_DAY); + inactivity[8] = (byte)calendar.get(Calendar.MINUTE); + inactivity[9] = (byte)calendar_end.get(Calendar.HOUR_OF_DAY); + inactivity[10] = (byte)calendar_end.get(Calendar.MINUTE); + } catch(Exception e) { + LOG.error("Unexpected exception in ZeTimeDeviceSupport.setInactivityAlert: " + e.getMessage()); + } + } catch(Exception e) { + LOG.error("Unexpected exception in ZeTimeDeviceSupport.setInactivityAlert: " + e.getMessage()); + } } sendMsgToWatch(builder, inactivity); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e86ca3de9..ce8ca4777 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -209,8 +209,11 @@ ZeTime settings Heart rate settings Screen on duration in seconds - Max heart rate alarm - Min heart rate alarm + Heart rate alarm + The watch will warn you when your heart rate exceeds the limits. + Enable the heart rate alarm + Max heart rate + Min heart rate Analog mode Only hands Hands and steps diff --git a/app/src/main/res/xml/zetime_preferences.xml b/app/src/main/res/xml/zetime_preferences.xml index 0b0bcf818..9f85c7c7e 100644 --- a/app/src/main/res/xml/zetime_preferences.xml +++ b/app/src/main/res/xml/zetime_preferences.xml @@ -180,18 +180,38 @@ android:key="heartrate_measurement_interval" android:summary="%s" android:title="@string/prefs_title_heartrate_measurement_interval" /> - + - + + + + + + + + + \ No newline at end of file From ecfd83ae657c40df90c26136e7a59db937e04669 Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Mon, 17 Sep 2018 13:53:24 +0200 Subject: [PATCH 0016/1017] Add setting alarms. Choose the type of the signaling in the preferences. --- .../devices/zetime/ZeTimeConstants.java | 5 +++ .../devices/zetime/ZeTimeDeviceSupport.java | 31 +++++++++++++++++++ app/src/main/res/values/arrays.xml | 10 ++++++ app/src/main/res/values/strings.xml | 4 +++ app/src/main/res/xml/zetime_preferences.xml | 8 +++++ 5 files changed, 58 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index a0d8deda1..e746f44aa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -77,6 +77,7 @@ public class ZeTimeConstants { public static final byte CMD_PUSH_EX_MSG = (byte) 0x76; public static final byte CMD_PUSH_WEATHER_DATA = (byte) 0x77; public static final byte CMD_SWITCH_SETTINGS = (byte) 0x90; + public static final byte CMD_REMINDERS = (byte) 0x97; public static final byte CMD_PUSH_CALENDAR_DAY = (byte) 0x99; public static final byte CMD_MUSIC_CONTROL = (byte) 0xD0; // here are the action commands @@ -109,6 +110,8 @@ public class ZeTimeConstants { public static final byte NOTIFICATION_UBER = (byte) 0x13; public static final byte NOTIFICATION_LINE = (byte) 0x14; public static final byte NOTIFICATION_SKYPE = (byte) 0x15; + // reminders types + public static final byte REMINDER_ALARM = (byte) 0x04; // watch settings public static final String PREF_WRIST = "zetime_wrist"; public static final byte WEAR_ON_LEFT_WRIST = (byte) 0x00; @@ -147,4 +150,6 @@ public class ZeTimeConstants { public static final String PREF_CALORIES_TYPE = "zetime_calories_type"; public static final String PREF_TIME_FORMAT = "zetime_time_format"; public static final String PREF_DATE_FORMAT = "zetime_date_format"; + + public static final String PREF_ALARM_SIGNALING = "zetime_alarm_signaling"; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index 51eaea75a..bf4efb818 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -229,7 +229,38 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { @Override public void onSetAlarms(ArrayList alarms) { + byte[] alarmMessage = null; + try { + TransactionBuilder builder = performInitialized("setAlarms"); + Prefs prefs = GBApplication.getPrefs(); + + for (Alarm alarm : alarms) { + alarmMessage = new byte[]{ + ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_REMINDERS, + ZeTimeConstants.CMD_SEND, + (byte) 0xb, + (byte) 0x0, + (byte) alarm.getIndex(), // index + ZeTimeConstants.REMINDER_ALARM, + (byte) 0x0, // year low byte + (byte) 0x0, // year high byte + (byte) 0x0, // month + (byte) 0x0, // day + (byte) alarm.getAlarmCal().get(Calendar.HOUR_OF_DAY), + (byte) alarm.getAlarmCal().get(Calendar.MINUTE), + (byte) alarm.getRepetitionMask(), + (byte) (alarm.isEnabled() ? 1 : 0), + (byte) prefs.getInt(ZeTimeConstants.PREF_ALARM_SIGNALING, 11), // reminder signaling + ZeTimeConstants.CMD_END + }; + sendMsgToWatch(builder, alarmMessage); + } + builder.queue(getQueue()); + } catch (IOException e) { + GB.toast(getContext(), "Error set alarms: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } } @Override diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 99403968d..5fd1849a5 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -490,5 +490,15 @@ 2 3 + + @string/zetime_signaling_vibrate + @string/zetime_signaling_buzzer + @string/zetime_signaling_vibrate_buzzer + + + 7 + 11 + 13 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce8ca4777..cc52bceb2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -239,6 +239,10 @@ Friday Saturday Sunday + Set type of signaling for the alarm + Vibrate + Buzzer + Vibrate and Buzzer Auto export diff --git a/app/src/main/res/xml/zetime_preferences.xml b/app/src/main/res/xml/zetime_preferences.xml index 9f85c7c7e..e4a5aa0d3 100644 --- a/app/src/main/res/xml/zetime_preferences.xml +++ b/app/src/main/res/xml/zetime_preferences.xml @@ -18,6 +18,14 @@ android:key="zetime_screentime" android:title="@string/zetime_title_screentime"/> + + Date: Mon, 17 Sep 2018 14:43:09 +0200 Subject: [PATCH 0017/1017] BUGFIX: use correct preference key to toggle wrist flick on and off. Add: fill function onFindDevice with test commands for the signaling of the watch, if watch is set to buzzer just the buzzer is used, ... and so on. --- .../devices/zetime/ZeTimeConstants.java | 1 + .../devices/zetime/ZeTimeDeviceSupport.java | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index e746f44aa..a8de5d504 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -80,6 +80,7 @@ public class ZeTimeConstants { public static final byte CMD_REMINDERS = (byte) 0x97; public static final byte CMD_PUSH_CALENDAR_DAY = (byte) 0x99; public static final byte CMD_MUSIC_CONTROL = (byte) 0xD0; + public static final byte CMD_TEST_SIGNALING = (byte) 0xFA; // here are the action commands public static final byte CMD_REQUEST = (byte) 0x70; public static final byte CMD_SEND = (byte) 0x71; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index bf4efb818..c46edf60e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -197,7 +197,22 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { @Override public void onFindDevice(boolean start) { - + try { + TransactionBuilder builder = performInitialized("onFindDevice"); + byte[] testSignaling = { + ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_TEST_SIGNALING, + ZeTimeConstants.CMD_SEND, + (byte)0x1, + (byte)0x0, + (byte)(start ? 1 : 0), + ZeTimeConstants.CMD_END + }; + sendMsgToWatch(builder, testSignaling); + builder.queue(getQueue()); + } catch (IOException e) { + GB.toast(getContext(), "Error on function onFindDevice: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } } @Override @@ -1528,7 +1543,7 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { private void setDisplayOnMovement(TransactionBuilder builder) { Prefs prefs = GBApplication.getPrefs(); - boolean movement = prefs.getBoolean(ZeTimeConstants.PREF_ACTIVITY_TRACKING, false); + boolean movement = prefs.getBoolean(ZeTimeConstants.PREF_HANDMOVE_DISPLAY, false); byte[] handmove = {ZeTimeConstants.CMD_PREAMBLE, ZeTimeConstants.CMD_SWITCH_SETTINGS, From a55c3d72205d90d437b45a65bc9d6ffa4586161c Mon Sep 17 00:00:00 2001 From: Newline Bot Date: Mon, 17 Sep 2018 18:28:56 +0200 Subject: [PATCH 0018/1017] Replace CRLF with LF (no content changes) --- .../devices/xwatch/XWatchCoordinator.java | 232 +++++++++--------- .../devices/xwatch/XWatchService.java | 68 ++--- 2 files changed, 150 insertions(+), 150 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchCoordinator.java index 207cc3fb2..821206651 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchCoordinator.java @@ -15,124 +15,124 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.devices.xwatch; - -import android.app.Activity; -import android.content.Context; -import android.net.Uri; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import nodomain.freeyourgadget.gadgetbridge.GBException; -import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; -import nodomain.freeyourgadget.gadgetbridge.entities.Device; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; - -public class XWatchCoordinator extends AbstractDeviceCoordinator { - @NonNull - @Override - public DeviceType getSupportedType(GBDeviceCandidate candidate) { - String name = candidate.getDevice().getName(); - if (name != null && name.startsWith("XWatch")) { - return DeviceType.XWATCH; - } - return DeviceType.UNKNOWN; - } - - @Override - protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException { - - } - - @Override - public DeviceType getDeviceType() { - return DeviceType.XWATCH; - } - - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - - @Override - public boolean supportsActivityDataFetching() { - return true; - } - - @Override - public boolean supportsActivityTracking() { - return true; - } - - @Override - public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { - return new XWatchSampleProvider(device, session); - } - - @Override - public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; - } - - @Override - public boolean supportsScreenshots() { - return false; - } - - @Override - public boolean supportsAlarmConfiguration() { - return true; - } - - @Override - public boolean supportsSmartWakeup(GBDevice device) { - return false; - } - - @Override - public boolean supportsHeartRateMeasurement(GBDevice device) { - return false; - } - - @Override - public String getManufacturer() { - return "Generic"; - } - - @Override - public boolean supportsAppsManagement() { - return false; - } - - @Override - public Class getAppsManagementActivity() { - return null; - } - - @Override - public boolean supportsCalendarEvents() { - return false; - } - - @Override - public boolean supportsRealtimeData() { - return false; - } - - @Override - public boolean supportsWeather() { - return false; - } +package nodomain.freeyourgadget.gadgetbridge.devices.xwatch; + +import android.app.Activity; +import android.content.Context; +import android.net.Uri; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; + +public class XWatchCoordinator extends AbstractDeviceCoordinator { + @NonNull + @Override + public DeviceType getSupportedType(GBDeviceCandidate candidate) { + String name = candidate.getDevice().getName(); + if (name != null && name.startsWith("XWatch")) { + return DeviceType.XWATCH; + } + return DeviceType.UNKNOWN; + } + + @Override + protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException { + + } + + @Override + public DeviceType getDeviceType() { + return DeviceType.XWATCH; + } + + @Nullable + @Override + public Class getPairingActivity() { + return null; + } + + @Override + public boolean supportsActivityDataFetching() { + return true; + } + + @Override + public boolean supportsActivityTracking() { + return true; + } + + @Override + public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { + return new XWatchSampleProvider(device, session); + } + + @Override + public InstallHandler findInstallHandler(Uri uri, Context context) { + return null; + } + + @Override + public boolean supportsScreenshots() { + return false; + } + + @Override + public boolean supportsAlarmConfiguration() { + return true; + } + + @Override + public boolean supportsSmartWakeup(GBDevice device) { + return false; + } + + @Override + public boolean supportsHeartRateMeasurement(GBDevice device) { + return false; + } + + @Override + public String getManufacturer() { + return "Generic"; + } + + @Override + public boolean supportsAppsManagement() { + return false; + } + + @Override + public Class getAppsManagementActivity() { + return null; + } + + @Override + public boolean supportsCalendarEvents() { + return false; + } + + @Override + public boolean supportsRealtimeData() { + return false; + } + + @Override + public boolean supportsWeather() { + return false; + } @Override public boolean supportsFindDevice() { return true; } -} +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java index aafcde504..63deb4b46 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java @@ -14,37 +14,37 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.devices.xwatch; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class XWatchService { - public static final UUID UUID_NOTIFY = UUID.fromString("0000fff7-0000-1000-8000-00805f9b34fb"); - public static final UUID UUID_SERVICE = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"); - public static final UUID UUID_WRITE = UUID.fromString("0000fff6-0000-1000-8000-00805f9b34fb"); - - public static final byte COMMAND_CONNECTED = 0x01; - public static final byte COMMAND_ACTION_BUTTON = 0x4c; - public static final byte COMMAND_ACTIVITY_DATA = 0x43; - public static final byte COMMAND_ACTIVITY_TOTALS = 0x46; - - private static final Map XWATCH_DEBUG; - - static { - XWATCH_DEBUG = new HashMap<>(); - - XWATCH_DEBUG.put(UUID_NOTIFY, "Read data"); - XWATCH_DEBUG.put(UUID_WRITE, "Write data"); - XWATCH_DEBUG.put(UUID_SERVICE, "Get service"); - } - - public static String lookup(UUID uuid, String fallback) { - String name = XWATCH_DEBUG.get(uuid); - if (name == null) { - name = fallback; - } - return name; - } -} +package nodomain.freeyourgadget.gadgetbridge.devices.xwatch; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class XWatchService { + public static final UUID UUID_NOTIFY = UUID.fromString("0000fff7-0000-1000-8000-00805f9b34fb"); + public static final UUID UUID_SERVICE = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"); + public static final UUID UUID_WRITE = UUID.fromString("0000fff6-0000-1000-8000-00805f9b34fb"); + + public static final byte COMMAND_CONNECTED = 0x01; + public static final byte COMMAND_ACTION_BUTTON = 0x4c; + public static final byte COMMAND_ACTIVITY_DATA = 0x43; + public static final byte COMMAND_ACTIVITY_TOTALS = 0x46; + + private static final Map XWATCH_DEBUG; + + static { + XWATCH_DEBUG = new HashMap<>(); + + XWATCH_DEBUG.put(UUID_NOTIFY, "Read data"); + XWATCH_DEBUG.put(UUID_WRITE, "Write data"); + XWATCH_DEBUG.put(UUID_SERVICE, "Get service"); + } + + public static String lookup(UUID uuid, String fallback) { + String name = XWATCH_DEBUG.get(uuid); + if (name == null) { + name = fallback; + } + return name; + } +} From cfddba0e4d762127c03538e01b88aeab652f060d Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 17 Sep 2018 22:11:15 +0200 Subject: [PATCH 0019/1017] Remove unused field and redundant casts --- .../activities/charts/LiveActivityFragment.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java index 0d8a7dcf2..ded591e60 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java @@ -85,7 +85,6 @@ public class LiveActivityFragment extends AbstractChartFragment { private final Steps mSteps = new Steps(); private ScheduledExecutorService pulseScheduler; private int maxStepsResetCounter; - private List heartRateValues; private LineDataSet mHeartRateSet; private int mHeartRate; private int mMaxHeartRate = 0; @@ -266,14 +265,13 @@ public class LiveActivityFragment extends AbstractChartFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { IntentFilter filterLocal = new IntentFilter(); filterLocal.addAction(DeviceService.ACTION_REALTIME_SAMPLES); - heartRateValues = new ArrayList<>(); tsTranslation = new TimestampTranslation(); View rootView = inflater.inflate(R.layout.fragment_live_activity, container, false); - mStepsPerMinuteCurrentChart = (CustomBarChart) rootView.findViewById(R.id.livechart_steps_per_minute_current); - mTotalStepsChart = (CustomBarChart) rootView.findViewById(R.id.livechart_steps_total); - mStepsPerMinuteHistoryChart = (BarLineChartBase) rootView.findViewById(R.id.livechart_steps_per_minute_history); + mStepsPerMinuteCurrentChart = rootView.findViewById(R.id.livechart_steps_per_minute_current); + mTotalStepsChart = rootView.findViewById(R.id.livechart_steps_total); + mStepsPerMinuteHistoryChart = rootView.findViewById(R.id.livechart_steps_per_minute_history); totalStepsEntry = new BarEntry(1, 0); stepsPerMinuteEntry = new BarEntry(1, 0); From d3fd203c6c3c7752fa8d0e15f515f1df7a86e46a Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 17 Sep 2018 22:28:13 +0200 Subject: [PATCH 0020/1017] Avoid possible NPE --- .../freeyourgadget/gadgetbridge/util/TimePreference.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java index 043cc4697..f549963f3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java @@ -85,7 +85,11 @@ public class TimePreference extends DialogPreference { time = getPersistedString(defaultValue.toString()); } } else { - time = defaultValue.toString(); + if (defaultValue != null) { + time = defaultValue.toString(); + } else { + time = "00:00"; + } } String[] pieces = time.split(":"); From 6d4d92fd8828290d8b1521c28d9d448a7528480b Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 17 Sep 2018 23:01:01 +0200 Subject: [PATCH 0021/1017] Live Activity: don't enable notifications every second This caused the BLE queue to fill up more and more. --- .../service/devices/huami/HuamiSupport.java | 11 ++++++++--- 1 file changed, 8 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 a90a174e8..aa3fafceb 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 @@ -179,6 +179,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { private boolean isMusicAppStarted = false; private MusicSpec bufferMusicSpec = null; private MusicStateSpec bufferMusicStateSpec = null; + private boolean heartRateNotifyEnabled; public HuamiSupport() { this(LOG); @@ -207,6 +208,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { @Override protected TransactionBuilder initializeDevice(TransactionBuilder builder) { try { + heartRateNotifyEnabled = false; boolean authenticate = needsAuth; needsAuth = false; byte authFlags = HuamiService.AUTH_BYTE; @@ -871,9 +873,12 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } try { TransactionBuilder builder = performInitialized("Enable realtime heart rate measurement"); - BluetoothGattCharacteristic heartrateCharacteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT); - if (heartrateCharacteristic != null) { - builder.notify(heartrateCharacteristic, enable); + if (heartRateNotifyEnabled != enable) { + BluetoothGattCharacteristic heartrateCharacteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT); + if (heartrateCharacteristic != null) { + builder.notify(heartrateCharacteristic, enable); + heartRateNotifyEnabled = enable; + } } if (enable) { builder.write(characteristicHRControlPoint, stopHeartMeasurementManual); From 6ea9cc29bd817b5b6e92d714fd551b044c616700 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 17 Sep 2018 23:06:04 +0200 Subject: [PATCH 0022/1017] Updated changelog for 0.30.0 release --- CHANGELOG.md | 2 +- app/src/main/res/xml/changelog_master.xml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15353a0cb..41bb28a34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,8 @@ * Mi Band 3: Support for night mode configuration * Huami devices: fix seldom activity/sports synchronization problem (#1264) * Preferences: Make minimum heart rate configurable (lower values will be disregarded) -* Preferences: Group language settings * Preferences: Configure minimum time between notifications +* Preferences: Group language settings * Attempt to fix BLE connection issues on Samsung S devices * Week sleep and steps charts: display balance (actual value vs. desired value) * Live Activity: show current/maximum heart rate, display minute steps and total steps and more improvements diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index 17e67ec87..6b627f792 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,5 +1,23 @@ + + Amazfit Bip + Mi Band 3: Support for right to left display (configurable) (#976) + Add Arabic, Bengali Farsi, Persian, Scandinavian transliteration + Add support for some Roidmi FM receivers + Mi Band 3: Allow enabling the "Workout" menu item + Mi Band 3: Support for night mode configuration + Huami devices: fix seldom activity/sports synchronization problem (#1264) + Preferences: Make minimum heart rate configurable (lower values will be disregarded) + Preferences: Configure minimum time between notifications + Preferences: Group language settings + Attempt to fix BLE connection issues on Samsung S devices + Week sleep and steps charts: display balance (actual value vs. desired value) + Live Activity: show current/maximum heart rate, display minute steps and total steps and more improvements + Live Activity: fix discrepancy between number of steps in Gadgetbridge and wearable device + Fix missing caller ID for incoming calls on Android 9 + Support for easy sharing of log files via the Debug screen + Misc small bugfixes + Mi Band 3: Support setting language to to German, Italian, French, Polish, Japanese, Korean (read wiki) Mi Band 3: Support flashing latest RES files From b1e122cbda25881b2afd53371ea60003e6785e52 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 17 Sep 2018 23:09:35 +0200 Subject: [PATCH 0023/1017] Bump version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0392369ad..9ab629e63 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,8 +25,8 @@ android { targetSdkVersion 27 // Note: always bump BOTH versionCode and versionName! - versionName "0.29.1" - versionCode 137 + versionName "0.30.0" + versionCode 138 vectorDrawables.useSupportLibrary = true } buildTypes { From c6d8086d32d719af90ca0e8f563ad992594ffcb2 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 17 Sep 2018 23:11:42 +0200 Subject: [PATCH 0024/1017] add fastlane changelog --- .../metadata/android/en-US/changelogs/138.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/138.txt diff --git a/fastlane/metadata/android/en-US/changelogs/138.txt b/fastlane/metadata/android/en-US/changelogs/138.txt new file mode 100644 index 000000000..12e961dbe --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/138.txt @@ -0,0 +1,16 @@ +* Amazfit Bip + Mi Band 3: Support for right to left display (configurable) (#976) +* Add Arabic, Bengali Farsi, Persian, Scandinavian transliteration +* Add support for some Roidmi FM receivers +* Mi Band 3: Allow enabling the "Workout" menu item +* Mi Band 3: Support for night mode configuration +* Huami devices: fix seldom activity/sports synchronization problem (#1264) +* Preferences: Make minimum heart rate configurable (lower values will be disregarded) +* Preferences: Configure minimum time between notifications +* Preferences: Group language settings +* Attempt to fix BLE connection issues on Samsung S devices +* Week sleep and steps charts: display balance (actual value vs. desired value) +* Live Activity: show current/maximum heart rate, display minute steps and total steps and more improvements +* Live Activity: fix discrepancy between number of steps in Gadgetbridge and wearable device +* Fix missing caller ID for incoming calls on Android 9 +* Support for easy sharing of log files via the Debug screen +* Misc small bugfixes From 9e44a7ad6dde01b869231d89783b3176c96ead5d Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Thu, 20 Sep 2018 00:03:45 +0200 Subject: [PATCH 0025/1017] Add .gitattributes for consistent eol handling --- .gitattributes | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..42736eec0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.java text +*.gradle text +*.md text +*.properties text +*.xml text + +# Declare files that will always have CRLF line endings on checkout. +#*.sln text eol=crlf + +# Denote all files that are truly binary and should not be modified. +#*.png binary +#*.jpg binary From 2df8dfed185c8bff63c7e8dfce7db7ab41d76144 Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Thu, 20 Sep 2018 14:38:06 +0200 Subject: [PATCH 0026/1017] Add a submenu to choose between different signal types. --- .../devices/zetime/ZeTimeConstants.java | 3 + .../zetime/ZeTimePreferenceActivity.java | 9 + .../devices/zetime/ZeTimeDeviceSupport.java | 60 ++++- app/src/main/res/values/arrays.xml | 16 +- app/src/main/res/values/strings.xml | 17 +- app/src/main/res/xml/zetime_preferences.xml | 244 +++++++++++++++++- 6 files changed, 335 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index a8de5d504..59ac4be1e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -153,4 +153,7 @@ public class ZeTimeConstants { public static final String PREF_DATE_FORMAT = "zetime_date_format"; public static final String PREF_ALARM_SIGNALING = "zetime_alarm_signaling"; + public static final String PREF_SMS_SIGNALING = "zetime_sms_signaling"; + public static final String PREF_SHOCK_STRENGTH = "zetime_shock_strength"; + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java index 8eabbc36f..4a10fc592 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java @@ -284,6 +284,15 @@ public class ZeTimePreferenceActivity extends AbstractSettingsActivity { return true; } }); + + final Preference smsSignaling = findPreference(ZeTimeConstants.PREF_SMS_SIGNALING); + smsSignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_SMS_SIGNALING); + return true; + } + }); } /** diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index c46edf60e..b7a0e38d3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -173,6 +173,12 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { case ZeTimeConstants.PREF_INACTIVITY_KEY: setInactivityAlert(builder); break; + case ZeTimeConstants.PREF_SMS_SIGNALING: + setSMSSignaling(builder); + break; + case ZeTimeConstants.PREF_SHOCK_STRENGTH: + setShockStrength(builder); + break; } builder.queue(getQueue()); } catch (IOException e) { @@ -426,7 +432,22 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { @Override public void onTestNewFunction() { - + byte[] strength = { + ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_SHOCK_STRENGTH, + ZeTimeConstants.CMD_REQUEST, + (byte)0x1, + (byte)0x0, + (byte)0x0, + ZeTimeConstants.CMD_END + }; + try { + TransactionBuilder builder = performInitialized("testNewFunction"); + sendMsgToWatch(builder, strength); + builder.queue(getQueue()); + } catch (IOException e) { + GB.toast(getContext(), "Error on testing new function: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } } @Override @@ -1733,4 +1754,41 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { sendMsgToWatch(builder, inactivity); } + + private void setShockStrength(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + int shockStrength = prefs.getInt(ZeTimeConstants.PREF_SHOCK_STRENGTH, 255); + + byte[] strength = { + ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_SHOCK_STRENGTH, + ZeTimeConstants.CMD_SEND, + (byte)0x1, + (byte)0x0, + (byte)shockStrength, + ZeTimeConstants.CMD_END + }; + + sendMsgToWatch(builder, strength); + } + + private void setSMSSignaling(TransactionBuilder builder) + { + Prefs prefs = GBApplication.getPrefs(); + int signalType = prefs.getInt(ZeTimeConstants.PREF_SMS_SIGNALING, 0); + + byte[] signaling = { + ZeTimeConstants.CMD_PREAMBLE, + ZeTimeConstants.CMD_SHOCK_MODE, + ZeTimeConstants.CMD_SEND, + (byte)0x2, + (byte)0x0, + (byte)0x4, + (byte)signalType, + ZeTimeConstants.CMD_END + }; + + sendMsgToWatch(builder, signaling); + } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 5fd1849a5..56a9920cb 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -491,13 +491,25 @@ 3 + @string/zetime_signaling_none + @string/zetime_signaling_vibrate_once + @string/zetime_signaling_vibrate_twice @string/zetime_signaling_vibrate - @string/zetime_signaling_buzzer - @string/zetime_signaling_vibrate_buzzer + @string/zetime_signaling_beep_once + @string/zetime_signaling_beep_twice + @string/zetime_signaling_beep + @string/zetime_signaling_vibrate_beep_once + @string/zetime_signaling_vibrate_beep + 0 + 2 + 4 7 + 9 + 10 11 + 12 13 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cc52bceb2..36cf72ee3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -240,9 +240,15 @@ Saturday Sunday Set type of signaling for the alarm - Vibrate - Buzzer - Vibrate and Buzzer + Silent + Continuous vibration + Continuous beeping + Continuous vibration and beeping + Vibrate once + Vibrate twice + Beep once + Beep twice + Vibrate and beep once Auto export @@ -342,9 +348,14 @@ Generic notification E-mail notification Incoming call notification + Missed call notification Chat Navigation Social network + Calendar notification + Inactivity notification + Low power warning + Anti-loss warning Whole day HR measurement once a minute diff --git a/app/src/main/res/xml/zetime_preferences.xml b/app/src/main/res/xml/zetime_preferences.xml index e4a5aa0d3..2f3b22154 100644 --- a/app/src/main/res/xml/zetime_preferences.xml +++ b/app/src/main/res/xml/zetime_preferences.xml @@ -18,14 +18,6 @@ android:key="zetime_screentime" android:title="@string/zetime_title_screentime"/> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 60397c88c00d5d41286d756418eeb165f729bcde Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sun, 23 Sep 2018 11:27:35 +0200 Subject: [PATCH 0027/1017] Avoid possible NPE --- .../freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java index 542e92fb8..7fe901f43 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java @@ -522,7 +522,9 @@ public final class BtLEQueue { private void checkWaitingCharacteristic(BluetoothGattCharacteristic characteristic, int status) { if (status != BluetoothGatt.GATT_SUCCESS) { - LOG.debug("failed btle action, aborting transaction: " + characteristic.getUuid() + getStatusString(status)); + if (characteristic != null) { + LOG.debug("failed btle action, aborting transaction: " + characteristic.getUuid() + getStatusString(status)); + } mAbortTransaction = true; } if (characteristic != null && BtLEQueue.this.mWaitCharacteristic != null && characteristic.getUuid().equals(BtLEQueue.this.mWaitCharacteristic.getUuid())) { From ab748eb5b19017019b9c4442897ee79a58104e67 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 17 Sep 2018 08:39:27 +0000 Subject: [PATCH 0028/1017] Translated using Weblate (Hebrew) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index be7550450..57a1987fa 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -647,4 +647,5 @@ עודף צעדים: %1$d אין נתונים + דופק נוכחי / מרבי: %1$d ‏/ %2$d From 73f0309c84a795d18c1ce7a3454770f94b96317d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sun, 16 Sep 2018 23:02:11 +0000 Subject: [PATCH 0029/1017] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 99.1% (573 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nb_NO/ --- app/src/main/res/values-nb-rNO/strings.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 24773bcfe..fb3b128d5 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -675,4 +675,26 @@ FM-frekvens Ugyldig frekvens Skriv inn en frekvens mellom 87.5 og 108.0 +Høyre-til-venstre + Skru på dette hvis din enhet ikke har støtte for språk som vises fra høyre til venstre. + Maksimal linjelengde for høyre-til-venstre + Når høyre-til-venstre er påslått, deles teksten inn i linjer. Endre denne verdien hvis linjene er for lange/korte. + + %1$s batteri snart tomt + %1$s batteri snart tomt: %2$s + Søvnmangel: %1$s + Sovet for lenge: %1$s + Ikke nok steg: %1$d + For mange steg: %1$d + Nåværende / maksimal puls: %1$d /%2$d + Diagraminnstillinger + Makspuls + Minimumspuls + + Kontekstuell arabisk + Skru på dette for kontekstuell arabisk støtte + Høyre-til-venstre -støtte + Ingen data + + Språk og stedsinnstillinger From c168f24c2d1b0fc421bb6b821492994e9e2522c4 Mon Sep 17 00:00:00 2001 From: Full Name Date: Mon, 17 Sep 2018 16:31:43 +0000 Subject: [PATCH 0030/1017] Translated using Weblate (Czech) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/cs/ --- app/src/main/res/values-cs/strings.xml | 160 +++++++++++++++++++++---- 1 file changed, 136 insertions(+), 24 deletions(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 2e6dd51a4..0bb4f73e7 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -5,7 +5,7 @@ Nastavení Ladění Ukončit - Načíst data + Synchronizovat Monitor spánku (alfa) Najít zařízení Pořídit snímek displeje @@ -44,31 +44,31 @@ Instalátor FW/App Instaluje firmvér %s do Mi Band místo stávajícího. - Instaluje firmvér %1$s a %2$s do Mi Band místo stávajícího. - Tento firmvér byl testován a je kompatibilní s Gadgetbridge. + Instaluje %1$s a %2$s firmvér, místo stávajícího. + Tento firmvér byl testován a je známa jeho kompatibilita s Gadgetbridge. Tento firmvér nebyl testován a nemusí být kompatibilní s Gadgetbridge. \n \nNedoporučujeme jej nahrávat do Mi Band! - Pokud budete prokračovat a vše bude fungovat běžně i potom, upozorněte vývojáře Gadgetbridge, aby označili tento firmvér: %s jako vyzkoušený + Chcete-li stále pokračovat a bude-li vše správně fungovat i po aktualizaci, oznamte vývojářům Gadgetbridge, aby označili tuto verzi firmvéru: %s jako funkční.. Nastavení - Základní nastavení - Připojit zařízení pokud je zapnutý BT + Obecná nastavení + Připojit Gadgetbridge k zařízení při zapnutí Bluetooth Spouštět automaticky Automatické znovupřipojení - Preferovaný přehrávač zvuků + Preferovaný přehrávač hudby Výchozí Datum a čas - Nastavit čas - Nastavit čas během připojení a při změně času v Androidu + Synchronizovat čas + Synchronizovat čas během připojení k zařízení a při změně času v Androidu Téma Světlé Tmavé Jazyk Skrýt notifikace Gadgetbridge Ikona ve stavové liště a notifikace na zamčeném displeji budou zobrazeny - Ikona ve stavové liště a notifikace na zamčeném displeji nebudou zobrazeny - Notifikace + Ikona ve stavové liště a notifikace na zamčeném displeji budou skryty + Upozornění Opakování Volání SMS @@ -77,7 +77,7 @@ Přístup k notifikacím Upozornění i při zapnuté obrazovce Nerušit - Neposílat nechtěné notifikace v režimu Nerušit + Neposílat nechtěná upozornění v režimu Nerušit Přepsání diakritiky Toto zapněte, pokud vaše zařízení nepodporuje písma pro vás jazyk Vždy @@ -217,7 +217,7 @@ Notifikace SMS Nastavení vibrací Obecné notifikace - Notifikace emailu + Upozornění emailu Notifikace volání Konverzace Navigace @@ -237,7 +237,7 @@ So Chytré buzení Nepodařilo se nastavit budík, zkuste to znovu! - Budík zaslán do zařízení! + Čas buzení odeslán do zařízení. Chybí data, provést stažení? Stahnout data %1$s z %2$s Cílový počet kroků na den @@ -279,7 +279,7 @@ Pokud není přenos dat potvrzen náramku, potom nebudou smazána. Užitečné pokud je GB používán dohromady s jinou aplikací. Zachová data o aktivitě v Mi Band i po synchronizaci. Užitečné pokud je GB používán dohromady s jinou aplikací. Použít režim z nízkým zpožděním pro aktualizace firmwaru - Může to pomoci u zařízení, kde aktualizace firmwaru selhala + Může to pomoci u zařízení, kde aktualizace firmwaru selhala. Historie kroků Aktuálně kroků/min Celkem kroků @@ -297,7 +297,7 @@ Budíky pro nadcházející události Použít sledování tepu pro zlepšení detekce spánku Časový posun zařízení v hodinách (pro zjišťování spánku směnařů) - Mi2: formát data + Formát data Čas Čas a dátum Zapnout displej při zvednutí @@ -350,7 +350,7 @@ Vibrace Párování Pebble - Dialog párování by se měl objevit na vašem zařízení s Androidem. Pokud se to nestane, zkontrolujte panel notifikací a potvrďte párování. Potom potvrďte párování na Pebble + Dialog párování by se měl objevit na vašem zařízení s Androidem. Pokud se to nestane, zkontrolujte panel notifikací a potvrďte párování. Poté potvrďte párování na Pebble. Ujistěte se, že tento skin je povolen v aplikaci pro oznámení počasí pro získávání informací v Pebble.\n\nNení třeba nic nastavovat.\n\nAplikaci pro počasí Pebble je možné povolit ve správě aplikací.\n\nPodporované ciferníky ukáží počasí automaticky. Zapnout párování BT Toto vypněte v případě problémů s připojením @@ -435,13 +435,13 @@ \nDĚLÁTE TO NA VLASTNÍ NEBEZPEČÍ! "Firmware Amazfit Bipu %1$s" Připojit - Chystáte se nainstalovat firmvér %s do vašeho Amazfit Cor. + Chystáte se nainstalovat firmvér %s do vašeho Amazfit Cor. +\n +\nProsím, ujistěte se, že jste nainstalovali soubor .fw a potom soubor .res. Vaše hodinky se po instalaci souboru .fw restartují. +\n +\nPoznámka: Nemusíte instalovat soubor .res, pokud je stejný jako nainstalován dříve. \n -\nProsím, ujistěte se, že jste nainstalovali soubor .fw a potom soubor .res. Vaše hodinky se po instalaci souboru .fw restartují. -\n -\nPoznámka: Nemusíte instalovat soubor .res, pokud je stejný jako nainstalován dříve. -\n -\n NETESTOVÁNO, MŮŽE UMRTVIT VAŠE ZAŘÍZENÍ, DĚLÁTE TO NA VLASTNÍ NEBEZPEČÍ! +\nPOKRAČUJTE NA VLASTNÍ NEBEZPEČÍ! Zapnout možnost potažení vlevo/vpravo v grafech aktivit Počasí @@ -473,7 +473,7 @@ Aktivity Webový pohled - Otevřít na telefonu + Otevřít na Android zařízení Ztlumit Znova @@ -532,4 +532,116 @@ Kompas Nastavení Alipay +Změnit barvu LED + Změnit FM frekvenci + Kalibrovat zařízení + + + Seznam všech zakázaných upozornění + Seznam všech povolených upozornění + + + Chystáte se nainstalovat firmvér %s do vašeho Mi Band 3. +\n +\nProsím, ujistěte se, že jste nainstalovali soubor .fw a potom soubor .res. Vaše hodinky se po instalaci souboru .fw restartují. +\n +\nPoznámka: Nemusíte instalovat soubor .res, pokud je stejný jako nainstalován dříve. +\n +\nNETESTOVÁNO, MŮŽE POŠKODIT VAŠE ZAŘÍZENÍ, POKRAČUJTE NA VLASTNÍ NEBEZPEČÍ! + Minimální doba mezi upozorněními + Zprava doleva + Povolte, podporuje-li vaše zařízení jazyky zprava doleva + Maximální délka řádku pro zprava doleva + Je-li zapnuta podpora pro zleva doprava, text je rozdělen do řádků. Změňte tuto hodnotu jsou-li řádky příliš dlouhé/krátké. + + ID115 nastavení + Orientace displeje + + Synchronizovat automaticky + Synchronizovat při odemčení obrazovky. Musí být nastaven zámek obrazovky! + Minimální doba mezi synchronizacemi + Synchronizovat každých %d minut + + Mi Band 2 nastavení + Mi Band 3 nastavení + Amazfit Cor nastavenís + Na šířku + Na výšku + Po zavibrování stiskněte tlačítko, nebo se zařízením zatřeste. + + %1$s nízký stav baterie + %1$s baterie vybitá: %2$s + Nedostatek spánku: %1$s + Příliš mnoho spánku: %1$s + Bez omezení + 5 vteřin + 10 vteřin + 20 vteřin + 30 vteřin + 1 minuta + 5 minut + 10 minut + 30 minut + + Příliš málo kroků: %1$d + Příliš mnoho kroků: %1$d + Aktuální / Maximální tepová frekvence: %1$d / %2$d + Spánek od %1$s do %2$s + Bez spánku + Odemčení obrazovky zařízení + Přejeďte prstem pro odemčení obrazovky zařízení + Noční režim + Nižší automatická intenzita displeje v noci + + Norsky Bokmål + Rusky + Německy + Italsky + Francouzky + Polsky + Korejsky + Japonsky + + Nastavení grafů + Maximální tepová frekvence + Minimální tepová frekvence + + Ok + + Při západu slunce + Záznamy aktivit + Běhací pás + Mi Band 3 + Q8 + MyKronoz ZeTime + ID115 + Watch 9 + Roidmi + Roidmi 3 + + Upozornění + Hudba + Více + + Minuty: + Hodiny: + Vteřiny: + Nastavit čas aktuálně zobrazený na zařízení. + Kalibrovat + Párování Watch 9 + Kalibrace Watch 9 + Kontextuální Arabština + Zapnout podporu pro kontextuální arabštinu + Podpora zprava doleva + Sdílet záznam + Prosím nezapomeňte, že ladící záznamy Gadgetbridge mohou obsahovat osobní informace, zahrnující například zdravotní data, identifikátory (MAC adresu), hudební preference a podobně. Tyto informace můžete vymazat před odesláním souboru do veřejného reportu. + Upozornění! + Žádná data + + Barva LED + + Frekvence FM + Neplatná frekvence + Nastavte frekvenci mezi 87.5 a 108.0 + Jazyk a místní nastavení From 4602e7a1db8a4bb3d6a27ab7eab944e9668ffb2a Mon Sep 17 00:00:00 2001 From: Full Name Date: Wed, 19 Sep 2018 18:41:31 +0000 Subject: [PATCH 0031/1017] Translated using Weblate (Czech) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/cs/ --- app/src/main/res/values-cs/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 0bb4f73e7..4e7a1d5ac 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -464,7 +464,7 @@ Každých 30 minut Jednou za hodinu - Export databáze selhal! Zkontrolujte svá nastavení. + Export databáze selhal! Zkontrolujte nastavení. Automaticky Zjednodušená Čínština Tradiční Čísština From aba21647f5a2fcff80c83106d8b74ceb7ec9211e Mon Sep 17 00:00:00 2001 From: postsorino Date: Wed, 19 Sep 2018 18:09:17 +0000 Subject: [PATCH 0032/1017] Translated using Weblate (Greek) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/el/ --- app/src/main/res/values-el/strings.xml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 11db0ccb0..e279ba533 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -685,4 +685,25 @@ Παρακαλώ εισάγετε συχνότητα από 87.5 έως 108.0 "Από δεξιά προς αριστερά " "Ενεργοποιήστε αυτή την επιλογή αν η συσκευή σας δεν έχει υποστήριξη για γλώσσες που γράφονται από δεξιά " - + Μέγιστο μήκος γραμμής στις γλώσσες που γράφονται από δεξιά + Όταν η γραφή από δεξιά είναι ενεργοποιημένη , το κείμενο χωρίζεται σε γραμμές. Αλλάξτε αυτή τη τιμή αν οι γραμμές είναι πολύ μακριές ή κοντές. + + %1$s χαμηλή μπαταρία + %1$s χαμηλή μπαταρία: %2$s +\n + Έλλειψη ύπνου: %1$s + Παραπάνω ύπνος: %1$s + Λιγότερα βήματα: %1$d + Περισσότερα βήματα: %1$d + Τωρινοί / Μέγιστοι παλμοί: %1$d / %2$d + "Ρυθμίσεις γραφήματος " + Μέγιστοι παλμοί + Ελάχιστοι παλμοί + + Συμφραζόμενα Αραβικά + Ενεργοποιήστε αυτή την επιλογή για υποστήριξη συμφραζόμενων Αραβικών + Υποστήριξη γλωσσών γραφής από τα δεξιά + Χωρίς δεδομένα + + Ρυθμίσεις γλώσσας και περιοχής + From 0ff52f8e7a49f0eb0fed90f04f476472c3b597c4 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Thu, 20 Sep 2018 04:05:45 +0000 Subject: [PATCH 0033/1017] Translated using Weblate (Hebrew) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 57a1987fa..2bef64896 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -633,9 +633,9 @@ דופק מזערי מימין לשמאל - הפעל אפשרות זו אם להתקן אין תמיכה בשפות הנכתבות מימין לשמאל + יש להפעיל אפשרות זו אם ההתקן לא יכול להציג שפות מימין לשמאל גודל שורה מרבי מימין לשמאל - כאשר התמיכה בכתיבה מימין לשמאל מופעלת, הטקסט מופרד לשורות. שנה ערך זה אם השורות קצרות/ארוכות מדי. + קיצור או הארכת השורות של טקסט מימין לשמאל ערבית מחוברת יש להפעיל אפשרות זו כדי לתמוך בערבית מחוברת From c7e2c16247f6e74e5ae8b6460f9d69ae3c854533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Thu, 20 Sep 2018 06:36:46 +0000 Subject: [PATCH 0034/1017] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 99.1% (573 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nb_NO/ --- app/src/main/res/values-nb-rNO/strings.xml | 4 ++-- 1 file changed, 2 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 fb3b128d5..600be9e8a 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -676,9 +676,9 @@ Ugyldig frekvens Skriv inn en frekvens mellom 87.5 og 108.0 Høyre-til-venstre - Skru på dette hvis din enhet ikke har støtte for språk som vises fra høyre til venstre. + Skru på dette hvis din enhet ikke kan vise høyre til venstre-språk. Maksimal linjelengde for høyre-til-venstre - Når høyre-til-venstre er påslått, deles teksten inn i linjer. Endre denne verdien hvis linjene er for lange/korte. + Strekker eller korter ned linjene høyre-til-venstre tekst inndeles i. %1$s batteri snart tomt %1$s batteri snart tomt: %2$s From ee1fa190d6420755a9a513690d3352660c9bfc4c Mon Sep 17 00:00:00 2001 From: Louis-Marie Croisez Date: Thu, 20 Sep 2018 12:59:47 +0000 Subject: [PATCH 0035/1017] Translated using Weblate (French) Currently translated at 94.4% (546 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fr/ --- app/src/main/res/values-fr/strings.xml | 74 ++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index f58ee5174..b141f49fb 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -62,7 +62,7 @@ Par défaut Date et heure Synchroniser l\'heure - Synchroniser l\'heure à l\'appareil lors de la connexion et lorsque l\'heure ou le fuseau horaire changent sur Android + Synchroniser l\'heure sur l\'appareil lors de la connexion, et lorsque l\'heure ou le fuseau horaire changent sur Android Thème Clair Sombre @@ -79,7 +79,7 @@ Support des notifications génériques ...y compris quand l\'écran est allumé Ne Pas Déranger - Arrêter l’envoi des notifications non désirées en mode Ne Pas Déranger + Les notifications non-sollicitées sont suspendues dans ce mode Transcription Activez ceci si votre appareil ne supporte pas la police de caractères Toujours @@ -242,7 +242,7 @@ Sam Réveil intelligent Une erreur s\'est produite lors du paramétrage des alarmes, veuillez réessayer ! - Alarmes envoyées à l\'appareil ! + Alarmes envoyées à l\'appareil. Aucune donnée. Synchroniser l\'appareil ? Sur le point de transférer %1$s de données à partir de %2$s Objectif de pas par jour @@ -566,4 +566,72 @@ NOTE : la base de données sera bien évidement plus grande ! Notifications Musique Suite +Changer la couleur de la LED + Changer la fréquence FM + Calibrer votre appareil + + + Temps minimum entre deux notifications + De droite à gauche + Cocher ceci si votre appareil n\'est pas compatible avec les langues \"droite-à-gauche\" + Longueur max. d\'une ligne en mode Droite-à-Gauche + Lorsque votre bracelet vibre, secouez-le ou pressez son bouton. + + %1$s niveau de batterie bas + %1$s niveau de batterie bas: %2$s + Manque de sommeil: %1$s + Excès de sommeil: %1$s + Sans limite + 5 secondes + 10 secondes + 20 secondes + 30 secondes + 1 minute + 5 minutes + 10 minutes + 30 minutes + + Manque d\'activité: %1$d + Trop d\'activité: %1$d + Mesure cardiaque actuelle / maximum: %1$d / %2$d + Vous avez dormi de %1$s à %2$s + Vous n\'avez pas dormi + Glisser le doigt vers le haut pour débloquer l\'écran du bracelet + Mode nuit + Diminuer la luminosité de l\'écran du bracelet automatiquement lorsqu\'il fait sombre + + Allemand + Italien + Français + Polonais + Koréen + Japonais + + Paramètres des graphiques + Fréquence cardiaque maximum + Fréquence cardiaque minimum + + Ok + + Au coucher du soleil + Watch 9 + Minutes: + Heures: + Secondes: + Régler l\'heure que votre appareil indique actuellement. + Calibrer + Appairage de la Watch 9 + Calibration de la Watch 9 + Support Droite-à-Gauche + Partager les logs + Veuillez garder en tête que les fichiers logs de Gadgetbridge peuvent contenir des tas d\'informations personnelles, incluant entre autre des données relatives à la santé, des identifiants uniques (telles que des adresses MAC), des préférences musicales, etc. Pensez à modifier le fichier et retirer ces informations personnelles avant toute publication sur un rapport de bug public. + Attention! + Pas de données + + Couleur de la LED + + Fréquence FM + Fréquence non-valide + Veuillez introduire une fréquence entre 87.5 et 108.0 + Paramètres de langue et de région From b1b318a18b13eb005348519757f3570f9c707bcb Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 23 Sep 2018 12:00:56 +0200 Subject: [PATCH 0036/1017] Amazfit Bip: Allow flashing latest gps firmware from Mi Fit 3.5.1.1 (Mili_dth.gps) This file seems to be for the Bip2, but firmwares.json also refereces this for the Bip. And it seems to work. --- .../devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java index 17ee1b594..eb1511a83 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java @@ -45,6 +45,11 @@ public class AmazfitBipFirmwareInfo extends HuamiFirmwareInfo { (byte) 0x8c, 0x36, 0x2e, (byte) 0x8c, (byte) 0x9c, 0x08, 0x54, (byte) 0xa6 }; + private static final byte[] GPS_HEADER5 = new byte[]{ + (byte) 0xec, 0x51, 0x73, 0x22 , 0x60 ,0x02 ,0x14, (byte) 0xb7, + (byte) 0xb5, (byte) 0xea, 0x4b, 0x22 , 0x5d, 0x23, (byte) 0xe5, 0x4f + }; + // this is the same as Cor private static final byte[] FW_HEADER = new byte[]{ 0x00, (byte) 0x98, 0x00, 0x20, (byte) 0xA5, 0x04, 0x00, 0x20, (byte) 0xAD, 0x04, 0x00, 0x20, (byte) 0xC5, 0x04, 0x00, 0x20 @@ -123,6 +128,7 @@ public class AmazfitBipFirmwareInfo extends HuamiFirmwareInfo { crcToVersion.put(8784, "9565,dfbd8fa,0,0,"); crcToVersion.put(16716, "9565,dfbd8faf42,0"); crcToVersion.put(54154, "9567,8b05506,0,0,"); + crcToVersion.put(15717, "15974,e61dd16,126"); // font crcToVersion.put(61054, "8"); @@ -141,7 +147,7 @@ public class AmazfitBipFirmwareInfo extends HuamiFirmwareInfo { } return HuamiFirmwareType.RES; } - if (ArrayUtils.startsWith(bytes, GPS_HEADER) || ArrayUtils.startsWith(bytes, GPS_HEADER2) || ArrayUtils.startsWith(bytes, GPS_HEADER3) || ArrayUtils.startsWith(bytes, GPS_HEADER4)) { + if (ArrayUtils.startsWith(bytes, GPS_HEADER) || ArrayUtils.startsWith(bytes, GPS_HEADER2) || ArrayUtils.startsWith(bytes, GPS_HEADER3) || ArrayUtils.startsWith(bytes, GPS_HEADER4) || ArrayUtils.startsWith(bytes, GPS_HEADER5)) { return HuamiFirmwareType.GPS; } if (ArrayUtils.startsWith(bytes, GPS_ALMANAC_HEADER)) { From 659316a40203c6491f928fedd19d0cbdf3e8941f Mon Sep 17 00:00:00 2001 From: mesnevi Date: Sat, 22 Sep 2018 14:11:41 +0000 Subject: [PATCH 0037/1017] Translated using Weblate (Russian) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 525e3401a..e9ab76bf1 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -275,8 +275,8 @@ Расстояние Жизненная активность Шагов сегодня, цель: %1$s - Недопройдено %1$d шагов. - Пройдено на %1$d шагов больше. + Не хватает: %1$d шагов + Пройдено на %1$d шагов больше Не подтверждать передачу данных об активности Если данные об активности не будут переданы на устройство, оно не будет очищено. Полезно, если GB используется с другими приложениями. Хранить данные о деятельности на Mi Band, даже после синхронизации. Полезно, если Mi Band используется совместно с другими приложениями. @@ -641,4 +641,12 @@ Максимальный пульс Минимальный пульс - +Справа налево + Включите, если ваше устройство поддерживает ввод справа налево + Максимальная длина строки при вводе справа налево + Изменяет длину строк, на которые разбит текст при вводе справа налево + + Контекстные формы для арабского языка + Включает поддержку контекстных форм арабского языка + Поддержка ввода справа налево + From e62fe363911c0189bb9df1b4bd573faaea8efa1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Fri, 28 Sep 2018 15:50:11 +0100 Subject: [PATCH 0038/1017] Roidmi 3: Fix and enable support --- .../adapter/GBDeviceAdapterv2.java | 17 ++++++++---- .../devices/roidmi/Roidmi1Coordinator.java | 5 ---- .../devices/roidmi/Roidmi3Coordinator.java | 3 +-- .../devices/roidmi/RoidmiCoordinator.java | 5 ++++ .../gadgetbridge/impl/GBDevice.java | 8 ++++++ .../service/AbstractDeviceSupport.java | 2 +- .../devices/roidmi/Roidmi3Protocol.java | 26 ++++++++++--------- 7 files changed, 41 insertions(+), 25 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 e9b057f05..9c38d606e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -146,7 +146,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter 0) { builder.setAllowPresets(true); - builder.setShowColorShades(false); - builder.setPresets(coordinator.getColorPresets()); + builder.setPresets(presets); } ColorPickerDialog dialog = builder.create(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi1Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi1Coordinator.java index 47351dd01..caba200a6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi1Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi1Coordinator.java @@ -49,9 +49,4 @@ public class Roidmi1Coordinator extends RoidmiCoordinator { public DeviceType getDeviceType() { return DeviceType.ROIDMI; } - - @Override - public int[] getColorPresets() { - return RoidmiConst.COLOR_PRESETS; - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi3Coordinator.java index 10c351844..81fb6b2e9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi3Coordinator.java @@ -36,8 +36,7 @@ public class Roidmi3Coordinator extends RoidmiCoordinator { String name = device.getName(); if (name != null && name.contains("Roidmi Music Blue C")) { - LOG.warn("Found a Roidmi 3, but support is disabled."); - return DeviceType.UNKNOWN; // TODO Roidmi 3 is not working atm + return DeviceType.ROIDMI3; } } catch (Exception ex) { LOG.error("unable to check device support", ex); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiCoordinator.java index 39d7ce76e..2b6fa4295 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiCoordinator.java @@ -132,4 +132,9 @@ public abstract class RoidmiCoordinator extends AbstractDeviceCoordinator { public boolean supportsLedColor() { return true; } + + @Override + public int[] getColorPresets() { + return RoidmiConst.COLOR_PRESETS; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java index 2adc2ae71..766ad799b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java @@ -274,6 +274,7 @@ public class GBDevice implements Parcelable { setFirmwareVersion(null); setFirmwareVersion2(null); setRssi(RSSI_UNKNOWN); + resetExtraInfos(); if (mBusyTask != null) { unsetBusyTask(); } @@ -403,6 +404,13 @@ public class GBDevice implements Parcelable { mExtraInfos.put(key, info); } + /** + * Deletes all the extra infos + */ + public void resetExtraInfos() { + mExtraInfos = null; + } + /** * Ranges from 0-100 (percent), or -1 if unknown * diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index dd969d237..1f995e4ca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -216,7 +216,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { protected void handleGBDeviceEvent(GBDeviceEventLEDColor colorEvent) { Context context = getContext(); - LOG.info("Got event for LED Color"); + LOG.info("Got event for LED Color: #" + Integer.toHexString(colorEvent.color).toUpperCase()); if (gbDevice == null) { return; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi3Protocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi3Protocol.java index a4d6412e7..38d192837 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi3Protocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi3Protocol.java @@ -24,6 +24,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInf import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFmFrequency; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventLEDColor; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.util.GB; public class Roidmi3Protocol extends RoidmiProtocol { @@ -40,7 +41,7 @@ public class Roidmi3Protocol extends RoidmiProtocol { private static final byte[] COMMAND_GET_VOLTAGE = new byte[]{0x06, (byte) 0x81}; private static final byte[] COMMAND_SET_COLOR = new byte[]{0x02, 0x01, 0x00, 0x00, 0x00}; - private static final byte[] COMMAND_SET_FREQUENCY = new byte[]{0x05, (byte) 0x81, 0x09, 0x64}; + private static final byte[] COMMAND_SET_FREQUENCY = new byte[]{0x05, 0x01, 0x09, 0x64}; private static final byte[] COMMAND_DENOISE_ON = new byte[]{0x05, 0x06, 0x12}; private static final byte[] COMMAND_DENOISE_OFF = new byte[]{0x05, 0x06, 0x00}; @@ -58,7 +59,7 @@ public class Roidmi3Protocol extends RoidmiProtocol { return null; } - if (calcChecksum(res) != res[res.length - 2]) { + if (calcChecksum(res) != res[res.length - 1]) { LOG.info("Invalid response checksum"); return null; } @@ -68,21 +69,22 @@ public class Roidmi3Protocol extends RoidmiProtocol { return null; } - if (res[1] != (byte) 0x81) { - LOG.error("Unrecognized response" + GB.hexdump(res, 0, res.length)); - return null; + if (res[2] != (byte) 0x81) { + LOG.warn("Potentially unsupported response: " + GB.hexdump(res, 0, res.length)); } if (res[1] == RESPONSE_VOLTAGE) { String voltageHex = GB.hexdump(res, 3, 2); - float voltage = Float.valueOf(voltageHex) / 10.0f; + float voltage = Float.valueOf(voltageHex) / 100.0f; LOG.debug("Got voltage: " + voltage); GBDeviceEventBatteryInfo evBattery = new GBDeviceEventBatteryInfo(); + evBattery.state = BatteryState.NO_BATTERY; + evBattery.level = GBDevice.BATTERY_UNKNOWN; evBattery.voltage = voltage; return new GBDeviceEvent[]{evBattery}; } else if (res[1] == RESPONSE_COLOR) { - LOG.debug("Got color: " + GB.hexdump(res, 3, 3)); - int color = res[3] << 16 | res[4] << 8 | res[4]; + LOG.debug("Got color: #" + GB.hexdump(res, 3, 3)); + int color = 0xFF000000 | ((res[3] << 16) & 0xFF0000) | ((res[4] << 8) & 0xFF00) | (res[5] & 0xFF); GBDeviceEventLEDColor evColor = new GBDeviceEventLEDColor(); evColor.color = color; return new GBDeviceEvent[]{evColor}; @@ -94,7 +96,7 @@ public class Roidmi3Protocol extends RoidmiProtocol { evFrequency.frequency = frequency; return new GBDeviceEvent[]{evFrequency}; } else { - LOG.error("Unrecognized response" + GB.hexdump(res, 0, res.length)); + LOG.error("Unrecognized response: " + GB.hexdump(res, 0, res.length)); return null; } } @@ -103,9 +105,9 @@ public class Roidmi3Protocol extends RoidmiProtocol { public byte[] encodeLedColor(int color) { byte[] cmd = COMMAND_SET_COLOR.clone(); - cmd[2] = (byte) color; + cmd[2] = (byte) (color >> 16); cmd[3] = (byte) (color >> 8); - cmd[4] = (byte) (color >> 16); + cmd[4] = (byte) color; return encodeCommand(cmd); } @@ -144,7 +146,7 @@ public class Roidmi3Protocol extends RoidmiProtocol { } public byte[] encodeGetVoltage() { - return COMMAND_GET_VOLTAGE; + return encodeCommand(COMMAND_GET_VOLTAGE); } public byte[] encodeDenoise(boolean enabled) { From 6fa2dc04f365a51e4ab315e0b8931746dbc80d1a Mon Sep 17 00:00:00 2001 From: Sebastian Kranz Date: Fri, 28 Sep 2018 19:36:35 +0200 Subject: [PATCH 0039/1017] Setting the signal types is written to the watch now. --- .../devices/zetime/ZeTimeConstants.java | 21 +++++- .../zetime/ZeTimePreferenceActivity.java | 64 +++++++++++++++++++ .../devices/zetime/ZeTimeDeviceSupport.java | 47 ++++++++++++-- app/src/main/res/values/arrays.xml | 4 +- app/src/main/res/xml/zetime_preferences.xml | 2 +- 5 files changed, 130 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index 59ac4be1e..38d6f7e02 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -113,6 +113,16 @@ public class ZeTimeConstants { public static final byte NOTIFICATION_SKYPE = (byte) 0x15; // reminders types public static final byte REMINDER_ALARM = (byte) 0x04; + // signaling types + public static final byte ANTI_LOSS_TYPE = (byte) 0x00; + public static final byte CALL_TYPE = (byte) 0x02; + public static final byte MISSED_CALL_TYPE = (byte) 0x03; + public static final byte SMS_TYPE = (byte) 0x04; + public static final byte SOCIAL_TYPE = (byte) 0x05; + public static final byte EMAIL_TYPE = (byte) 0x06; + public static final byte CALENDAR_TYPE = (byte) 0x07; + public static final byte INACTIVITY_TYPE = (byte) 0x08; + public static final byte LOW_POWER_TYPE = (byte) 0x09; // watch settings public static final String PREF_WRIST = "zetime_wrist"; public static final byte WEAR_ON_LEFT_WRIST = (byte) 0x00; @@ -153,7 +163,16 @@ public class ZeTimeConstants { public static final String PREF_DATE_FORMAT = "zetime_date_format"; public static final String PREF_ALARM_SIGNALING = "zetime_alarm_signaling"; - public static final String PREF_SMS_SIGNALING = "zetime_sms_signaling"; + public static final String PREF_SMS_SIGNALING = "zetime_vibration_profile_sms"; + public static final String PREF_CALL_SIGNALING = "zetime_vibration_profile_incoming_call"; + public static final String PREF_MISSED_CALL_SIGNALING = "zetime_vibration_profile_missed_call"; + public static final String PREF_EMAIL_SIGNALING = "zetime_vibration_profile_generic_email"; + public static final String PREF_SOCIAL_SIGNALING = "zetime_vibration_profile_generic_social"; + public static final String PREF_CALENDAR_SIGNALING = "zetime_vibration_profile_calendar"; + public static final String PREF_INACTIVITY_SIGNALING = "zetime_vibration_profile_inactivity"; + public static final String PREF_LOW_POWER_SIGNALING = "zetime_vibration_profile_lowpower"; + public static final String PREF_ANTI_LOSS_SIGNALING = "zetime_vibration_profile_antiloss"; + public static final String PREF_SHOCK_STRENGTH = "zetime_shock_strength"; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java index 4a10fc592..364a2943c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java @@ -293,6 +293,70 @@ public class ZeTimePreferenceActivity extends AbstractSettingsActivity { return true; } }); + final Preference antiSignaling = findPreference(ZeTimeConstants.PREF_ANTI_LOSS_SIGNALING); + antiSignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_ANTI_LOSS_SIGNALING); + return true; + } + }); + final Preference calendarSignaling = findPreference(ZeTimeConstants.PREF_CALENDAR_SIGNALING); + calendarSignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_CALENDAR_SIGNALING); + return true; + } + }); + final Preference callSignaling = findPreference(ZeTimeConstants.PREF_CALL_SIGNALING); + callSignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_CALL_SIGNALING); + return true; + } + }); + final Preference missedSignaling = findPreference(ZeTimeConstants.PREF_MISSED_CALL_SIGNALING); + missedSignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_MISSED_CALL_SIGNALING); + return true; + } + }); + final Preference emailSignaling = findPreference(ZeTimeConstants.PREF_EMAIL_SIGNALING); + emailSignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_EMAIL_SIGNALING); + return true; + } + }); + final Preference inactivitySignaling = findPreference(ZeTimeConstants.PREF_INACTIVITY_SIGNALING); + inactivitySignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_INACTIVITY_SIGNALING); + return true; + } + }); + final Preference powerSignaling = findPreference(ZeTimeConstants.PREF_LOW_POWER_SIGNALING); + powerSignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_LOW_POWER_SIGNALING); + return true; + } + }); + final Preference socialSignaling = findPreference(ZeTimeConstants.PREF_SOCIAL_SIGNALING); + socialSignaling.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSendConfiguration(ZeTimeConstants.PREF_SOCIAL_SIGNALING); + return true; + } + }); } /** diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index b7a0e38d3..3604e620f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -174,7 +174,15 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { setInactivityAlert(builder); break; case ZeTimeConstants.PREF_SMS_SIGNALING: - setSMSSignaling(builder); + case ZeTimeConstants.PREF_CALL_SIGNALING: + case ZeTimeConstants.PREF_MISSED_CALL_SIGNALING: + case ZeTimeConstants.PREF_EMAIL_SIGNALING: + case ZeTimeConstants.PREF_SOCIAL_SIGNALING: + case ZeTimeConstants.PREF_CALENDAR_SIGNALING: + case ZeTimeConstants.PREF_INACTIVITY_SIGNALING: + case ZeTimeConstants.PREF_LOW_POWER_SIGNALING: + case ZeTimeConstants.PREF_ANTI_LOSS_SIGNALING: + setSignaling(builder, config); break; case ZeTimeConstants.PREF_SHOCK_STRENGTH: setShockStrength(builder); @@ -1773,10 +1781,10 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { sendMsgToWatch(builder, strength); } - private void setSMSSignaling(TransactionBuilder builder) + private void setSignaling(TransactionBuilder builder, String signalingType) { Prefs prefs = GBApplication.getPrefs(); - int signalType = prefs.getInt(ZeTimeConstants.PREF_SMS_SIGNALING, 0); + int signalType = prefs.getInt(signalingType, 0); byte[] signaling = { ZeTimeConstants.CMD_PREAMBLE, @@ -1784,11 +1792,42 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { ZeTimeConstants.CMD_SEND, (byte)0x2, (byte)0x0, - (byte)0x4, + (byte)0x0, (byte)signalType, ZeTimeConstants.CMD_END }; + switch(signalingType) + { + case ZeTimeConstants.PREF_SMS_SIGNALING: + signaling[5] = ZeTimeConstants.SMS_TYPE; + break; + case ZeTimeConstants.PREF_CALL_SIGNALING: + signaling[5] = ZeTimeConstants.CALL_TYPE; + break; + case ZeTimeConstants.PREF_MISSED_CALL_SIGNALING: + signaling[5] = ZeTimeConstants.MISSED_CALL_TYPE; + break; + case ZeTimeConstants.PREF_EMAIL_SIGNALING: + signaling[5] = ZeTimeConstants.EMAIL_TYPE; + break; + case ZeTimeConstants.PREF_SOCIAL_SIGNALING: + signaling[5] = ZeTimeConstants.SOCIAL_TYPE; + break; + case ZeTimeConstants.PREF_CALENDAR_SIGNALING: + signaling[5] = ZeTimeConstants.CALENDAR_TYPE; + break; + case ZeTimeConstants.PREF_INACTIVITY_SIGNALING: + signaling[5] = ZeTimeConstants.INACTIVITY_TYPE; + break; + case ZeTimeConstants.PREF_LOW_POWER_SIGNALING: + signaling[5] = ZeTimeConstants.LOW_POWER_TYPE; + break; + case ZeTimeConstants.PREF_ANTI_LOSS_SIGNALING: + signaling[5] = ZeTimeConstants.ANTI_LOSS_TYPE; + break; + } + sendMsgToWatch(builder, signaling); } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 56a9920cb..b85bbbaae 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -491,7 +491,6 @@ 3 - @string/zetime_signaling_none @string/zetime_signaling_vibrate_once @string/zetime_signaling_vibrate_twice @string/zetime_signaling_vibrate @@ -500,9 +499,9 @@ @string/zetime_signaling_beep @string/zetime_signaling_vibrate_beep_once @string/zetime_signaling_vibrate_beep + @string/zetime_signaling_none - 0 2 4 7 @@ -511,6 +510,7 @@ 11 12 13 + 14 diff --git a/app/src/main/res/xml/zetime_preferences.xml b/app/src/main/res/xml/zetime_preferences.xml index 2f3b22154..653d9bd02 100644 --- a/app/src/main/res/xml/zetime_preferences.xml +++ b/app/src/main/res/xml/zetime_preferences.xml @@ -233,7 +233,7 @@ android:defaultValue="2" android:entries="@array/zetime_signaling_types" android:entryValues="@array/zetime_signaling_types_values" - android:key="zetime_sms_signaling" + android:key="zetime_vibration_profile_sms" android:title="@string/miband_prefs_vibration" android:summary="%s" /> From c203023fea28dd263a447c2197568955bddafad4 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Fri, 28 Sep 2018 22:15:10 +0200 Subject: [PATCH 0040/1017] Update build tools to 3.2.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ea23aab55..e1aec6bd7 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'com.android.tools.build:gradle:3.2.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From c92ed132cfc54acf1d601fe41f4f86ee09abccad Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Fri, 28 Sep 2018 22:17:54 +0200 Subject: [PATCH 0041/1017] Update gradle to 4.10.2 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a69b4079b..5c2db3913 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip From 045c0840e3fb31bc03b8115fa4d3a7d1319ccd23 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sat, 29 Sep 2018 00:01:53 +0200 Subject: [PATCH 0042/1017] Update build-tools to 28.0.2 --- .travis.yml | 2 +- app/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cf293dad1..616bc59d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ android: - tools # The BuildTools version used by your project - - build-tools-27.0.3 + - build-tools-28.0.2 # The SDK version used to compile your project - android-27 diff --git a/app/build.gradle b/app/build.gradle index 9ab629e63..d48ca5237 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,7 +17,7 @@ android { targetCompatibility JavaVersion.VERSION_1_7 } compileSdkVersion 27 - buildToolsVersion "27.0.3" + buildToolsVersion "28.0.2" defaultConfig { applicationId "nodomain.freeyourgadget.gadgetbridge" From 56477efcdfa96e239a3d6b46f5d1b617a1955917 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sat, 29 Sep 2018 21:49:13 +0200 Subject: [PATCH 0043/1017] Specify new path to classes for findbugs after gradle update --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d48ca5237..71251a875 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -143,7 +143,7 @@ task findbugs(type: FindBugs) { effort = "default" reportLevel = "medium" excludeFilter = new File("${project.rootDir}/config/findbugs/findbugs-filter.xml") - classes = files("${project.rootDir}/app/build/intermediates/classes") + classes = files("${project.rootDir}/app/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes") source = fileTree("src/main/java/") classpath = files() reports { From e66d0a2d10883a8d58013bdc586759f8d70bdd00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A6=89=E0=A7=8E=E0=A6=B8=E0=A6=AC=20=E0=A6=B0=E0=A6=BE?= =?UTF-8?q?=E0=A7=9F=28Utsob=20Roy=29?= Date: Tue, 2 Oct 2018 03:04:51 +0600 Subject: [PATCH 0044/1017] Enhancement and Fixes for Bengali Transliteration. (#1263) * Added various fixes and enhancment for Bengali transliteration. * various fixes and enhancment for Bengali transliteration * fixed a coding typo [master] * Boolean lowercase and added .project in .gitignore * Boolean lowercase and added .project in .gitignore * typo fix [master] * fixed negative index error [master] * fixed negative index error [master] * unprinted character fix [master] * enhanced transliteration [master] * lowercased boolean and replaced Integer with int [master] * removed .setting, .classpath and .project and added them to .gitignore too. * bug fix and multilingual testcase [master] --- .gitignore | 3 + .settings/org.eclipse.buildship.core.prefs | 2 + app/src/main/.classpath | 11 --- app/src/main/.project | 33 ------- .../main/.settings/org.eclipse.jdt.core.prefs | 12 --- .../util/BengaliLanguageUtils.java | 88 +++++++++++++++++-- .../gadgetbridge/test/LanguageUtilsTest.java | 9 +- 7 files changed, 93 insertions(+), 65 deletions(-) create mode 100644 .settings/org.eclipse.buildship.core.prefs delete mode 100644 app/src/main/.classpath delete mode 100644 app/src/main/.project delete mode 100644 app/src/main/.settings/org.eclipse.jdt.core.prefs diff --git a/.gitignore b/.gitignore index 9bcb005c7..abeb34c90 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ proguard/ MPChartLib fw.dirs +**/.project +**/.settings +**/.classpath diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000..e8895216f --- /dev/null +++ b/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/app/src/main/.classpath b/app/src/main/.classpath deleted file mode 100644 index 60ab2ffa5..000000000 --- a/app/src/main/.classpath +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/.project b/app/src/main/.project deleted file mode 100644 index f8b13a0fd..000000000 --- a/app/src/main/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Gadgetbridge - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/app/src/main/.settings/org.eclipse.jdt.core.prefs b/app/src/main/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index d17b6724d..000000000 --- a/app/src/main/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,12 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java index 8c91eb7b9..a59acfbe1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java @@ -22,7 +22,7 @@ import java.util.regex.*; // What's the reason to extending LanguageUtils? // Just doing it because already done in the previous code. public class BengaliLanguageUtils extends LanguageUtils { - // Composite Letters. + // Composite Letters. private final static HashMap composites = new HashMap() { { put("ক্ষ", "kkh"); @@ -39,7 +39,25 @@ public class BengaliLanguageUtils extends LanguageUtils { put("্ব", "w"); } }; + // Vowels Only + private final static HashMap vowels = new HashMap() { + { + put("আ", "aa"); + put("অ", "a"); + put("ই", "i"); + put("ঈ", "ii"); + put("উ", "u"); + put("ঊ", "uu"); + put("ঋ", "ri"); + put("এ", "e"); + put("ঐ", "oi"); + put("ও", "o"); + put("ঔ", "ou"); + } + }; + + // Vowels and Hasants private final static HashMap vowelsAndHasants = new HashMap() { { put("আ", "aa"); @@ -149,7 +167,8 @@ public class BengaliLanguageUtils extends LanguageUtils { }; // The regex to extract Bengali characters in nested groups. - private final static String pattern = "(র্){0,1}(([অ-হড়-য়])(্([অ-মশ-হড়-য়]))*)((‍){0,1}(্([য-ল]))){0,1}([া-ৌ]){0,1}|([্ঁঃংৎ০-৯।])| "; + private final static String pattern = "(র্){0,1}(([অ-হড়-য়])(্([অ-মশ-হড়-য়]))*)((‍){0,1}(্([য-ল]))){0,1}([া-ৌ]){0,1}|([্ঁঃংৎ০-৯।])|(\\s)"; + private final static Pattern bengaliRegex = Pattern.compile(pattern); private static String getVal(String key) { @@ -173,7 +192,15 @@ public class BengaliLanguageUtils extends LanguageUtils { Matcher m = bengaliRegex.matcher(txt); StringBuffer sb = new StringBuffer(); + String lastChar = ""; + boolean lastHadComposition = false; + boolean lastHadKaar = false; + boolean nextNeedsO = false; + int lastHadO = 0; while (m.find()) { + boolean thisNeedsO = false; + boolean changePronounciation = false; + boolean thisHadKaar = false; String appendableString = ""; String reff = m.group(1); if (reff != null) { @@ -200,6 +227,10 @@ public class BengaliLanguageUtils extends LanguageUtils { g = g + 1; } } + if (m.group(2) != null && m.group(2).equals("ক্ষ")) { + changePronounciation = true; + thisNeedsO = true; + } int g = 6; while (g < 10) { String key = getVal(m.group(g)); @@ -209,16 +240,24 @@ public class BengaliLanguageUtils extends LanguageUtils { } g = g + 1; } + String phala = m.group(8); + if (phala != null && phala.equals("্য")) { + changePronounciation = true; + thisNeedsO = true; + } + String jukto = m.group(4); + if (jukto != null) { + thisNeedsO = true; + } String kaar = m.group(10); if (kaar != null) { String kaarStr = letters.get(kaar); if (kaarStr != null) { appendableString = appendableString + kaarStr; } - } else if (appendableString.length() > 0 && !vowelsAndHasants.containsKey(m.group(0))) { - // Adding 'a' like ITRANS if no vowel is present. - // TODO: Have to add it dynamically using Bengali grammer rules. - appendableString = appendableString + "a"; + if (kaarStr.equals("i") || kaarStr.equals("ii") || kaarStr.equals("u") || kaarStr.equals("uu")) { + changePronounciation = true; + } } String singleton = m.group(11); if (singleton != null) { @@ -227,6 +266,9 @@ public class BengaliLanguageUtils extends LanguageUtils { appendableString = appendableString + singleStr; } } + if (changePronounciation && lastChar.equals("a")) { + sb.setCharAt(sb.length() - 1, 'o'); + } String others = m.group(0); if (others != null) { @@ -234,7 +276,41 @@ public class BengaliLanguageUtils extends LanguageUtils { appendableString = appendableString + others; } } + String whitespace = m.group(12); + if (nextNeedsO && kaar == null && whitespace == null && !vowels.containsKey(m.group(0))) { + appendableString = appendableString + "o"; + lastHadO++; + thisNeedsO = false; + } + + if (((kaar != null && lastHadO > 1) || whitespace != null) && !lastHadKaar && sb.length() > 0 + && sb.charAt(sb.length() - 1) == 'o' && !lastHadComposition) { + sb.deleteCharAt(sb.length() - 1); + lastHadO = 0; + } + nextNeedsO = false; + if (thisNeedsO && kaar == null && whitespace == null && !vowels.containsKey(m.group(0))) { + appendableString = appendableString + "o"; + lastHadO++; + } + if (appendableString.length() > 0 && !vowelsAndHasants.containsKey(m.group(0)) && kaar == null) { + nextNeedsO = true; + } + if (reff != null || m.group(4) != null || m.group(6) != null) { + lastHadComposition = true; + } else { + lastHadComposition = false; + } + if (kaar != null) { + lastHadKaar = true; + } else { + lastHadKaar = false; + } m.appendReplacement(sb, appendableString); + lastChar = appendableString; + } + if (!lastHadKaar && sb.length() > 0 && sb.charAt(sb.length() - 1) == 'o' && !lastHadComposition) { + sb.deleteCharAt(sb.length() - 1); } m.appendTail(sb); return sb.toString(); diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/LanguageUtilsTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/LanguageUtilsTest.java index c5a780189..d648116ba 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/LanguageUtilsTest.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/LanguageUtilsTest.java @@ -57,11 +57,14 @@ public class LanguageUtilsTest extends TestBase { assertEquals("Farsi transiteration failed", farsiExpected, farsiActual); } + @Test public void testStringTransliterateBengali() throws Exception { // input with cyrillic and diacritic letters - String[] inputs = { "অনিরুদ্ধ", "বিজ্ঞানযাত্রা চলছে চলবে।", "আমি সব দেখেশুনে ক্ষেপে গিয়ে করি বাঙলায় চিৎকার!" }; - String[] outputs = { "aniruddha", "biggaanaJaatraa chalachhe chalabe.", - "aami saba dekheshune kkhepe giye kari baangalaaya chitkaara!" }; + String[] inputs = { "অনিরুদ্ধ", "বিজ্ঞানযাত্রা চলছে চলবে।", "আমি সব দেখেশুনে ক্ষেপে গিয়ে করি বাঙলায় চিৎকার!", + "আমার জাভা কোড is so bad! কী আর বলবো!" }; + String[] outputs = { "oniruddho", "biggaanJaatraa cholchhe cholbe.", + "aami sob dekheshune kkhepe giye kori baanglaay chitkaar!", + "aamaar jaabhaa koD is so bad! kii aar bolbo!"}; String result; From a399b4be451ee9586e4287018090b55a3436c93c Mon Sep 17 00:00:00 2001 From: postsorino Date: Sun, 23 Sep 2018 13:29:15 +0000 Subject: [PATCH 0045/1017] Translated using Weblate (Greek) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/el/ --- app/src/main/res/values-el/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index e279ba533..9b4d623da 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -686,7 +686,7 @@ "Από δεξιά προς αριστερά " "Ενεργοποιήστε αυτή την επιλογή αν η συσκευή σας δεν έχει υποστήριξη για γλώσσες που γράφονται από δεξιά " Μέγιστο μήκος γραμμής στις γλώσσες που γράφονται από δεξιά - Όταν η γραφή από δεξιά είναι ενεργοποιημένη , το κείμενο χωρίζεται σε γραμμές. Αλλάξτε αυτή τη τιμή αν οι γραμμές είναι πολύ μακριές ή κοντές. + Μακραίνει ή κονταίνει τις γραμμές στις γλώσσες που γράφονται από δεξιά %1$s χαμηλή μπαταρία %1$s χαμηλή μπαταρία: %2$s From 2c0615e0dcbe132aacb84074d7ac974537fb1337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gilles=20=C3=89milien=20MOREL?= Date: Mon, 24 Sep 2018 17:34:58 +0000 Subject: [PATCH 0046/1017] Translated using Weblate (French) Currently translated at 95.3% (551 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fr/ --- app/src/main/res/values-fr/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b141f49fb..f8f8f1d35 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -10,16 +10,16 @@ Suivi du sommeil (ALPHA) Retrouver votre appareil perdu Prendre une capture d\'écran - Déconnexion + Déconnecter Supprimer l’appareil Supprimer %1$s - Ceci va supprimer l’appareil et toutes les données associées ! + Ceci va supprimer l’appareil et toutes les données associées ! Ouvrir le tiroir de navigation Fermer le tiroir de navigation Presser longuement l\'icône pour déconnecter Déconnexion Connexion - Capture d\'écran de l\'appareil + Capturer l\'écran de l\'appareil Déboguer Gestionnaire d\'application @@ -51,7 +51,7 @@ Ce micrologiciel n\'a pas été testé et peut ne pas être compatible avec Gadgetbridge. \n \nIl n\'est PAS conseillé de le flasher sur votre Mi Band ! - Si vous désirez continuer et que tout fonctionne correctement par la suite, veuillez en informer les développeurs de Gadgetbridge pour demander l\'ajout du micrologiciel %s à leur liste + Si vous désirez continuer et que tout fonctionne correctement par la suite, veuillez en informer les développeurs de Gadgetbridge pour demander l\'ajout du micrologiciel %s à leur liste. Paramètres Paramètres généraux From 81ed44a7078a7c96ddbc3e0ae5a5b1fbf3a7c9ec Mon Sep 17 00:00:00 2001 From: Full Name Date: Tue, 25 Sep 2018 15:54:25 +0000 Subject: [PATCH 0047/1017] Translated using Weblate (Czech) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/cs/ --- app/src/main/res/values-cs/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 4e7a1d5ac..5c7c27a1f 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -550,9 +550,9 @@ \nNETESTOVÁNO, MŮŽE POŠKODIT VAŠE ZAŘÍZENÍ, POKRAČUJTE NA VLASTNÍ NEBEZPEČÍ! Minimální doba mezi upozorněními Zprava doleva - Povolte, podporuje-li vaše zařízení jazyky zprava doleva + Povolte, nepodporuje-li vaše zařízení jazyky zprava doleva Maximální délka řádku pro zprava doleva - Je-li zapnuta podpora pro zleva doprava, text je rozdělen do řádků. Změňte tuto hodnotu jsou-li řádky příliš dlouhé/krátké. + Prodlužuje/zkracuje text řádků jazyků zleva doprava ID115 nastavení Orientace displeje From 027a7a44761018f188ccb35ad200efc845c59c4a Mon Sep 17 00:00:00 2001 From: youzhiran <2668760098@qq.com> Date: Sat, 29 Sep 2018 11:34:51 +0000 Subject: [PATCH 0048/1017] Translated using Weblate (Chinese (Simplified)) Currently translated at 74.7% (432 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index dd1509100..6d1d02325 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -36,8 +36,8 @@ 停用 打开心率检测 关闭心率检测 - 启用系统天气预报应用 - 禁用系统天气预报应用 + 启用系统天气应用 + 禁用系统天气应用 安装天气通知应用 配置 移至顶部 @@ -539,4 +539,13 @@ HPlus 选择导出位置 Gadgetbridge 通知 - +更换LED灯颜色 + 调整FM频率 + 校准设备 + + + 屏蔽所有通知 + 开启所有通知 + + + From 0b2009dbc34ed5140b8cd07fdb9f2755c28da168 Mon Sep 17 00:00:00 2001 From: Dreamwalker Date: Sun, 30 Sep 2018 03:06:45 +0000 Subject: [PATCH 0049/1017] Translated using Weblate (Korean) Currently translated at 88.9% (514 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ko/ --- app/src/main/res/values-ko/strings.xml | 108 +++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index c8569a3b1..41505922f 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -158,16 +158,16 @@ 설치 상태를 파악하는 동안 기다려주세요... 기기의 배터리 잔량이 적습니다! %1$s 배터리 남음: %2$s%% - 마지막 충전: %s \n + 마지막 충전: %s 충전 횟수: %s 당신의 수면 - 주간 걸음 수 + "주간 걸음 수 " 당신의 활동과 수면 - 펌웨어 업데이트 중... + 펌웨어 업데이트 중… 파일을 설치할 수 없습니다. 기기가 준비되어 있지 않습니다. %1$s: %2$s %3$s 호환 버전 - 테스트를 거치지 않은 버전 + 테스트를 거치지 않은 버전! 기기에 연결: %1$s Pebble 펌웨어 %1$s 올바른 하드웨어 리비전 @@ -371,7 +371,7 @@ 총 분수 분당 걸음 수 - 주간 수면 시간 + "주간 수면 시간 " 오늘의 수면, 목표 수면 시간: %1$s 칼로리 거리 @@ -556,4 +556,100 @@ 설정 Alipay - + LED 색상 변경 + FM 주파수 변경 + 디바이스 조정하기 + + + 모든 알람 블랙리스트 + 모든 알람을 위한 화이트리스트 + + + %s 펌웨어를 Mi Band 3에 설치하려고 합니다. +\n +\n.res 파일을 먼저 설치하고 .fw 파일을 설치하십시오. .fw 파일이 설치된 이후에 기기가 재시작될 것입니다. +\n +\n기존의 .res 파일과 설치하려는 .res 파일이 동일하다면, .res 파일을 다시 설치할 필요는 없습니다. +\n +\n테스트되지 않은 기능입니다. 기기가 고장날 가능성이 있습니다. 본인의 책임 하에 진행하십시오! + 알람간 최소 시간 + 오른쪽에서 왼쪽으로 + 만약 당신의 디바이스에서 좌우 언어가 보이지 않는다면 이것을 활성화하세요 + 좌우 최대 라인 길이 + 텍스트 좌우 길이 조정은 분리된다 + + 날씨 + "GATT client 만 " + "이것은 Pebble2 만의 것이고 실험적입니다. 만약 연결 문제가 있다면 시도해보세요 " + ID115 설정 + 화면 방향 + + 자동 추출 + 자동 추출 활성화 + 추출 장소 + 추출 간격 + "매 %d 시간 마다 추출 " + + 활동 데이터 자동으로 가져오기 + 가져 오기는 화면 잠금 해제시 발생합니다. 잠금 메커니즘이 설정된 경우에만 작동합니다! + 가져오는 최소 시간 + 매 %d 분마다 데이터 가져오기 + + Mi Band 2 설정 + Mi Band 3 설정 + Amazfit Cor 설정s + 수평 + 수직 + 시계가 진동하면 장치를 흔들거나 버튼을 누르십시오. + + %1$s 배터리 부족 + %1$s 배터리 부족: %2$s + 데이터베이스 추출 실패! 당신의 설정을 확인해주세요. + 수면 부족: %1$s + 늦잠: %1$s + 제한 없음 + 5초 + 10초 + 20초 + 30초 + 1분 + 5분 + 10분 + 30분 + + 걸음수 부족: %1$d + 걸음수 초과 : %1$d + 현재 / 최대 심박수: %1$d / %2$d + 당신의 수면시간은 %1$s 부터 %2$s 까지 + 잠을 자지 않았습니다 + 밴드 스크린 언락 + 슬어올려 밴드 스크린 화면 잠금 해제 + 야간 모드 + 밤이 되면 자동으로 밴드 밝기 감소 + + 노르웨이 + 스페인어 + 러시아어 + 독일어 + 이탈리아어 + 프랑스어(불어) + 폴란드어 + 한국어 + 일본어 + + 차트 설정 + 최대 심박수 + 최소 심박수 + + 확인 + + 켜기 + 일몰 + MyKronoz ZeTime + "Watch 9 " + "Roidmi " + "Roidmi 3 " + + 알람 + 언어 및 지역 설정 + From f59f972f2bfd6ec7f0ad54ded7d3592dcf274536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sun, 30 Sep 2018 11:11:09 +0000 Subject: [PATCH 0050/1017] Translated using Weblate (English) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/en/ --- app/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 91dec54a0..2b15468ad 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -527,7 +527,7 @@ Overwrite Cancel Delete - Ok + OK Vibration @@ -655,7 +655,7 @@ Enable this to support contextual Arabic Right To Left Support Share log - Please keep in mind Gadgetbridge log files may contain lots of personal information, including but not limited to health data, unique identifiers (such as a device MAC address), music preferences, etc. Consider editing the file and removing this information before sending the file to a public issue report. + Please keep in mind Gadgetbridge logs files that may contain lots of personal info, including but not limited to health data, unique identifiers (such as a device\'s MAC address), music preferences, etc. Consider editing the file and removing this info before sending the file to a public issue report. Warning! No data From f513dad014b44a61a47bf103d3ec90a407ce6e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sun, 30 Sep 2018 11:10:23 +0000 Subject: [PATCH 0051/1017] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nb_NO/ --- app/src/main/res/values-nb-rNO/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 600be9e8a..d14f24a29 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -663,7 +663,7 @@ OK Del logg - Ha i minnet at Gadgetbridge-loggfiler kan inneholde mye personlig informasjon, inkludert, og ikke begrenset til helsedata, unike indetifikatorer (som enhetens MAC-adresse), musikkpreferanser, osv. Overvei å redigere filen for fjerning av denne infoen før du sender filen til som offentlig feilrapport. + Ha i minnet at Gadgetbridge-loggfiler kan inneholde mye personlig info, inkludert, og ikke begrenset til helsedata, unike identifikatorer (som enhetens MAC-adresse), musikkpreferanser, osv. Overvei å redigere filen for fjerning av denne info-en før du sender filen til som offentlig feilrapport. Advarsel! Endre LED-farge Endre FM-frekvens @@ -676,9 +676,9 @@ Ugyldig frekvens Skriv inn en frekvens mellom 87.5 og 108.0 Høyre-til-venstre - Skru på dette hvis din enhet ikke kan vise høyre til venstre-språk. + Skru på dette hvis din enhet ikke kan vise høyre til venstre-språk Maksimal linjelengde for høyre-til-venstre - Strekker eller korter ned linjene høyre-til-venstre tekst inndeles i. + Strekker eller korter ned linjene høyre-til-venstre tekst inndeles i %1$s batteri snart tomt %1$s batteri snart tomt: %2$s From 099389a7f9bb0954632ae894109d9a88669ac5f6 Mon Sep 17 00:00:00 2001 From: hr-sales Date: Wed, 3 Oct 2018 16:29:39 +0000 Subject: [PATCH 0052/1017] Translated using Weblate (Portuguese (Brazil)) Currently translated at 45.1% (261 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/pt_BR/ --- app/src/main/res/values-pt-rBR/strings.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index a6b89a5b4..406df3794 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -7,7 +7,7 @@ Sair Sincronizar Monitor de sono (ALPHA) - Buscando dispositivo desconectado + Buscar dispositivo desconectado Print da tela Desconectar Apagar dispositivo @@ -420,4 +420,6 @@ Ativar botão Ativar vibração Notificações - Gadgetbridge - +Alterar cor do LED + Alterar frequência FM + From 93b12c2f6ebcc4f2b125315602b9d2e026f5c3a2 Mon Sep 17 00:00:00 2001 From: postsorino Date: Mon, 8 Oct 2018 19:25:48 +0000 Subject: [PATCH 0053/1017] Translated using Weblate (Greek) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/el/ --- app/src/main/res/values-el/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 9b4d623da..6c1aaf839 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -668,7 +668,7 @@ Λειτουργία \"νύχτας\" Μείωση φωτεινότητας της οθόνης του Mi band 3 κατά τη διάρκεια της νύχτας - Οκ + ΟΚ Στη δύση του ηλίου "Roidmi " From 06d3d458741611a30eb22e936b114f2aa357d562 Mon Sep 17 00:00:00 2001 From: Hirnchirurg Date: Mon, 8 Oct 2018 20:41:16 +0000 Subject: [PATCH 0054/1017] Translated using Weblate (German) Currently translated at 92.5% (535 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/de/ --- app/src/main/res/values-de/strings.xml | 65 ++++++++++++++++++++------ 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 620b4618f..6639802a7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -45,15 +45,15 @@ Blockierte Kalenderbenachrichtigungen FW/App Installer - Es soll die Firmware %s anstelle der aktuell installierten Version auf das Mi Band gespielt werden. + Es soll die Firmware %s anstelle der aktuell installierten Version auf das Mi Band installiert werden. Es sollen die Firmwares %1$s und %2$s anstelle der aktuell installierten Versionen auf das Mi Band gespielt werden. Diese Firmware ist getestet worden und ist mit Gadgetbridge kompatibel. Diese Firmware ist nicht getestet und könnte inkompatibel mit Gadgetbridge sein.\n\nEs wird nicht empfohlen, sie auf dem Mi Band zu installieren! - Wenn du dennoch fortfahren möchtest und das Gerät anschliessend korrekt funktioniert, melde bitte den Gadgetbridge Entwicklern, dass diese Firmwareversion %s funktioniert + Wenn du dennoch fortfahren möchtest und das Gerät anschliessend korrekt funktioniert, melde bitte den Gadgetbridge-Entwicklern, dass diese Firmwareversion %s funktioniert Einstellungen Allgemeine Einstellungen - Verbinde, wenn Bluetooth eingeschaltet wird + Verbinde mit Gadgetbridge, wenn Bluetooth eingeschaltet wird Automatisch starten Verbindung automatisch wiederherstellen Bevorzugter Audioplayer @@ -130,7 +130,7 @@ Benachrichtigungsprotokoll erzwingen Diese Option erzwingt das neuste Benachrichtigungsprotokoll abhängig von der Firmwareversion. NUR EINSCHALTEN, WENN DU WEISST, WAS DU TUST! Ungetestete Features freischalten - Schaltet ungetetestete Features frei. NUR EINSCHALTEN, WENN DU WEISST WAS DU TUST! + Schaltet ungetestete Features frei. NUR EINSCHALTEN, WENN DU WEISST WAS DU TUST! BLE immer bevorzugen Nutze den experimentellen LE support für alle Pebbles anstelle von klassischem BT. Setzt voraus, dass die \"Pebble LE\" gekoppelt wird, nachdem die nicht-LE Pebble einmal verbunden war. Pebble 2/LE GATT MTU Limit @@ -285,15 +285,15 @@ Live Aktivität Schritte heute, Ziel: %1$s Transfer von Aktivitätsdaten nicht bestätigen (kein ACK) - Wenn der Transfer der Aktivitätsdaten nicht bestätigt wird, werden die Daten nicht auf dem Mi Band gelöscht. Das ist sinnvoll, wenn neben Gadgetbridge noch andere Apps auf das Mi Band zugreifen. - Aktivitätsdaten verbleiben auf dem Mi Band, auch nach der Synchronisierung. Hilfreich, wenn das Mi Band mit weiteren Apps verwendet wird. + Wenn der Transfer der Aktivitätsdaten nicht bestätigt wird, werden die Daten nicht auf dem MiBand gelöscht. Das ist sinnvoll, wenn neben Gadgetbridge noch andere Apps auf das MiBand zugreifen. + Aktivitätsdaten verbleiben auf dem MiBand, auch nach der Synchronisierung. Hilfreich, wenn das MiBand mit weiteren Apps verwendet wird. Benutze Modus mit niedriger Latenz für Firmware-Updates Dies kann bei Geräten helfen, bei denen Firmwareupdates fehlschlagen Schritteverlauf Akt. Schritte pro Minute Schritte insgesamt Verlauf Schritte pro Minute - Starte Deine Aktivität + Starte deine Aktivität Aktivität Leichter Schlaf Tiefschlaf @@ -306,7 +306,7 @@ Wecker für zukünftige Ereignisse vormerken Verwende den Herzfrequenzsensor, um die Schlaferkennung zu verbessern Zeitausgleich in Stunden (um den Schlaf von Schichtarbeitern zu erkennen) - Mi2: Datumsformat + Datumsformat Zeit Zeit & Datum Benachrichtigungen bei Schrittziel @@ -345,7 +345,7 @@ Puls Puls Rohdaten in der Datenbank speichern - Wenn eingeschaltet, werden Daten so wie sie eingehen für eine spätere analyse gespeichert. Achtung: Die Datenbank wird dadurch größer! + Wenn eingeschaltet, werden Daten so wie sie eingehen für eine spätere Analyse gespeichert. Achtung: Die Datenbank wird dadurch grösser! Datenbankverwaltung Datenbankverwaltung Die Datenbankoperationen verwenden den folgenden Pfad auf dem Gerät. \nDieser Pfad ist von anderen Android-Apps und ihrem Computer aus zugreifbar. \nSie finden die exportierte Datenbank hier (bzw. legen die zu importierende dort ab): @@ -353,7 +353,7 @@ Kann nicht auf den Exportpfad zugreifen. Bitte die Entwickler kontaktieren. Exportiert nach: %1$s Fehler beim Exportieren der DB: %1$s - Fehler beim Exlortieren der Einstellungen: %1$s + Fehler beim Exportieren der Einstellungen: %1$s Daten importieren? Wirklich die aktuelle Datenbank überschreiben? Alle aktuellen Aktivitätsdaten (sofern vorhanden) gehen verloren. Import erfolgreich. @@ -374,7 +374,7 @@ Vibration Pebble-Kopplung - Ein Kopplungsdialog sollte auf dem Android-Gerät aufpoppen. Falls das nicht passiert, schau in die Benachrichtigungen und akzeptiere die Kopplungsanfrage. Akzeptiere danach die Kopplungsanfrage auf Deiner Pebble + Ein Kopplungsdialog sollte auf dem Android-Gerät erscheinen. Falls das nicht passiert, schau in die Benachrichtigungen und akzeptiere die Kopplungsanfrage. Akzeptiere danach die Kopplungsanfrage auf deiner Pebble Stelle sicher, dass dieses Skin in der Wetter-App aktiviert ist, damit du Wetterdaten auf deine Pebble erhältst. \n\nKeine Konfiguration nötig. \n\nDu kannst die System-Wetter-App deiner Pebble im App-Management aktivieren. \n\nUnterstützte Watchfaces werden die Wetterdaten automatisch anzeigen. Bluetooth-Kopplung aktivieren Deaktiviere dies, falls du Probleme beim Verbinden hast @@ -387,7 +387,7 @@ Gefunden! Mi2: Uhrzeitformat Installiere Version %1$s vor dem Installieren der Firmware! - Text Benachrichtigung + Text-Benachrichtigung = 1.0.1.28 und installiertes Mili_pro.ft* benötigt.]]> Aus Aus @@ -414,7 +414,7 @@ Aktion bei Tastendruck Bestimmte Aktion bei Tastendruck auf dem Mi Band 2 Anzahl der Tastendrücke, die einen Broadcast auslöst - Zu Sendende Broadcast-Nachricht + Zu sendende Broadcast-Nachricht Aktiviere Tastenaktion Aktiviere Aktion bei einer bestimmten Anzahl an Tastendrücken Aktiviere Vibration @@ -453,7 +453,7 @@ stündlich automatisch - Web View Aktivität + Web-View Aktivität Wetter Firmware @@ -571,4 +571,41 @@ Koreanisch Japanisch + LED Farbe wechseln + FM Frequenz wechseln + Minimale Zeit zwischen den Benachrichtigungen + Von rechts nach links + Dies anschalten, wenn dein Gerät keine Sprachen von rechts nach links anzeigen kann + Nur GATT-Client + Bildschirmausrichtung + + Minimale Zeit zwischen den Abrufen + Alle %d Minuten abrufen + + %1$s Batterie gering + Kein Limit + 5 Sekunden + 10 Sekunden + 20 Sekunden + 30 Sekunden + 1 Minute + 5 Minuten + 10 Minuten + 30 Minuten + + Fehlende Schritte: %1$d + Überschritte: %1$d + Aktueller / Maximaler Puls: %1$d / %2$d + MiBand-Bildschirm entsperren + Wische nach oben, um den Bildschirm vom MiBand zu entriegeln. + Nachtmodus + Niedrigere MiBand-Bildschirmhelligkeit nachts automatisch einstellen + + Diagrammeinstellungen + Maximaler Puls + Minimaler Puls + + Akzeptieren + + Bei Sonnenuntergang From cbf3d7c2b3d8c407c062d18e180ce2ce42cf2e54 Mon Sep 17 00:00:00 2001 From: Full Name Date: Tue, 16 Oct 2018 08:34:53 +0000 Subject: [PATCH 0055/1017] Translated using Weblate (Czech) Currently translated at 100.0% (578 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/cs/ --- app/src/main/res/values-cs/strings.xml | 38 ++++++++++++++------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 5c7c27a1f..1528e95c8 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -107,8 +107,8 @@ Povolit přístup třetích stran k aplikaci Android Povolit experimentální podporu pro aplikace Androidu přes PebbleKit Východ a západ slunce - Zasílat časy východu a západu slunce podle umístění do Pebble časové osi - Odstraňovat skryté notifikace automaticky + Zasílat časy východu a západu slunce podle umístění do časové osy Pebble + Automaticky odstraňovat skryté notifikace Notifikace budou z Pebble odstraněny automaticky, pokud byly skryty na zařízení s Androidem Soukromý režim Běžné notifikace @@ -149,7 +149,7 @@ (neznámé) Test Test notifikací - Toto je notifikace z Gadgetbridge + Toto je testovací notifikace z Gadgetbridge. Diakritika: ěščřžýáíéúů BT není podporován. BT je vypnutý. Dotkněte se zařízení pro App Manager @@ -188,8 +188,8 @@ Muž Žena Jiný - Vlevo - Vpravo + Levá + Pravá Data uživatele nejsou platná, nyní používám vzorová. Když Mi Band zavibruje a blikne, dotkněte se jej několikrát po sobě. Instalovat @@ -223,7 +223,7 @@ Navigace Sociální sítě Najit ztracené zařízení - Zrušit pro zastavení vibrací. + Zastavit vibrací. Vaše aktivita Nastavit buzení Nastavit buzení @@ -326,13 +326,15 @@ Pokud je zatrženo, tak jsou data uložena v původní podobě pro pozdější vyhodnocení. Databáze bude v tom případě větší! Správa databáze Správa databáze - Operace s databází použití následující cestu v zařízení. \nTato cesta je dostupní pro ostatní aplikace Androidu a váš počítač. \nExportovanou databázi (nebo místo pro importovanou databázi) naleznete tady: + Operace s databází použijí následující cestu v zařízení. +\nTato cesta je dostupná pro ostatní aplikace Androidu a váš počítač. +\nExportovanou databázi (nebo místo pro importovanou databázi) naleznete zde: Smazat původní databázi Nelze přistoupit na zadanou cestu. Kontaktujte vývojáře. Exportováno do: %1$s Chyba při exportu DB: %1$s Importovat data? - Opravdu chcete přepsat aktuální databázi? Všechna uložená data o aktivitě se ztratí. + Opravdu chcete přepsat aktuální databázi\? Všechna uložená data aktivit budou ztracena. Importováno. Chyba při importu DB: %1$s Smazat data o aktivitách? @@ -368,7 +370,7 @@ Skrýť číslo, ale zobrazit jméno Zakázané kalendáře - Časová os Pebble + Časová osa Pebble Synchronizace kalendáře Odesílat události kalendáře na časovou osu @@ -389,7 +391,7 @@ Nerušit Náramek nebude přijímat upozornění, pokud je aktivní režim Nerušit Upozornění na nečinnost - Náramek zavibruje, když budete zadaný čas bez pohybu + Náramek zavibruje po určité době neaktivity Limit času bez pohybu (v minutách) Vypnutí upozornění na nečinnost během zadaného časového intervalu Od @@ -467,7 +469,7 @@ Export databáze selhal! Zkontrolujte nastavení. Automaticky Zjednodušená Čínština - Tradiční Čísština + Tradiční Čínština Angličtina Španělština @@ -537,8 +539,8 @@ Kalibrovat zařízení - Seznam všech zakázaných upozornění - Seznam všech povolených upozornění + Zakázat všechny aplikace + Povolit všechny aplikace Chystáte se nainstalovat firmvér %s do vašeho Mi Band 3. @@ -562,9 +564,9 @@ Minimální doba mezi synchronizacemi Synchronizovat každých %d minut - Mi Band 2 nastavení - Mi Band 3 nastavení - Amazfit Cor nastavenís + Nastavení Mi Band 2 + Nastavení Mi Band 3 + Nastavení Amazfit Cors Na šířku Na výšku Po zavibrování stiskněte tlačítko, nebo se zařízením zatřeste. @@ -588,7 +590,7 @@ Aktuální / Maximální tepová frekvence: %1$d / %2$d Spánek od %1$s do %2$s Bez spánku - Odemčení obrazovky zařízení + Odemknutí obrazovky zařízení Přejeďte prstem pro odemčení obrazovky zařízení Noční režim Nižší automatická intenzita displeje v noci @@ -632,7 +634,7 @@ Kalibrace Watch 9 Kontextuální Arabština Zapnout podporu pro kontextuální arabštinu - Podpora zprava doleva + Podpora jazyků zprava doleva Sdílet záznam Prosím nezapomeňte, že ladící záznamy Gadgetbridge mohou obsahovat osobní informace, zahrnující například zdravotní data, identifikátory (MAC adresu), hudební preference a podobně. Tyto informace můžete vymazat před odesláním souboru do veřejného reportu. Upozornění! From 24afaa8b44f92446453a5f015fba9f12feb69d74 Mon Sep 17 00:00:00 2001 From: WaldiS Date: Sat, 20 Oct 2018 12:50:12 +0000 Subject: [PATCH 0056/1017] Translated using Weblate (Polish) Currently translated at 51.3% (297 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/pl/ --- app/src/main/res/values-pl/strings.xml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d610f46d8..c2c52a793 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -7,7 +7,7 @@ Zakończ Synchronizuj Monitor snu (ALPHA) - Odnajdź zagubione urządzenie + Znajdź zgubione urządzenie Zrób zrzut ekranu Rozłącz Usuń urządzenie @@ -272,15 +272,15 @@ Tworzenie zrzutu ekranu urządzenia - Aktywuj systemową aplikację pogodową - Dezaktywuj systemową aplikację pogodową - Zainstaluj powiadomienia pogodowe + Aktywuj Systemową Aplikację Pogody + Dezaktywuj Systemową Aplikację Pogody + Zainstaluj aplikację Powiadomienia o pogodzie Czarna lista kalendarzy Uruchom automatycznie Ukryj powiadomienia z Gadgetbridge - Ikona na pasku stanu i powiadomienia na zablokowanym ekranie wyświetlają się - Ikona na pasku stanu i powiadomienia na zablokowanym ekranie są ukryte + "Ikona na pasku stanu i powiadomienia pokazują się na zablokowanym ekranie " + Ikona na pasku stanu i powiadomienia jest ukryta na zablokowanym ekranie Niechciane powiadomienia są wyłączone w tym trybie Transliteracja @@ -408,4 +408,6 @@ Przesuń tekst powiadomienia poza ekran Spróbuj uzyskać obecną lokalizację podczas biegu, używaj zapisanej lokalizacji jako rezerwowej + Zmień kolor diody LED + Zmień częstotliwość FM From cc3271ad146cbf3313e6c6f87c976f88fc42120b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=BCydar?= Date: Sat, 20 Oct 2018 12:58:54 +0000 Subject: [PATCH 0057/1017] Translated using Weblate (Polish) Currently translated at 51.3% (297 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/pl/ --- app/src/main/res/values-pl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index c2c52a793..5ef1591a3 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -58,7 +58,7 @@ Rozmowy telefoniczne SMS Wiadomości Pebble - Obsługa ogólnych powiadomień + Obsługa powiadomień generycznych ...także gdy ekran jest włączony Nie przeszkadzać Zawsze From 6e731885fd3e0fe3d46434677f664653d75df392 Mon Sep 17 00:00:00 2001 From: WaldiS Date: Sat, 20 Oct 2018 12:59:00 +0000 Subject: [PATCH 0058/1017] Translated using Weblate (Polish) Currently translated at 53.4% (309 of 578 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/pl/ --- app/src/main/res/values-pl/strings.xml | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 5ef1591a3..de1874c64 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -58,7 +58,7 @@ Rozmowy telefoniczne SMS Wiadomości Pebble - Obsługa powiadomień generycznych + Ogólna obsługa powiadomień ...także gdy ekran jest włączony Nie przeszkadzać Zawsze @@ -71,14 +71,14 @@ Ustawienia programisty Adres Mi Band Ustawienia Pebble - Monitory aktywności + Monitorowanie aktywności Preferowany monitor aktywności Synchronizuj Pebble Health Synchronizuj Misfit Synchronizuj Morpheuz Zezwól zewnętrznym aplikacjom Android na dostęp - Włącz eksperymentalną obsługę aplikacji Android przez PebbleKit - Wschód i zachód + Włącz eksperymentalną obsługę aplikacji Android za pomocą PebbleKit + Wschód i zachód słońca Wyślij czas wschodu i zachodu bazując na lokazliacji do ośi czasu Pebble Lokalizacja Uzyskaj lokalizację @@ -269,7 +269,7 @@ Przytrzymaj aby rozłączyć Rozłączanie Łączenie - Tworzenie zrzutu ekranu urządzenia + Wykonaj zrzut ekranu urządzenia Aktywuj Systemową Aplikację Pogody @@ -284,7 +284,7 @@ Niechciane powiadomienia są wyłączone w tym trybie Transliteracja - Włącz tą opcję jeśli twoje urządzenie nie wspiera czcionki w twoim języku + Włącz tę opcję, jeśli twoje urządzenie nie obsługuje czcionki twojego języka Prywatność Wyświetl nazwę i numer @@ -343,9 +343,9 @@ Opóźnienie po wciśnięciu przycisku akcji Opaska zawibruje gdy zostanie osiągnięty dzienny cel korków Nie przeszkadzać - Obsługa aplikacji, które wysyłają powiadomienia na Pebble przy użyciu PebbleKit. + Obsługa aplikacji wysyłających powiadomienia do Pebble za pośrednictwem PebbleKit. Pogoda - Odrzucanie połączeń + Odrzuć połączenie Całodobowy pomiar tętna Automatyczny eksport Eksportować co %d godzin @@ -369,7 +369,7 @@ Kalibracja urządzenia - Czarna lista dla wszystkich powiadomień + Czarna lista dla powiadomień Biała lista dla wszystkich powiadomień @@ -398,10 +398,10 @@ Włącz gesty lewo/prawo w wykresie aktywności Minimalny czas pomiędzy powiadomieniami - Włącz tryb prywatny - Lokalizacja pogody + Tryb prywatności połączeń telefonicznych + Lokalizacja pogody (CM/LOS) - Wyłączenie tej opcji zatrzyma również Pebble 2/LE w wibracjach połączeń wychodzących + Wyłączenie tej opcji spowoduje również, że Pebble 2/LE przestanie wibrować przy połączeniach wychodzących Powiadomienia są automatycznie usuwane z Pebble po usunięciu ich z urządzenia Android @@ -410,4 +410,7 @@ Zmień kolor diody LED Zmień częstotliwość FM + Od prawej do lewej + Włącz tę opcję, jeśli Twoje urządzenie nie może wyświetlać języków z pisownią od prawej do lewej + Max. Długość linii od prawej do lewej From dde8a5044fce9776ce69a6e22d455d0e004ceb38 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 28 Oct 2018 15:32:57 +0100 Subject: [PATCH 0059/1017] Mi Band 3: Whitelist FW 1.8.0.0 --- .../service/devices/huami/miband3/MiBand3FirmwareInfo.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java index 995cebb2d..881979125 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java @@ -51,12 +51,14 @@ public class MiBand3FirmwareInfo extends HuamiFirmwareInfo { crcToVersion.put(38254, "1.5.0.7"); crcToVersion.put(46985, "1.5.0.11"); crcToVersion.put(31330, "1.6.0.16"); + crcToVersion.put(10930, "1.8.0.0"); // resources crcToVersion.put(54724, "1.2.0.8"); crcToVersion.put(52589, "1.3.0.4"); crcToVersion.put(34642, "1.3.0.8"); crcToVersion.put(25278, "1.4.0.12-1.6.0.16"); + crcToVersion.put(23249, "1.8.0.0"); // font crcToVersion.put(19775, "1"); From 29dc806fb16d708ae5c154bd2013f7f651350a2e Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sun, 28 Oct 2018 17:58:24 +0100 Subject: [PATCH 0060/1017] Ignore notifications that are older than 1 second In case of grouped notifications, we get multiple notifications also if the android device shows only one. This means that with this change the most recently updated chat will get through, but others will not. This should help with #1062 and #657 --- .../gadgetbridge/externalevents/NotificationListener.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index 18f6242bb..0c03d5c15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -209,6 +209,10 @@ public class NotificationListener extends NotificationListenerService { String source = sbn.getPackageName().toLowerCase(); Notification notification = sbn.getNotification(); + if (notification.when < (sbn.getPostTime() - 1000)) { + LOG.info("NOT processing notification, too old. notification.when: " + notification.when + " post time: " + sbn.getPostTime() + " now: " + System.currentTimeMillis()); + return; + } NotificationSpec notificationSpec = new NotificationSpec(); notificationSpec.id = (int) sbn.getPostTime(); //FIXME: a truly unique id would be better From 6b136210a1d20a9182a6c8c8f7c51edc43cd487a Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 28 Oct 2018 21:31:09 +0100 Subject: [PATCH 0061/1017] bump android gradle plugin and build tools version --- app/build.gradle | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 71251a875..ef18ee942 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,7 +17,7 @@ android { targetCompatibility JavaVersion.VERSION_1_7 } compileSdkVersion 27 - buildToolsVersion "28.0.2" + buildToolsVersion '28.0.3' defaultConfig { applicationId "nodomain.freeyourgadget.gadgetbridge" diff --git a/build.gradle b/build.gradle index e1aec6bd7..6b7dab00b 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.0' + classpath 'com.android.tools.build:gradle:3.2.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From b9999edf2a2634e0b4fb62c6526c60caa62718f9 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Mon, 29 Oct 2018 18:39:38 +0100 Subject: [PATCH 0062/1017] Ignore notifications that are older than the last forwarded one for the same source. This reuses the data structure populated to prevent overflow, but avoids to forward notifications that are older than the reference. --- .../externalevents/NotificationListener.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index 0c03d5c15..89353f897 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -209,9 +209,12 @@ public class NotificationListener extends NotificationListenerService { String source = sbn.getPackageName().toLowerCase(); Notification notification = sbn.getNotification(); - if (notification.when < (sbn.getPostTime() - 1000)) { - LOG.info("NOT processing notification, too old. notification.when: " + notification.when + " post time: " + sbn.getPostTime() + " now: " + System.currentTimeMillis()); - return; + if (notificationTimes.containsKey(source)) { + long last_time = notificationTimes.get(source); + if (notification.when <= last_time) { + LOG.info("NOT processing notification, too old. notification.when: " + notification.when + " last notification for this source: " + last_time); + return; + } } NotificationSpec notificationSpec = new NotificationSpec(); notificationSpec.id = (int) sbn.getPostTime(); //FIXME: a truly unique id would be better From eede85a9c98f850de7f21333a14812c530d87153 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Wed, 31 Oct 2018 21:47:12 +0100 Subject: [PATCH 0063/1017] Various improvements and bugfixes to notification handling Prevent duplicate notifications with a dedicated data structure (not reusing the anti-burst one) #1062, #657 Pebble: Forward the actions attached to notifications (not only reply) inspired by the work of dnastase #705 --- .../activities/DebugActivity.java | 1 - .../GBDeviceEventNotificationControl.java | 1 + .../externalevents/AlarmClockReceiver.java | 8 +- .../externalevents/NotificationListener.java | 59 +++++++----- .../externalevents/PebbleReceiver.java | 1 - .../externalevents/SMSReceiver.java | 1 - .../gadgetbridge/impl/GBDeviceService.java | 3 +- .../gadgetbridge/model/DeviceService.java | 1 + .../gadgetbridge/model/NotificationSpec.java | 34 ++++++- .../service/AbstractDeviceSupport.java | 3 +- .../service/DeviceCommunicationService.java | 12 ++- .../devices/pebble/PebbleProtocol.java | 95 +++++++++++++------ 12 files changed, 145 insertions(+), 74 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index 95cd9e3c8..d9cc22359 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -122,7 +122,6 @@ public class DebugActivity extends AbstractGBActivity { notificationSpec.subject = testString; notificationSpec.type = NotificationType.values()[sendTypeSpinner.getSelectedItemPosition()]; notificationSpec.pebbleColor = notificationSpec.type.color; - notificationSpec.id = -1; GBApplication.deviceService().onNotification(notificationSpec); } }); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java index 1e7037b17..25fd8bf31 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java @@ -20,6 +20,7 @@ public class GBDeviceEventNotificationControl extends GBDeviceEvent { public int handle; public String phoneNumber; public String reply; + public String title; public Event event = Event.UNKNOWN; public enum Event { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmClockReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmClockReceiver.java index aafdf94f5..b92566fa3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmClockReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmClockReceiver.java @@ -64,10 +64,10 @@ public class AlarmClockReceiver extends BroadcastReceiver { private synchronized void sendAlarm(boolean on) { dismissLastAlarm(); if (on) { - lastId = generateId(); NotificationSpec spec = new NotificationSpec(); + //TODO: can we attach a dismiss action to the notification and not use the notification ID explicitly? + lastId = spec.getId(); spec.type = NotificationType.GENERIC_ALARM_CLOCK; - spec.id = lastId; spec.sourceName = "ALARMCLOCKRECEIVER"; // can we get the alarm title somehow? GBApplication.deviceService().onNotification(spec); @@ -81,8 +81,4 @@ public class AlarmClockReceiver extends BroadcastReceiver { } } - private int generateId() { - // lacks negative values, but should be sufficient - return (int) (Math.random() * Integer.MAX_VALUE); - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index 89353f897..77df28c99 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -50,6 +50,7 @@ import android.support.v7.graphics.Palette; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Objects; @@ -87,7 +88,8 @@ public class NotificationListener extends NotificationListenerService { private LimitedQueue mActionLookup = new LimitedQueue(16); - private HashMap notificationTimes = new HashMap<>(); + private HashMap notificationBurstPrevention = new HashMap<>(); + private HashMap notificationOldRepeatPrevention = new HashMap<>(); private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -145,19 +147,20 @@ public class NotificationListener extends NotificationListenerService { break; case ACTION_REPLY: int id = intent.getIntExtra("handle", -1); + NotificationCompat.Action wearableAction = (NotificationCompat.Action) mActionLookup.lookup(id); String reply = intent.getStringExtra("reply"); - NotificationCompat.Action replyAction = (NotificationCompat.Action) mActionLookup.lookup(id); - if (replyAction != null && replyAction.getRemoteInputs() != null) { - RemoteInput[] remoteInputs = replyAction.getRemoteInputs(); - PendingIntent actionIntent = replyAction.getActionIntent(); + if (wearableAction != null) { + PendingIntent actionIntent = wearableAction.getActionIntent(); Intent localIntent = new Intent(); localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - Bundle extras = new Bundle(); - extras.putCharSequence(remoteInputs[0].getResultKey(), reply); - RemoteInput.addResultsToIntent(remoteInputs, localIntent, extras); - + if(wearableAction.getRemoteInputs()!=null) { + RemoteInput[] remoteInputs = wearableAction.getRemoteInputs(); + Bundle extras = new Bundle(); + extras.putCharSequence(remoteInputs[0].getResultKey(), reply); + RemoteInput.addResultsToIntent(remoteInputs, localIntent, extras); + } try { - LOG.info("will send reply intent to remote application"); + LOG.info("will send exec intent to remote application"); actionIntent.send(context, 0, localIntent); mActionLookup.remove(id); } catch (PendingIntent.CanceledException e) { @@ -209,15 +212,13 @@ public class NotificationListener extends NotificationListenerService { String source = sbn.getPackageName().toLowerCase(); Notification notification = sbn.getNotification(); - if (notificationTimes.containsKey(source)) { - long last_time = notificationTimes.get(source); - if (notification.when <= last_time) { - LOG.info("NOT processing notification, too old. notification.when: " + notification.when + " last notification for this source: " + last_time); + if (notificationOldRepeatPrevention.containsKey(source)) { + if (notification.when <= notificationOldRepeatPrevention.get(source)) { + LOG.info("NOT processing notification, already sent newer notifications from this source."); return; } } NotificationSpec notificationSpec = new NotificationSpec(); - notificationSpec.id = (int) sbn.getPostTime(); //FIXME: a truly unique id would be better // determinate Source App Name ("Label") PackageManager pm = getPackageManager(); @@ -249,7 +250,7 @@ public class NotificationListener extends NotificationListenerService { // Get color notificationSpec.pebbleColor = getPebbleColorForNotification(notificationSpec); - LOG.info("Processing notification " + notificationSpec.id + " from source " + source + " with flags: " + notification.flags); + LOG.info("Processing notification " + notificationSpec.getId() + " age: " + (System.currentTimeMillis() - notification.when) + " from source " + source + " with flags: " + notification.flags); dissectNotificationTo(notification, notificationSpec, preferBigText); @@ -263,16 +264,23 @@ public class NotificationListener extends NotificationListenerService { NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender(notification); List actions = wearableExtender.getActions(); + notificationSpec.attachedActions = new ArrayList<>(); for (NotificationCompat.Action act : actions) { - if (act != null && act.getRemoteInputs() != null) { - LOG.info("found wearable action: " + act.getTitle() + " " + sbn.getTag()); - mActionLookup.add(notificationSpec.id, act); - notificationSpec.flags |= NotificationSpec.FLAG_WEARABLE_REPLY; - break; + if (act != null) { + NotificationSpec.Action wearableAction = new NotificationSpec.Action(); + wearableAction.title = act.getTitle().toString(); + if(act.getRemoteInputs()!=null) { + wearableAction.isReply = true; + } + notificationSpec.flags |= NotificationSpec.FLAG_WEARABLE_ACTIONS; + notificationSpec.attachedActions.add(wearableAction); + mActionLookup.add((notificationSpec.getId()<<4) + notificationSpec.attachedActions.size(), act); + LOG.info("found wearable action: " + notificationSpec.attachedActions.size() + " - "+ act.getTitle() + " " + sbn.getTag()); } } - if ((notificationSpec.flags & NotificationSpec.FLAG_WEARABLE_REPLY) == 0 && NotificationCompat.isGroupSummary(notification)) { //this could cause #395 to come back + + if ((notificationSpec.flags & NotificationSpec.FLAG_WEARABLE_ACTIONS) == 0 && NotificationCompat.isGroupSummary(notification)) { //this could cause #395 to come back LOG.info("Not forwarding notification, FLAG_GROUP_SUMMARY is set and no wearable action present. Notification flags: " + notification.flags); return; } @@ -280,14 +288,15 @@ public class NotificationListener extends NotificationListenerService { // Ignore too frequent notifications, according to user preference long min_timeout = prefs.getInt("notifications_timeout", 0) * 1000; long cur_time = System.currentTimeMillis(); - if (notificationTimes.containsKey(source)) { - long last_time = notificationTimes.get(source); + if (notificationBurstPrevention.containsKey(source)) { + long last_time = notificationBurstPrevention.get(source); if (cur_time - last_time < min_timeout) { LOG.info("Ignoring frequent notification, last one was " + (cur_time - last_time) + "ms ago"); return; } } - notificationTimes.put(source, cur_time); + notificationBurstPrevention.put(source, cur_time); + notificationOldRepeatPrevention.put(source, notification.when); GBApplication.deviceService().onNotification(notificationSpec); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java index a2091a662..e8e889e64 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java @@ -62,7 +62,6 @@ public class PebbleReceiver extends BroadcastReceiver { } NotificationSpec notificationSpec = new NotificationSpec(); - notificationSpec.id = -1; String notificationData = intent.getStringExtra("notificationData"); try { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java index be96e4381..0e1d77422 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java @@ -50,7 +50,6 @@ public class SMSReceiver extends BroadcastReceiver { } NotificationSpec notificationSpec = new NotificationSpec(); - notificationSpec.id = -1; notificationSpec.type = NotificationType.GENERIC_SMS; Bundle bundle = intent.getExtras(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 854260788..d69c4d64c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -150,8 +150,9 @@ public class GBDeviceService implements DeviceService { .putExtra(EXTRA_NOTIFICATION_SUBJECT, notificationSpec.subject) .putExtra(EXTRA_NOTIFICATION_TITLE, notificationSpec.title) .putExtra(EXTRA_NOTIFICATION_BODY, notificationSpec.body) - .putExtra(EXTRA_NOTIFICATION_ID, notificationSpec.id) + .putExtra(EXTRA_NOTIFICATION_ID, notificationSpec.getId()) .putExtra(EXTRA_NOTIFICATION_TYPE, notificationSpec.type) + .putExtra(EXTRA_NOTIFICATION_ACTIONS, notificationSpec.attachedActions) .putExtra(EXTRA_NOTIFICATION_SOURCENAME, notificationSpec.sourceName) .putExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR, notificationSpec.pebbleColor) .putExtra(EXTRA_NOTIFICATION_SOURCEAPPID, notificationSpec.sourceAppId); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index d15e858db..974a1cbf2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -77,6 +77,7 @@ public interface DeviceService extends EventHandler { String EXTRA_NOTIFICATION_SUBJECT = "notification_subject"; String EXTRA_NOTIFICATION_TITLE = "notification_title"; String EXTRA_NOTIFICATION_TYPE = "notification_type"; + String EXTRA_NOTIFICATION_ACTIONS = "notification_actions"; String EXTRA_NOTIFICATION_PEBBLE_COLOR = "notification_pebble_color"; String EXTRA_FIND_START = "find_start"; String EXTRA_VIBRATION_INTENSITY = "vibration_intensity"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationSpec.java index 7d0ff891f..24503d42d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationSpec.java @@ -16,11 +16,16 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.model; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicInteger; + public class NotificationSpec { - public static final int FLAG_WEARABLE_REPLY = 0x00000001; + public static final int FLAG_WEARABLE_ACTIONS = 0x00000001; public int flags; - public int id; + private static final AtomicInteger c = new AtomicInteger((int) (System.currentTimeMillis()/1000)); + private int id; public String sender; public String phoneNumber; public String title; @@ -29,7 +34,10 @@ public class NotificationSpec { public NotificationType type; public String sourceName; public String[] cannedReplies; - + /** + * Wearable actions that were attached to the incoming notifications and will be passed to the gadget (includes the "reply" action) + */ + public ArrayList attachedActions; /** * The application that generated the notification. */ @@ -39,4 +47,24 @@ public class NotificationSpec { * The color that should be assigned to this notification when displayed on a Pebble */ public byte pebbleColor; + + public NotificationSpec() { + this.id = c.incrementAndGet(); + } + + public NotificationSpec(int id) { + if (id != -1) + this.id = id; + else + this.id = c.incrementAndGet(); + } + + public int getId() { + return id; + } + + public static class Action implements Serializable { + public boolean isReply = false; + public String title; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 1f995e4ca..d55053972 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -52,8 +52,8 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventDisplayMessage; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFmFrequency; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFmFrequency; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventLEDColor; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventNotificationControl; @@ -337,6 +337,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { if (action != null) { Intent notificationListenerIntent = new Intent(action); notificationListenerIntent.putExtra("handle", deviceEvent.handle); + notificationListenerIntent.putExtra("title", deviceEvent.title); if (deviceEvent.reply != null) { Prefs prefs = GBApplication.getPrefs(); String suffix = prefs.getString("canned_reply_suffix", null); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 065c8045a..e96c59935 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -147,6 +147,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUS import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACK; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACKCOUNT; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACKNR; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_ACTIONS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_BODY; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_FLAGS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_ID; @@ -356,7 +357,8 @@ public class DeviceCommunicationService extends Service implements SharedPrefere mGBDevice.sendDeviceUpdateIntent(this); break; case ACTION_NOTIFICATION: { - NotificationSpec notificationSpec = new NotificationSpec(); + int desiredId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); + NotificationSpec notificationSpec = new NotificationSpec(desiredId); notificationSpec.phoneNumber = intent.getStringExtra(EXTRA_NOTIFICATION_PHONENUMBER); notificationSpec.sender = intent.getStringExtra(EXTRA_NOTIFICATION_SENDER); notificationSpec.subject = intent.getStringExtra(EXTRA_NOTIFICATION_SUBJECT); @@ -364,17 +366,17 @@ public class DeviceCommunicationService extends Service implements SharedPrefere notificationSpec.body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY); notificationSpec.sourceName = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCENAME); notificationSpec.type = (NotificationType) intent.getSerializableExtra(EXTRA_NOTIFICATION_TYPE); + notificationSpec.attachedActions = (ArrayList) intent.getSerializableExtra(EXTRA_NOTIFICATION_ACTIONS); notificationSpec.pebbleColor = (byte) intent.getSerializableExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR); - notificationSpec.id = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); notificationSpec.flags = intent.getIntExtra(EXTRA_NOTIFICATION_FLAGS, 0); notificationSpec.sourceAppId = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCEAPPID); if (notificationSpec.type == NotificationType.GENERIC_SMS && notificationSpec.phoneNumber != null) { - notificationSpec.id = mRandom.nextInt(); // FIXME: add this in external SMS Receiver? - GBApplication.getIDSenderLookup().add(notificationSpec.id, notificationSpec.phoneNumber); + GBApplication.getIDSenderLookup().add(notificationSpec.getId(), notificationSpec.phoneNumber); } - if (((notificationSpec.flags & NotificationSpec.FLAG_WEARABLE_REPLY) > 0) + //TODO: check if at least one of the attached actions is a reply action instead? + if (((notificationSpec.flags & NotificationSpec.FLAG_WEARABLE_ACTIONS) > 0) || (notificationSpec.type == NotificationType.GENERIC_SMS && notificationSpec.phoneNumber != null)) { // NOTE: maybe not where it belongs if (prefs.getBoolean("pebble_force_untested", false)) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index a9ff4a8ad..74aa5b504 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -60,6 +60,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec.Action; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.Weather; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; @@ -484,8 +485,9 @@ public class PebbleProtocol extends GBDeviceProtocol { @Override public byte[] encodeNotification(NotificationSpec notificationSpec) { - boolean hasHandle = notificationSpec.id != -1 && notificationSpec.phoneNumber == null; - int id = notificationSpec.id != -1 ? notificationSpec.id : mRandom.nextInt(); + //TODO: simplify this logic? is hasHandle still needed? + boolean hasHandle = notificationSpec.getId() != -1 && notificationSpec.phoneNumber == null; + int id = notificationSpec.getId() != -1 ? notificationSpec.getId() : mRandom.nextInt(); String title; String subtitle = null; @@ -507,11 +509,11 @@ public class PebbleProtocol extends GBDeviceProtocol { // 3.x notification return encodeBlobdbNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, notificationSpec.sourceName, hasHandle, notificationSpec.type, notificationSpec.pebbleColor, - notificationSpec.cannedReplies); + notificationSpec.cannedReplies, notificationSpec.attachedActions); } else if (mForceProtocol || notificationSpec.type != NotificationType.GENERIC_EMAIL) { // 2.x notification return encodeExtensibleNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, - notificationSpec.sourceName, hasHandle, notificationSpec.cannedReplies); + notificationSpec.sourceName, hasHandle, notificationSpec.cannedReplies, notificationSpec.attachedActions); } else { // 1.x notification on FW 2.X String[] parts = {title, notificationSpec.body, String.valueOf(ts), subtitle}; @@ -594,7 +596,8 @@ public class PebbleProtocol extends GBDeviceProtocol { */ } - private byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, String[] cannedReplies) { + //TODO: add support for attachedActions + private byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, String[] cannedReplies, ArrayList attachedActions) { final short ACTION_LENGTH_MIN = 10; String[] parts = {title, subtitle, body}; @@ -930,7 +933,7 @@ public class PebbleProtocol extends GBDeviceProtocol { private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, NotificationType notificationType, byte backgroundColor, - String[] cannedReplies) { + String[] cannedReplies, ArrayList attachedActions) { final short NOTIFICATION_PIN_LENGTH = 46; final short ACTION_LENGTH_MIN = 10; @@ -943,36 +946,43 @@ public class PebbleProtocol extends GBDeviceProtocol { int icon_id = notificationType.icon; // Calculate length first - byte actions_count; - short actions_length; + byte actions_count = 0; + short actions_length = 0; String dismiss_string; String open_string = "Open on phone"; String mute_string = "Mute"; - String reply_string = "Reply"; if (sourceName != null) { mute_string += " " + sourceName; } byte dismiss_action_id; if (hasHandle && !"ALARMCLOCKRECEIVER".equals(sourceName)) { - actions_count = 3; + actions_count += 3; dismiss_string = "Dismiss"; dismiss_action_id = 0x02; - actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.getBytes().length + open_string.getBytes().length + mute_string.getBytes().length); + //TODO: ACTION_LENGTH_MIN disagrees with my observation of the needed bytes. I used 6 instead of 10 + actions_length += (short) (6 * 3 + dismiss_string.getBytes().length + open_string.getBytes().length + mute_string.getBytes().length); } else { - actions_count = 1; + actions_count += 1; dismiss_string = "Dismiss all"; dismiss_action_id = 0x03; - actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.getBytes().length); + actions_length += (short) (ACTION_LENGTH_MIN + dismiss_string.getBytes().length); + } + if (attachedActions != null && attachedActions.size() > 0) { + for (Action act : attachedActions) { + actions_count++; + actions_length += (short) (6 + act.title.getBytes().length); + } } int replies_length = -1; if (cannedReplies != null && cannedReplies.length > 0) { - actions_count++; + //do not increment actions_count! reply is an action and was already added above for (String reply : cannedReplies) { replies_length += reply.getBytes().length + 1; } - actions_length += ACTION_LENGTH_MIN + reply_string.getBytes().length + replies_length + 3; // 3 = attribute id (byte) + length(short) + //similarly, only the replies lenght has to be added, the lenght for the bare action was already added above + actions_length += replies_length + 3; // 3 = attribute id (byte) + length(short) } byte attributes_count = 2; // icon @@ -1053,21 +1063,31 @@ public class PebbleProtocol extends GBDeviceProtocol { buf.put(mute_string.getBytes()); } - if (cannedReplies != null && replies_length > 0) { - buf.put((byte) 0x05); - buf.put((byte) 0x03); // reply action - buf.put((byte) 0x02); // number attributes - buf.put((byte) 0x01); // title - buf.putShort((short) reply_string.getBytes().length); - buf.put(reply_string.getBytes()); - buf.put((byte) 0x08); // canned replies - buf.putShort((short) replies_length); - for (int i = 0; i < cannedReplies.length - 1; i++) { - buf.put(cannedReplies[i].getBytes()); - buf.put((byte) 0x00); + if (attachedActions != null && attachedActions.size() > 0) { + for (int ai = 0 ; ai= 0x00 && action <= 0x05) { + if (action >= 0x00 && action <= 0xf) { GBDeviceEventNotificationControl devEvtNotificationControl = new GBDeviceEventNotificationControl(); devEvtNotificationControl.handle = id; String caption = "undefined"; @@ -2125,6 +2145,7 @@ public class PebbleProtocol extends GBDeviceProtocol { caption = "Muted"; icon_id = PebbleIconID.RESULT_MUTE; break; + //TODO: 0x05 is not a special case anymore, and reply action might have an index that is higher. see default below case 0x05: case 0x00: boolean failed = true; @@ -2145,6 +2166,7 @@ public class PebbleProtocol extends GBDeviceProtocol { } devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.REPLY; devEvtNotificationControl.reply = new String(reply); + devEvtNotificationControl.handle = (devEvtNotificationControl.handle << 4) + 1; caption = "SENT"; icon_id = PebbleIconID.RESULT_SENT; failed = false; @@ -2156,6 +2178,19 @@ public class PebbleProtocol extends GBDeviceProtocol { devEvtNotificationControl = null; // error } break; + default: + if (action > 0x05) { + int simpleActionId = action - 0x05; + caption = "EXECUTED"; + devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.REPLY; + devEvtNotificationControl.handle = (devEvtNotificationControl.handle << 4) + simpleActionId; + LOG.info("detected simple action, subId:" + simpleActionId + " title:" + devEvtNotificationControl.title); + } else { + caption = "FAILED"; + icon_id = PebbleIconID.RESULT_FAILED; + devEvtNotificationControl = null; // error + } + break; } GBDeviceEventSendBytes sendBytesAck = null; if (mFwMajor >= 3 || needsAck2x) { From 086fc75629100402b9d9787b829bd5283cb785be Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Wed, 31 Oct 2018 22:03:40 +0100 Subject: [PATCH 0064/1017] try to satisfy travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 616bc59d9..502f7e95a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ android: - tools # The BuildTools version used by your project - - build-tools-28.0.2 + - build-tools-28.0.3 # The SDK version used to compile your project - android-27 From f3e16c5b1de45befbc2fd6a1e7d5b2eebd2d46e1 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 1 Nov 2018 14:55:14 +0100 Subject: [PATCH 0065/1017] Pebble: Fix regression causing "Open on Phone" and "Dismiss" to appear on Pebble notification with no corresponding Android notification (i.e. PebbleKit notifications) --- .../gadgetbridge/service/devices/pebble/PebbleProtocol.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 74aa5b504..2a31534af 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -485,8 +485,7 @@ public class PebbleProtocol extends GBDeviceProtocol { @Override public byte[] encodeNotification(NotificationSpec notificationSpec) { - //TODO: simplify this logic? is hasHandle still needed? - boolean hasHandle = notificationSpec.getId() != -1 && notificationSpec.phoneNumber == null; + boolean hasHandle = notificationSpec.sourceAppId != null; int id = notificationSpec.getId() != -1 ? notificationSpec.getId() : mRandom.nextInt(); String title; String subtitle = null; From 22de76620d8145b1330067cdfab89c1298a1ba40 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 1 Nov 2018 15:04:16 +0100 Subject: [PATCH 0066/1017] Debug: Add button to send a PebbleKit notification --- .../gadgetbridge/activities/DebugActivity.java | 15 +++++++++++++++ app/src/main/res/layout/activity_debug.xml | 7 +++++++ 2 files changed, 22 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index d9cc22359..475d229c2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -224,6 +224,14 @@ public class DebugActivity extends AbstractGBActivity { } }); + Button testPebbleKitNotificationButton = findViewById(R.id.testPebbleKitNotificationButton); + testPebbleKitNotificationButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + testPebbleKitNotification(); + } + }); + Button fetchDebugLogsButton = findViewById(R.id.fetchDebugLogsButton); fetchDebugLogsButton.setOnClickListener(new View.OnClickListener() { @Override @@ -328,6 +336,13 @@ public class DebugActivity extends AbstractGBActivity { } } + private void testPebbleKitNotification() { + Intent pebbleKitIntent = new Intent("com.getpebble.action.SEND_NOTIFICATION"); + pebbleKitIntent.putExtra("messageType", "PEBBLE_ALERT"); + pebbleKitIntent.putExtra("notificationData", "[{\"title\":\"PebbleKitTest\",\"body\":\"sent from Gadgetbridge\"}]"); + getApplicationContext().sendBroadcast(pebbleKitIntent); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { diff --git a/app/src/main/res/layout/activity_debug.xml b/app/src/main/res/layout/activity_debug.xml index 6bbfe1b94..86088c0c5 100644 --- a/app/src/main/res/layout/activity_debug.xml +++ b/app/src/main/res/layout/activity_debug.xml @@ -124,6 +124,13 @@ grid:layout_columnSpan="2" grid:layout_gravity="fill_horizontal" android:text="create test notification" /> +