From e0a49c95ecf27d2d57022a63d8671d159b76bb1d Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 21 Oct 2026 20:58:27 +0200 Subject: [PATCH] fix: name a development manufacturer in the course's FileId gexporter is not a Garmin product. Like the FIT SDK's EncodeCourse example, write Manufacturer.DEVELOPMENT with product 0 instead of Manufacturer.GARMIN with the made-up product 12345. The serial number stays 12345, as in the example. --- .../java/org/surfsite/gexporter/Gpx2Fit.java | 4 ++-- .../org/surfsite/gexporter/TestCourseFit.java | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/surfsite/gexporter/Gpx2Fit.java b/app/src/main/java/org/surfsite/gexporter/Gpx2Fit.java index fe18665..2057db9 100644 --- a/app/src/main/java/org/surfsite/gexporter/Gpx2Fit.java +++ b/app/src/main/java/org/surfsite/gexporter/Gpx2Fit.java @@ -507,9 +507,9 @@ public void writeFit(File outfile) { { //Generate FileIdMessage FileIdMesg fileIdMesg = new FileIdMesg(); // Every FIT file MUST contain a 'File ID' message as the first message - fileIdMesg.setManufacturer(Manufacturer.GARMIN); + fileIdMesg.setManufacturer(Manufacturer.DEVELOPMENT); // not a Garmin product, as in the FIT SDK's EncodeCourse example fileIdMesg.setType(com.garmin.fit.File.COURSE); - fileIdMesg.setProduct(12345); + fileIdMesg.setProduct(0); fileIdMesg.setSerialNumber(12345L); fileIdMesg.setNumber(trkPoints.hashCode()); fileIdMesg.setTimeCreated(new DateTime(new Date())); diff --git a/app/src/test/java/org/surfsite/gexporter/TestCourseFit.java b/app/src/test/java/org/surfsite/gexporter/TestCourseFit.java index 5571e0f..b2bac3b 100644 --- a/app/src/test/java/org/surfsite/gexporter/TestCourseFit.java +++ b/app/src/test/java/org/surfsite/gexporter/TestCourseFit.java @@ -6,6 +6,8 @@ import com.garmin.fit.CoursePointMesg; import com.garmin.fit.Decode; +import com.garmin.fit.FileIdMesg; +import com.garmin.fit.Manufacturer; import com.garmin.fit.MesgBroadcaster; import com.garmin.fit.RecordMesg; @@ -32,6 +34,7 @@ public class TestCourseFit { private final List records = new ArrayList<>(); private final List coursePoints = new ArrayList<>(); + private final List fileIds = new ArrayList<>(); /** A straight track north, 0.01° (about 1.1 km) per point. */ private File gpx(String wpts, String timeFormat) throws Exception { @@ -64,6 +67,7 @@ private void convertAndDecode(File gpx) throws Exception { MesgBroadcaster broadcaster = new MesgBroadcaster(decode); broadcaster.addListener((com.garmin.fit.RecordMesgListener) records::add); broadcaster.addListener((com.garmin.fit.CoursePointMesgListener) coursePoints::add); + broadcaster.addListener((com.garmin.fit.FileIdMesgListener) fileIds::add); try (InputStream in = new FileInputStream(fit)) { assertTrue("FIT integrity", decode.checkFileIntegrity(in)); } @@ -115,4 +119,18 @@ public void currentTimesAreKept() throws Exception { long expected = (1788602400000L - 631065600000L) / 1000L; assertEquals(expected, (long) records.get(0).getTimestamp().getTimestamp()); } + + @Test + public void fileIdNamesADevelopmentManufacturer() throws Exception { + convertAndDecode(gpx("", null)); + + // gexporter is not a Garmin product, so it does not claim to be one + // (as in the FIT SDK's EncodeCourse example) + assertEquals(1, fileIds.size()); + FileIdMesg fileId = fileIds.get(0); + assertEquals(com.garmin.fit.File.COURSE, fileId.getType()); + assertEquals(Manufacturer.DEVELOPMENT, (int) fileId.getManufacturer()); + assertEquals(0, (int) fileId.getProduct()); + assertEquals(12345L, (long) fileId.getSerialNumber()); + } }