diff --git a/.tx/config b/.tx/config deleted file mode 100644 index 0ed637b5b..000000000 --- a/.tx/config +++ /dev/null @@ -1,9 +0,0 @@ -[main] -host = https://www.transifex.com - -[gadgetbridge.strings] -file_filter = app/src/main/res/values-/strings.xml -source_file = app/src/main/res/values/strings.xml -source_lang = en_US -deviceType = ANDROID -minimum_perc = 50 diff --git a/CHANGELOG.md b/CHANGELOG.md index aa843dd4e..784d2e82a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ ### Changelog +#### Version 0.20.2 +* Amazfit Bip: Various fixes regarding weather, add condition string support for FW 0.0.8.74 +* Amazfit Bip: enable caller display in later firmwares +* Amazfit Bip: initial firmware update support (EXPERIMENTAL, AT YOUR OWN RISK) +* Re-enable improved speed zones tab +* Probably fix crash with certain music players +* Improve theme and add changelog icon + #### Version 0.20.1 * Amazfit Bip: Support icons and text body for notifications * Mi Band: Fix setting smart alarms diff --git a/README.md b/README.md index 84ab9df6d..8e713ba50 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ Contributions are welcome, be it feedback, bugreports, documentation, translatio on any of the open [issues](https://github.com/Freeyourgadget/Gadgetbridge/issues?q=is%3Aopen+is%3Aissue); just leave a comment that you're working on one to avoid duplicated work. -Translations can be contributed via https://www.transifex.com/projects/p/gadgetbridge/resource/strings/ or manually. +Translations can be contributed via https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ ## Do you have further questions or feedback? diff --git a/app/build.gradle b/app/build.gradle index ffe34039a..06027cc0f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { targetSdkVersion 25 // note: always bump BOTH versionCode and versionName! - versionName "0.20.1" - versionCode 99 + versionName "0.20.2" + versionCode 100 vectorDrawables.useSupportLibrary = true } buildTypes { @@ -68,6 +68,7 @@ dependencies { compile 'com.android.support:cardview-v7:25.3.1' compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.android.support:support-v4:25.3.1' + compile 'com.android.support:gridlayout-v7:25.3.1' compile 'com.android.support:design:25.3.1' compile 'com.github.tony19:logback-android-classic:1.1.1-6' compile 'org.slf4j:slf4j-api:1.7.7' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d9302f71..1b170f94c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -114,6 +114,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -187,6 +207,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java index d5aff21ed..86c7f1153 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Carsten Pfeiffer +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java index e3fb25570..ea92116a6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Andreas Shimokawa +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityAnalysis.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityAnalysis.java index d5ef1535a..db82772d8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityAnalysis.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityAnalysis.java @@ -1,5 +1,5 @@ /* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele - Gobbetti + Gobbetti, Vebryn This file is part of Gadgetbridge. @@ -21,25 +21,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmount; import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; class ActivityAnalysis { + private static final Logger LOG = LoggerFactory.getLogger(ActivityAnalysis.class); + // store raw steps and duration protected HashMap stats = new HashMap(); - // normalize steps - protected HashMap statsQuantified = new HashMap(); - // store maxSpeed / resolution - protected float maxSpeedQuantifier; - // store an average of round precision - protected float roundPrecision = 0f; - // max speed determined from samples private int maxSpeed = 0; - // number of bars on stats chart - private int resolution = 5; ActivityAmounts calculateActivityAmounts(List samples) { ActivityAmount deepSleep = new ActivityAmount(ActivityKind.TYPE_DEEP_SLEEP); @@ -89,11 +85,11 @@ class ActivityAnalysis { } if (!stats.containsKey(steps)) { - //System.out.println("Adding: " + steps); + LOG.info("Adding: " + steps); stats.put(steps, timeDifference); } else { long time = stats.get(steps); - //System.out.println("Updating: " + steps + " " + timeDifference + time); + LOG.info("Updating: " + steps + " " + timeDifference + time); stats.put(steps, timeDifference + time); } } @@ -103,34 +99,6 @@ class ActivityAnalysis { previousSample = sample; } - maxSpeedQuantifier = maxSpeed / resolution; - for (Map.Entry entry : stats.entrySet()) { - // 0.1 precision - //float keyQuantified = Math.round(entry.getKey() / maxSpeedQuantifier * 10f) / 10f; - - // 1 precision - float keyQuantified = entry.getKey() / maxSpeedQuantifier; - float keyQuantifiedRounded = Math.round(entry.getKey() / maxSpeedQuantifier); - float keyQuantifiedPrecision = keyQuantifiedRounded - keyQuantified; - roundPrecision = (roundPrecision + Math.abs(keyQuantifiedPrecision)) / 2; - //System.out.println("Precision: " + roundPrecision); - - // no scale - //keyQuantified = entry.getKey(); - - // scaling to minutes - float timeMinutes = entry.getValue() / 60; - - if (!statsQuantified.containsKey(keyQuantifiedRounded)) { - //System.out.println("Adding: " + keyQuantified + "/" + timeMinutes); - statsQuantified.put(keyQuantifiedRounded, timeMinutes); - } else { - float previousTime = statsQuantified.get(keyQuantifiedRounded); - //System.out.println("Updating: " + keyQuantified + "/" + (timeMinutes + previousTime)); - statsQuantified.put(keyQuantifiedRounded, (timeMinutes + previousTime)); - } - } - ActivityAmounts result = new ActivityAmounts(); if (deepSleep.getTotalSeconds() > 0) { result.addAmount(deepSleep); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java index 2d6cf205a..c28cc6d26 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java @@ -1,5 +1,5 @@ /* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele - Gobbetti + Gobbetti, Vebryn This file is part of Gadgetbridge. @@ -328,22 +328,21 @@ public class ChartsActivity extends AbstractGBFragmentActivity implements Charts case 3: return new WeekStepsChartFragment(); case 4: - return new LiveActivityFragment(); + return new SpeedZonesFragment(); case 5: - return new StatsChartFragment(); - + return new LiveActivityFragment(); } return null; } @Override public int getCount() { - // Show 4 or 5 total pages. (always hide speed zones) + // Show 5 or 6 total pages. DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(mGBDevice); if (coordinator.supportsRealtimeData()) { - return 5; + return 6; } - return 4; + return 5; } @Override @@ -358,9 +357,9 @@ public class ChartsActivity extends AbstractGBFragmentActivity implements Charts case 3: return getString(R.string.weekstepschart_steps_a_week); case 4: - return getString(R.string.liveactivity_live_activity); - case 5: return getString(R.string.stats_title); + case 5: + return getString(R.string.liveactivity_live_activity); } return super.getPageTitle(position); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StatsChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SpeedZonesFragment.java similarity index 71% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StatsChartFragment.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SpeedZonesFragment.java index 181508d99..bab6754fd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StatsChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SpeedZonesFragment.java @@ -24,7 +24,6 @@ import android.view.ViewGroup; import com.github.mikephil.charting.charts.Chart; import com.github.mikephil.charting.charts.HorizontalBarChart; -import com.github.mikephil.charting.components.LegendEntry; import com.github.mikephil.charting.components.XAxis; import com.github.mikephil.charting.components.YAxis; import com.github.mikephil.charting.data.BarData; @@ -43,12 +42,11 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; - -import static android.R.attr.x; +import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; -public class StatsChartFragment extends AbstractChartFragment { - protected static final Logger LOG = LoggerFactory.getLogger(StatsChartFragment.class); +public class SpeedZonesFragment extends AbstractChartFragment { + protected static final Logger LOG = LoggerFactory.getLogger(SpeedZonesFragment.class); private HorizontalBarChart mStatsChart; @@ -67,13 +65,17 @@ public class StatsChartFragment extends AbstractChartFragment { BarData data = new BarData(); data.setValueTextColor(CHART_TEXT_COLOR); List entries = new ArrayList<>(); - XAxisValueFormatter customXAxis = new XAxisValueFormatter(); - for (Map.Entry entry : analysis.statsQuantified.entrySet()) { - entries.add(new BarEntry(entry.getKey(), entry.getValue())); - /*float realValue = entry.getKey() * analysis.maxSpeedQuantifier; - String customLabel = Math.round(realValue * (1 - analysis.roundPrecision) * 10f) / 10f + " - " + Math.round(realValue * (1 + analysis.roundPrecision) * 10f) / 10f;*/ - customXAxis.add("" + entry.getKey() * analysis.maxSpeedQuantifier); + ActivityUser user = new ActivityUser(); + /*double distanceFactorCm; + if (user.getGender() == user.GENDER_MALE){ + distanceFactorCm = user.getHeightCm() * user.GENDER_MALE_DISTANCE_FACTOR / 1000; + } else { + distanceFactorCm = user.getHeightCm() * user.GENDER_FEMALE_DISTANCE_FACTOR / 1000; + }*/ + + for (Map.Entry entry : analysis.stats.entrySet()) { + entries.add(new BarEntry(entry.getKey(), entry.getValue() / 60)); } BarDataSet set = new BarDataSet(entries, ""); @@ -83,14 +85,6 @@ public class StatsChartFragment extends AbstractChartFragment { //data.setBarWidth(0.1f); data.addDataSet(set); - // set X axis - customXAxis.sort(); - XAxis left = mStatsChart.getXAxis(); - left.setValueFormatter(customXAxis); - - // display precision - //mStatsChart.getDescription().setText(Math.round(analysis.roundPrecision * 100) + "%"); - return new MySpeedZonesData(data); } @@ -127,34 +121,16 @@ public class StatsChartFragment extends AbstractChartFragment { mStatsChart.setTouchEnabled(false); mStatsChart.getDescription().setText(""); - XAxis x = mStatsChart.getXAxis(); - x.setTextColor(CHART_TEXT_COLOR); + XAxis right = mStatsChart.getXAxis(); //believe it or not, the X axis is vertical for HorizontalBarChart + right.setTextColor(CHART_TEXT_COLOR); - YAxis yr = mStatsChart.getAxisRight(); - yr.setTextColor(CHART_TEXT_COLOR); - } + YAxis bottom = mStatsChart.getAxisRight(); + bottom.setTextColor(CHART_TEXT_COLOR); + bottom.setGranularity(1f); - @Override - protected void setupLegend(Chart chart) { - List legendEntries = new ArrayList<>(3); - LegendEntry lightSleepEntry = new LegendEntry(); - lightSleepEntry.label = akLightSleep.label; - lightSleepEntry.formColor = akLightSleep.color; - legendEntries.add(lightSleepEntry); - - LegendEntry deepSleepEntry = new LegendEntry(); - deepSleepEntry.label = akDeepSleep.label; - deepSleepEntry.formColor = akDeepSleep.color; - legendEntries.add(deepSleepEntry); - - if (supportsHeartrate(getChartsHost().getDevice())) { - LegendEntry hrEntry = new LegendEntry(); - hrEntry.label = HEARTRATE_LABEL; - hrEntry.formColor = HEARTRATE_COLOR; - legendEntries.add(hrEntry); - } - chart.getLegend().setCustom(legendEntries); - chart.getLegend().setTextColor(LEGEND_TEXT_COLOR); + YAxis top = mStatsChart.getAxisLeft(); + top.setTextColor(CHART_TEXT_COLOR); + top.setGranularity(1f); } @Override @@ -162,6 +138,12 @@ public class StatsChartFragment extends AbstractChartFragment { return super.getAllSamples(db, device, tsFrom, tsTo); } + @Override + protected void setupLegend(Chart chart) { + // no legend here, it is all about the steps here + chart.getLegend().setEnabled(false); + } + @Override protected void renderCharts() { mStatsChart.invalidate(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/XAxisValueFormatter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/XAxisValueFormatter.java deleted file mode 100644 index 62bce3cb0..000000000 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/XAxisValueFormatter.java +++ /dev/null @@ -1,42 +0,0 @@ -package nodomain.freeyourgadget.gadgetbridge.activities.charts; - -import com.github.mikephil.charting.components.AxisBase; -import com.github.mikephil.charting.formatter.IAxisValueFormatter; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Created by nhu on 30/04/17. - */ - -public class XAxisValueFormatter implements IAxisValueFormatter { - private List mValues = new ArrayList<>(); - - public XAxisValueFormatter() { - super(); - } - - public void add(String label) { - mValues.add(label); - } - - public void sort() { - //System.out.println("Sorting " + mValues); - Collections.sort(mValues); - } - - @Override - public String getFormattedValue(float value, AxisBase axis) { - String returnString = "N/A"; - - try { - returnString = mValues.get((int) value).toString(); - //System.out.println("Asking " + value + ", returning " + returnString); - } catch (Exception e) { - System.out.println(e.getMessage()); - } - return returnString; - } -} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipCooordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipCooordinator.java index 3490a4545..5b33e08aa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipCooordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipCooordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Andreas Shimokawa +/* Copyright (C) 2017 Andreas Shimokawa, João Paulo Barraca This file is part of Gadgetbridge. @@ -52,10 +52,9 @@ public class AmazfitBipCooordinator extends MiBand2Coordinator { return DeviceType.UNKNOWN; } - @Override public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; // not supported yet + AmazfitBipFWInstallHandler handler = new AmazfitBipFWInstallHandler(uri, context); + return handler.isValid() ? handler : null; } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipFWHelper.java new file mode 100644 index 000000000..01fda7c43 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipFWHelper.java @@ -0,0 +1,90 @@ +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + 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.amazfitbip; + +import android.content.Context; +import android.net.Uri; +import android.support.annotation.NonNull; + +import java.io.IOException; + +import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip.AmazfitBipFirmwareInfo; + +public class AmazfitBipFWHelper extends AbstractMiBandFWHelper { + + public AmazfitBipFWHelper(Uri uri, Context context) throws IOException { + super(uri, context); + } + + private AmazfitBipFirmwareInfo firmwareInfo; + + @Override + public String format(int version) { + return AmazfitBipFirmwareInfo.toVersion(version); + } + + @Override + public int getFirmwareVersion() { + return firmwareInfo.getFirmwareVersion(); + } + + @Override + public int getFirmware2Version() { + return 0; + } + + @Override + public String getHumanFirmwareVersion2() { + return ""; + } + + @Override + protected int[] getWhitelistedFirmwareVersions() { + return AmazfitBipFirmwareInfo.getWhitelistedVersions(); + } + + @Override + public boolean isFirmwareGenerallyCompatibleWith(GBDevice device) { + return firmwareInfo.isGenerallyCompatibleWith(device); + } + + @Override + public boolean isSingleFirmware() { + return true; + } + + @NonNull + @Override + protected void determineFirmwareInfo(byte[] wholeFirmwareBytes) { + firmwareInfo = new AmazfitBipFirmwareInfo(wholeFirmwareBytes); + if (!firmwareInfo.isHeaderValid()) { + throw new IllegalArgumentException("Not a an Amazifit Bip firmware"); + } + } + + @Override + public void checkValid() throws IllegalArgumentException { + firmwareInfo.checkValid(); + } + + public AmazfitBipFirmwareInfo getFirmwareInfo() { + return firmwareInfo; + } + +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipFWInstallHandler.java new file mode 100644 index 000000000..990d60ea8 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipFWInstallHandler.java @@ -0,0 +1,55 @@ +/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + 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.amazfitbip; + +import android.content.Context; +import android.net.Uri; + +import java.io.IOException; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.model.GenericItem; + +class AmazfitBipFWInstallHandler extends AbstractMiBandFWInstallHandler { + AmazfitBipFWInstallHandler(Uri uri, Context context) { + super(uri, context); + } + + @Override + protected GenericItem createInstallItem() { + return new GenericItem(mContext.getString(R.string.amazfitbip_firmware, helper.getHumanFirmwareVersion())); + } + + @Override + protected String getFwUpgradeNotice() { + return mContext.getString(R.string.fw_upgrade_notice_amazfitbip, helper.getHumanFirmwareVersion()); + } + + @Override + protected AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException { + return new AmazfitBipFWHelper(uri, context); + } + + @Override + protected boolean isSupportedDeviceType(GBDevice device) { + return device.getType() == DeviceType.AMAZFITBIP; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipService.java index 92fe7e858..4140c9798 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Andreas Shimokawa +/* Copyright (C) 2015-2017 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipWeatherConditions.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipWeatherConditions.java index 0284c9bf1..02dd5b9ad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipWeatherConditions.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/AmazfitBipWeatherConditions.java @@ -157,33 +157,4 @@ public class AmazfitBipWeatherConditions { return 0; } } - - public static String mapToOpenWeatherMapIcon(int openWeatherMapCondition) { - //see https://openweathermap.org/weather-conditions - String condition = "02d"; //generic "variable" icon - - if (openWeatherMapCondition >= 200 && openWeatherMapCondition < 300) { - condition = "11d"; - } else if (openWeatherMapCondition >= 300 && openWeatherMapCondition < 500) { - condition = "09d"; - } else if (openWeatherMapCondition >= 500 && openWeatherMapCondition < 510) { - condition = "10d"; - } else if (openWeatherMapCondition >= 511 && openWeatherMapCondition < 600) { - condition = "09d"; - } else if (openWeatherMapCondition >= 600 && openWeatherMapCondition < 700) { - condition = "13d"; - } else if (openWeatherMapCondition >= 700 && openWeatherMapCondition < 800) { - condition = "50d"; - } else if (openWeatherMapCondition == 800) { - condition = "01d"; //TODO: night? - } else if (openWeatherMapCondition == 801) { - condition = "02d"; //TODO: night? - } else if (openWeatherMapCondition == 802) { - condition = "03d"; //TODO: night? - } else if (openWeatherMapCondition == 803 || openWeatherMapCondition == 804) { - condition = "04d"; //TODO: night? - } - - return condition; - } -} +} \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java index d52b698b1..f677ab442 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java @@ -33,8 +33,8 @@ import nodomain.freeyourgadget.gadgetbridge.model.GenericItem; public abstract class AbstractMiBandFWInstallHandler implements InstallHandler { private static final Logger LOG = LoggerFactory.getLogger(AbstractMiBandFWInstallHandler.class); - private final Context mContext; - private AbstractMiBandFWHelper helper; + protected final Context mContext; + protected AbstractMiBandFWHelper helper; private String errorMessage; public AbstractMiBandFWInstallHandler(Uri uri, Context context) { @@ -58,6 +58,13 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler { protected abstract AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException; + protected GenericItem createInstallItem() { + return new GenericItem(mContext.getString(R.string.miband_installhandler_miband_firmware, helper.getHumanFirmwareVersion())); + } + + protected String getFwUpgradeNotice() { + return mContext.getString(R.string.fw_upgrade_notice, helper.getHumanFirmwareVersion()); + } @Override public void validateInstallation(InstallActivity installActivity, GBDevice device) { @@ -81,8 +88,8 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler { return; } - GenericItem fwItem = new GenericItem(mContext.getString(R.string.miband_installhandler_miband_firmware, helper.getHumanFirmwareVersion())); - fwItem.setIcon(R.drawable.ic_device_miband); + GenericItem fwItem = createInstallItem(); + fwItem.setIcon(device.getType().getIcon()); if (!helper.isFirmwareGenerallyCompatibleWith(device)) { fwItem.setDetails(mContext.getString(R.string.miband_fwinstaller_incompatible_version)); @@ -92,7 +99,8 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler { } StringBuilder builder = new StringBuilder(); if (helper.isSingleFirmware()) { - builder.append(mContext.getString(R.string.fw_upgrade_notice, helper.getHumanFirmwareVersion())); + getFwUpgradeNotice(); + builder.append(getFwUpgradeNotice()); } else { builder.append(mContext.getString(R.string.fw_multi_upgrade_notice, helper.getHumanFirmwareVersion(), helper.getHumanFirmwareVersion2())); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java index 138fd275a..912909ae5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java @@ -1,3 +1,19 @@ +/* Copyright (C) 2017 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + 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.miband; public enum DoNotDisturb { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Coordinator.java index 7cc267211..24ca4794a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Carsten Pfeiffer +/* Copyright (C) 2016-2017 Carsten Pfeiffer, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index 90fb9c7b7..6fc1ce244 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2016-2017 Carsten Pfeiffer, JohnnySun, Uwe Hermann +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer, JohnnySun, + José Rebelo, Uwe Hermann This file is part of Gadgetbridge. @@ -53,7 +54,6 @@ public class MiBand2Service { public static final int ALERT_LEVEL_MESSAGE = 1; public static final int ALERT_LEVEL_PHONE_CALL = 2; public static final int ALERT_LEVEL_VIBRATE_ONLY = 3; - public static final int ALERT_LEVEL_CUSTOM = 0xfa; // followed by another uin8 to select the actual icon // set metric distance // set 12 hour time mode @@ -171,6 +171,8 @@ public class MiBand2Service { public static final byte[] COMMAND_DISABLE_GOAL_NOTIFICATION = new byte[]{ENDPOINT_DISPLAY, 0x06, 0x00, 0x00}; public static final byte[] COMMAND_ENABLE_ROTATE_WRIST_TO_SWITCH_INFO = new byte[]{ENDPOINT_DISPLAY, 0x0d, 0x00, 0x01}; public static final byte[] COMMAND_DISABLE_ROTATE_WRIST_TO_SWITCH_INFO = new byte[]{ENDPOINT_DISPLAY, 0x0d, 0x00, 0x00}; + public static final byte[] COMMAND_ENABLE_DISPLAY_CALLER = new byte[]{ENDPOINT_DISPLAY, 0x10, 0x00, 0x00, 0x01}; + public static final byte[] COMMAND_DISABLE_DISPLAY_CALLER = new byte[]{ENDPOINT_DISPLAY, 0x10, 0x00, 0x00, 0x00}; public static final byte[] DISPLAY_XXX = new byte[] {ENDPOINT_DISPLAY, 0x03, 0x0, 0x0 }; public static final byte[] DISPLAY_YYY = new byte[] {ENDPOINT_DISPLAY, 0x10, 0x0, 0x1, 0x1 }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java index cba053dfd..7028be7ce 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java @@ -1,5 +1,5 @@ /* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Christian - Fischer, Daniele Gobbetti, Szymon Tomasz Stefanek + Fischer, Daniele Gobbetti, José Rebelo, Szymon Tomasz Stefanek This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java index 9aabf77ed..cb9337e34 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java @@ -1,5 +1,5 @@ /* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Christian - Fischer, Daniele Gobbetti, Szymon Tomasz Stefanek + Fischer, Daniele Gobbetti, José Rebelo, Szymon Tomasz Stefanek This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java index 102978d65..99d4bd6db 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java @@ -48,6 +48,12 @@ public class MusicPlaybackReceiver extends BroadcastReceiver { MusicStateSpec stateSpec = new MusicStateSpec(lastStateSpec); Bundle incomingBundle = intent.getExtras(); + + if (incomingBundle == null) { + LOG.warn("Not processing incoming null bundle."); + return; + } + for (String key : incomingBundle.keySet()) { Object incoming = incomingBundle.get(key); if (incoming instanceof String && "artist".equals(key)) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationReceiver.java index 0dfd82724..809ebe0f5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationReceiver.java @@ -23,8 +23,6 @@ import android.content.Intent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.SimpleTimeZone; - import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.model.Weather; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; @@ -53,7 +51,7 @@ public class WeatherNotificationReceiver extends BroadcastReceiver { LOG.info("weather in " + weather.location + " is " + weather.currentCondition + " (" + (weather.currentTemp - 273) + "°C)"); WeatherSpec weatherSpec = new WeatherSpec(); - weatherSpec.timestamp = (int) ((weather.queryTime - SimpleTimeZone.getDefault().getOffset(weather.queryTime)) / 1000); + weatherSpec.timestamp = (int) (weather.queryTime / 1000); weatherSpec.location = weather.location; weatherSpec.currentTemp = weather.currentTemp; weatherSpec.currentCondition = weather.currentCondition; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java index 750bde0fd..08bf2fe7e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Daniele Gobbetti +/* Copyright (C) 2016-2017 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCallback.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCallback.java index 107af38da..da5fe2dd5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCallback.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCallback.java @@ -1,3 +1,19 @@ +/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ /* * Copyright (C) 2013 The Android Open Source Project * diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java index 3af81a015..4a896f411 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Carsten Pfeiffer, Uwe Hermann +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer, Uwe Hermann This file is part of Gadgetbridge. @@ -38,7 +38,7 @@ public enum AlertCategory { // 251-255 defined by service specification Any(255), Custom(-1), - CustomAmazfitBip(-6); + CustomMiBand2(-6); private final int id; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java index 062333a5b..11d3d9f47 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Carsten Pfeiffer +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -103,7 +103,7 @@ public class AlertNotificationProfile exten ByteArrayOutputStream stream = new ByteArrayOutputStream(100); stream.write(BLETypeConversions.fromUint8(alert.getCategory().getId())); stream.write(BLETypeConversions.fromUint8(alert.getNumAlerts())); - if (alert.getCategory() == AlertCategory.CustomAmazfitBip) { + if (alert.getCategory() == AlertCategory.CustomMiBand2) { stream.write(BLETypeConversions.fromUint8(alert.getCustomIcon())); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java index 28a836bbb..3aa43dba5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Carsten Pfeiffer +/* Copyright (C) 2017 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipFirmwareInfo.java new file mode 100644 index 000000000..0a126309e --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipFirmwareInfo.java @@ -0,0 +1,80 @@ +/* Copyright (C) 2017 Andreas Shimokawa + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip; + +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.FirmwareType; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.Mi2FirmwareInfo; +import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils; + +public class AmazfitBipFirmwareInfo extends Mi2FirmwareInfo { + // total crap maybe + private static final byte[] GPS_HEADER = new byte[]{ + (byte) 0xcb, 0x51, (byte) 0xc1, 0x30, 0x41, (byte) 0x9e, 0x5e, (byte) 0xd3, + 0x51, 0x35, (byte) 0xdf, 0x66, (byte) 0xed, (byte) 0xd9, 0x5f, (byte) 0xa7 + }; + + // guessed - at least it is the same accross current versions and different from other devices + private static final byte[] FW_HEADER = new byte[]{ + 0x68, 0x46, 0x70, 0x47, 0x68, 0x46, 0x70, 0x47, + 0x68, 0x46, 0x70, 0x47, 0x68, 0x46, 0x70, 0x47 + }; + + private static final int FW_HEADER_OFFSET = 0x9330; + + private static final byte[] RES_HEADER = new byte[]{ // HMRES resources file (*.res) + 0x48, 0x4d, 0x52, 0x45, 0x53 + }; + + + static { + // firmware + crcToVersion.put(25257, "0.0.8.74"); + + // resources + crcToVersion.put(12586, "RES 0.0.8.74"); + + // gps + crcToVersion.put(61520, "GPS 0.0.8.xx"); + } + + public AmazfitBipFirmwareInfo(byte[] bytes) { + super(bytes); + } + + @Override + protected FirmwareType determineFirmwareType(byte[] bytes) { + if (ArrayUtils.startsWith(bytes, RES_HEADER)) { + return FirmwareType.RES; + } + if (ArrayUtils.startsWith(bytes, GPS_HEADER)) { + return FirmwareType.GPS; + } + if (ArrayUtils.equals(bytes, FW_HEADER, FW_HEADER_OFFSET)) { + // TODO: this is certainly not a correct validation, but it works for now + return FirmwareType.FIRMWARE; + } + return FirmwareType.INVALID; + } + + @Override + public boolean isGenerallyCompatibleWith(GBDevice device) { + return isHeaderValid() && device.getType() == DeviceType.AMAZFITBIP; + } + +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipSupport.java index 2f549f01f..eb8157fcc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipSupport.java @@ -16,12 +16,16 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip; +import android.net.Uri; +import android.widget.Toast; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.SimpleTimeZone; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; import nodomain.freeyourgadget.gadgetbridge.devices.amazfitbip.AmazfitBipIcon; @@ -35,9 +39,12 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert; +import nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip.operations.AmazfitBipUpdateFirmwareOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.MiBand2Support; +import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; +import nodomain.freeyourgadget.gadgetbridge.util.Version; public class AmazfitBipSupport extends MiBand2Support { @@ -72,7 +79,7 @@ public class AmazfitBipSupport extends MiBand2Support { int customIconId = AmazfitBipIcon.mapToIconId(notificationSpec.type); - AlertCategory alertCategory = AlertCategory.CustomAmazfitBip; + AlertCategory alertCategory = AlertCategory.CustomMiBand2; // The SMS icon for AlertCategory.SMS is unique and not available as iconId if (notificationSpec.type == NotificationType.GENERIC_SMS) { @@ -112,16 +119,41 @@ public class AmazfitBipSupport extends MiBand2Support { evaluateGBDeviceEvent(callCmd); } + @Override + public void onInstallApp(Uri uri) { + try { + new AmazfitBipUpdateFirmwareOperation(uri, this).perform(); + } catch (IOException ex) { + GB.toast(getContext(), "Firmware cannot be installed: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex); + } + } + @Override public void onSendWeather(WeatherSpec weatherSpec) { try { TransactionBuilder builder = performInitialized("Sending weather forecast"); + Version version = new Version(gbDevice.getFirmwareVersion()); + + boolean supportsConditionString = false; + if (version.compareTo(new Version("0.0.8.74")) >= 0) { + supportsConditionString = true; + } + final byte NR_DAYS = 2; - ByteBuffer buf = ByteBuffer.allocate(7 + 4 * NR_DAYS); + int bytesPerDay = 4; + int conditionsLength = 0; + if (supportsConditionString) { + bytesPerDay = 5; + conditionsLength = weatherSpec.currentCondition.getBytes().length; + } + int length = 7 + bytesPerDay * NR_DAYS + conditionsLength; + ByteBuffer buf = ByteBuffer.allocate(length); + buf.order(ByteOrder.LITTLE_ENDIAN); buf.put((byte) 1); buf.putInt(weatherSpec.timestamp); - buf.put((byte) 0); + int tz_offset_hours = SimpleTimeZone.getDefault().getOffset(weatherSpec.timestamp * 1000L) / (1000 * 60 * 60); + buf.put((byte) (tz_offset_hours * 4)); buf.put(NR_DAYS); @@ -130,13 +162,19 @@ public class AmazfitBipSupport extends MiBand2Support { buf.put(condition); buf.put((byte) (weatherSpec.todayMaxTemp - 273)); buf.put((byte) (weatherSpec.todayMinTemp - 273)); - + if (supportsConditionString) { + buf.put(weatherSpec.currentCondition.getBytes()); + buf.put((byte) 0); // + } condition = AmazfitBipWeatherConditions.mapToAmazfitBipWeatherCode(weatherSpec.tomorrowConditionCode); buf.put(condition); buf.put(condition); buf.put((byte) (weatherSpec.tomorrowMaxTemp - 273)); buf.put((byte) (weatherSpec.tomorrowMinTemp - 273)); + if (supportsConditionString) { + buf.put((byte) 0); // not yet in weatherspec + } builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array()); builder.queue(getQueue()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/operations/AmazfitBipUpdateFirmwareOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/operations/AmazfitBipUpdateFirmwareOperation.java new file mode 100644 index 000000000..a27c7ef08 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/operations/AmazfitBipUpdateFirmwareOperation.java @@ -0,0 +1,49 @@ +/* Copyright (C) 2017 Andreas Shimokawa + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip.operations; + +import android.net.Uri; +import android.widget.Toast; + +import java.io.IOException; + +import nodomain.freeyourgadget.gadgetbridge.devices.amazfitbip.AmazfitBipFWHelper; +import nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip.AmazfitBipSupport; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations.UpdateFirmwareOperation; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class AmazfitBipUpdateFirmwareOperation extends UpdateFirmwareOperation { + public AmazfitBipUpdateFirmwareOperation(Uri uri, AmazfitBipSupport support) { + super(uri, support); + } + + @Override + protected void doPerform() throws IOException { + AmazfitBipFWHelper mFwHelper = new AmazfitBipFWHelper(uri, getContext()); + + firmwareInfo = mFwHelper.getFirmwareInfo(); + if (!firmwareInfo.isGenerallyCompatibleWith(getDevice())) { + throw new IOException("Firmware is not compatible with the given device: " + getDevice().getAddress()); + } + + if (!sendFwInfo()) { + displayMessage(getContext(), "Error sending firmware info, aborting.", Toast.LENGTH_LONG, GB.ERROR); + done(); + } + //the firmware will be sent by the notification listener if the band confirms that the metadata are ok. + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 222d97a69..dee5805a6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -1,5 +1,5 @@ /* Copyright (C) 2016-2017 Alberto, Andreas Shimokawa, Carsten Pfeiffer, - ivanovlev, João Paulo Barraca + ivanovlev, João Paulo Barraca, Pavel Motyrev This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index 7b988b733..a67543b36 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -1,6 +1,6 @@ /* Copyright (C) 2015-2017 Andreas Shimokawa, atkyritsis, Carsten Pfeiffer, - Christian Fischer, Daniele Gobbetti, JohnnySun, Julien Pivotto, Kasha, - Sergey Trofimov, Steffen Liebergeld + Christian Fischer, Daniele Gobbetti, freezed-or-frozen, JohnnySun, Julien + Pivotto, Kasha, Sergey Trofimov, Steffen Liebergeld This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/FirmwareType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/FirmwareType.java index ce9b6b7ba..b83131fa1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/FirmwareType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/FirmwareType.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Carsten Pfeiffer +/* Copyright (C) 2017 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -19,8 +19,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband2; public enum FirmwareType { FIRMWARE((byte) 0), FONT((byte) 1), - UNKNOWN1((byte) 2), - UNKNOWN2((byte) 3), + RES((byte) 2), + GPS((byte) 3), INVALID(Byte.MIN_VALUE); private final byte value; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java index a08a27afa..ff13165d3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Carsten Pfeiffer +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -53,7 +53,7 @@ public class Mi2FirmwareInfo { 0x4b }; - private static Map crcToVersion = new HashMap<>(); + protected static Map crcToVersion = new HashMap<>(); static { // firmware crcToVersion.put(41899, "1.0.0.39"); @@ -89,7 +89,7 @@ public class Mi2FirmwareInfo { firmwareType = determineFirmwareType(bytes); } - private FirmwareType determineFirmwareType(byte[] bytes) { + protected FirmwareType determineFirmwareType(byte[] bytes) { if (ArrayUtils.startsWith(bytes, FT_HEADER)) { return FirmwareType.FONT; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java index 416da22d5..8b6d11f65 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Carsten Pfeiffer +/* Copyright (C) 2017 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -18,7 +18,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband2; import android.bluetooth.BluetoothGattCharacteristic; import android.support.annotation.NonNull; -import android.util.Log; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; @@ -67,11 +66,11 @@ public class Mi2TextNotificationStrategy extends Mi2NotificationStrategy { if (simpleNotification != null) { switch (simpleNotification.getAlertCategory()) { case Email: - return new byte[] { BLETypeConversions.fromUint8(MiBand2Service.ALERT_LEVEL_MESSAGE), BLETypeConversions.fromUint8(numAlerts)}; + return new byte[] { BLETypeConversions.fromUint8(AlertCategory.Email.getId()), BLETypeConversions.fromUint8(numAlerts)}; case InstantMessage: - return new byte[] { BLETypeConversions.fromUint8(MiBand2Service.ALERT_LEVEL_CUSTOM), BLETypeConversions.fromUint8(numAlerts), MiBand2Service.ICON_CHAT}; + return new byte[] { BLETypeConversions.fromUint8(AlertCategory.CustomMiBand2.getId()), BLETypeConversions.fromUint8(numAlerts), MiBand2Service.ICON_CHAT}; case News: - return new byte[] { BLETypeConversions.fromUint8(MiBand2Service.ALERT_LEVEL_CUSTOM), BLETypeConversions.fromUint8(numAlerts), MiBand2Service.ICON_PENGUIN}; + return new byte[] { BLETypeConversions.fromUint8(AlertCategory.CustomMiBand2.getId()), BLETypeConversions.fromUint8(numAlerts), MiBand2Service.ICON_PENGUIN}; } } return new byte[] { BLETypeConversions.fromUint8(AlertCategory.SMS.getId()), BLETypeConversions.fromUint8(numAlerts)}; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java index 18db942aa..1ccf040e6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java @@ -1,6 +1,6 @@ /* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Christian - Fischer, Daniele Gobbetti, JohnnySun, Julien Pivotto, Kasha, Sergey Trofimov, - Steffen Liebergeld + Fischer, Daniele Gobbetti, JohnnySun, José Rebelo, Julien Pivotto, Kasha, + Sergey Trofimov, Steffen Liebergeld This file is part of Gadgetbridge. @@ -1215,6 +1215,11 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } + private MiBand2Support setDisplayCaller(TransactionBuilder builder) { + builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_ENABLE_DISPLAY_CALLER); + return this; + } + private MiBand2Support setDoNotDisturb(TransactionBuilder builder) { DoNotDisturb doNotDisturb = MiBand2Coordinator.getDoNotDisturb(getContext()); LOG.info("Setting do not disturb to " + doNotDisturb); @@ -1314,6 +1319,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { setDoNotDisturb(builder); setRotateWristToSwitchInfo(builder); setActivateDisplayOnLiftWrist(builder); + setDisplayCaller(builder); setGoalNotification(builder); setInactivityWarnings(builder); setHeartrateSleepSupport(builder); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/UpdateFirmwareOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/UpdateFirmwareOperation.java index 3e48640cd..fd5793e8d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/UpdateFirmwareOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/UpdateFirmwareOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Carsten Pfeiffer +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -48,11 +48,11 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class UpdateFirmwareOperation extends AbstractMiBand2Operation { private static final Logger LOG = LoggerFactory.getLogger(UpdateFirmwareOperation.class); - private final Uri uri; - private final BluetoothGattCharacteristic fwCControlChar; - private final BluetoothGattCharacteristic fwCDataChar; - final Prefs prefs = GBApplication.getPrefs(); - private Mi2FirmwareInfo firmwareInfo; + protected final Uri uri; + protected final BluetoothGattCharacteristic fwCControlChar; + protected final BluetoothGattCharacteristic fwCDataChar; + protected final Prefs prefs = GBApplication.getPrefs(); + protected Mi2FirmwareInfo firmwareInfo; public UpdateFirmwareOperation(Uri uri, MiBand2Support support) { super(support); @@ -82,7 +82,7 @@ public class UpdateFirmwareOperation extends AbstractMiBand2Operation { //the firmware will be sent by the notification listener if the band confirms that the metadata are ok. } - private void done() { + protected void done() { LOG.info("Operation done."); operationFinished(); unsetBusy(); @@ -163,7 +163,7 @@ public class UpdateFirmwareOperation extends AbstractMiBand2Operation { done(); } } - private void displayMessage(Context context, String message, int duration, int severity) { + protected void displayMessage(Context context, String message, int duration, int severity) { getSupport().handleGBDeviceEvent(new GBDeviceEventDisplayMessage(message, duration, severity)); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java index 01af3d819..d94f12b65 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 Carsten Pfeiffer +/* Copyright (C) 2016-2017 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ImportExportSharedPreferences.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ImportExportSharedPreferences.java index 77dd0f669..a4f75191b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ImportExportSharedPreferences.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ImportExportSharedPreferences.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Alberto, Carsten Pfeiffer +/* Copyright (C) 2017 Alberto, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java index 66193245a..246940f5a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2017 ivanovlev, Yaron Shahrabani +/* Copyright (C) 2017 Andreas Shimokawa, ivanovlev, lazarosfs, Yaron + Shahrabani This file is part of Gadgetbridge. 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 409557db6..2342e7608 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java @@ -1,3 +1,19 @@ +/* Copyright (C) 2017 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.util; import android.content.Context; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java index df0efe2c2..82a397f78 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java @@ -28,7 +28,9 @@ public class Version implements Comparable { public Version(String version) { if(version == null) throw new IllegalArgumentException("Version can not be null"); - if(!version.matches("[0-9]+(\\.[0-9]+)*")) + + version = version.trim(); + if (!version.matches("[0-9]+(\\.[0-9]+)*")) throw new IllegalArgumentException("Invalid version format"); this.version = version; } diff --git a/app/src/main/res/color/btn_dark.xml b/app/src/main/res/color/btn_dark.xml new file mode 100644 index 000000000..0e4a3f3db --- /dev/null +++ b/app/src/main/res/color/btn_dark.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_history_black.xml b/app/src/main/res/drawable/ic_history_black.xml new file mode 100644 index 000000000..d9f75ea6d --- /dev/null +++ b/app/src/main/res/drawable/ic_history_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_db_management.xml b/app/src/main/res/layout/activity_db_management.xml index a66eba216..56cbe2c39 100644 --- a/app/src/main/res/layout/activity_db_management.xml +++ b/app/src/main/res/layout/activity_db_management.xml @@ -6,53 +6,49 @@ - + android:paddingTop="@dimen/activity_vertical_margin" + grid:alignmentMode="alignBounds" + grid:columnCount="2"> - +