From 49ef8c9f40252b30c696e96cf62ceee7abd70b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Wed, 28 Aug 2024 19:18:06 +0100 Subject: [PATCH] Garmin: View and share gpx files --- .../activities/ActivitySummaryDetail.java | 174 ++++++++++++------ .../devices/garmin/GarminWorkoutParser.java | 5 + .../gadgetbridge/export/GPXExporter.java | 30 +-- .../model/ActivitySummaryEntries.java | 7 + .../model/ActivitySummaryJsonSummary.java | 3 + .../banglejs/BangleJSActivityTrack.java | 8 +- .../devices/cmfwatchpro/CmfActivitySync.java | 1 - .../fetch/FetchSportsDetailsOperation.java | 8 +- .../activity/impl/WorkoutGpsParser.java | 1 - app/src/main/res/xml/shared_paths.xml | 1 + 10 files changed, 152 insertions(+), 86 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java index 7ef8c3230..ba9832a52 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java @@ -49,6 +49,7 @@ import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.core.content.FileProvider; @@ -73,20 +74,24 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; -import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.export.ActivityTrackExporter; +import nodomain.freeyourgadget.gadgetbridge.export.GPXExporter; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; +import nodomain.freeyourgadget.gadgetbridge.model.ActivityPoint; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryItems; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryJsonSummary; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser; +import nodomain.freeyourgadget.gadgetbridge.model.ActivityTrack; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitFile; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitRecord; import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; @@ -141,7 +146,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity { final long dateToFilter = bundle.getLong("dateToFilter", 0); final long deviceFilter = bundle.getLong("deviceFilter", 0); final String nameContainsFilter = bundle.getString("nameContainsFilter"); - final List itemsFilter = (List) bundle.getSerializable("itemsFilter"); + final List itemsFilter = (List) bundle.getSerializable("itemsFilter"); final ActivitySummaryItems items = new ActivitySummaryItems(this, gbDevice, activityFilter, dateFromFilter, dateToFilter, nameContainsFilter, deviceFilter, itemsFilter); final ScrollView layout = findViewById(R.id.activity_summary_detail_scroll_layout); @@ -184,11 +189,11 @@ public class ActivitySummaryDetail extends AbstractGBActivity { makeSummaryHeader(newItem); makeSummaryContent(newItem); activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), currentItem.getStartTime().getTime() / 1000, currentItem.getEndTime().getTime() / 1000); - if (getTrackFile() != null) { - showCanvas(); + if (itemHasGps()) { + showGpsCanvas(); activitySummariesGpsFragment.set_data(getTrackFile()); } else { - hideCanvas(); + hideGpsCanvas(); } layout.startAnimation(animFadeRight); @@ -206,11 +211,11 @@ public class ActivitySummaryDetail extends AbstractGBActivity { makeSummaryHeader(newItem); makeSummaryContent(newItem); activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), currentItem.getStartTime().getTime() / 1000, currentItem.getEndTime().getTime() / 1000); - if (getTrackFile() != null) { - showCanvas(); + if (itemHasGps()) { + showGpsCanvas(); activitySummariesGpsFragment.set_data(getTrackFile()); } else { - hideCanvas(); + hideGpsCanvas(); } @@ -227,11 +232,11 @@ public class ActivitySummaryDetail extends AbstractGBActivity { makeSummaryHeader(currentItem); makeSummaryContent(currentItem); activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), currentItem.getStartTime().getTime() / 1000, currentItem.getEndTime().getTime() / 1000); - if (getTrackFile() != null) { - showCanvas(); + if (itemHasGps()) { + showGpsCanvas(); activitySummariesGpsFragment.set_data(getTrackFile()); } else { - hideCanvas(); + hideGpsCanvas(); } } @@ -320,11 +325,11 @@ public class ActivitySummaryDetail extends AbstractGBActivity { public void onClick(DialogInterface dialog, int which) { currentItem.setGpxTrack(selectedGpxFile); currentItem.update(); - if (getTrackFile() != null) { - showCanvas(); + if (itemHasGps()) { + showGpsCanvas(); activitySummariesGpsFragment.set_data(getTrackFile()); } else { - hideCanvas(); + hideGpsCanvas(); } } }) @@ -590,14 +595,14 @@ public class ActivitySummaryDetail extends AbstractGBActivity { private void take_share_screenshot(Context context) { final ScrollView layout = findViewById(R.id.activity_summary_detail_scroll_layout); - int width = layout.getChildAt(0).getHeight(); - int height = layout.getChildAt(0).getWidth(); - Bitmap screenShot = getScreenShot(layout, width, height, context); + final int width = layout.getChildAt(0).getWidth(); + final int height = layout.getChildAt(0).getHeight(); + final Bitmap screenShot = getScreenShot(layout, height, width, context); - String fileName = FileUtils.makeValidFileName("Screenshot-" + ActivityKind.fromCode(currentItem.getActivityKind()).getLabel(context).toLowerCase() + "-" + DateTimeUtils.formatIso8601(currentItem.getStartTime()) + ".png"); + final String fileName = FileUtils.makeValidFileName("Screenshot-" + ActivityKind.fromCode(currentItem.getActivityKind()).getLabel(context).toLowerCase() + "-" + DateTimeUtils.formatIso8601(currentItem.getStartTime()) + ".png"); try { - File targetFile = new File(FileUtils.getExternalFilesDir(), fileName); - FileOutputStream fOut = new FileOutputStream(targetFile); + final File targetFile = new File(FileUtils.getExternalFilesDir(), fileName); + final FileOutputStream fOut = new FileOutputStream(targetFile); screenShot.compress(Bitmap.CompressFormat.PNG, 85, fOut); fOut.flush(); fOut.close(); @@ -626,27 +631,70 @@ public class ActivitySummaryDetail extends AbstractGBActivity { } private void viewGpxTrack(Context context) { - final String gpxTrack = currentItem.getGpxTrack(); - - if (gpxTrack != null) { - try { - AndroidUtils.viewFile(gpxTrack, "application/gpx+xml", context); - } catch (IOException e) { - GB.toast(getApplicationContext(), "Unable to display GPX track: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e); - } - } else { + final File trackFile = getTrackFile(); + if (trackFile == null) { GB.toast(getApplicationContext(), "No GPX track in this activity", Toast.LENGTH_LONG, GB.INFO); + return; + } + + try { + if (trackFile.getName().endsWith(".gpx")) { + AndroidUtils.viewFile(trackFile.getPath(), "application/gpx+xml", context); + } else if (trackFile.getName().endsWith(".fit")) { + final File gpxFile = convertFitToGpx(trackFile); + AndroidUtils.viewFile(gpxFile.getPath(), "application/gpx+xml", context); + } else { + GB.toast(getApplicationContext(), "Unknown track format", Toast.LENGTH_LONG, GB.INFO); + } + } catch (final Exception e) { + GB.toast(getApplicationContext(), "Unable to display GPX track: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e); } } - private static void shareGpxTrack(final Context context, final BaseActivitySummary summary) { + private void shareGpxTrack(final Context context, final BaseActivitySummary summary) { + final File trackFile = getTrackFile(); + if (trackFile == null) { + GB.toast(getApplicationContext(), "No GPX track in this activity", Toast.LENGTH_LONG, GB.INFO); + return; + } + try { - AndroidUtils.shareFile(context, new File(summary.getGpxTrack())); + if (trackFile.getName().endsWith(".gpx")) { + AndroidUtils.shareFile(context, trackFile); + } else if (trackFile.getName().endsWith(".fit")) { + final File gpxFile = convertFitToGpx(trackFile); + AndroidUtils.shareFile(context, gpxFile); + } else { + GB.toast(getApplicationContext(), "Unknown track format", Toast.LENGTH_LONG, GB.INFO); + } } catch (final Exception e) { GB.toast(context, "Unable to share GPX track: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e); } } + private File convertFitToGpx(final File file) throws IOException, ActivityTrackExporter.GPXTrackEmptyException { + final FitFile fitFile = FitFile.parseIncoming(file); + final List activityPoints = fitFile.getRecords().stream() + .filter(r -> r instanceof FitRecord) + .map(r -> ((FitRecord) r).toActivityPoint()) + .filter(ap -> ap.getLocation() != null) + .collect(Collectors.toList()); + + final ActivityTrack activityTrack = new ActivityTrack(); + activityTrack.setName(currentItem.getName()); + activityTrack.addTrackPoints(activityPoints); + + final File cacheDir = getCacheDir(); + final File rawCacheDir = new File(cacheDir, "gpx"); + rawCacheDir.mkdir(); + final File gpxFile = new File(rawCacheDir, file.getName().replace(".fit", ".gpx")); + + final GPXExporter gpxExporter = new GPXExporter(); + gpxExporter.performExport(activityTrack, gpxFile); + + return gpxFile; + } + private static void shareRawSummary(final Context context, final BaseActivitySummary summary) { if (summary.getRawSummaryData() == null) { GB.toast(context, "No raw summary in this activity", Toast.LENGTH_LONG, GB.WARN); @@ -681,7 +729,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity { boolean hasRawDetails = false; if (currentItem != null) { - hasGpx = currentItem.getGpxTrack() != null; + hasGpx = itemHasGps(); hasRawSummary = currentItem.getRawSummaryData() != null; final String rawDetailsPath = currentItem.getRawDetailsPath(); @@ -698,20 +746,40 @@ public class ActivitySummaryDetail extends AbstractGBActivity { devToolsMenu.setVisible(devToolsMenu.getSubMenu().hasVisibleItems()); } - private void showCanvas() { - View gpsView = findViewById(R.id.gpsFragmentHolder); - ViewGroup.LayoutParams params = gpsView.getLayoutParams(); + private void showGpsCanvas() { + final View gpsView = findViewById(R.id.gpsFragmentHolder); + final ViewGroup.LayoutParams params = gpsView.getLayoutParams(); params.height = (int) (300 * getApplicationContext().getResources().getDisplayMetrics().density); gpsView.setLayoutParams(params); } - private void hideCanvas() { - View gpsView = findViewById(R.id.gpsFragmentHolder); - ViewGroup.LayoutParams params = gpsView.getLayoutParams(); + private void hideGpsCanvas() { + final View gpsView = findViewById(R.id.gpsFragmentHolder); + final ViewGroup.LayoutParams params = gpsView.getLayoutParams(); params.height = 0; gpsView.setLayoutParams(params); } + private boolean itemHasGps() { + if (currentItem.getGpxTrack() != null) { + return new File(currentItem.getGpxTrack()).canRead(); + } + final String summaryData = currentItem.getSummaryData(); + if (summaryData.contains(INTERNAL_HAS_GPS)) { + try { + final JSONObject summaryDataObject = new JSONObject(summaryData); + final JSONObject internalHasGps = summaryDataObject.getJSONObject(INTERNAL_HAS_GPS); + return "true".equals(internalHasGps.optString("value", "false")); + } catch (final JSONException e) { + LOG.error("Failed to parse summary data json", e); + return false; + } + } + + return false; + } + + @Nullable private File getTrackFile() { final String gpxTrack = currentItem.getGpxTrack(); if (gpxTrack != null) { @@ -734,9 +802,8 @@ public class ActivitySummaryDetail extends AbstractGBActivity { return null; } - @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(final Menu menu) { super.onCreateOptionsMenu(menu); mOptionsMenu = menu; getMenuInflater().inflate(R.menu.activity_take_screenshot_menu, menu); @@ -744,21 +811,12 @@ public class ActivitySummaryDetail extends AbstractGBActivity { return true; } - private GBDevice getGBDevice(Device findDevice) { - DaoSession daoSession; - GBApplication gbApp = (GBApplication) getApplicationContext(); - List devices = gbApp.getDeviceManager().getDevices(); - - try (DBHandler handler = GBApplication.acquireDB()) { - daoSession = handler.getDaoSession(); - for (GBDevice device : devices) { - Device dbDevice = DBHelper.findDevice(device, daoSession); - if (dbDevice.equals(findDevice)) return device; - } - } catch (Exception e) { - LOG.debug("Error getting device: " + e); - } - return null; + @Nullable + private static GBDevice getGBDevice(final Device findDevice) { + return GBApplication.app().getDeviceManager().getDevices() + .stream() + .filter(d -> d.getAddress().equalsIgnoreCase(findDevice.getIdentifier())) + .findFirst() + .orElse(null); } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminWorkoutParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminWorkoutParser.java index 1036059fe..197020bf5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminWorkoutParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminWorkoutParser.java @@ -250,6 +250,11 @@ public class GarminWorkoutParser implements ActivitySummaryParser { } } + summaryData.add( + INTERNAL_HAS_GPS, + String.valueOf(activityPoints.stream().anyMatch(p -> p.getLocation() != null)) + ); + summary.setSummaryData(summaryData.toString()); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java index ae4b1a836..620d5d037 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java @@ -33,7 +33,9 @@ import java.util.Date; import java.util.List; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils; +import nodomain.freeyourgadget.gadgetbridge.entities.User; import nodomain.freeyourgadget.gadgetbridge.model.ActivityPoint; import nodomain.freeyourgadget.gadgetbridge.model.ActivityTrack; import nodomain.freeyourgadget.gadgetbridge.model.GPSCoordinate; @@ -68,7 +70,11 @@ public class GPXExporter implements ActivityTrackExporter { ser.startTag(NS_GPX_URI, "gpx"); ser.attribute(null, "version", "1.1"); - ser.attribute(null, "creator", getCreator()); + if (creator != null) { + ser.attribute(null, "creator", creator); + } else { + ser.attribute(null, "creator", GBApplication.app().getNameAndVersion()); + } ser.attribute(NS_XSI_URI, "schemaLocation", NS_GPX_URI + " " + TOPOGRAFIX_NAMESPACE_XSD + " " + OPENTRACKS_NAMESPACE_URI + " " + OPENTRACKS_NAMESPACE_XSD); @@ -84,11 +90,16 @@ public class GPXExporter implements ActivityTrackExporter { private void exportMetadata(XmlSerializer ser, ActivityTrack track) throws IOException { ser.startTag(NS_GPX_URI, "metadata"); - ser.startTag(NS_GPX_URI, "name").text(track.getName()).endTag(NS_GPX_URI, "name"); + if (track.getName() != null) { + ser.startTag(NS_GPX_URI, "name").text(track.getName()).endTag(NS_GPX_URI, "name"); + } - ser.startTag(NS_GPX_URI, "author"); - ser.startTag(NS_GPX_URI, "name").text(track.getUser().getName()).endTag(NS_GPX_URI, "name"); - ser.endTag(NS_GPX_URI, "author"); + final User user = track.getUser(); + if (user != null) { + ser.startTag(NS_GPX_URI, "author"); + ser.startTag(NS_GPX_URI, "name").text(user.getName()).endTag(NS_GPX_URI, "name"); + ser.endTag(NS_GPX_URI, "author"); + } ser.startTag(NS_GPX_URI, "time").text(formatTime(new Date())).endTag(NS_GPX_URI, "time"); @@ -107,7 +118,6 @@ public class GPXExporter implements ActivityTrackExporter { ser.endTag(NS_GPX_URI, "extensions"); List> segments = track.getSegments(); - String source = getSource(track); boolean atLeastOnePointExported = false; for (List segment : segments) { if (segment.isEmpty()) { @@ -117,7 +127,7 @@ public class GPXExporter implements ActivityTrackExporter { ser.startTag(NS_GPX_URI, "trkseg"); for (ActivityPoint point : segment) { - atLeastOnePointExported |= exportTrackPoint(ser, point, source, segment); + atLeastOnePointExported |= exportTrackPoint(ser, point, segment); } ser.endTag(NS_GPX_URI, "trkseg"); } @@ -129,11 +139,7 @@ public class GPXExporter implements ActivityTrackExporter { ser.endTag(NS_GPX_URI, "trk"); } - private String getSource(ActivityTrack track) { - return track.getDevice().getName(); - } - - private boolean exportTrackPoint(XmlSerializer ser, ActivityPoint point, String source, List trackPoints) throws IOException { + private boolean exportTrackPoint(XmlSerializer ser, ActivityPoint point, List trackPoints) throws IOException { GPSCoordinate location = point.getLocation(); if (location == null) { return false; // skip invalid points, that just contain hr data, for example diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryEntries.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryEntries.java index cff10357d..92cba8e34 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryEntries.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryEntries.java @@ -140,4 +140,11 @@ public class ActivitySummaryEntries { public static final String UNIT_DEGREES = "degrees"; public static final String GROUP_PACE = "Pace"; + + /** + * Used to signal that this activity has a gps track. This is currently used by ActivitySummaryDetail + * to display the share and view gpx buttons, even though there's no gpx file. + * FIXME: We should have a cleaner way of doing this. + */ + public static final String INTERNAL_HAS_GPS = "internal_hasGps"; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java index 321d2b3dd..ef1d3a7e0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java @@ -132,6 +132,9 @@ public class ActivitySummaryJsonSummary { while (keys.hasNext()) { String key = keys.next(); + if (INTERNAL_HAS_GPS.equals(key)) { + continue; + } try { JSONObject innerData = (JSONObject) summaryDatalist.get(key); Object value = innerData.get("value"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSActivityTrack.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSActivityTrack.java index 4acc39332..17c85ebb1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSActivityTrack.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSActivityTrack.java @@ -575,7 +575,7 @@ class BangleJSActivityTrack { point = new ActivityPoint(); } - ActivityTrackExporter exporter = createExporter(); + ActivityTrackExporter exporter = new GPXExporter(); String trackType = "track"; switch (ActivityKind.fromCode(summary.getActivityKind())) { case CYCLING: @@ -812,12 +812,6 @@ class BangleJSActivityTrack { } } - private static ActivityTrackExporter createExporter() { - GPXExporter exporter = new GPXExporter(); - exporter.setCreator(GBApplication.app().getNameAndVersion()); - return exporter; - } - private static JSONObject addSummaryData(JSONObject summaryData, String key, float value, String unit) { if (value > 0) { try { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cmfwatchpro/CmfActivitySync.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cmfwatchpro/CmfActivitySync.java index d4d2010bd..c8e214798 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cmfwatchpro/CmfActivitySync.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cmfwatchpro/CmfActivitySync.java @@ -544,7 +544,6 @@ public class CmfActivitySync { @Nullable private File exportGpx(final BaseActivitySummary summary, final ActivityTrack activityTrack) { final GPXExporter exporter = new GPXExporter(); - exporter.setCreator(GBApplication.app().getNameAndVersion()); final String gpxFileName = FileUtils.makeValidFileName("gadgetbridge-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx"); final File gpxTargetFile; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/fetch/FetchSportsDetailsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/fetch/FetchSportsDetailsOperation.java index deea6d5cd..f4663ffde 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/fetch/FetchSportsDetailsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/fetch/FetchSportsDetailsOperation.java @@ -97,7 +97,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { try { final ActivityTrack track = detailsParser.parse(buffer.toByteArray()); - final ActivityTrackExporter exporter = createExporter(); + final ActivityTrackExporter exporter = new GPXExporter(); final String trackType; switch (ActivityKind.fromCode(summary.getActivityKind())) { case CYCLING: @@ -183,12 +183,6 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { return true; } - private ActivityTrackExporter createExporter() { - final GPXExporter exporter = new GPXExporter(); - exporter.setCreator(GBApplication.app().getNameAndVersion()); - return exporter; - } - @Override protected String getLastSyncTimeKey() { return lastSyncTimeKey; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/impl/WorkoutGpsParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/impl/WorkoutGpsParser.java index a3e5d5c71..5e0efdce9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/impl/WorkoutGpsParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/impl/WorkoutGpsParser.java @@ -118,7 +118,6 @@ public class WorkoutGpsParser extends XiaomiActivityParser { // Save the gpx file final GPXExporter exporter = new GPXExporter(); - exporter.setCreator(GBApplication.app().getNameAndVersion()); final String gpxFileName = FileUtils.makeValidFileName("gadgetbridge-" + DateTimeUtils.formatIso8601(fileId.getTimestamp()) + ".gpx"); final File gpxTargetFile = new File(FileUtils.getExternalFilesDir(), gpxFileName); diff --git a/app/src/main/res/xml/shared_paths.xml b/app/src/main/res/xml/shared_paths.xml index 302c4af4e..4cd3168de 100644 --- a/app/src/main/res/xml/shared_paths.xml +++ b/app/src/main/res/xml/shared_paths.xml @@ -4,4 +4,5 @@ +