Compare commits

...

266 Commits

Author SHA1 Message Date
Dennis Guse d6da5f0862 Release: v3.22.0 2021-11-14 21:28:31 +01:00
Dennis Guse c3d55127fe Bugfix: running sensor data total is distance is UINT_32. 2021-11-14 21:20:24 +01:00
Román Martínez b1032f898a New field for recording layout: clock.
With this change fields can be: short, wide, clock short or clock wide.
Fixes #1015.
2021-11-14 16:27:37 +01:00
Dennis Guse d4a3762641 Merge remote-tracking branch 'weblate/main' 2021-11-13 20:10:19 +01:00
Dennis Guse ce5eec6a68 Bugfix: prevent NPE when disabling voice announcements while recording.
Fixes #940.
2021-11-13 20:07:32 +01:00
FTno cf71829bec Translated using Weblate (Norwegian Bokmål)
Currently translated at 92.1% (70 of 76 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/nb_NO/
2021-11-11 08:50:24 +01:00
FTno 39606ccd9f Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (439 of 439 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-11-11 08:50:24 +01:00
Dennis Guse 9dd67e4db7 CI: nightly build with flexible file names. 2021-11-11 08:50:02 +01:00
Peter Storch 212345dea1 Set distinct versionCode and name for nightlies 2021-11-11 08:50:02 +01:00
Dennis Guse 08ba7d50c7 Only record a TrackPoint if the traveled distance is greater than recording distance interval.
Code seemed to be a leftover from the removed idle/non-idle functionality.

Fixed #1007.

Co-authored-by: vlmendz <91810638+vlmendz@users.noreply.github.com>
2021-11-08 22:42:14 +01:00
Dennis Guse 62401b2c5c Cleanup. 2021-11-07 22:19:02 +01:00
Dennis Guse 7cfdacecc3 UI: Remove "Sensor:" prefix from speed description. 2021-11-07 17:58:28 +01:00
mondstern 8f2e234c63 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (439 of 439 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/vi/
2021-11-04 23:06:38 +01:00
mondstern dcd101a20a Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (439 of 439 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-11-04 23:06:38 +01:00
mondstern cb5f3ace5a Translated using Weblate (Galician)
Currently translated at 100.0% (439 of 439 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/gl/
2021-11-04 23:06:37 +01:00
mondstern 8e889fbce2 Translated using Weblate (Czech)
Currently translated at 100.0% (439 of 439 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-11-04 23:06:36 +01:00
mondstern ec390c4a81 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (439 of 439 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pt_BR/
2021-11-04 01:55:09 +01:00
Vinicius 30e9e930ab Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.7% (438 of 439 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pt_BR/
2021-11-03 06:08:52 +01:00
mondstern 3719d9ac8f Translated using Weblate (Czech)
Currently translated at 98.8% (429 of 434 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-11-03 06:08:51 +01:00
dependabot[bot] e33cfa8666 Bump actions/checkout from 2.3.5 to 2.4.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.5 to 2.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.5...v2.4.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-03 06:08:33 +01:00
Dennis Guse 8ff1db6a23 README: add link to Amazon App Store 2021-11-02 22:03:09 +01:00
Dennis Guse a9228017fc Setting: add option to adjust idle speed.
New default: 0.5km/h (replaces 0.5mp/h).

Fixes #1004.
2021-11-01 22:36:29 +01:00
Román Martínez 41e5e71804 Bugfix: intervals expected gain and loss to be null or not (both or neither). But only one of them could be null. Fixes #996. 2021-10-31 18:12:28 +01:00
Dennis Guse 9f858168f8 Release: v3.21.0 2021-10-29 07:54:59 +02:00
Andrij Mizyk cfdcea2d88 Translated using Weblate (Ukrainian)
Currently translated at 92.6% (402 of 434 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/uk/
2021-10-29 05:58:50 +02:00
Quang Trung 2d2db41c5d Translated using Weblate (Vietnamese)
Currently translated at 100.0% (434 of 434 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/vi/
2021-10-29 05:58:50 +02:00
Xosé M 2c73d0645a Translated using Weblate (Galician)
Currently translated at 100.0% (434 of 434 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/gl/
2021-10-29 05:58:50 +02:00
☆Verdulo ed1027eccc Translated using Weblate (Esperanto)
Currently translated at 92.0% (69 of 75 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/eo/
2021-10-29 05:58:49 +02:00
Dennis Guse 0dec17eba5 Bugfix: prevent NPE in onDestroy. 2021-10-29 05:58:22 +02:00
dependabot[bot] 774d701a09 Bump reactivecircus/android-emulator-runner from 2.20.0 to 2.21.0
Bumps [reactivecircus/android-emulator-runner](https://github.com/reactivecircus/android-emulator-runner) from 2.20.0 to 2.21.0.
- [Release notes](https://github.com/reactivecircus/android-emulator-runner/releases)
- [Changelog](https://github.com/ReactiveCircus/android-emulator-runner/blob/main/CHANGELOG.md)
- [Commits](https://github.com/reactivecircus/android-emulator-runner/compare/v2.20.0...v2.21.0)

---
updated-dependencies:
- dependency-name: reactivecircus/android-emulator-runner
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-25 20:18:39 +02:00
Dennis Guse 23bcbf09a5 GPX importer supports speed without namespace (compatibility with other tools).
Fixed #774.
2021-10-20 21:50:51 +02:00
Dennis Guse 115966cbdf Bugfix: NPE using a cycling sensor. 2021-10-20 19:44:47 +02:00
Dennis Guse 1862bcc6f4 Cleanup. 2021-10-19 17:53:08 +02:00
Dennis Guse 900910e9f7 While recording: show cadence and speed from different sensor types correctly.
Fixes #970.
2021-10-19 17:53:08 +02:00
Dennis Guse 45571c68c9 Rename TrackPoint's cycling cadence to cadence as it may contain running data.
Part of #970.
2021-10-19 17:53:08 +02:00
Román Martínez 083b620e41 GPS data recording: remove idle/non-idle changes due to reported speed greater than 0.5mph.
This avoids that to storing GPS locations if the user r actually is not moving (likely bad GPS reception).

Fixes #968.

Co-authored-by: vlmendz <91810638+vlmendz@users.noreply.github.com>
Co-authored-by: Dennis Guse <dennis.guse@alumni.tu-berlin.de>
2021-10-18 23:26:07 +02:00
Dennis Guse 2f7a56bb17 Bugfix: importing files without speed resulted in moving time 0s and max speed of 0.
Fixes #982.
2021-10-18 18:41:53 +02:00
dependabot[bot] d8988663cb Bump actions/checkout from 2.3.4 to 2.3.5
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.3.5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.4...v2.3.5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-18 12:42:34 +02:00
FTno c742dae6e0 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (434 of 434 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-10-16 10:23:21 +02:00
FTno 292437e6bd Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (429 of 429 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-10-16 10:23:20 +02:00
J. Lavoie 8e9cde7222 Translated using Weblate (French)
Currently translated at 100.0% (429 of 429 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fr/
2021-10-16 10:23:20 +02:00
Dennis Guse d07ab3cc22 TrackRecordingManager: do not store altitude changes twice (previous …
…TrackPoint's storage was delayed).

Fixes #969.
2021-10-16 10:23:09 +02:00
Dennis Guse 90493ae498 TrackRecordingManager: do not store sensor distance twice (previous TrackPoint's storage was delayed).
Fixes #969.
2021-10-16 10:23:09 +02:00
Dennis Guse f6b994572a TrackRecordingManager: cache last stored TrackPoint. 2021-10-16 10:23:09 +02:00
Dennis Guse 24826ff442 TrackRecordingManager: cleanup. 2021-10-16 10:23:09 +02:00
Dennis Guse d97e5ab1ef TrackRecordingManager: only keep lastTrackPoint if was not stored. 2021-10-16 10:23:09 +02:00
Dennis Guse 52a110d998 Bugfix: reset on SensorDataSet should only take place if the TrackPoint was stored
Fixes #969.
2021-10-16 10:23:09 +02:00
Román Martínez 12e18b0bcd Bugfix: activity type preference has to update the icon when user change the activity type. Fixes #985. 2021-10-15 22:16:17 +02:00
Román Martínez 66dac4b0ca Reorganize settings into multiple pages. The main page has icons, titles and summaries. Fixes #960. 2021-10-15 22:04:54 +02:00
Dennis Guse 1bb8cbb82a Running sensor Stryd works.
Fixes #962.
2021-10-15 07:57:29 +02:00
Dennis Guse 2f5b7b63e4 Opening from notification: pressing back goes to TrackListActivity.
Fixes #928.
2021-10-14 18:33:44 +02:00
Ristello 58ca78b976 Removed interface AppConfig, since it is technically not needed. 2021-10-13 22:02:38 +02:00
Ristello 8079a25a42 Use an in-memory database when running instrumented tests.
- added new TestRunner and new TestApplication
- The TestRunner loads TestApplication as the apps Application instance when running the tests
- added new interface AppConfig to retrieve the database name
- changed Startup (Application) so that it implements AppConfig
- changed CustomSQLiteOpenHelper so that it retrieves the database name from the Application instance
- Startup provides the production database name
- TestApplication provides null which yields an in-mememory database
2021-10-13 22:02:38 +02:00
Dennis Guse 0527e4ab14 Cleanup: move AnnouncementUtils to VoiceAnnouncement.
Part of #963
2021-10-12 22:24:51 +02:00
Dennis Guse b6b4c5aa39 Cleanup: move PreferencesUtils into settings package.
Part of #963
2021-10-12 22:24:51 +02:00
Dennis Guse 8c5c9d7947 Cleanup: extract preference functionality from StringUtils to PreferenceHelper.
Part of #963.
2021-10-12 22:24:51 +02:00
Dennis Guse eac3d4b3db Cleanup: SharedPreference as static variable.
Fixes #961.
2021-10-12 22:24:51 +02:00
dependabot[bot] d7bc550b29 Bump gradle from 7.0.2 to 7.0.3
Bumps gradle from 7.0.2 to 7.0.3.

---
updated-dependencies:
- dependency-name: com.android.tools.build:gradle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-12 22:16:13 +02:00
Dennis Guse d76d5673a8 Bugfix: running sensor's data should be null if not connected.
Fixes #950.
2021-10-09 14:24:50 +02:00
dependabot[bot] 847be686ea Bump mockito-android from 3.12.4 to 4.0.0
Bumps [mockito-android](https://github.com/mockito/mockito) from 3.12.4 to 4.0.0.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v3.12.4...v4.0.0)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-android
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-08 07:12:11 +02:00
Dennis Guse 1e3445cfa2 Nightly build: app name with suffix.
Part of #952.
2021-10-05 19:23:00 +02:00
Román Martínez d0f7939f1a Added phones with barometric sensor information. 2021-10-01 16:16:16 +02:00
vsevjednom-cz 000b8149f8 Translated using Weblate (Czech)
Currently translated at 99.0% (425 of 429 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-09-28 11:06:25 +02:00
Quang Trung 05ffa5a373 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (429 of 429 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/vi/
2021-09-25 00:06:30 +02:00
Vinicius e92f1107aa Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (429 of 429 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pt_BR/
2021-09-25 00:06:30 +02:00
Quang Trung 2ad1fab670 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (427 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/vi/
2021-09-22 22:30:43 +02:00
mondstern 8c04129ef9 Translated using Weblate (Vietnamese)
Currently translated at 98.3% (420 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/vi/
2021-09-22 22:30:43 +02:00
Mario 400d9fe948 Translated using Weblate (Spanish)
Currently translated at 100.0% (427 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es/
2021-09-22 22:30:42 +02:00
Mario 5d79510750 Translated using Weblate (Spanish (Latin America))
Currently translated at 100.0% (427 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es_419/
2021-09-22 22:30:42 +02:00
vsevjednom-cz 18bb64580f Translated using Weblate (Slovak)
Currently translated at 71.6% (306 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sk/
2021-09-22 22:30:42 +02:00
vsevjednom-cz 7adebfc0d1 Translated using Weblate (Czech)
Currently translated at 97.8% (418 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-09-22 22:30:42 +02:00
Román Martínez 2178ff97d3 Release: v3.20.2 2021-09-22 22:30:16 +02:00
Timo Schwarzer f070495fb4 Ask for permission before using Bluetooth 2021-09-22 22:14:53 +02:00
Román Martínez d99fb5ea47 Cadence set to 0 when connected but user is not pedaling. Fixes #931.
Speed set to 0 when connected but last value is outdated. Fixes #930.
Bug: overflow when reset sensors (cadence and speed). Fixes #833.
Moving time stops when is not moving (the last track point is not moving) and restarts when last track point is moving.
2021-09-21 18:07:23 +02:00
Román Martínez d69a726e0e Renaming variables. 2021-09-18 16:17:29 +02:00
Román Martínez e0111c2ffd Gain and loss are integers. 2021-09-18 16:17:29 +02:00
Timo Schwarzer 487bd6c3a0 Set FLAG_IMMUTABLE for PendingIntents
This fixes a crash on Android 12, since it explicitly requires setting either FLAG_MUTABLE or FLAG_IMMUTABLE
2021-09-07 23:18:14 +02:00
Román Martínez 40aab9444a Time interval setting is in minutes. 2021-09-06 22:06:48 +02:00
Dennis Guse 82b460b57b Release: v3.20.1 2021-09-03 19:46:51 +02:00
Mario 68baad16e2 Translated using Weblate (Spanish (Latin America))
Currently translated at 100.0% (427 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es_419/
2021-09-02 21:55:28 +02:00
Dennis Guse 26ed9b24d3 CI: build nightly on push.
Fixes #894.
2021-09-02 21:55:25 +02:00
dependabot[bot] 9f6089e7f1 Bump gradle from 7.0.1 to 7.0.2
Bumps gradle from 7.0.1 to 7.0.2.

---
updated-dependencies:
- dependency-name: com.android.tools.build:gradle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-02 21:55:15 +02:00
FTno d0eef44bf8 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (427 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-08-31 08:45:48 +02:00
Mario eead3b5721 Translated using Weblate (Spanish)
Currently translated at 100.0% (427 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es/
2021-08-31 06:47:45 +02:00
Mario b8f0c59198 Translated using Weblate (Spanish (Latin America))
Currently translated at 99.5% (425 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es_419/
2021-08-31 06:47:45 +02:00
vsevjednom-cz 8f408dceba Translated using Weblate (Slovak)
Currently translated at 68.7% (292 of 425 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sk/
2021-08-31 06:47:45 +02:00
vsevjednom-cz d1dfaa5443 Translated using Weblate (Czech)
Currently translated at 96.7% (411 of 425 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-08-31 06:47:45 +02:00
vsevjednom-cz b2da849e25 Translated using Weblate (Czech)
Currently translated at 95.7% (407 of 425 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-08-31 06:47:45 +02:00
Xosé M 88579be0a2 Translated using Weblate (Galician)
Currently translated at 100.0% (427 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/gl/
2021-08-31 06:47:45 +02:00
FTno 70d971d8fd Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (427 of 427 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-08-31 06:47:45 +02:00
mondstern 70b0dac4b6 Translated using Weblate (Tagalog)
Currently translated at 72.7% (297 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/tl/
2021-08-31 06:47:45 +02:00
Carl Dea 038e8d3e06 Using Zulu builds of OpenJDK in GH actions
The AdoptOpenJDK has been discontinued since July 2021. When using Zulu you get all the latest updated (TCK Tested) builds for all versions of OpenJDK.
2021-08-31 06:46:34 +02:00
Dennis Guse 932bb5ed5a KMLTrackExporter: uses NumberFormat to export sensor data.
Fixes #832.
2021-08-30 17:48:01 +02:00
Dennis Guse 8f2d1722ad Announcements: can be triggered by time and distance (instead of either).
Fixes #921.
2021-08-30 17:24:51 +02:00
Dennis Guse 9cb3d8c1bb Finished renaming: TrackPointCreator was still referenced as HandlerServer. 2021-08-30 17:24:51 +02:00
Dennis Guse fa02ba9c69 Voice announcements: if TTS is not available play a sound file.
Fixes #862.
2021-08-30 17:24:51 +02:00
Dennis Guse 4f31607e3e Voice announcements are now triggered by the TrackRecordingService's timer that is also used for UI updates. 2021-08-30 17:24:51 +02:00
Dennis Guse b5165de7f0 PeriodicTaskExecutor: use a Handler instead of Timer. 2021-08-30 17:24:51 +02:00
Dennis Guse b32e87e10b PeriodTaskFactory: refactor interfaces. 2021-08-30 17:24:51 +02:00
dependabot[bot] 29a1daa177 Bump reactivecircus/android-emulator-runner from 2.19.1 to 2.20.0
Bumps [reactivecircus/android-emulator-runner](https://github.com/reactivecircus/android-emulator-runner) from 2.19.1 to 2.20.0.
- [Release notes](https://github.com/reactivecircus/android-emulator-runner/releases)
- [Changelog](https://github.com/ReactiveCircus/android-emulator-runner/blob/main/CHANGELOG.md)
- [Commits](https://github.com/reactivecircus/android-emulator-runner/compare/v2.19.1...v2.20.0)

---
updated-dependencies:
- dependency-name: reactivecircus/android-emulator-runner
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-30 17:23:53 +02:00
Dennis Guse d5cfd118f6 Cleanup. 2021-08-28 19:00:06 +02:00
Dennis Guse 5981340bb9 TrackRecordingManager: only keeps reference to TrackId. 2021-08-28 19:00:06 +02:00
dependabot[bot] f562d51d9a Bump mockito-android from 3.12.3 to 3.12.4
Bumps [mockito-android](https://github.com/mockito/mockito) from 3.12.3 to 3.12.4.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v3.12.3...v3.12.4)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-android
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-26 12:15:22 +02:00
Dennis Guse d77b9243af RecordingStatus provides methods for status changes. 2021-08-25 22:58:45 +02:00
dependabot[bot] 2c7e665206 Bump mockito-android from 3.12.1 to 3.12.3
Bumps [mockito-android](https://github.com/mockito/mockito) from 3.12.1 to 3.12.3.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v3.12.1...v3.12.3)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-android
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-25 07:00:23 +02:00
Dennis Guse 1aa6b94f19 Revert "Translated using Weblate (Slovenian)"
This reverts commit 8f39bf13
2021-08-24 18:38:12 +02:00
Dennis Guse 68c447f77e Removed AdaptiveLocationListenerPolicy.
Fixes #886.
2021-08-24 18:26:09 +02:00
Román Martínez 6b3a2eae5e Added Garmin HRM-Dual heart rate sensor 2021-08-23 13:13:11 +02:00
dependabot[bot] 3869dba72b Bump mockito-android from 3.12.0 to 3.12.1
Bumps [mockito-android](https://github.com/mockito/mockito) from 3.12.0 to 3.12.1.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v3.12.0...v3.12.1)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-android
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-23 12:02:42 +02:00
Dennis Guse 5594a125d0 Release: v3.20.0 2021-08-22 22:08:23 +02:00
Román Martínez 13380afef0 TrackRecordingManager only updates track's statistics every time a new track point is inserted. Fixes #916. 2021-08-22 20:01:38 +02:00
Román Martínez 9c4c8131f5 Recording stats layout customizable.
Users can select the order, visibility and importance (primary or secondary) of all stats for recording layout from the Settings.
Also, users can select the number of columns per row in the recording layout: 1, 2 or 3.
Finally, show altitude/coordinate from settings have been removed (not needed anymore).
Fixes #659.
Fixes #302.
Fixes #820.
2021-08-21 19:40:31 +02:00
dependabot[bot] 7f10ae5c3f Bump mockito-android from 3.10.0 to 3.12.0
Bumps [mockito-android](https://github.com/mockito/mockito) from 3.10.0 to 3.12.0.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v3.10.0...v3.12.0)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-android
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-20 07:37:15 +02:00
dependabot[bot] 1fa45a3393 Bump gradle from 7.0.0 to 7.0.1
Bumps gradle from 7.0.0 to 7.0.1.

---
updated-dependencies:
- dependency-name: com.android.tools.build:gradle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-19 10:11:22 +02:00
Dennis Guse f1b0c83196 Merge branch 'translations' 2021-08-16 22:17:29 +02:00
Dennis Guse f0f7bca54b Translations: fix fr. 2021-08-16 22:16:58 +02:00
mondstern 8f39bf139c Translated using Weblate (Slovenian)
Currently translated at 71.5% (292 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sl/
2021-08-16 22:15:27 +02:00
mondstern 85585969bd Translated using Weblate (Russian)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ru/
2021-08-16 22:15:27 +02:00
mondstern 976e7be370 Translated using Weblate (French)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fr/
2021-08-16 22:15:27 +02:00
Jaroslav Lichtblau 48dc64d4d7 Translated using Weblate (Czech)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-08-16 22:15:27 +02:00
Pablo 16e69e850b Translated using Weblate (Spanish (Latin America))
Currently translated at 98.2% (401 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es_419/
2021-08-16 22:15:27 +02:00
FTno 5ece301ac0 Translated using Weblate (Norwegian Bokmål)
Currently translated at 98.5% (70 of 71 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/nb_NO/
2021-08-16 22:15:27 +02:00
☆Verdulo a5e500cdb1 Translated using Weblate (Esperanto)
Currently translated at 97.1% (69 of 71 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/eo/
2021-08-16 22:15:27 +02:00
Román Martínez 8433ed82fe Release: v3.19.1 2021-08-15 20:19:08 +02:00
Dennis Guse 7c7defa233 Merge pull request #912 from OpenTracksApp/raceCondition
Bugfix: LocationHandler should ignore locations after stopping.
2021-08-15 15:53:30 +02:00
Dennis Guse 1f84e44a8d Bugfix: LocationHandler should ignore locations after stopping. 2021-08-15 14:30:57 +02:00
Dennis Guse 858a8f20a8 Merge pull request #910 from OpenTracksApp/translations
Translations
2021-08-14 20:36:20 +02:00
Dennis Guse 6761c41dbf Translations: removed invalid plurals. 2021-08-14 19:46:40 +02:00
FTno 59e55be214 Translated using Weblate (Norwegian Bokmål)
Currently translated at 98.5% (70 of 71 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/nb_NO/
2021-08-09 20:06:09 +02:00
☆Verdulo 1b68cba1ba Translated using Weblate (Esperanto)
Currently translated at 97.1% (69 of 71 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/eo/
2021-08-09 20:06:08 +02:00
mondstern 32f47340a9 Translated using Weblate (Latvian)
Currently translated at 99.0% (404 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/lv/
2021-08-09 20:06:07 +02:00
mondstern e25814c674 Translated using Weblate (Lithuanian)
Currently translated at 98.2% (401 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/lt/
2021-08-09 20:06:05 +02:00
FTno 522baa5193 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-08-09 11:54:21 +02:00
mondstern b597b56b84 Translated using Weblate (Romanian)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ro/
2021-08-07 19:37:23 +02:00
mondstern d956e8d3f0 Translated using Weblate (Romanian)
Currently translated at 99.0% (404 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ro/
2021-08-07 19:37:23 +02:00
mondstern 274781ccfa Translated using Weblate (Romanian)
Currently translated at 83.3% (340 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ro/
2021-08-07 19:37:23 +02:00
mondstern e7e3ef23ff Translated using Weblate (Lithuanian)
Currently translated at 97.5% (398 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/lt/
2021-08-07 19:37:23 +02:00
Quang Trung 3289fa27e4 Translated using Weblate (Vietnamese)
Currently translated at 88.7% (362 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/vi/
2021-08-07 19:37:23 +02:00
mondstern 96fc074a4b Translated using Weblate (Ukrainian)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/uk/
2021-08-07 19:37:23 +02:00
mondstern eaab09747c Translated using Weblate (Swedish)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sv/
2021-08-07 19:37:23 +02:00
mondstern bdb2a9dbc6 Translated using Weblate (Russian)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ru/
2021-08-07 19:37:23 +02:00
mondstern 7e26571124 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pt_BR/
2021-08-07 19:37:23 +02:00
mondstern 33b23a6e8f Translated using Weblate (Polish)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pl/
2021-08-07 19:37:23 +02:00
mondstern 584adc7c57 Translated using Weblate (Dutch)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nl/
2021-08-07 19:37:23 +02:00
mondstern 667da76c4f Translated using Weblate (Italian)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/it/
2021-08-07 19:37:23 +02:00
mondstern df6a3a7f04 Translated using Weblate (Hungarian)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/hu/
2021-08-07 19:37:23 +02:00
mondstern b254f5e40b Translated using Weblate (Galician)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/gl/
2021-08-07 19:37:23 +02:00
mondstern 7a9c3efb3b Translated using Weblate (French)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fr/
2021-08-07 19:37:23 +02:00
mondstern 53dd7ada1f Translated using Weblate (Finnish)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fi/
2021-08-07 19:37:23 +02:00
mondstern 6a5edcbdef Translated using Weblate (Basque)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/eu/
2021-08-07 19:37:23 +02:00
mondstern 6e954261bb Translated using Weblate (Estonian)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/et/
2021-08-07 19:37:23 +02:00
mondstern 277061ad27 Translated using Weblate (Spanish)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es/
2021-08-07 19:37:23 +02:00
mondstern c03f9fc792 Translated using Weblate (Danish)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/da/
2021-08-07 19:37:23 +02:00
mondstern 657b82b57a Translated using Weblate (Czech)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-08-07 19:37:23 +02:00
mondstern 4608edec56 Translated using Weblate (Bulgarian)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/bg/
2021-08-07 19:37:23 +02:00
FTno b086c30696 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-08-07 19:37:23 +02:00
mondstern 7eca033a8e Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (408 of 408 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-08-07 19:37:23 +02:00
Dennis Guse 6f3efd9ff2 Bugfix: reset TrackRecordingManager properly.
Fixes #901.
2021-08-07 19:37:14 +02:00
A Rabbit 7a2741e508 Fix: README 2021-08-06 16:42:22 +02:00
Román Martínez 017eee8b68 Bugfix: generated fields for include and merge tags. Fixes #902. 2021-08-05 18:01:34 +02:00
Dennis Guse 024d7f8652 PlayStore: describe metadata upload. 2021-08-04 17:11:29 +02:00
Dennis Guse 05c3a89682 Release: v3.19.0 2021-08-01 18:53:12 +02:00
Dennis Guse a3872581bb Cleanup: Renamed HandlerServer to TrackPointCreator. 2021-08-01 18:40:38 +02:00
Dennis Guse e75451dab3 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (407 of 407 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/uk/
2021-08-01 18:22:52 +02:00
Dennis Guse 2897171132 Translated using Weblate (Thai)
Currently translated at 71.7% (292 of 407 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/th/
2021-08-01 18:22:51 +02:00
Dennis Guse ed2f506b7b Translated using Weblate (Serbian)
Currently translated at 71.0% (289 of 407 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sr/
2021-08-01 18:22:51 +02:00
Dennis Guse 1e2ba3798d Translated using Weblate (Malay)
Currently translated at 71.7% (292 of 407 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ms/
2021-08-01 18:22:51 +02:00
Dennis Guse a0a8ef9016 Translated using Weblate (Moldavian)
Currently translated at 71.4% (291 of 407 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ro_MD/
2021-08-01 18:22:51 +02:00
Dennis Guse e1f4406674 Translated using Weblate (Latvian)
Currently translated at 70.7% (288 of 407 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/lv/
2021-08-01 18:22:51 +02:00
Dennis Guse d9b7f77bbb Translated using Weblate (Catalan)
Currently translated at 72.2% (294 of 407 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ca/
2021-08-01 18:22:51 +02:00
Dennis Guse e60dcbe539 Translated using Weblate (Spanish (Latin America))
Currently translated at 98.5% (401 of 407 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es_419/
2021-08-01 18:22:51 +02:00
Dennis Guse fc0cec6157 Share picture: if sharing a track, a share picture (PNG) is created in addition.
Fixes #363.
2021-08-01 18:22:42 +02:00
Dennis Guse 0ac34e0638 Sensor parsing: fixed test.
Part of #891.
2021-07-31 19:00:32 +02:00
Dennis Guse 242147e491 Sensor: adding Running Speed and Cadence.
Fixes #891.
2021-07-31 18:44:42 +02:00
Dennis Guse eba7a7fd89 Settings: use already available custom summary. 2021-07-31 17:54:57 +02:00
Dennis Guse 348f74c4b3 Cleanup. 2021-07-31 17:54:57 +02:00
Dennis Guse d898d51f1a Merge remote-tracking branch 'weblate/main' into main 2021-07-31 07:23:56 +02:00
Dennis Guse 6e9c95f232 Translations: removed unused ones. 2021-07-31 07:19:41 +02:00
Vinicius 9c7f458802 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (70 of 70 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/pt_BR/
2021-07-31 06:49:31 +02:00
mondstern f52b153e3a Translated using Weblate (Slovenian)
Currently translated at 100.0% (70 of 70 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/sl/
2021-07-31 06:49:30 +02:00
mondstern 145cbf870b Translated using Weblate (Swedish)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sv/
2021-07-31 06:49:30 +02:00
mondstern 8e52574378 Translated using Weblate (Slovenian)
Currently translated at 99.0% (440 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sl/
2021-07-31 06:49:30 +02:00
Dennis Guse e3ca1b7f21 Translations: fixed linting errors. 2021-07-31 06:44:02 +02:00
mondstern 2cdae4f460 Translated using Weblate (Lithuanian)
Currently translated at 100.0% (70 of 70 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/lt/
2021-07-29 22:55:05 +02:00
Allan Nordhøy 422e171406 Translated using Weblate (Norwegian Bokmål)
Currently translated at 98.5% (69 of 70 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/nb_NO/
2021-07-29 22:55:05 +02:00
mondstern 130581da6f Translated using Weblate (Swedish)
Currently translated at 98.5% (69 of 70 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/sv/
2021-07-29 22:55:05 +02:00
mondstern 9cd212f6b1 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/uk/
2021-07-29 22:55:05 +02:00
mondstern 08701dcbf9 Translated using Weblate (Swedish)
Currently translated at 98.8% (439 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sv/
2021-07-29 22:55:05 +02:00
mondstern 0f7f332087 Translated using Weblate (Russian)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ru/
2021-07-29 22:55:05 +02:00
mondstern 9eed5aa70f Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pt_BR/
2021-07-29 22:55:05 +02:00
mondstern ea8cd9b6fc Translated using Weblate (Polish)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pl/
2021-07-29 22:55:05 +02:00
mondstern 0ef40e7fab Translated using Weblate (Dutch)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nl/
2021-07-29 22:55:05 +02:00
FTno 919ecbbffb Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-07-29 22:55:05 +02:00
mondstern 21369860a7 Translated using Weblate (Lithuanian)
Currently translated at 96.8% (430 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/lt/
2021-07-29 22:55:05 +02:00
mondstern 7bad6a106a Translated using Weblate (Italian)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/it/
2021-07-29 22:55:05 +02:00
mondstern bdf0c91714 Translated using Weblate (Hungarian)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/hu/
2021-07-29 22:55:05 +02:00
Xosé M 453cbd705e Translated using Weblate (Galician)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/gl/
2021-07-29 22:55:05 +02:00
mondstern 0669eadc01 Translated using Weblate (French)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fr/
2021-07-29 22:55:05 +02:00
mondstern 7a661cb521 Translated using Weblate (Finnish)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fi/
2021-07-29 22:55:05 +02:00
mondstern bb7cba0e47 Translated using Weblate (Basque)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/eu/
2021-07-29 22:55:05 +02:00
mondstern 1402563702 Translated using Weblate (Estonian)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/et/
2021-07-29 22:55:05 +02:00
mondstern 4d8c8e4ec9 Translated using Weblate (German)
Currently translated at 99.5% (442 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/de/
2021-07-29 22:55:05 +02:00
mondstern ef7f36d49e Translated using Weblate (Danish)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/da/
2021-07-29 22:55:05 +02:00
mondstern e2ebf04621 Translated using Weblate (Czech)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/cs/
2021-07-29 22:55:05 +02:00
mondstern 029b60efff Translated using Weblate (Bulgarian)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/bg/
2021-07-29 22:55:05 +02:00
Allan Nordhøy 70bfa3e862 Translated using Weblate (English)
Currently translated at 100.0% (70 of 70 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/en/
2021-07-29 22:55:05 +02:00
FTno 9f1087c9e6 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-07-29 22:55:05 +02:00
mondstern c64bae827b Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (444 of 444 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-07-29 22:55:05 +02:00
mondstern 05bde1cf33 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/uk/
2021-07-29 22:55:05 +02:00
mondstern 13c65b25ae Translated using Weblate (Serbian)
Currently translated at 73.0% (323 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/sr/
2021-07-29 22:55:05 +02:00
mondstern 0ab0f5d7a3 Translated using Weblate (Russian)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/ru/
2021-07-29 22:55:05 +02:00
mondstern 70ca0d50e2 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pt_BR/
2021-07-29 22:55:05 +02:00
mondstern 8da64ad28d Translated using Weblate (Polish)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/pl/
2021-07-29 22:55:05 +02:00
mondstern 48d19aaa67 Translated using Weblate (Dutch)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nl/
2021-07-29 22:55:05 +02:00
mondstern 63bb512e3a Translated using Weblate (Italian)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/it/
2021-07-29 22:55:05 +02:00
mondstern 3205c9de8a Translated using Weblate (Indonesian)
Currently translated at 79.6% (352 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/id/
2021-07-29 22:55:05 +02:00
mondstern bda1603e87 Translated using Weblate (Hungarian)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/hu/
2021-07-29 22:55:05 +02:00
mondstern 28d2f42096 Translated using Weblate (French)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fr/
2021-07-29 22:55:05 +02:00
mondstern d83bc0b32a Translated using Weblate (Finnish)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fi/
2021-07-29 22:55:05 +02:00
mondstern 87508fca3f Translated using Weblate (Basque)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/eu/
2021-07-29 22:55:05 +02:00
mondstern 3250be9480 Translated using Weblate (Estonian)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/et/
2021-07-29 22:55:05 +02:00
mondstern 3848dd8fbd Translated using Weblate (Spanish)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/es/
2021-07-29 22:55:05 +02:00
mondstern 022cf5835b Translated using Weblate (Danish)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/da/
2021-07-29 22:55:03 +02:00
mondstern 325681c6cd Translated using Weblate (Bulgarian)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/bg/
2021-07-29 22:55:03 +02:00
Dennis Guse 54be1b74fb Lint: fix AGP7.0.0 found linting errors. 2021-07-29 22:54:57 +02:00
Dennis Guse fd1a53d1a6 CI: lint instead of CodeQL. 2021-07-29 22:54:57 +02:00
Dennis Guse 19f6a477c4 Upgrade to Android Gradle Plugin 7.0.0 (incl. Java11). 2021-07-29 22:54:57 +02:00
Dennis Guse 94babc9cd2 CI: Use JDK11. 2021-07-29 22:54:57 +02:00
Dennis Guse 26414b0c7c Upgrade to API level 31 (Android12).
Fixes #803.
2021-07-29 22:54:57 +02:00
Dennis Guse 956031264f Settings: use separate titles for cycling-only sensors. 2021-07-25 19:18:34 +02:00
Dennis Guse 7d8ac1f411 Merge remote-tracking branch 'weblate/main' into main 2021-07-25 10:29:53 +02:00
Dennis Guse a4121319fa Tests: close cursor. 2021-07-25 10:27:22 +02:00
Xosé M 1fdf1dd607 Translated using Weblate (Galician)
Currently translated at 100.0% (442 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/gl/
2021-07-22 17:18:41 +02:00
☆Verdulo 7759d1f9b0 Translated using Weblate (Esperanto)
Currently translated at 98.5% (69 of 70 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/eo/
2021-07-22 17:18:41 +02:00
Quang Trung 43b114b64b Translated using Weblate (Vietnamese)
Currently translated at 77.3% (342 of 442 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/vi/
2021-07-22 17:18:41 +02:00
Dennis Guse a808c52d48 Bugfix: recording layout constraint was not correct. 2021-07-22 17:18:31 +02:00
Dennis Guse bb90c53057 Simplified voice announcement interface.
Part of #822.
2021-07-22 17:18:31 +02:00
Dennis Guse bd5bf530f0 TrackRecordingService: extracted storing data into TrackRecordingManager.
Part of #822.
2021-07-22 17:18:31 +02:00
Dennis Guse a4580fc84e Cleanup. 2021-07-22 17:18:31 +02:00
Dennis Guse 9ab34eb846 TrackRecordingService: EGM2008 computation should only be done for UI.
Reverting 16483d4261ff780f940fe4ea223957c898023e14
2021-07-22 17:18:31 +02:00
Dennis Guse 997ddbb4f1 ExportImportTest: made tests deterministic (simulate GPS/sensors).
Fixes #761.
2021-07-22 17:18:31 +02:00
Dennis Guse 86a0054c24 Bugfix: TrackStatistics' total time was not restored correctly, when having pause/stop and then resume. 2021-07-22 17:18:31 +02:00
Dennis Guse 3bd00c906a LocationHandler.onStop(): reset state. 2021-07-22 17:18:31 +02:00
Dennis Guse 684419e86e Version info: show only git describe --tags.
The commitId is included if there are commits after this tag.
2021-07-22 17:18:31 +02:00
Dennis Guse d42d1214ea While recording: UI updates altitude, speed, and bearing to most recently received value.
Fixes #866.
2021-07-22 17:18:31 +02:00
Dennis Guse db24639829 Cleanup: horizontal accuracy is now a Distance (and named consistently). 2021-07-22 17:18:31 +02:00
Dennis Guse 0f6480197b Cleanup. 2021-07-22 17:18:31 +02:00
Dennis Guse cce62c4c47 CI: store logs as artifact. 2021-07-22 17:18:31 +02:00
Dennis Guse bfdc04fbd9 CI: use orchestrator to continue tests after crash + set overall timeout. 2021-07-22 17:18:31 +02:00
Dennis Guse 18702bb6b3 Cleanup. 2021-07-22 17:18:31 +02:00
Dennis Guse 65e920e8b6 ExportImportTest: made tests deterministic.
Fixes #761.
2021-07-22 17:18:31 +02:00
Dennis Guse 7d24262b38 TrackRecordingService: generate timestamps for TrackPoints in HandlerServer.
Part of #822.
2021-07-22 17:18:31 +02:00
Dennis Guse 223ad70d36 TrackRecordingService: move BluetoothRemoteSensorManager and AltitudeSumManager to HandlerServer.
Part of #822.
2021-07-22 17:18:31 +02:00
Dennis Guse 7f618da7a6 TrackPointAssert: provide better error messages on assertion failure. 2021-07-22 17:18:31 +02:00
Dennis Guse 0332b9eb87 ExportImportTest: only cleanup if necessary. 2021-07-22 17:18:31 +02:00
Dennis Guse 29aefff788 Cleanup: remove HandlerInterface. 2021-07-22 17:18:31 +02:00
Dennis Guse c9478ea38d HandlerServer: disable serviceExecutor to simplify testing for now.
Part of #882.
2021-07-22 17:18:31 +02:00
Dennis Guse 1255ec8111 TrackRecordingService: extract EGM2008CorrectionManager into HandlerServer.
Part of #882.
2021-07-22 17:18:31 +02:00
Dennis Guse f9d3108cb2 Extract EGM2008CorrectionManager.
Part of #882.
2021-07-22 17:18:31 +02:00
dependabot[bot] e18d6b942d Bump appcompat from 1.3.0 to 1.3.1
Bumps appcompat from 1.3.0 to 1.3.1.

---
updated-dependencies:
- dependency-name: androidx.appcompat:appcompat
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-22 07:45:57 +02:00
dependabot[bot] cc5ced6383 Bump reactivecircus/android-emulator-runner from 2.19.0 to 2.19.1
Bumps [reactivecircus/android-emulator-runner](https://github.com/reactivecircus/android-emulator-runner) from 2.19.0 to 2.19.1.
- [Release notes](https://github.com/reactivecircus/android-emulator-runner/releases)
- [Changelog](https://github.com/ReactiveCircus/android-emulator-runner/blob/main/CHANGELOG.md)
- [Commits](https://github.com/reactivecircus/android-emulator-runner/compare/v2.19.0...v2.19.1)

---
updated-dependencies:
- dependency-name: reactivecircus/android-emulator-runner
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-21 07:50:54 +02:00
Dennis Guse 163879487c CI: Disable API level 29 as this creates timeouts. 2021-07-20 22:54:02 +02:00
Dennis Guse d7dd9f7c1b CI: only build on push.
Avoid triggering two builds.
2021-07-20 22:53:37 +02:00
Dennis Guse 1259c42d28 TrackRecordingService: notification should not vibrate.
Fixes #611.
2021-07-11 23:05:05 +02:00
Dennis Guse 9bccbe79a4 Typo in italian translation.
Fixes #879.
2021-07-11 16:54:24 +02:00
Dennis Guse 401e07d7e7 Cleanup. 2021-07-09 23:17:18 +02:00
316 changed files with 8680 additions and 6774 deletions
+34
View File
@@ -0,0 +1,34 @@
#https://github.com/marketplace/actions/android-emulator-runner
name: Build nightly
on: [ push ]
jobs:
nightly-build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2.4.0
- uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '11'
- name: Assemble nighlty APK
shell: bash
run: |
echo ${NIGHTLY_STORE_FILE} | base64 -d > KEY_NIGHTLY.jks
./gradlew assembleNightly -Dnightly_store_file=KEY_NIGHTLY.jks -Dnightly_store_password="${NIGHTLY_STORE_PASSWORD}" -Dnightly_key_alias="${NIGHTLY_KEY_ALIAS}" -Dnightly_key_password="${NIGHTLY_STORE_PASSWORD}"
env:
NIGHTLY_STORE_FILE: ${{ secrets.NIGHTLY_STORE_FILE }}
NIGHTLY_STORE_PASSWORD: ${{ secrets.NIGHTLY_STORE_PASSWORD }}
NIGHTLY_KEY_ALIAS: ${{ secrets.NIGHTLY_KEY_ALIAS }}
- name: Archive
if: always()
uses: actions/upload-artifact@v2
with:
name: OpenTracks-nightly.apk
path: ./build/outputs/apk/nightly/*.apk
retention-days: 7
-31
View File
@@ -1,31 +0,0 @@
name: "CodeQL"
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1'
jobs:
analyse:
name: Analyse
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2.3.4
with:
fetch-depth: 2
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: java
- run: |
./gradlew build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
+19
View File
@@ -0,0 +1,19 @@
name: Linting
on: [ push ]
jobs:
analyse:
name: Analyse
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2.4.0
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: '11'
- run: ./gradlew lint
+19 -5
View File
@@ -1,19 +1,25 @@
#https://github.com/marketplace/actions/android-emulator-runner
name: Test
on: [push, pull_request]
on: [ push ]
jobs:
test:
timeout-minutes: 45
runs-on: macos-latest
strategy:
matrix:
api-level: [ 23, 26, 29 ]
target: [default]
api-level: [ 23, 26 ] #TODO Re-enable 29
target: [ default ]
steps:
- name: checkout
uses: actions/checkout@v2.3.4
uses: actions/checkout@v2.4.0
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: '11'
- name: run tests
uses: reactivecircus/android-emulator-runner@v2.19.0
uses: reactivecircus/android-emulator-runner@v2.21.0
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
@@ -21,3 +27,11 @@ jobs:
profile: Nexus 6
script: ./gradlew connectedCheck
- name: Archive
if: always()
uses: actions/upload-artifact@v2
with:
name: code-coverage-report
path: build/reports/androidTests/
retention-days: 7
+1 -1
View File
@@ -6,4 +6,4 @@
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
</project>
-13
View File
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
+20 -9
View File
@@ -47,20 +47,29 @@ _OpenTracks_ is a sport tracking application that completely respects your priva
</td>
<td></td>
</tr>
<tr>
<td></td>
<td align="center">
<a href="https://www.amazon.de/dp/B09K2KNQ7X/">
<img alt="Get it on Amazon App Store" src="https://images-na.ssl-images-amazon.com/images/G/01/mobile-apps/devportal2/res/images/amazon-appstore-badge-english-white.png" height="40" align="middle">
</a>
</td>
<td></td>
</tr>
</table>
## Screenshots
<div>
<img width="23%" src="fastlane/metadata/android/en-US/phoneScreenshots/screenshot1.png">
<img width="23%" src="fastlane/metadata/android/en-US/phoneScreenshots/screenshot2.png">
<img width="23%" src="fastlane/metadata/android/en-US/phoneScreenshots/screenshot3.png">
<img width="23%" src="fastlane/metadata/android/en-US/phoneScreenshots/screenshot4.png">
<img width="23%" src="fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot1.png">
<img width="23%" src="fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot2.png">
<img width="23%" src="fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot3.png">
<img width="23%" src="fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot4.png">
</div>
<div>
<img width="23%" src="fastlane/metadata/android/en-US/phoneScreenshots/screenshot5.png">
<img width="23%" src="fastlane/metadata/android/en-US/phoneScreenshots/screenshot6.png">
<img width="23%" src="fastlane/metadata/android/en-US/phoneScreenshots/screenshot7.png">
<img width="23%" src="fastlane/metadata/android/en-US/phoneScreenshots/screenshot8.png">
<img width="23%" src="fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot5.png">
<img width="23%" src="fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot6.png">
<img width="23%" src="fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot7.png">
<img width="23%" src="fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot8.png">
</div>
## Features
@@ -79,6 +88,8 @@ _OpenTracks_ is a sport tracking application that completely respects your priva
* cycling: speed and distance
* cycling: cadence
* cycling: power meter
* running: speed and cadence
An overview of tested sensors: [README_TESTED_SENSORS.md](README_TESTED_SENSORS.md)
### Gadgetbridge integration
@@ -130,4 +141,4 @@ Artwork, logos and user interface remained more or less unchanged.
More information about _Google My Tracks_:
* [Wikipedia page](https://en.wikipedia.org/wiki/MyTracks)
* [Google code archive](https://code.google.com/archive/p/mytracks/)
* [Google code archive](https://code.google.com/archive/p/mytracks/)
+4 -3
View File
@@ -28,9 +28,10 @@ Requirement: `gem install fastlane`
(requires keystore)
2. Upload signed apk to [Google Play Console](https://play.google.com/apps/publish)
3. Update store meta data (e.g., description and screenshots)
`fastlane supply --version_code VERSION_CODE --skip_upload_apk`
(use the version code from the manifest)
(requires API key)
`fastlane metadata`
(requires API key configured in `Appfile`)
Supported languages: https://support.google.com/googleplay/android-developer/table/4419860
## Translations (localization)
+30 -3
View File
@@ -1,6 +1,6 @@
# Overview of tested Bluetooth LE sensors
## HRS: Heartrate Service
## 0x180D: Heartrate Service
* Decathlon|Geonaute|Kalenji Dual HRM Belt
* moofit heart rate monitor
@@ -11,8 +11,9 @@
* Wahoo Tickr (Model: WFBTHR02)
* Mi Band 3, Amazfit Band 5, Amazfit Bip. These devices are manufactured by Huami, and other Huami devices will very likely work. Theoretically, this sensor must be enabled, but testing reveals that it works even without enabling. For details on how to enable see [Gadgetbridge wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Huami-Heartrate-measurement#bluetooth-heart-rate-sensor)
* Amazfit Neo. But first you have to enable "Discoverable" and "Activity heart rate sharing" in the official Zepp app. (after pairing with OpenTracks you can disable them again)
* Garmin HRM-Dual (Reference: 010-12883-00)
## CSCP: Cycling Cadence and Speed Service
## 0x1816: Cycling Cadence and Speed Service
Please note that the according to the specification these sensors _may_ provide speed as well as cadence.
However, often only one value is provided.
@@ -35,7 +36,7 @@ However, often only one value is provided.
This sensor reports cadence data as speed.
A workaround is in place.
## Cycling Power Measurement
## 0x1818: Power Measurement
We only support _Instantaneous Power_.
@@ -43,6 +44,7 @@ _WARNING_: we only support physically movements with valid GPS coordinates.
Using a device indoors (no GPS available) will only show the current power values, but won't store anything.
Also the distance is not computed.
For cycling:
* Assioma Duo Powermeter
* Elite drivo II
* QUARQ Red DZero Powermeter
@@ -50,3 +52,28 @@ Also the distance is not computed.
* Wahoo Kickr v4.0
* Rotor 2INpower DM Road (only supports power measurement, cadence measurement is propietary @ firmware v1.061)
For running:
* Stryd
## 0x1814: running cadence and speed
We do not support type of movement (i.e., walking vs running).
* Polar Stride
* Stryd (incl. power)
## Tested Barometric Sensor Smartphones
There are smartphones that have a barometric sensor that OpenTracks uses to compute altitude gain and loss.
In our tests there are smartphones whose barometric sensor works well and others don't. Here is a list of the smartphones tested:
|Brand|Model|Android Version|Tests|
|-----|-----|---------------|-----------|
|Google|Pixel|LineageOS 17.1|Ok|
|Google|Pixel 2 XL|LineageOS 17.1|Ok on the bike handlebars but it fails when I carry it in a pocket or backpack|
|Google|Pixel 3|Android 11|Failure|
|Google|Pixel 3a|Android 11|Ok|
|Google|Pixel 3a|Lineage 18.1|Ok|
|Google|Pixel 4a|Android 11|Ok|
|Sony|Xperia XZ1 Compact|LineageOS 16.1|Failure|
+45 -19
View File
@@ -6,7 +6,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
classpath 'com.android.tools.build:gradle:7.0.3'
}
}
@@ -24,29 +24,30 @@ def getVersionName = { ->
commandLine 'git', 'describe', '--tags'
standardOutput = stdout
}
exec {
commandLine 'git', 'log', '--format="%h"', '-n 1'
standardOutput = stdout
}
return stdout.toString().replace('\n', '-').replace('"', '').trim()
}
catch (ignored) {
return stdout.toString().trim()
} catch (ignored) {
return null
}
}
def versionCodeFromDate = { ->
def date = new Date()
def formattedDate = date.format('yyyyMMdd')
return Integer.valueOf(formattedDate)
}
android {
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
compileSdkVersion 30
compileSdkVersion 31
buildFeatures {
viewBinding = true
viewBinding true
}
aaptOptions {
@@ -55,17 +56,27 @@ android {
defaultConfig {
applicationId "de.dennisguse.opentracks"
versionCode 4253
versionName "v3.18.6"
versionCode 4519
versionName "v3.22.0"
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
minSdkVersion 21
targetSdkVersion 30
targetSdkVersion 31
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "de.dennisguse.opentracks.TestRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
}
signingConfigs {
nightly {
if (System.getProperty("nightly_store_file") != null) {
storeFile file(System.getProperty("nightly_store_file"))
storePassword System.getProperty("nightly_store_password")
keyAlias System.getProperty("nightly_key_alias")
keyPassword System.getProperty("nightly_key_password")
}
}
}
buildTypes {
@@ -74,6 +85,11 @@ android {
versionNameSuffix "-debug"
}
nightly {
signingConfig signingConfigs.nightly
applicationIdSuffix ".nightly"
}
release {
minifyEnabled false
}
@@ -86,13 +102,21 @@ android {
applicationVariants.all { variant ->
variant.resValue "string", "applicationId", variant.applicationId
if (variant.buildType.name == 'nightly') {
variant.outputs.all {
setVersionCodeOverride(versionCodeFromDate())
setVersionNameOverride(getVersionName())
outputFileName = "${applicationId}_${variant.versionCode}.apk"
}
}
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'com.google.android.material:material:1.4.0'
@@ -103,5 +127,7 @@ dependencies {
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'org.mockito:mockito-android:3.10.0'
androidTestImplementation 'org.mockito:mockito-android:4.0.0'
androidTestUtil 'androidx.test:orchestrator:1.4.0'
}
+21 -2
View File
@@ -43,7 +43,6 @@ class TrackPoint {
- sensor_power
}
class Marker {
- id
- trackId
@@ -58,6 +57,26 @@ class Marker {
- photoUrl
}
class DataField {
- key
- title
- isVisible
- isPrimary
- isWide
}
class StatisticData {
- value
- unit
- description
}
StatisticData o-- DataField
class Layout {
- profile
}
Layout "1" o-- "many" DataField
note left of TrackPoint
As of OpenTracks version 3.15.0, all times are using device time.
Before that TrackPoint.time contained GPS time (determined by GPS hardware).
@@ -77,4 +96,4 @@ Trackpoints of Type.SEGMENT_START_MANUAL or Type.SEGMENT_END_MANUAL do not conta
Tracks recorded prior to OpenTracks version 3.15.0, do neither begin with a Type.SEGMENT_START_MANUAL nor end with a Type.SEGMENT_END_MANUAL.
end note
@enduml
@enduml
+3
View File
@@ -0,0 +1,3 @@
README.md
Appfile
report.xml
+6 -18
View File
@@ -16,23 +16,11 @@
default_platform(:android)
platform :android do
desc "Runs all the tests"
lane :test do
gradle(task: "test")
end
desc "Submit a new Beta Build to Crashlytics Beta"
lane :beta do
gradle(task: "clean assembleRelease")
crashlytics
# sh "your_script.sh"
# You can also use other beta testing services here
end
desc "Deploy a new version to the Google Play"
lane :deploy do
gradle(task: "clean assembleRelease")
upload_to_play_store
desc "Upload metadata"
lane :metadata do
upload_to_play_store(
skip_upload_apk: true,
skip_upload_changelogs: true
)
end
end
@@ -12,4 +12,4 @@ Changes:
- Removed Bluetooth classic sensors
- Removed Protobuf
- Removed calorie estimation and activity estimation
- Removed MyTracks Service API (i.e., no integration with other apps)
- Removed MyTracks Service API (i.e., no integration with other apps)
@@ -14,4 +14,4 @@ Bugfixes:
Developer:
- Test are executable (but many failing)
- Enabled continuous integration with TravisCI (no tests)
- Enabled continuous integration with TravisCI (no tests)
@@ -11,4 +11,4 @@ Bugfix:
Developer:
- Upgrade to Gradle 5.6
- Do not minify release builds
- Do not minify release builds
@@ -13,4 +13,4 @@ Developer:
- Removed unused parcelable functionality
- Major cleanup and reformatting
- Do not use broadcast for app to widget communication
- stats_content.xml does not include other files
- stats_content.xml does not include other files
@@ -4,4 +4,4 @@ Changes:
- Settings are now on a single page
Developer:
- Settings moved to Androidx compat (uses fragments)
- Settings moved to Androidx compat (uses fragments)
@@ -10,4 +10,4 @@ Bugfix:
Developer:
- Replaced actionbar with toolbar
- Migrated to androidx appcompat (incl. Material Design)
- Migrated to androidx appcompat (incl. Material Design)
@@ -11,4 +11,4 @@ Bugfix:
- Heart rate wasn't always shown while recording
Developer:
- Enabled TravisCI instrumentation tests
- Enabled TravisCI instrumentation tests
@@ -2,4 +2,4 @@ v3.2.4: OpenTracks
Bugfix:
- Settings activity crashes
Removed possibility to change voice/split frequency from the context menu
Removed possibility to change voice/split frequency from the context menu
@@ -12,4 +12,4 @@ Developer:
- if Settings cannot be loaded reset all preferences
- moved access to preferences to PreferencesUtil
- moved default of preferences from code to xml
- use SummaryProvider
- use SummaryProvider
@@ -5,4 +5,4 @@ Changes:
- Remove shortcut to Bluetooth settings
Developer:
- Preferences: moved default of preferences from code to xml
- Preferences: moved default of preferences from code to xml
@@ -7,4 +7,4 @@ Changes:
- Added help (in Settings)
Bugfix:
- TrackDetailActivity: disabled non-working landscape mode (temporary)
- TrackDetailActivity: disabled non-working landscape mode (temporary)
@@ -7,4 +7,4 @@ Bugfixes:
- Export via KMZ did not export picture filenames correctly
- Sharing multiple tracks did not include KMZ files
- MarkerDetailActivity's UI was not shown
- Settings crashed if preference of heart rate was not initialized
- Settings crashed if preference of heart rate was not initialized
@@ -7,4 +7,4 @@ Changes:
Bugfixes:
- Statistics: heart rate was not shown
- Statistics: time was briefly reset to 0s
- Statistics: time was briefly reset to 0s
@@ -9,4 +9,4 @@ Bugfix:
Developer:
- Replaced TabHost by TabsLayout
- Removed special first waypoint
- Removed duplicate translations
- Removed duplicate translations
@@ -11,4 +11,4 @@ Bugfix:
Developer:
- Database: remove unused columns
- Database: add indices
- Database: add indices
@@ -7,4 +7,4 @@ Bugfix:
- Import of KMZ did not process the photo URL correctly
Developer:
- Simplified data processing
- Simplified data processing
@@ -1,4 +1,4 @@
v3.6.1: OpenTracks
Bugfix:
- KMZ import: store correct picture path
- KMZ import: store correct picture path
@@ -1,4 +1,4 @@
v3.6.2: OpenTracks
Bugfix:
- Charts were not shown correctly (introduced in v3.6.0)
- Charts were not shown correctly (introduced in v3.6.0)
@@ -10,4 +10,4 @@ Bugfix:
- KMZ import: only import used images
Developer:
- Refactored TrackRecordingService
- Refactored TrackRecordingService
@@ -4,4 +4,4 @@ Workaround:
- Hide start GPS button
Bugfix:
- Fixed null pointer
- Fixed null pointer
@@ -3,4 +3,4 @@ v3.7.2: OpenTracks
Bugfix:
- Re-added start GPS button
- Track name is not overwritten at the end of a recording
- Markers: removing a photo also deletes the file
- Markers: removing a photo also deletes the file
@@ -4,4 +4,4 @@ Bugfix:
- Fixed computation of cadence and speed (via Bluetooth LE sensor)
Developer:
- Removed unused translations
- Removed unused translations
@@ -9,4 +9,4 @@ Bugfix:
Developer:
- Split TrackDetailActivity
- StatsFragement successor uses ConstraintLayout
- StatsFragement successor uses ConstraintLayout
@@ -8,4 +8,4 @@ Changes:
- Show track on map: file format can be selected and opening dashboard works on Android R (API 30+)
Bugfix:
- App icon now correctly implemented
- App icon now correctly implemented
@@ -8,4 +8,4 @@ Changes:
Developer:
- Replaced AsyncTasks with Threads
- Synchronization: UUID is generated per track (not yet exported)
- Synchronization: UUID is generated per track (not yet exported)
@@ -13,4 +13,4 @@ Bugfixes:
- Editing a marker failed on orientation change
Developer:
- Refactored TrackRecordingService
- Refactored TrackRecordingService
@@ -5,4 +5,4 @@ Changes:
- Dashboard is started on the same task
Bugfixes:
- Intent filters for importing files were far too optimistic
- Intent filters for importing files were far too optimistic
@@ -11,4 +11,4 @@ Changes:
Bugfixes:
- Fixed some rare crashes (NPE)
- Pace formatting corrected
- App icon in launcher repositioned
- App icon in launcher repositioned
@@ -1,4 +1,4 @@
v3.9.1: OpenTracks
Bugfixes:
- GPS pre-start shows status of fix
- GPS pre-start shows status of fix
@@ -2,4 +2,4 @@ v3.9.2: OpenTracks
Bugfixes:
- Fixed force close on API<25 (due to an animation)
- Reset recording state (on app startup) if crashed while recording
- Reset recording state (on app startup) if crashed while recording
@@ -1,4 +1,4 @@
v3.9.3: OpenTracks
Bugfixes:
- Fixed export all tracks bug.
- Fixed export all tracks bug.
@@ -7,4 +7,4 @@ Changes:
Bugfix:
- GPS was not turned off when stopping a recording
- Show on map via KML/KMZ/GPX was broken due to refactoring
- Show on map via KML/KMZ/GPX was broken due to refactoring
@@ -2,4 +2,3 @@ v3.13.2: OpenTracks
Bugfix:
- Crash in landscape mode
@@ -7,4 +7,4 @@ Changes:
- Marker list performance improved
Developer:
- Track.Id/Marker.Id: use null
- Track.Id/Marker.Id: use null
@@ -15,4 +15,3 @@ Developer:
- Replaced communication via SharedPreferences
- Use non-static service binder
- Use altitude in the code base (instead of elevation)
@@ -8,4 +8,3 @@ Bugfix:
- Crash if using pace for voice announcements (introduced in v3.17.0)
- Statistics showed pace initially (introduced in v3.17.0)
- Rare crash when deleting tracks
@@ -0,0 +1,16 @@
v3.19.0: OpenTracks
Changes:
- Support for Running Speed and Cadence (RCS) sensors implemented
- When sharing a track: a share picture is created
- No vibration when starting a recording
- While recording: UI shows most recently received altitude, speed, and bearing (even if not stored)
Bugfix:
- Computation of total duration should not include paused durations (requires re-import)
- (again) Use custom summaries if present
Developer:
- Upgrade to SDK31 and AGP7.0.0 (requires JDK11)
- TrackRecordingService: extacted sensor fusion (TrackPointCreator) and TrackPoint storage (TrackRecordingManager)
- ExportImportTest is now deterministics/ constant
@@ -0,0 +1,8 @@
v3.19.1: OpenTracks
Changes:
- Updated translations.
Bugfix:
- Export All Tracks bug fixed.
- Resume Track bug fixed.
@@ -0,0 +1,9 @@
v3.20.0: OpenTracks
Changes:
- While recording: statistics UI is now configurable
Bugfix:
- Changing track name/ category while recording was ignored (introduced in v3.19.0)
@@ -0,0 +1,7 @@
v3.20.1: OpenTracks
Changes:
- Announcements can now be used by both distance and time
- Announcements beep if no Text-to-speech software is installed
- Removed adaptive GPS location frequency
@@ -0,0 +1,11 @@
v3.20.2: OpenTracks
Changes:
- Elevation gain and loss are integers instead of floats
- Ask for permission before using Bluetooth by a Toast message
Bugfix:
- Set FLAG_IMMUTABLE for PendingIntents to avoid crash on Android 12
- Cadence sensor returns 0 instead of None when user is not pedaling
- Speed sensor returns 0 instead of the last speed when it's stopped
- With sensors, moving time stops when is not moving
@@ -0,0 +1,19 @@
v3.21.0: OpenTracks
Changes:
- While recording: remove idle/non-idle creation of TrackPoints
- Settings are now in separate folders
- Opening OpenTracks from notification (while recording) and pressing back opens track list
- GPX compatibilty: support <speed> for import
Bugfixes:
- Altitude and distance (from BlE sensor): only reset counters if data was actually stored
- Import without speed, requires computing speed
- BLE running sensor not connected, should not be reported as present
- BLE running sensor: show data while recording
- Activity type icon was not updated while changing activity
Developer:
- SharedPrefences via static reference
- Tests are executed against in-memory database
- TrackRecordingManager keeps last TrackPoint in memory
@@ -0,0 +1,11 @@
v3.22.0: OpenTracks
Changes:
- Locations are only stored if traveled distance > recording distance interval
(removed left over functionality from idle/non-idle detection)
- UI can be configured to show a clock
- Idle speed is now configurable
Bugfix:
- Intervals: crash when gain but not loss was stored
- While recording: prevent crash when disabling voice announcements
@@ -7,4 +7,4 @@ Bugfix:
-
Developer:
-
-
@@ -7,5 +7,5 @@ Features:
* Altitude shown in EGM2008 (above mean sea level); exported as WGS84
* Voice announcements
* Supports Bluetooth LE sensors: heart rate, speed and distance (cycling), cadence (cycling), and power meter (cycling)
* Export data: export tracks either as KMZ (incl. photos), KML, or GPX
* No Internet access: Internet is not used
* Export data: export tracks either as KMZ (incl. photos), KML, or GPX
* No Internet access: Internet is not used

Before

Width:  |  Height:  |  Size: 303 KiB

After

Width:  |  Height:  |  Size: 303 KiB

Before

Width:  |  Height:  |  Size: 574 KiB

After

Width:  |  Height:  |  Size: 574 KiB

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before

Width:  |  Height:  |  Size: 456 KiB

After

Width:  |  Height:  |  Size: 456 KiB

Before

Width:  |  Height:  |  Size: 630 KiB

After

Width:  |  Height:  |  Size: 630 KiB

Before

Width:  |  Height:  |  Size: 416 KiB

After

Width:  |  Height:  |  Size: 416 KiB

Before

Width:  |  Height:  |  Size: 508 KiB

After

Width:  |  Height:  |  Size: 508 KiB

Before

Width:  |  Height:  |  Size: 798 KiB

After

Width:  |  Height:  |  Size: 798 KiB

@@ -1 +1 @@
A sport tracker that completely respects your privacy.
A sport tracker that completely respects your privacy.
@@ -1,11 +1,11 @@
OpenTracks estas sporto spuranta aplikon kiu tute respektas vian privatecon.
OpenTracks estas aplikaĵo por registri vian sportan aktivecon, kiu plene respektas vian privatecon.
Karakterizaĵoj:
* Sporto spurado: spuri via sporto kaj subĉielaj aktivecoj
* Fotoj kaj signoj: mark interesaj lokoj dum spurado
* Altitudo akiro kaj perdo: tra barometric sentilo
* Altitudo montrita en EGM2008 (supre signifas marnivelo); eksportita kiel WGS84
* # Vo? o anoncoj
* Elportas Bluetooth LE sentiloj: koro imposto, rapido kaj distanco (biciklado), kadenco (biciklado), kaj potenco metro (biciklado)
* Eksportado datumoj: eksporti vojetoj aŭ kiel KMZ (incl. fotoj), KML, aŭ GPX
* Neniu aliro al Interreto: Internet ne estas uzita
Ebloj:
• registri vian sportan kaj alian aktivecon eksterdome
• fotoj kaj markoj: marki interesajn lokojn dum registri aktivecon
• registri ŝanĝon de altitudo uzante barometron
• montri altitudon en EGM2008 (super averaĝa marnivelo); elporti ilin kiel WGS84
• voĉaj anoncoj
• subteno por sentiloj BLE por registri vian pulson, rapidon, veturigitan distancon, pedal-rapidon, povumon (biciklado)
• elporti datumojn al dosieroj KMZ (kun fotoj), KML aŭ GPX
• funkcias malkonekte: interreta permeso ne estas uzata
@@ -1 +1 @@
Sporto spuristo ke tute respektas vian privatecon.
Registrilo de via sporta aktiveco, kiu respektas vian privatecon.
@@ -0,0 +1,16 @@
v3.18.6: „OpenTracks“
Pakeitimai:
- „Rodyti žemėlapyje“ funkcionalumas per KML, o ne KMZ
- Pranešime balsu nėra programos pavadinimo
- Įrašant: aukščio padidėjimas / praradimas atnaujinamas kas sekundę
- Išversti parduotuvės aprašymai
Bufiksai:
- Ištaisyti neteisingi balso pranešimų vertimai
Programuotojas:
- „Android12“ leidimai (BLUETOOTH_SCAN)
- „Android12“ leidimai (ACCESS_COARSE_LOCATION)
- Tvirtinimas „TrackPoints“ (testavimas)
- Pašalinti nepanaudoti vertimai
@@ -0,0 +1,11 @@
„OpenTracks“ yra sporto stebėjimo programa, visiškai gerbianti jūsų privatumą.
Funkcijos:
* Sporto sekimas: stebėkite savo sportinę ir lauko veiklą
* Nuotraukos ir žymekliai: stebėdami stebėkite įdomias vietas
* Aukščio padidėjimas ir praradimas: per barometrinį jutiklį
* EGM2008 nurodytas aukštis (virš vidutinio jūros lygio); eksportuota kaip WGS84
* Balso pranešimai
* Palaiko „Bluetooth LE“ jutiklius: širdies ritmą, greitį ir atstumą (važiuojant dviračiu), ritmą (dviračiu) ir galios matuoklį (važiuojant dviračiu)
* Eksportuoti duomenis: eksportuoti takelius kaip KMZ (įskaitant nuotraukas), KML arba GPX
* Nėra interneto prieigos: internetas nenaudojamas
@@ -0,0 +1 @@
Sporto sekimo priemonė, visiškai gerbianti jūsų privatumą.
+1
View File
@@ -0,0 +1 @@
OpenTracks
@@ -0,0 +1,16 @@
v3.18.6: OpenTracks
Endringer:
- «Vis på kart»-funksjonalitet via KML istedenfor KMZ
- Stemmekunngjøringer inkluderer ikke programnavn
- Under opptak: Høydeendringer registrert hvert sekund
- Butikk-oversettelser oversatt
Feilfikser:
- Fikset ugyldige stemmekunngjøringsoversettelser
Utviklere:
- Android12-tilganger (Blåtannsskanning)
- Android12-tilganger (tilgang til grovposisjon)
- Fastsetting for TrackPoints (testing)
- Fjernet ubrukte oversettelser
@@ -0,0 +1,11 @@
OpenTracks er en app for opptak av sportsaktivitet som respekterer ditt personvern.
Funksjoner:
* Sportsporing: Registrer dine sports- og utendørsaktiviteter
* Bilder og markører: Marker interessante steder under sporing
* Total stigning og nedstigning: via barometersensor
* Høyde vist i EGM2008 (over havnivå); eksportert som WGS84
* Talemeldinger
* Støtter Blåtann LE-sensorer: puls, hastighet og distanse (sykling), kadens (sykling) og wattmåler (sykling)
* Eksport av data: Enten som KMZ (inkl. bilder), KML eller GPX
* Ingen internettilgang: Internett brukes ikke
@@ -0,0 +1 @@
En opptaker av sportsaktivitet som respekterer ditt personvern.
@@ -0,0 +1 @@
OpenTracks
@@ -0,0 +1,16 @@
v3.18.6: OpenTracks
Mudanças:
- Funcionalidade "Mostrar no mapa" via KML em vez de KMZ
- O anúncio de voz não inclui o nome do aplicativo
- Durante a gravação: o ganho / perda de elevação é atualizado a cada segundo
- Descrições da loja traduzidas
Correções:
- Correções de traduções inválidas no anúncios de voz
Desenvolvedores:
- Permissões Android12 (BLUETOOTH_SCAN)
- Permissões Android12 (ACCESS_COARSE_LOCATION)
- Confirmação de TrackPoints (em teste)
- Removidas as traduções não utilizadas
@@ -7,5 +7,5 @@ Características:
* Altitude mostrada no EGM2008 (acima do nível médio do mar); exportado como WGS84
* Anúncios de voz
* Suporta sensores Bluetooth LE: frequência cardíaca, velocidade e distância (ciclismo), cadência (ciclismo) e medidor de potência (ciclismo)
* Exportar dados: exporte trilhas como KMZ (incluindo fotos), KML ou GPX
* Exportar dados: exporte trilhas como KMZ (incluindo fotos), KML, ou GPX
* Sem acesso à Internet: a Internet não é usada
@@ -0,0 +1,16 @@
v3.18.6: OpenTracks
Spremembe:
- "Prikaži na zemljevidu"-funkcionalnost prek KML namesto KMZ
- Glasovno obvestilo ne vključuje imena aplikacije
- Med snemanjem: pridobitev/izguba nadmorske višine se posodobi vsako sekundo
- Prevedeni opisi trgovin
Bufiksi:
- Vključene so bile naslednje možnosti: popravljeni neveljavni prevodi glasovnih napovedi
Razvijalec:
- Android12 (BLUETOOTH_SCAN)
- Android12 dovoljenja (ACCESS_COARSE_LOCATION)
- Zagotavljanje za TrackPoints (testiranje)
@@ -1,7 +1,7 @@
OpenTracks je aplikacija za sledenje športu, ki popolnoma spoštuje vašo zasebnost.
Značilnosti:
* Športno sledenje: sledite svojim športnim aktivnostim in aktivnostim na prostem.
* Sledenje športu: sledite svojim športnim aktivnostim in aktivnostim na prostem.
* Fotografije in oznake: med sledenjem označite zanimive lokacije
* Pridobivanje in izgubljanje nadmorske višine: prek barometričnega senzorja
* Nadmorska višina je prikazana v EGM2008 (nad srednjo morsko gladino); izvozi se kot WGS84
@@ -0,0 +1,16 @@
v3.18.6: OpenTracks
Förändring:
- "Visa på kartan" - funktionalitet via KML istället för KMZ
- Röstmeddelande inkluderar inte appnamn
- Under inspelning: höjd vinst / förlust uppdateras varje sekund
- Store beskrivningar översatt
Bufixar:
- Fast ogiltig röst tillkännagivande översättningar
Utvecklare:
- Android12 behörigheter (BLUETOOTH_SCAN)
- Android12 behörigheter (ACCESS_COARSE_LOCATION)
- Bedömning av spårpunkter (provning)
- Bort oanvända översättningar
+3 -2
View File
@@ -1,5 +1,6 @@
#Wed Jul 28 23:10:13 CEST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
@@ -1,191 +0,0 @@
package de.dennisguse.opentracks;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import androidx.test.espresso.DataInteraction;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.GrantPermissionRule;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import static androidx.test.espresso.Espresso.onData;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anything;
import static org.hamcrest.Matchers.is;
/**
* Espresso test that checks the unit for activity category selected.
* Also it checks that unit is properly when user change from a pace activity to an speed one.
*/
@LargeTest
@RunWith(AndroidJUnit4.class)
public class EspressoCategoryUnitTest {
@Rule
public ActivityScenarioRule<TrackListActivity> mActivityTestRule = new ActivityScenarioRule<>(TrackListActivity.class);
@Rule
public TestRule mRuntimePermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
private final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
@Rule
public TestRule mLocaleRule = new PreferenceMetricUnitRule(context, true);
@Test
public void changeBetweenCategoryUpdateProperlyUnitTest() {
// Start record.
ViewInteraction appCompatImageButton = onView(
allOf(withId(R.id.controller_record), withContentDescription("Record"),
childAtPosition(
allOf(withId(R.id.controller_container),
childAtPosition(
withId(R.id.controller_fragment),
0)),
0),
isDisplayed()));
appCompatImageButton.perform(click());
{
// Change to running activity (pace activity).
ViewInteraction appCompatImageView = onView(
allOf(withId(R.id.stats_activity_type_icon),
childAtPosition(
childAtPosition(
withClassName(is("android.widget.ScrollView")),
0),
7)));
appCompatImageView.perform(scrollTo(), click());
DataInteraction imageView = onData(anything())
.inAdapterView(allOf(withId(R.id.choose_activity_type_grid_view),
childAtPosition(
withClassName(is("android.widget.LinearLayout")),
0)))
.atPosition(1);
imageView.perform(click());
}
// Pace (min/km) in all fields.
{
ViewInteraction textView = onView(allOf(withId(R.id.stats_speed_unit)));
textView.perform(waitFor(2000));
textView.check(matches(withText("min/km")));
}
{
ViewInteraction textView = onView(allOf(withId(R.id.stats_average_speed_unit)));
textView.check(matches(withText("min/km")));
}
{
ViewInteraction textView = onView(allOf(withId(R.id.stats_max_speed_unit)));
textView.check(matches(withText("min/km")));
}
{
ViewInteraction textView = onView(allOf(withId(R.id.stats_moving_speed_unit)));
textView.check(matches(withText("min/km")));
}
{
// Change to biking activity (speed activity).
ViewInteraction appCompatImageView = onView(
allOf(withId(R.id.stats_activity_type_icon),
childAtPosition(
childAtPosition(
withClassName(is("android.widget.ScrollView")),
0),
7)));
appCompatImageView.perform(scrollTo(), click());
DataInteraction imageView = onData(anything())
.inAdapterView(allOf(withId(R.id.choose_activity_type_grid_view),
childAtPosition(
withClassName(is("android.widget.LinearLayout")),
0)))
.atPosition(9);
imageView.perform(click());
}
// Speed (km/h) in all fields.
{
ViewInteraction textView = onView(allOf(withId(R.id.stats_speed_unit)));
textView.perform(waitFor(2000));
textView.check(matches(withText("km/h")));
}
{
ViewInteraction textView = onView(allOf(withId(R.id.stats_average_speed_unit)));
textView.check(matches(withText("km/h")));
}
{
ViewInteraction textView = onView(allOf(withId(R.id.stats_max_speed_unit)));
textView.check(matches(withText("km/h")));
}
{
ViewInteraction textView = onView(allOf(withId(R.id.stats_moving_speed_unit)));
textView.check(matches(withText("km/h")));
}
}
private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
private static ViewAction waitFor(final long duration_ms) {
return new ViewAction() {
@Override
public String getDescription() {
return "Wait for milliseconds.";
}
@Override
public Matcher<View> getConstraints() {
return isDisplayed();
}
@Override
public void perform(UiController uiController, final View view) {
uiController.loopMainThreadForAtLeast(duration_ms);
}
};
}
}
@@ -0,0 +1,136 @@
package de.dennisguse.opentracks;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.ViewAssertion;
import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.action.MotionEvents;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.*;
import static androidx.test.espresso.matcher.ViewMatchers.*;
import de.dennisguse.opentracks.content.data.DataField;
import de.dennisguse.opentracks.content.data.Layout;
import de.dennisguse.opentracks.settings.PreferencesUtils;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.hamcrest.CoreMatchers.is;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class EspressoCustomLayoutTest {
private final Context context = ApplicationProvider.getApplicationContext();
@Rule
public ActivityTestRule<TrackListActivity> mActivityTestRule = new ActivityTestRule<>(TrackListActivity.class);
@Rule
public GrantPermissionRule mGrantPermissionRule =
GrantPermissionRule.grant(
"android.permission.ACCESS_FINE_LOCATION");
@Test
public void customLayoutTest() {
// TrackListActivity: start recording
ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
trackControllerRecordButton.perform(click());
// Get custom layout preferences and check all data fields are showed.
Layout layout = PreferencesUtils.getCustomLayout();
onView(withId(R.id.stats_recycler_view)).check(new RecyclerViewItemCountAssertion((int) layout.getFields().stream().filter(DataField::isVisible).count()));
// stop recording
ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop));
trackControllerStopButton.perform(veryLongTouch(1600));
}
private static class RecyclerViewItemCountAssertion implements ViewAssertion {
private final int expectedCount;
public RecyclerViewItemCountAssertion(int expectedCount) {
this.expectedCount = expectedCount;
}
@Override
public void check(View view, NoMatchingViewException noViewFoundException) {
if (noViewFoundException != null) {
throw noViewFoundException;
}
RecyclerView recyclerView = (RecyclerView) view;
RecyclerView.Adapter<?> adapter = recyclerView.getAdapter();
assertThat(adapter.getItemCount(), is(expectedCount));
}
}
private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
private static ViewAction veryLongTouch(final int duration_ms) {
return new ViewAction() {
@Override
public String getDescription() {
return "Perform long touch.";
}
@Override
public Matcher<View> getConstraints() {
return isDisplayed();
}
@Override
public void perform(UiController uiController, final View view) {
// Get view absolute position
int[] location = new int[2];
view.getLocationOnScreen(location);
// Offset coordinates by view position
float[] coordinates = new float[]{location[0] + 1, location[1] + 1};
// Send down event, pause, and send up
MotionEvent down = MotionEvents.sendDown(uiController, coordinates, new float[]{1f, 1f}).down;
uiController.loopMainThreadForAtLeast(duration_ms);
MotionEvents.sendUp(uiController, down, coordinates);
}
};
}
}
@@ -143,7 +143,7 @@ public class EspressoDeleteTrackTest {
private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<View>() {
return new TypeSafeMatcher<>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
@@ -160,13 +160,15 @@ public class EspressoDeleteTrackTest {
}
public static Matcher<View> withListSize (final int size) {
return new TypeSafeMatcher<View> () {
@Override public boolean matchesSafely (final View view) {
return ((ListView) view).getCount () == size;
return new TypeSafeMatcher<>() {
@Override
public boolean matchesSafely(final View view) {
return ((ListView) view).getCount() == size;
}
@Override public void describeTo (final Description description) {
description.appendText ("ListView should have " + size + " items");
@Override
public void describeTo(final Description description) {
description.appendText("ListView should have " + size + " items");
}
};
}
@@ -0,0 +1,261 @@
package de.dennisguse.opentracks;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import androidx.test.espresso.PerformException;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.action.MotionEvents;
import androidx.test.espresso.util.HumanReadables;
import androidx.test.espresso.util.TreeIterables;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.hamcrest.core.IsInstanceOf;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.TimeoutException;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class EspressoEditTrackRecordingTest {
@Rule
public ActivityTestRule<TrackListActivity> mActivityTestRule = new ActivityTestRule<>(TrackListActivity.class);
@Rule
public GrantPermissionRule mGrantPermissionRule =
GrantPermissionRule.grant(
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.ACCESS_COARSE_LOCATION");
@LargeTest
@Test
public void espressoEditTrackRecordingTest() {
{
// TrackListActivity: start recording
ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
trackControllerRecordButton.perform(click());
}
{
// TrackRecordingActivity
ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop));
// wait; stay recording
trackControllerRecordButton.perform(waitFor(15000));
// open menu
ViewInteraction overflowMenuButton = onView(
allOf(withContentDescription("More options"),
childAtPosition(
childAtPosition(
withId(R.id.toolbar),
2),
2),
isDisplayed()));
overflowMenuButton.perform(click());
// click on edit
ViewInteraction appCompatTextView = onView(
allOf(withId(R.id.title), withText("Edit"),
childAtPosition(
childAtPosition(
withId(R.id.content),
0),
0),
isDisplayed()));
appCompatTextView.perform(click());
// change name for "New Name"
ViewInteraction textInputEditText = onView(
allOf(withId(R.id.track_edit_name),
childAtPosition(
childAtPosition(
withClassName(is("com.google.android.material.textfield.TextInputLayout")),
0),
1)));
textInputEditText.perform(scrollTo(), replaceText("New Name"));
ViewInteraction textInputEditText2 = onView(
allOf(withId(R.id.track_edit_name), withText("New Name"),
childAtPosition(
childAtPosition(
withClassName(is("com.google.android.material.textfield.TextInputLayout")),
0),
1),
isDisplayed()));
textInputEditText2.perform(closeSoftKeyboard());
// save edition
ViewInteraction appCompatButton = onView(
allOf(withId(R.id.track_edit_save),
childAtPosition(
childAtPosition(
withClassName(is("android.widget.LinearLayout")),
3),
1),
isDisplayed()));
appCompatButton.perform(click());
//pause
trackControllerRecordButton.perform(veryLongTouch(1600));
// wait; stay paused
trackControllerRecordButton.perform(waitFor(1000));
// resume
trackControllerRecordButton.perform(click());
// wait; stay recording
trackControllerRecordButton.perform(waitFor(1000));
// stop;
trackControllerStopButton.perform(veryLongTouch(1600));
// check track's name is "New Name"
ViewInteraction textView = onView(
allOf(withId(R.id.stats_name_value),
withParent(withParent(IsInstanceOf.instanceOf(android.widget.ScrollView.class))),
isDisplayed()));
textView.check(matches(withText("New Name")));
}
}
private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
public static ViewAction waitId(final int viewId, final long millis) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isRoot();
}
@Override
public String getDescription() {
return "wait for a specific view with id <" + viewId + "> during " + millis + " millis.";
}
@Override
public void perform(final UiController uiController, final View view) {
uiController.loopMainThreadUntilIdle();
final long startTime = System.currentTimeMillis();
final long endTime = startTime + millis;
final Matcher<View> viewMatcher = withId(viewId);
do {
for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
// found view with required ID
if (viewMatcher.matches(child)) {
return;
}
}
uiController.loopMainThreadForAtLeast(50);
}
while (System.currentTimeMillis() < endTime);
// timeout happens
throw new PerformException.Builder()
.withActionDescription(this.getDescription())
.withViewDescription(HumanReadables.describe(view))
.withCause(new TimeoutException())
.build();
}
};
}
private static ViewAction waitFor(final long duration_ms) {
return new ViewAction() {
@Override
public String getDescription() {
return "Wait for milliseconds.";
}
@Override
public Matcher<View> getConstraints() {
return isDisplayed();
}
@Override
public void perform(UiController uiController, final View view) {
uiController.loopMainThreadForAtLeast(duration_ms);
}
};
}
private static ViewAction veryLongTouch(final int duration_ms) {
return new ViewAction() {
@Override
public String getDescription() {
return "Perform long touch.";
}
@Override
public Matcher<View> getConstraints() {
return isDisplayed();
}
@Override
public void perform(UiController uiController, final View view) {
// Get view absolute position
int[] location = new int[2];
view.getLocationOnScreen(location);
// Offset coordinates by view position
float[] coordinates = new float[]{location[0] + 1, location[1] + 1};
// Send down event, pause, and send up
MotionEvent down = MotionEvents.sendDown(uiController, coordinates, new float[]{1f, 1f}).down;
uiController.loopMainThreadForAtLeast(duration_ms);
MotionEvents.sendUp(uiController, down, coordinates);
}
};
}
}
@@ -1,7 +1,6 @@
package de.dennisguse.opentracks;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
@@ -9,7 +8,7 @@ import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.settings.PreferencesUtils;
public class PreferenceMetricUnitRule implements TestRule {
private final Context context;
@@ -25,14 +24,13 @@ public class PreferenceMetricUnitRule implements TestRule {
return new Statement() {
@Override
public void evaluate() throws Throwable {
SharedPreferences sharedPreferences = PreferencesUtils.getSharedPreferences(context);
final boolean previousMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context);
final boolean previousMetricUnits = PreferencesUtils.isMetricUnits();
try {
PreferencesUtils.setMetricUnits(sharedPreferences, context, metricUnits);
PreferencesUtils.setMetricUnits(metricUnits);
base.evaluate();
} finally {
PreferencesUtils.setMetricUnits(sharedPreferences, context, previousMetricUnits);
PreferencesUtils.setMetricUnits(previousMetricUnits);
}
}
};
@@ -0,0 +1,9 @@
package de.dennisguse.opentracks;
public class TestApplication extends Startup {
@Override
public String getDatabaseName() {
// null will make SQLiteOpenHelper create an in-memory database
return null;
}
}
@@ -0,0 +1,13 @@
package de.dennisguse.opentracks;
import android.app.Application;
import android.content.Context;
import androidx.test.runner.AndroidJUnitRunner;
public class TestRunner extends AndroidJUnitRunner {
@Override
public Application newApplication(ClassLoader cl, String className, Context context) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
return super.newApplication(cl, TestApplication.class.getName(), context);
}
}
@@ -78,7 +78,7 @@ public class ChartPointTest {
// given
TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint();
trackPoint.setHeartRate_bpm(100f);
trackPoint.setCyclingCadence_rpm(101f);
trackPoint.setCadence_rpm(101f);
trackPoint.setPower(102f);
TrackStatistics statistics = new TrackStatistics();
@@ -112,16 +112,15 @@ public class TestDataUtil {
}
public static TrackPoint createTrackPoint(int i) {
TrackPoint trackPoint = new TrackPoint(TrackPoint.Type.TRACKPOINT);
TrackPoint trackPoint = new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochSecond(i + 1));
trackPoint.setLatitude(INITIAL_LATITUDE + (double) i / 10000.0);
trackPoint.setLongitude(INITIAL_LONGITUDE - (double) i / 10000.0);
trackPoint.setAccuracy((float) i / 100.0f);
trackPoint.setHorizontalAccuracy(Distance.of(i / 100.0f));
trackPoint.setAltitude(i * ALTITUDE_INTERVAL);
trackPoint.setTime(Instant.ofEpochSecond(i + 1));
trackPoint.setSpeed(Speed.of(5f + (i / 10f)));
trackPoint.setHeartRate_bpm(100f + i);
trackPoint.setCyclingCadence_rpm(300f + i);
trackPoint.setCadence_rpm(300f + i);
trackPoint.setPower(400f + i);
trackPoint.setAltitudeGain(ALTITUDE_GAIN);
trackPoint.setAltitudeLoss(ALTITUDE_LOSS);
@@ -160,12 +159,13 @@ public class TestDataUtil {
}
public static List<TrackPoint> getTrackPoints(ContentProviderUtils contentProviderUtils, Track.Id trackId) {
TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null);
ArrayList<TrackPoint> trackPoints = new ArrayList<>();
while (trackPointIterator.hasNext()) {
trackPoints.add(trackPointIterator.next());
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) {
ArrayList<TrackPoint> trackPoints = new ArrayList<>();
while (trackPointIterator.hasNext()) {
trackPoints.add(trackPointIterator.next());
}
return trackPoints;
}
return trackPoints;
}
public static Pair<Track.Id, TrackStatistics> buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) {
@@ -12,16 +12,15 @@ public class TestSensorDataUtil {
public void add(Instant time, Float hr, Float cadence, Float power, TrackPoint.Type type) {
sensorDataList.add(new TestSensorDataUtil.SensorData(time, hr, cadence, power, type));
TrackPoint tp = new TrackPoint(type);
TrackPoint tp = new TrackPoint(type, time);
int i = trackPointList.size() + 1;
tp.setLatitude(TestDataUtil.INITIAL_LATITUDE + (double) i / 10000.0);
tp.setLongitude(TestDataUtil.INITIAL_LONGITUDE - (double) i / 10000.0);
tp.setHeartRate_bpm(hr);
tp.setCyclingCadence_rpm(cadence);
tp.setCadence_rpm(cadence);
tp.setPower(power);
tp.setAccuracy(1f);
tp.setHorizontalAccuracy(Distance.of(1f));
tp.setAltitude(1f);
tp.setTime(time);
tp.setSpeed(Speed.of(5f + (i / 10f)));
tp.setAltitudeGain(3f);
tp.setAltitudeLoss(3f);
@@ -13,27 +13,25 @@ public class TrackPointTest {
@Test
public void isRecent_true() {
TrackPoint tp = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL);
tp.setTime(Instant.now());
TrackPoint tp = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.now());
assertTrue(tp.isRecent());
}
@Test
public void isRecent_false() {
TrackPoint tp = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL);
tp.setTime(Instant.now().minus(2, ChronoUnit.MINUTES));
TrackPoint tp = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.now().minus(2, ChronoUnit.MINUTES));
assertFalse(tp.isRecent());
}
@Test
public void distanceToPrevious() {
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.TRACKPOINT)
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochMilli(0))
.setLatitude(0)
.setLongitude(0.0001);
TrackPoint tp2 = new TrackPoint(TrackPoint.Type.TRACKPOINT)
TrackPoint tp2 = new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochMilli(1))
.setLatitude(0)
.setLongitude(0.0002);
@@ -135,10 +135,10 @@ public class CustomContentProviderUtilsTest {
List<TrackPoint> trackPoints = new ArrayList<>(numPoints);
for (int i = 0; i < numPoints; ++i) {
TrackPoint trackPoint = new TrackPoint(TrackPoint.Type.TRACKPOINT)
TrackPoint trackPoint = new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochMilli(i))
.setLatitude(37.0 + (double) i / 10000.0)
.setLongitude(57.0 - (double) i / 10000.0)
.setAccuracy((float) i / 100.0f)
.setHorizontalAccuracy(Distance.of(i / 100.0f))
.setAltitude(i * 2.5);
trackPoints.add(trackPoint);
}
@@ -835,7 +835,7 @@ public class CustomContentProviderUtilsTest {
TrackPoint trackPoint = TestDataUtil.createTrackPoint(5);
trackPoint.setHeartRate_bpm(1F);
trackPoint.setCyclingCadence_rpm(2F);
trackPoint.setCadence_rpm(2F);
trackPoint.setPower(3F);
// when
@@ -845,7 +845,7 @@ public class CustomContentProviderUtilsTest {
List<TrackPoint> trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId);
assertTrue(trackPoints.get(10).hasHeartRate());
assertEquals(trackPoint.getHeartRate_bpm(), trackPoints.get(10).getHeartRate_bpm(), 0.01);
assertEquals(trackPoint.getCyclingCadence_rpm(), trackPoints.get(10).getCyclingCadence_rpm(), 0.01);
assertEquals(trackPoint.getCadence_rpm(), trackPoints.get(10).getCadence_rpm(), 0.01);
assertEquals(trackPoint.getPower(), trackPoints.get(10).getPower(), 0.01);
}
@@ -934,7 +934,7 @@ public class CustomContentProviderUtilsTest {
TrackPoint trackPoint = TestDataUtil.createTrackPoint(1);
trackPoint.setType(TrackPoint.Type.TRACKPOINT);
trackPoint.setPower(null);
trackPoint.setCyclingCadence_rpm(null);
trackPoint.setCadence_rpm(null);
trackPoint.setHeartRate_bpm(null);
trackPointList.add(trackPoint);
Track.Id trackId = new Track.Id(System.currentTimeMillis());
@@ -2,6 +2,7 @@ package de.dennisguse.opentracks.content.sensor;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -11,6 +12,7 @@ import de.dennisguse.opentracks.util.UintUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
@RunWith(AndroidJUnit4.class)
public class SensorDataCyclingTest {
@@ -81,7 +83,9 @@ public class SensorDataCyclingTest {
assertEquals(60, current.getValue(), 0.01);
}
@Ignore("Disabled from #953")
@Test
@Deprecated
public void compute_cadence_rollOverCount() {
// given
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024);
@@ -94,6 +98,19 @@ public class SensorDataCyclingTest {
assertEquals(60, current.getValue(), 0.01);
}
@Test
public void compute_cadence_overflow() {
// given
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024);
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 0, 2048);
// when
current.compute(previous);
// then
assertNull(current.getValue());
}
@Test
public void compute_speed() {
// given
@@ -104,11 +121,13 @@ public class SensorDataCyclingTest {
current.compute(previous, Distance.ofMM(2150));
// then
assertEquals(2.15, current.getValue().distance.toM(), 0.01);
assertEquals(1.20, current.getValue().speed.toMPS(), 0.01);
assertEquals(2.15, current.getValue().getDistance().toM(), 0.01);
assertEquals(1.20, current.getValue().getSpeed().toMPS(), 0.01);
}
@Ignore("Disabled from #953")
@Test
@Deprecated
public void compute_speed_rollOverCount() {
// given
SensorDataCycling.DistanceSpeed previous = new SensorDataCycling.DistanceSpeed("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024);
@@ -118,8 +137,21 @@ public class SensorDataCyclingTest {
current.compute(previous, Distance.ofMM(2000));
// then
assertEquals(2, current.getValue().distance.toM(), 0.01);
assertEquals(2, current.getValue().speed.toMPS(), 0.01);
assertEquals(2, current.getValue().getDistance().toM(), 0.01);
assertEquals(2, current.getValue().getSpeed().toMPS(), 0.01);
}
@Test
public void compute_speed_overflow() {
// given
SensorDataCycling.DistanceSpeed previous = new SensorDataCycling.DistanceSpeed("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024);
SensorDataCycling.DistanceSpeed current = new SensorDataCycling.DistanceSpeed("sensorAddress", "sensorName", 0, 2048);
// when
current.compute(previous, Distance.ofMM(2000));
// then
assertNull(current.getValue());
}
@Test
@@ -18,6 +18,7 @@ package de.dennisguse.opentracks.fragments;
import java.time.Instant;
import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.TrackPoint;
@@ -32,7 +33,7 @@ public class TrackStubUtils {
public static final long INITIAL_TIME = 1000L;
private static final double INITIAL_LATITUDE = 22;
private static final double INITIAL_LONGITUDE = 22;
private static final float INITIAL_ACCURACY = 5;
private static final Distance INITIAL_ACCURACY = Distance.of(5);
private static final Speed INITIAL_SPEED = Speed.of(10);
private static final float INITIAL_BEARING = 3.0f;
@@ -55,7 +56,7 @@ public class TrackStubUtils {
.setLatitude(latitude)
.setLongitude(longitude)
.setAltitude(altitude)
.setAccuracy(INITIAL_ACCURACY)
.setHorizontalAccuracy(INITIAL_ACCURACY)
.setSpeed(INITIAL_SPEED)
.setBearing(INITIAL_BEARING);
}
@@ -1,11 +1,17 @@
package de.dennisguse.opentracks.io.file.importer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.net.Uri;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -19,11 +25,15 @@ import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -31,7 +41,6 @@ import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Speed;
@@ -39,25 +48,24 @@ import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
import de.dennisguse.opentracks.content.sensor.SensorDataCyclingPower;
import de.dennisguse.opentracks.content.sensor.SensorDataHeartRate;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.io.file.exporter.TrackExporter;
import de.dennisguse.opentracks.services.TrackRecordingService;
import de.dennisguse.opentracks.services.handlers.TrackPointCreator;
import de.dennisguse.opentracks.services.sensors.AltitudeSumManager;
import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
import de.dennisguse.opentracks.stats.TrackStatistics;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Export a track to {@link TrackFileFormat} and verify that the import is identical.
* <p>
*/
@RunWith(AndroidJUnit4.class)
public class ExportImportTest {
private static final String TAG = ExportImportTest.class.getSimpleName();
@Rule
public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(5, TimeUnit.SECONDS);
@@ -81,7 +89,6 @@ public class ExportImportTest {
private File tmpFile;
private Uri tmpFileUri;
private Track track;
private List<Marker> markers = new ArrayList<>();
private List<TrackPoint> trackPoints = new ArrayList<>();
@@ -99,35 +106,50 @@ public class ExportImportTest {
}
@After
public void FileTearDown() {
public void FileTearDown() throws TimeoutException {
tmpFile.deleteOnExit();
tmpFileUri = null;
TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(new Intent(context, TrackRecordingService.class)))
.getService();
service.getTrackPointCreator().setClock(Clock.systemUTC());
}
public void setUp(boolean hasSensorDistance) throws TimeoutException {
TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(new Intent(context, TrackRecordingService.class)))
.getService();
TrackPointCreator trackPointCreator = service.getTrackPointCreator();
trackPointCreator.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:02Z"), ZoneId.of("CET")));
trackId = service.startNewTrack();
Distance sensorDistance = hasSensorDistance ? Distance.of(5) : null;
service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14, 10, 15, 10, 1, 66, 3, 50, sensorDistance), 0);
sendLocation(trackPointCreator, Instant.parse("2020-02-02T02:02:03Z"), 3, 14, 10, 15, 10, 1, 66, 3, 50, sensorDistance);
service.insertMarker("Marker 1", "Marker 1 category", "Marker 1 desc", null);
service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.001, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0);
service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.002, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0);
sendLocation(trackPointCreator, Instant.parse("2020-02-02T02:02:04Z"), 3, 14.001, 10, 15, 10, 0, 66, 3, 50, sensorDistance);
sendLocation(trackPointCreator, Instant.parse("2020-02-02T02:02:05Z"), 3, 14.002, 10, 15, 10, 0, 66, 3, 50, sensorDistance);
service.insertMarker("Marker 2", "Marker 2 category", "Marker 2 desc", null);
trackPointCreator.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:06Z"), ZoneId.of("CET")));
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context));
service.pauseCurrentTrack();
trackPointCreator.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:20Z"), ZoneId.of("CET")));
service.resumeCurrentTrack();
service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.003, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0);
service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 16, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0);
service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 16.001, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0);
trackPointCreator.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:21Z"), ZoneId.of("CET")));
sendLocation(trackPointCreator, Instant.parse("2020-02-02T02:02:21Z"), 3, 14.003, 10, 15, 10, 0, 66, 3, 50, sensorDistance);
sendLocation(trackPointCreator, Instant.parse("2020-02-02T02:02:22Z"), 3, 16, 10, 15, 10, 0, 66, 3, 50, sensorDistance);
sendLocation(trackPointCreator, Instant.parse("2020-02-02T02:02:23Z"), 3, 16.001, 10, 15, 10, 0, 66, 3, 50, sensorDistance);
trackPointCreator.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:24Z"), ZoneId.of("CET")));
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context));
service.endCurrentTrack();
track = contentProviderUtils.getTrack(trackId);
Track track = contentProviderUtils.getTrack(trackId);
track.setIcon(TRACK_ICON);
track.setCategory(TRACK_CATEGORY);
track.setDescription(TRACK_DESCRIPTION);
@@ -142,53 +164,14 @@ public class ExportImportTest {
@After
public void tearDown() {
contentProviderUtils.deleteTrack(context, trackId);
if (trackId != null) {
contentProviderUtils.deleteTrack(context, trackId);
}
if (importTrackId != null) {
contentProviderUtils.deleteTrack(context, importTrackId);
}
}
@LargeTest
@Test
public void kml_with_trackdetail_and_sensordata() throws TimeoutException, IOException {
setUp(true);
// given
Track track = contentProviderUtils.getTrack(trackId);
TrackExporter trackExporter = TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA.createTrackExporter(context);
// when
// 1. export
trackExporter.writeTrack(track, context.getContentResolver().openOutputStream(tmpFileUri));
contentProviderUtils.deleteTrack(context, trackId);
// 2. import
InputStream inputStream = context.getContentResolver().openInputStream(tmpFileUri);
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
importTrackId = importer.importFile(inputStream).get(0);
// then
// 1. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack);
assertEquals(track.getCategory(), importedTrack.getCategory());
assertEquals(track.getDescription(), importedTrack.getDescription());
assertEquals(track.getName(), importedTrack.getName());
assertEquals(track.getIcon(), importedTrack.getIcon());
// 2. trackpoints
TrackPointAssert a = new TrackPointAssert()
.noAccuracy();
a.assertEquals(trackPoints, TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId));
// 2. trackstatistics
assertTrackStatistics(false, true);
// 4. markers
assertMarkers();
}
//TODO Does not test images
@LargeTest
@Test
@@ -223,8 +206,30 @@ public class ExportImportTest {
.noAccuracy();
a.assertEquals(trackPoints, TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId));
// 2. trackstatistics
assertTrackStatistics(false, true);
// 3. trackstatistics
TrackStatistics importedTrackStatistics = importedTrack.getTrackStatistics();
// Time
assertEquals(Instant.parse("2020-02-02T02:02:02Z"), importedTrackStatistics.getStartTime());
assertEquals(Instant.parse("2020-02-02T02:02:24Z"), importedTrackStatistics.getStopTime());
assertEquals(track.getTrackStatistics().getTotalTime(), importedTrackStatistics.getTotalTime());
assertEquals(Duration.ofSeconds(8), importedTrackStatistics.getTotalTime());
assertEquals(Duration.ofSeconds(4), importedTrackStatistics.getMovingTime());
// Distance
assertEquals(Distance.of(30), importedTrackStatistics.getTotalDistance());
// Speed
assertEquals(Speed.of(15), importedTrackStatistics.getMaxSpeed());
assertEquals(Speed.of(3.75), importedTrackStatistics.getAverageSpeed());
assertEquals(Speed.of(7.5), importedTrackStatistics.getAverageMovingSpeed());
// Altitude
assertEquals(10, importedTrackStatistics.getMinAltitude(), 0.01);
assertEquals(10, importedTrackStatistics.getMaxAltitude(), 0.01);
assertEquals(1, importedTrackStatistics.getTotalAltitudeGain(), 0.01);
assertEquals(1, importedTrackStatistics.getTotalAltitudeLoss(), 0.01);
// 4. markers
assertMarkers();
@@ -278,14 +283,14 @@ public class ExportImportTest {
// then
// 1. track
Track trackImported = contentProviderUtils.getTrack(importTrackId);
assertNotNull(trackImported);
assertEquals(track.getCategory(), trackImported.getCategory());
assertEquals(track.getDescription(), trackImported.getDescription());
assertEquals(track.getName(), trackImported.getName());
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack);
assertEquals(track.getCategory(), importedTrack.getCategory());
assertEquals(track.getDescription(), importedTrack.getDescription());
assertEquals(track.getName(), importedTrack.getName());
//TODO exporting and importing a track icon is not yet supported by GpxTrackWriter.
//assertEquals(track.getIcon(), trackImported.getIcon());
//assertEquals(track.getIcon(), importedTrack.getIcon());
// 2. trackpoints
// The GPX exporter does not support exporting TrackPoints without lat/lng.
@@ -300,7 +305,29 @@ public class ExportImportTest {
a.assertEquals(trackPointsWithCoordinates, TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId));
// 3. trackstatistics
assertTrackStatistics(true, false);
TrackStatistics trackStatistics = track.getTrackStatistics();
TrackStatistics importedTrackStatistics = importedTrack.getTrackStatistics();
// Time
assertEquals(Instant.parse("2020-02-02T02:02:03Z"), importedTrackStatistics.getStartTime());
assertEquals(Instant.parse("2020-02-02T02:02:23Z"), importedTrackStatistics.getStopTime());
assertEquals(Duration.ofSeconds(20), importedTrackStatistics.getTotalTime());
assertEquals(Duration.ofSeconds(19), importedTrackStatistics.getMovingTime());
// Distance
assertEquals(Distance.of(30), importedTrackStatistics.getTotalDistance());
// Speed
assertEquals(Speed.of(15), importedTrackStatistics.getMaxSpeed());
assertEquals(Speed.of(1.5), importedTrackStatistics.getAverageSpeed());
assertEquals(Speed.of(1.5789473684210527), importedTrackStatistics.getAverageMovingSpeed());
// Altitude
assertEquals(10, importedTrackStatistics.getMinAltitude(), 0.01);
assertEquals(10, importedTrackStatistics.getMaxAltitude(), 0.01);
assertEquals(1, importedTrackStatistics.getTotalAltitudeGain(), 0.01);
assertEquals(1, importedTrackStatistics.getTotalAltitudeLoss(), 0.01);
// 4. markers
assertMarkers();
@@ -353,56 +380,49 @@ public class ExportImportTest {
}
}
private void assertTrackStatistics(boolean isGpx, boolean verifyDistance) {
double delta = isGpx ? 0.1 : 0.01;
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
private void sendLocation(TrackPointCreator trackPointCreator, Instant time, double latitude, double longitude, float accuracy, float speed, float altitude, float altitudeGain, float heartRate, float cyclingCadence, float power, Distance distance) {
Location location = new Location("mock");
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setAccuracy(accuracy);
location.setSpeed(speed);
location.setAltitude(altitude);
assertNotNull(importedTrack.getTrackStatistics());
TrackStatistics trackStatistics = track.getTrackStatistics();
TrackStatistics importedTrackStatistics = importedTrack.getTrackStatistics();
// Time
assertTrue(trackStatistics.getStartTime().isBefore(trackStatistics.getStopTime())); //Just to be sure.
if (!isGpx) {
assertEquals(trackStatistics.getStartTime(), importedTrackStatistics.getStartTime());
assertEquals(trackStatistics.getStopTime(), importedTrackStatistics.getStopTime());
assertEquals(trackStatistics.getTotalTime(), importedTrackStatistics.getTotalTime());
assertEquals(trackStatistics.getMovingTime(), importedTrackStatistics.getMovingTime());
// Distance
if (verifyDistance) {
assertEquals(trackStatistics.getTotalDistance(), importedTrackStatistics.getTotalDistance());
trackPointCreator.setAltitudeSumManager(new AltitudeSumManager() {
@Override
public void fill(@NonNull TrackPoint trackPoint) {
trackPoint.setAltitudeGain(altitudeGain);
trackPoint.setAltitudeLoss(altitudeGain);
}
});
// Speed
assertEquals(trackStatistics.getMaxSpeed(), importedTrackStatistics.getMaxSpeed());
assertEquals(trackStatistics.getAverageSpeed(), importedTrackStatistics.getAverageSpeed());
assertEquals(trackStatistics.getAverageMovingSpeed(), importedTrackStatistics.getAverageMovingSpeed());
}
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context) {
@Override
public SensorDataSet fill(@NonNull TrackPoint trackPoint) {
SensorDataSet sensorDataSet = new SensorDataSet();
sensorDataSet.set(new SensorDataCyclingPower("power", "power", power));
sensorDataSet.set(new SensorDataHeartRate("heartRate", "heartRate", heartRate));
// Altitude
assertEquals(trackStatistics.getMinAltitude(), importedTrackStatistics.getMinAltitude(), delta);
if (isGpx) {
assertEquals(trackStatistics.getMaxAltitude(), importedTrackStatistics.getMaxAltitude(), 2);
} else {
assertEquals(trackStatistics.getMaxAltitude(), importedTrackStatistics.getMaxAltitude(), delta);
}
assertEquals(trackStatistics.getTotalAltitudeGain(), importedTrackStatistics.getTotalAltitudeGain(), delta);
assertEquals(trackStatistics.getTotalAltitudeLoss(), importedTrackStatistics.getTotalAltitudeLoss(), delta);
}
SensorDataCycling.Cadence cadence = Mockito.mock(SensorDataCycling.Cadence.class);
Mockito.when(cadence.hasValue()).thenReturn(true);
Mockito.when(cadence.getValue()).thenReturn(cyclingCadence);
sensorDataSet.set(cadence);
private static TrackPoint createTrackPoint(long time, double latitude, double longitude, float accuracy, float speed, float altitude, float altitudeGain, float heartRate, float cyclingCadence, float power, Distance distance) {
TrackPoint tp = new TrackPoint(latitude, longitude, Altitude.WGS84.of(altitude), Instant.ofEpochMilli(time));
tp.setAccuracy(accuracy);
tp.setSpeed(Speed.of(speed));
tp.setHeartRate_bpm(heartRate);
tp.setCyclingCadence_rpm(cyclingCadence);
tp.setPower(power);
tp.setAltitudeGain(altitudeGain);
tp.setAltitudeLoss(altitudeGain); //TODO
tp.setSensorDistance(distance);
return tp;
SensorDataCycling.DistanceSpeed.Data distanceSpeedData = Mockito.mock(SensorDataCycling.DistanceSpeed.Data.class);
Mockito.when(distanceSpeedData.getDistanceOverall()).thenReturn(distance);
Mockito.when(distanceSpeedData.getSpeed()).thenReturn(Speed.of(speed));
SensorDataCycling.DistanceSpeed distanceSpeed = Mockito.mock(SensorDataCycling.DistanceSpeed.class);
Mockito.when(distanceSpeed.hasValue()).thenReturn(true);
Mockito.when(distanceSpeed.getValue()).thenReturn(distanceSpeedData);
sensorDataSet.set(distanceSpeed);
sensorDataSet.fillTrackPoint(trackPoint);
return sensorDataSet;
}
});
trackPointCreator.setClock(Clock.fixed(time, ZoneId.of("CET")));
trackPointCreator.getLocationHandler().onLocationChanged(location);
}
}
@@ -14,6 +14,7 @@ import org.junit.runners.JUnit4;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
@@ -23,6 +24,7 @@ import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.stats.TrackStatistics;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -67,7 +69,7 @@ public class GPXImportTest {
importTrackId = importer.importFile(inputStream).get(0);
// then
// 1. track
// 2. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack);
assertEquals("the category", importedTrack.getCategory());
@@ -75,6 +77,8 @@ public class GPXImportTest {
assertEquals("2021-01-07 22:51", importedTrack.getName());
assertEquals("UNKNOWN", importedTrack.getIcon());
//TODO Check trackstatistics
// 3. trackpoints
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
assertEquals(6, importedTrackPoints.size());
@@ -106,4 +110,102 @@ public class GPXImportTest {
.setAltitude(10)
), importedTrackPoints);
}
@LargeTest
@Test
public void gpx_without_speed() throws IOException {
// given
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx11_without_speed);
// when
// 1. import
importTrackId = importer.importFile(inputStream).get(0);
// then
// 2. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack);
assertEquals("", importedTrack.getCategory());
assertEquals("", importedTrack.getDescription());
assertEquals("20210907_213924.gpx", importedTrack.getName());
assertEquals("", importedTrack.getIcon());
// 3. trackstatistics
TrackStatistics trackStatistics = importedTrack.getTrackStatistics();
assertEquals(1.44, trackStatistics.getMaxSpeed().toMPS(), 0.01);
assertEquals(Duration.ofSeconds(53), trackStatistics.getMovingTime());
// 4. trackpoints
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
assertEquals(3, importedTrackPoints.size());
TrackPointAssert a = new TrackPointAssert();
a.assertEquals(List.of(
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC, Instant.parse("2021-09-07T22:10:19Z"))
.setLatitude(30.14185982)
.setLongitude(-40.3863038)
.setAltitude(-5),
new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2021-09-07T22:11:07Z"))
.setLatitude(30.14184657)
.setLongitude(-40.38670089)
.setAltitude(-5)
.setSpeed(Speed.of(0.7976524233818054)),
new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2021-09-07T22:12:00Z"))
.setLatitude(30.14185982)
.setLongitude(-40.3863038)
.setAltitude(-5)
.setSpeed(Speed.of(0.7224021553993225))
), importedTrackPoints);
}
@LargeTest
@Test
public void gpx_speed_no_namespace() throws IOException {
// given
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx11_with_speed_no_namespace);
// when
// 1. import
importTrackId = importer.importFile(inputStream).get(0);
// then
// 2. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack);
assertEquals("", importedTrack.getCategory());
assertEquals("", importedTrack.getDescription());
assertEquals("20210907_213924.gpx", importedTrack.getName());
assertEquals("", importedTrack.getIcon());
// 3. trackstatistics
TrackStatistics trackStatistics = importedTrack.getTrackStatistics();
assertEquals(4, trackStatistics.getMaxSpeed().toMPS(), 0.01);
assertEquals(Duration.ofSeconds(101), trackStatistics.getMovingTime());
// 4. trackpoints
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
assertEquals(3, importedTrackPoints.size());
TrackPointAssert a = new TrackPointAssert();
a.assertEquals(List.of(
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC, Instant.parse("2021-09-07T22:10:19Z"))
.setLatitude(30.14185982)
.setLongitude(-40.3863038)
.setAltitude(-5)
.setSpeed(Speed.of(5)),
new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2021-09-07T22:11:07Z"))
.setLatitude(30.14184657)
.setLongitude(-40.38670089)
.setAltitude(-5)
.setSpeed(Speed.of(0.7976524233818054))
.setSpeed(Speed.of(4)),
new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2021-09-07T22:12:00Z"))
.setLatitude(30.14185982)
.setLongitude(-40.3863038)
.setAltitude(-5)
.setSpeed(Speed.of(3))
), importedTrackPoints);
}
}
@@ -50,12 +50,12 @@ public class TrackPointAssert {
}
if (assertAccuracy) {
Assert.assertEquals(expected.hasAccuracy(), actual.hasAccuracy());
if (expected.hasAccuracy()) {
Assert.assertEquals(expected.getAccuracy(), actual.getAccuracy(), delta);
Assert.assertEquals(expected.hasHorizontalAccuracy(), actual.hasHorizontalAccuracy());
if (expected.hasHorizontalAccuracy()) {
Assert.assertEquals(expected.getHorizontalAccuracy().toM(), actual.getHorizontalAccuracy().toM(), delta);
}
} else {
Assert.assertFalse(actual.hasAccuracy());
Assert.assertFalse(actual.hasHorizontalAccuracy());
}
Assert.assertEquals(expected.hasSensorDistance(), actual.hasSensorDistance());
@@ -73,13 +73,26 @@ public class TrackPointAssert {
Assert.assertEquals(expected.getPower(), actual.getPower(), delta);
}
Assert.assertEquals(expected.hasCyclingCadence(), actual.hasCyclingCadence());
if (expected.hasCyclingCadence()) {
Assert.assertEquals(expected.getCyclingCadence_rpm(), actual.getCyclingCadence_rpm(), delta);
Assert.assertEquals(expected.hasCadence(), actual.hasCadence());
if (expected.hasCadence()) {
Assert.assertEquals(expected.getCadence_rpm(), actual.getCadence_rpm(), delta);
}
}
public void assertEquals(List<TrackPoint> expected, List<TrackPoint> actual) {
try {
Assert.assertEquals(expected.size(), actual.size());
} catch (AssertionError e) {
throw new AssertionError("Expected: " + expected + "\n actual: " + actual);
}
for (int i = 0; i < expected.size(); i++) {
try {
assertEquals(expected.get(i), actual.get(i));
} catch (AssertionError e) {
throw new AssertionError("Expected: " + expected.get(i) + "\n actual: " + actual.get(i), e);
}
}
Assert.assertEquals(expected.size(), actual.size());
for (int i = 0; i < expected.size(); i++) {

Some files were not shown because too many files have changed in this diff Show More