activity_files 0.7.6
activity_files: ^0.7.6 copied to clipboard
A pure Dart toolkit for parsing, editing, validating, and converting workout activity files in GPX, TCX, FIT, GeoJSON, and CSV formats.
activity_files #
A pure Dart toolkit for parsing, editing, validating, and converting workout activity files in GPX, TCX, FIT, GeoJSON, and CSV formats.
Highlights #
- Format-agnostic
RawActivitymodel covering GPS points, laps, sensor channels, and device metadata. ActivityFilesfacade and CLI: load, normalize, validate, and convert between all five formats in a few calls.- Stream-aware builders (
builderFromStreams,convertAndExport) accept raw timestamp/value tuples, so servers can skip manual model assembly. - Parsers never throw on malformed files; every issue is reported as a
diagnostic with a stable
code, asuggestedFix, and apriority. - FIT session and lap statistics on
ActivitySummaryandLap, mapped per the official FIT profile and verified against real device files, including swim metrics (pool length, stroke, lengths) and strength sets (WorkoutSet). - Point-level editing on
RawEditor:insertPoint,deletePointAt,updatePoint,deleteRange,insertPause,removePause. - Multi-sport workflows:
ActivityFiles.merge(preserveSportPerLap: true)combines swim/bike/run files into one triathlon;splitBySport()breaks a multi-sport file back into single-sport activities. - Batch import (
ActivityFiles.loadBatch) with per-file error capture and progress reporting. - Multi-track GPX round-trips: extra
<trk>elements survive GPX export; single-track targets (TCX/FIT/CSV/GeoJSON) merge them so no points are lost. - Encoder options for GPX 1.0/1.1 and TCX v1/v2 output, channel tolerances, and coordinate precision.
Found a bug, or have real-world files to share? #
Open an issue with a sample file and what you expected vs. got.
Real-world GPX, TCX, FIT, GeoJSON, and CSV files are also highly appreciated. (I only have one device to test against). Used for local testing only, never published or committed.
Send to: packages@eikedreier.xyz
Quick links #
- Usage guide – Flutter, CLI, streaming, and error-handling walkthroughs.
- Example app – runnable end-to-end demo: load, edit, validate, export.
- CHANGELOG – migration notes and release history.
Getting started #
Add the package to pubspec.yaml:
dependencies:
activity_files: ^0.7.6
Then install dependencies:
dart pub get
Then jump straight into the facade:
import 'package:activity_files/activity_files.dart';
Future<void> convertGpxToFit(Uint8List bytes) async {
// 1) Load + auto-detect format.
final load = await ActivityFiles.load(
bytes,
useIsolate: true,
);
if (load.hasErrors) {
throw StateError('Load failed:\n${load.diagnosticsSummary()}');
}
// 2) Normalize (sort/dedup + trim invalid points) before exporting.
final normalized = ActivityFiles.normalizeActivity(load.activity);
// 3) Export with validation so warnings/errors surface alongside the payload.
final export = ActivityFiles.export(
activity: normalized,
to: ActivityFileFormat.fit,
runValidation: true,
);
if (export.hasErrors) {
throw StateError('Export failed:\n${export.diagnosticsSummary()}');
}
// 4) Use the payload. FIT is binary; GPX/TCX use `asString()`.
final fitBytes = export.asBytes();
// upload(fitBytes);
}
For the detailed Flutter, streaming, CLI, and isolate walkthroughs, see the
usage guide; for a complete runnable program
(load → normalize → validate → export), see example/main.dart.
Working with large or malformed files #
- Parsing/export never throw on malformed input; check
hasErrorsanddiagnosticsSummary()on the result (see error handling). - Inline payloads/streams are capped at 64MB
(
ActivityFiles.defaultMaxPayloadBytes); useuseIsolate/exportInIsolateand the streaming APIs for bigger files (see async export & streaming). - GPX multi-track inputs are flattened when exported to single-track formats (no points lost); TCX multi-activity inputs are merged on parse instead, with per-lap sport preserved. See format handling for details.
Contributing #
Issues and pull requests are welcome, especially for additional format fixtures. The package is released under the BSD 3-Clause license.