{"id":25219534,"url":"https://github.com/bradpatras/gpx-recorder","last_synced_at":"2026-05-09T06:14:20.758Z","repository":{"id":44432564,"uuid":"111255193","full_name":"BradPatras/gpx-recorder","owner":"BradPatras","description":"Android app to record routes in background and export to gpx/geoJSON files","archived":false,"fork":false,"pushed_at":"2025-10-18T03:35:22.000Z","size":15725,"stargazers_count":50,"open_issues_count":3,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-18T06:58:13.730Z","etag":null,"topics":["android","geojson","gpx","kotlin"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BradPatras.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-11-19T01:37:53.000Z","updated_at":"2025-10-18T03:35:26.000Z","dependencies_parsed_at":"2024-01-07T00:57:05.869Z","dependency_job_id":"3bdc32cc-2698-49af-a3c2-c1edf59fa118","html_url":"https://github.com/BradPatras/gpx-recorder","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/BradPatras/gpx-recorder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BradPatras%2Fgpx-recorder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BradPatras%2Fgpx-recorder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BradPatras%2Fgpx-recorder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BradPatras%2Fgpx-recorder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BradPatras","download_url":"https://codeload.github.com/BradPatras/gpx-recorder/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BradPatras%2Fgpx-recorder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32809154,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","geojson","gpx","kotlin"],"created_at":"2025-02-10T21:09:02.817Z","updated_at":"2026-05-09T06:14:20.718Z","avatar_url":"https://github.com/BradPatras.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gpx-recorder 🛰 🗺\r\n\r\nAndroid app to record gps routes in the background and allow user to export routes to GPX or GeoJSON files\r\n\r\n[Google Play Store link](https://play.google.com/store/apps/details?id=com.iboism.gpxrecorder)\r\n\r\n\u003cimg src=\"sc-1.png\" width=150/\u003e \u0026nbsp;\u0026nbsp;\u0026nbsp; \u003cimg src=\"sc-2.png\" width=150/\u003e\r\n\r\n## Libs and stuff \r\n\r\n- [Realm](https://www.realm.io) for data persistence\r\n- [Dexter](https://github.com/Karumi/Dexter) for permissions\r\n- [FusedLocationProvider](https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient) for location services\r\n- [Apache Commons IO](https://commons.apache.org/proper/commons-io/) for file writing\r\n- [RxJava](https://github.com/ReactiveX/RxJava) for handling everything asynchronous\r\n- [EventBus](https://github.com/greenrobot/EventBus) For assisting with Service↔️App communication\r\n\u003cbr\u003e\u003cbr\u003e\r\n\r\n## Arch Notes\r\n### Background Recording\r\nTo record location in the background, the app uses a [foreground service](https://developer.android.com/guide/components/foreground-services) class, [LocationRecorderService](https://github.com/BradPatras/gpx-recorder/blob/7ba14c9e5d526b578ae5ad00b2dbfdf61f5a8f48/app/src/main/java/com/iboism/gpxrecorder/recording/LocationRecorderService.kt#L26).  The nice thing about using foreground services is that it's much less likely to be killed by over-zealous system optimization initiatives. The main requirement of a foreground service is that you must display a notification as long as it's running. This requirement works perfectly for this app because it allows us to provide the user with route recording actions such as pausing/stopping/adding a waypoint without needing to open the app. \r\n\r\nInternally the `LocationRecorderService` utilizes the [FusedLocationProvider](https://developers.google.com/location-context/fused-location-provider) library from google.  The interface is pretty simple, you feed it a [configuration](https://github.com/BradPatras/gpx-recorder/blob/7ba14c9e5d526b578ae5ad00b2dbfdf61f5a8f48/app/src/main/java/com/iboism/gpxrecorder/model/RecordingConfiguration.kt#L18), start the location request, and then handle the location updates as they roll in.\r\n\r\nThe foreground service is controlled in two ways: \r\n#### Android Intents\r\nWhen a user taps on a button on the foreground service notification, the service receives an intent. It checks the intent's extras for keys and performs the [corresponding action](https://github.com/BradPatras/gpx-recorder/blob/7ba14c9e5d526b578ae5ad00b2dbfdf61f5a8f48/app/src/main/java/com/iboism/gpxrecorder/recording/LocationRecorderService.kt#L61).\r\n\r\n#### Service Binding\r\nThe app can't directly access the running service like a normal static instance or class, a connection must be made using a [Service Binding](https://github.com/BradPatras/gpx-recorder/blob/master/app/src/main/java/com/iboism/gpxrecorder/recording/RecorderServiceConnection.kt).  Once a connection is established, functions of the service can be accessed through the connection.\r\n\r\n[EventBus](https://github.com/greenrobot/EventBus) is also used to allow the service to notify the app when important things happen that may require UI to be updated.\r\n\r\n### Route Storage\r\nThe routes are all stored locally with a [Realm](https://www.realm.io) database. The format of realm object storage makes it really straightforward to store the nested data that makes up a route.  `Routes` have `Waypoints` and `Tracks` which are made up of `Segments` which are made up of `TrackPoints`.  The app is entirely offline focused so the realm database is the source of truth and all updates to the UI related to routes happen as a result of the database being updated.\r\n\r\nA Route is converted to the `gpx` or `geojson` file format on-demand and the app **only** knows how to do `Route` -\u003e `.gpx`/`geojson` conversions.  Converting files back into `Route` objects is not currently a feature.\r\n\r\n## Releases\r\nReleases are now documented using this repo's `Releases` page.\r\n\u003cdetails\u003e\r\n\u003csummary\u003eOlder releases\u003c/summary\u003e\r\n\r\n### - 2.11 | Dec 5, 2023\r\n- Fixed [#43](https://github.com/BradPatras/gpx-recorder/issues/43), [#44](https://github.com/BradPatras/gpx-recorder/issues/44), [#45](https://github.com/BradPatras/gpx-recorder/issues/45), [#46](https://github.com/BradPatras/gpx-recorder/issues/46)\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.10 | Sep 25, 2023\r\n- Migrated from deprecated startActivityForResult\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.9 | Aug 16, 2023\r\n- Czech translations added (thanks to @pocitas for contributing!)\r\n- French, Spanish, German translations added (auto-generated)\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.8 | Jun 13, 2023\r\n- Fixed crashes around navigation\r\n- UI tweaks\r\n  - Sped up animations\r\n  - Updated verbiage in resume workflow\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.7 | Jun 10, 2023\r\n- Updated foreground service code to adhere to new Android requirements\r\n- Fixed some styling issues\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.6 | Sep 12, 2022\r\n- Fixed a crash related to realm library update\r\n- Add waypoint to stopped route feature\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.5 | Sep 4, 2022\r\n- Resume route feature\r\n- GeoJSON export format support\r\n- UI component updates\r\n- Dark mode support (color system rework)\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.4 | Feb 20, 2022\r\n- Updated dependency versions\r\n- Added licenses info\r\n- Migrated from Kotlin synthetics to view binding\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.3 | Aug 13, 2021\r\n- Fixed time zone issue - timestamps are always in UTC now\r\n- Reduced waypoint location max wait time to 5 seconds\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.2 | Oct 10, 2020\r\n- Updated target to Android 11\r\n- Added \"Save to device\" option when exporting route.\r\n- Updated background location permission request flow for Android 10 and 11\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.1 | Dec 22, 2019\r\n- Moved recording controls to a list cell\r\n- Added recorder page to allow viewing route while recording\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 2.0 | July 5, 2019\r\n- Removed route previews from list\r\n- Removed Glide library from project\r\n- Added warnings for route deletion\r\n- Added map type toggle\r\n- Implemented bottom app bar and bottom menu sheet\r\n- Added currently recording route controls to main app screen\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.8 | March 19, 2019\r\n- Switched all route preview loading and caching to Glide using DataFetcher and ModelLoader subclasses\r\n- Added link to legal\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.7 | February 23, 2019\r\n- Swapped interval selector to Number Pickers\r\n- Persist last selected interval as default\r\n- Fixed memory leaks\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.6 | November 3, 2018\r\n- Added App Shortcut for starting a new recording\r\n- Use localized date and time formats\r\n- Added export button to details page\r\n- Added warning to rooted users that the app may not function properly\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.5 | October 21, 2018\r\n- Reduced app size by 65%\r\n- Fixed more issues with Android 9\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.4 | October 16, 2018\r\n- Revert app bundle and apk size changes due to build crashes\r\n- Fix Android 9 issues\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.4 | October 15, 2018\r\n- Updates for Android Pie\r\n- Fix for rooted devices\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.3 | October 14, 2018\r\n- Fix for crash on detail page on specific devices\r\n- Reduced app install size by about 65%\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.2 | September 8, 2018\r\n- Fixed an issue where the app was taking a large amount of disk space\r\n- Misc. improvements and optimizations\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.1 | August 16, 2018\r\n- Rewrote the route list to be more reliable. \r\n- Added additional error handling for devices that cannot initialize the local database.\r\n- Fixed crashes\r\n\u003cbr\u003e\u003cbr\u003e\r\n### - 1.0 | July 5, 2018\r\n- Initial release!\r\n\u003c/details\u003e\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbradpatras%2Fgpx-recorder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbradpatras%2Fgpx-recorder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbradpatras%2Fgpx-recorder/lists"}