Compare commits

..

50 Commits

Author SHA1 Message Date
Dennis Guse f1b3ce9db5 Release: v4.21.1 2025-07-12 00:20:53 +02:00
Dennis Guse 6f65808932 Bugfix: set a default theme.
Introduced in c34e9bd7

Part of #2123.
2025-07-11 20:26:13 +02:00
dependabot[bot] cf4e1d07ef Bump com.android.tools.build:gradle from 8.11.0 to 8.11.1
Bumps com.android.tools.build:gradle from 8.11.0 to 8.11.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-11 07:13:51 +02:00
Dennis Guse dff5cd0088 Launcher icon was sometimes incorrectly scaled (e.g., kvaesitso).
Use same icon as OSMDashboard for launcher (w/o background).

This time, we re-add the proper icon (white) for the reproducible builds (REALLY).

Fixes #2108
2025-07-06 13:25:13 +02:00
Dennis Guse 3c52a5b38a Release: v4.21.0 2025-07-04 23:40:21 +02:00
Dennis Guse ea53326183 Themes: OLED friendly has now bottomAppBar that is black. 2025-07-04 23:16:28 +02:00
Dennis Guse 5bea48096c TrackList: swipe to delete. 2025-07-04 20:53:08 +02:00
Dennis Guse c34e9bd7b6 Themes: use separate themes for DayNight/OLED/DynamicColors.
Fixes #2123.
2025-07-04 16:49:35 +02:00
Dennis Guse edac784b1e ChartView should get colors from Material library (for Dynamic colors).
Part of #2123.
2025-07-04 16:49:35 +02:00
𝗛𝗼𝗹𝗶 87228d2341 Update Turkish 2025-07-04 16:46:32 +02:00
Cloud Esp 00e62b7d6f Translated using Weblate (French)
Currently translated at 95.3% (513 of 538 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/fr/
2025-07-03 18:13:02 +02:00
Patrick Santa Maria 024e5e0e5f Translated using Weblate (Corsican)
Currently translated at 100.0% (538 of 538 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/co/
2025-07-03 18:13:02 +02:00
Fjuro 2feb7d1c1e Translated using Weblate (Czech)
Currently translated at 100.0% (167 of 167 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://hosted.weblate.org/projects/opentracks/app-store-metadata-files/cs/
2025-07-03 18:13:02 +02:00
Ghost of Sparta 2f29433a09 Translated using Weblate (Hungarian)
Currently translated at 100.0% (538 of 538 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/hu/
2025-07-03 18:13:02 +02:00
Ghost of Sparta 5ecb058789 Translated using Weblate (Hungarian)
Currently translated at 100.0% (538 of 538 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/hu/
2025-07-03 18:13:02 +02:00
josé m 820f26cf1d Translated using Weblate (Galician)
Currently translated at 99.8% (537 of 538 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/gl/
2025-07-03 18:13:02 +02:00
Fjuro d91f59e1ff Translated using Weblate (Czech)
Currently translated at 100.0% (538 of 538 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/cs/
2025-07-03 18:13:02 +02:00
schmaker 0b541b7590 Update README_TESTED_SENSORS.md
Mojawa HaptiFit Terra confirmed to work
2025-07-03 18:12:58 +02:00
dependabot[bot] f3f8075a5e Bump androidx.mediarouter:mediarouter from 1.8.0 to 1.8.1
Bumps androidx.mediarouter:mediarouter from 1.8.0 to 1.8.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-03 06:52:38 +02:00
Dennis Guse e41df73919 Launcher icon was sometimes incorrectly scaled (e.g., kvaesitso).
Use same icon as OSMDashboard for launcher (w/o background).

This time, we re-add the proper icon (white) for the reproducible builds.

Fixes #2108.
2025-06-29 08:30:59 +02:00
Dennis Guse 0f05100807 Release: v4.20.0 2025-06-27 21:01:11 +02:00
Fjuro d16de9789f Translated using Weblate (Czech)
Currently translated at 100.0% (166 of 166 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://hosted.weblate.org/projects/opentracks/app-store-metadata-files/cs/
2025-06-27 15:51:59 +02:00
mcliquid ca809bde6b Translated using Weblate (German)
Currently translated at 100.0% (540 of 540 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/de/
2025-06-27 15:51:58 +02:00
Fjuro 692650cf99 Translated using Weblate (Czech)
Currently translated at 100.0% (540 of 540 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/cs/
2025-06-27 15:51:58 +02:00
Patrick Santa Maria 9bf77c41a0 Translated using Weblate (Corsican)
Currently translated at 100.0% (540 of 540 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/co/
2025-06-27 15:51:58 +02:00
Aindriú Mac Giolla Eoin 3986172095 Translated using Weblate (Irish)
Currently translated at 100.0% (166 of 166 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://hosted.weblate.org/projects/opentracks/app-store-metadata-files/ga/
2025-06-27 15:51:58 +02:00
Ghost of Sparta 943e05f17d Translated using Weblate (Hungarian)
Currently translated at 100.0% (540 of 540 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/hu/
2025-06-27 15:51:58 +02:00
Aindriú Mac Giolla Eoin 65e7044d49 Translated using Weblate (Irish)
Currently translated at 100.0% (540 of 540 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://hosted.weblate.org/projects/opentracks/opentracks-src-main-res-values-strings-xml-main/ga/
2025-06-27 15:51:58 +02:00
Aindriú Mac Giolla Eoin b072635a32 Translated using Weblate (Irish)
Currently translated at 100.0% (165 of 165 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://hosted.weblate.org/projects/opentracks/app-store-metadata-files/ga/
2025-06-27 15:51:58 +02:00
Fjuro 9237693063 Translated using Weblate (Czech)
Currently translated at 100.0% (165 of 165 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://hosted.weblate.org/projects/opentracks/app-store-metadata-files/cs/
2025-06-27 15:51:58 +02:00
Dennis Guse 4999b54a97 Reworked MarkerDetail UI. 2025-06-27 15:51:51 +02:00
Dennis Guse 0dca1461e1 Cleanup: list adapters. 2025-06-27 15:51:51 +02:00
Dennis Guse 2e13054042 Cleanup: TrackPoint exposes Position. 2025-06-27 15:51:51 +02:00
Dennis Guse 3eba204b9d MarkerDetail page shows name in title. 2025-06-27 15:51:51 +02:00
Dennis Guse 8b8eaa5ea9 MarkerDetailActivity must call onDestroy(). 2025-06-27 15:51:51 +02:00
dependabot[bot] c0b6b9e5e4 Bump com.android.tools.build:gradle from 8.10.1 to 8.11.0
Bumps com.android.tools.build:gradle from 8.10.1 to 8.11.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-25 20:09:43 +02:00
Dennis Guse da109fb8fe Import+Export activity: removed "require twice back navigation".
onBackPressed() is not support anymore as of Android gradle plugin 8.11.0
2025-06-25 19:58:40 +02:00
Dennis Guse fca4206c86 Migrated MarkerDetailActivity to ViewPager2. 2025-06-25 19:44:38 +02:00
Dennis Guse a2531c8651 Cleanup: MarkerDetailFragment uses MenuProvider. 2025-06-25 19:44:38 +02:00
Dennis Guse 7b4ab81f5c Marker: replaced orange pushpin. 2025-06-25 19:44:38 +02:00
Dennis Guse 90446639b0 Cleanup: remove TrackUtils by inlining functionality. 2025-06-25 19:44:38 +02:00
Dennis Guse 8744724c0f Enable to edit timezone offset for recorded tracks.
Fixes #2014.
2025-06-25 19:44:38 +02:00
Dennis Guse 1113cb1764 Bugfix: always update track meta data. 2025-06-25 19:44:38 +02:00
Dennis Guse f9466b7347 Cleanup: inline TrackEdit UI into one file. 2025-06-25 19:44:38 +02:00
Dennis Guse 45be184d76 Upgrade to Gradlew 8.14.2 2025-06-25 19:43:38 +02:00
Dennis Guse 730ace0b60 Cleanup: moved colors into colors.xml 2025-06-24 10:37:52 +02:00
Dennis Guse b662a8bc42 Launcher icon was sometimes incorrectly scaled (e.g., kvaesitso).
Use same icon as OSMDashboard for launcher (w/o background).

This time also for the reproducible build.

Fixes #2108.
2025-06-23 09:28:25 +02:00
Dennis Guse a0b4f78977 Cleanup: remove support for launcher icons before SDK26.
Part of #2108.
2025-06-23 08:54:20 +02:00
Dennis Guse 6334c03dbc Edge-2-edge: adjust for virtual keyboard changes.
Part of #2073.
2025-06-22 22:28:45 +02:00
Dennis Guse 57fd2fd160 Track edit: description should be multiline. 2025-06-22 22:14:51 +02:00
130 changed files with 1108 additions and 1540 deletions
+35
View File
@@ -1,5 +1,40 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JavaCodeStyleSettings>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false" module="true" />
<package name="android" withSubpackages="true" static="true" />
<package name="androidx" withSubpackages="true" static="true" />
<package name="com" withSubpackages="true" static="true" />
<package name="junit" withSubpackages="true" static="true" />
<package name="net" withSubpackages="true" static="true" />
<package name="org" withSubpackages="true" static="true" />
<package name="java" withSubpackages="true" static="true" />
<package name="javax" withSubpackages="true" static="true" />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="androidx" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
</value>
</option>
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
+1
View File
@@ -13,6 +13,7 @@
* 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)
* CYCPLUS H1
* Mojawa Haptifit Terra - all you have to do is connect the app to device called "HT"
## 0x1816: Cycling Cadence and Speed Service
+4 -4
View File
@@ -6,7 +6,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.10.1'
classpath 'com.android.tools.build:gradle:8.11.1'
}
}
@@ -46,8 +46,8 @@ android {
defaultConfig {
applicationId 'de.dennisguse.opentracks'
versionCode 6187
versionName "v4.19.6"
versionCode 6237
versionName "v4.21.1"
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
@@ -150,7 +150,7 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'androidx.core:core:1.16.0'
implementation 'androidx.core:core-splashscreen:1.0.1'
implementation 'androidx.mediarouter:mediarouter:1.8.0'
implementation 'androidx.mediarouter:mediarouter:1.8.1'
implementation 'androidx.core:core-location-altitude:1.0.0-alpha03'
androidTestImplementation 'androidx.test:core:1.6.1'
@@ -1,116 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="ic_marker_orange_pushpin_with_shadow.svg">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient871"
x1="91.712517"
y1="266.48581"
x2="95.902588"
y2="266.72339"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(22.027833,208.46275,168.26892)"
>
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="0"
id="stop867" />
<stop
style="stop-color:#898d8d;stop-opacity:1"
offset="1"
id="stop869" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="298.98541"
inkscape:cy="561.0427"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1012"
inkscape:window-x="0"
inkscape:window-y="1080"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<path
d="m 108.52826,213.29755 a 56.035402,7.0061195 5.281088 0 0 -22.425508,2.5321 56.035402,7.0061195 5.281088 0 0 -0.233576,0.17697 l -0.206706,-0.0237 c -0.04471,0.11554 -0.07454,0.2314 -0.09612,0.34752 a 56.035402,7.0061195 5.281088 0 0 0.337963,1.58159 c 0.980726,1.70884 3.760629,3.46326 6.583579,5.2188 l -22.744347,15.50009 a 67.064653,11.556784 4.2275244 0 0 -39.967588,5.26867 67.064653,11.556784 4.2275244 0 0 -0.729154,0.57564 67.064653,11.556784 4.2275244 0 0 -2.754353,1.36358 67.064653,11.556784 4.2275244 0 0 38.908736,16.04324 l -32.176847,27.0646 52.228334,-24.74551 a 67.064653,11.556784 4.2275244 0 0 71.411147,-3.8186 67.064653,11.556784 4.2275244 0 0 0.72812,-0.57507 67.064653,11.556784 4.2275244 0 0 2.75539,-1.36415 67.064653,11.556784 4.2275244 0 0 -12.38374,-10.59818 40.033569,5.0733922 5.2502179 0 0 0.0563,-0.0369 40.033569,5.0733922 5.2502179 0 0 0.37672,-0.34325 l 22.45186,-15.30075 c 8.23597,-0.65161 17.65581,-1.47811 22.94433,-3.00957 a 56.035402,7.0061195 5.281088 0 0 2.65514,-1.03772 56.035402,7.0061195 5.281088 0 0 -46.08401,-12.26953 56.035402,7.0061195 5.281088 0 0 -41.6357,-2.54991 z"
style="fill:#333333;fill-opacity:0.49421525;stroke:#000000;stroke-width:0.138931px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.265501"
id="path839" />
<path
style="fill:url(#linearGradient871);fill-opacity:1;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.265501"
d="M 70.603317,174.30832 33.024148,288.94657 94.566672,183.19473 Z"
id="path865"
sodipodi:nodetypes="cccc" />
<ellipse
cx="144.42586"
cy="113.06232"
rx="70.318817"
ry="39.974442"
id="ellipse26"
style="fill:#d45500;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
transform="rotate(22.027833)" />
<ellipse
style="fill:#ff6600;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
id="ellipse30"
ry="39.974442"
rx="70.318817"
cy="105.23625"
cx="145.017"
transform="rotate(22.027833)" />
<path
id="rect28"
style="fill:#d45500;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
d="m 85.662408,24.322061 c -0.890996,8.350369 2.928035,17.133472 6.825491,25.923906 l -23.333902,57.672763 -0.730686,1.80598 0.248621,0.10059 a 42.43035,17.360788 22.027833 0 0 33.303948,30.10067 42.43035,17.360788 22.027833 0 0 44.86507,1.52585 l 0.13892,0.0562 0.24519,-0.60599 a 42.43035,17.360788 22.027833 0 0 0.59472,-1.15581 42.43035,17.360788 22.027833 0 0 0.37668,-1.24514 l 22.45185,-55.492655 c 9.28986,-2.66566 20.09069,-6.13552 24.76397,-13.17485 z" />
<ellipse
style="fill:#ff6600;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
id="path24"
ry="23.966745"
rx="59.409279"
cy="-10.262156"
cx="148.14029"
transform="rotate(22.027833)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.0 KiB

@@ -0,0 +1,5 @@
v4.19.5: OpenTracks
Oprava chyby:
- Ikona v launcheru byla někdy příliš malá
- Ikona trasy v podrobnostech používá lokalizovaný typ aktivity
@@ -0,0 +1,4 @@
v4.19.6: OpenTracks
Změny:
- Podpora edge-to-edge by nyní měla fungovat na všech verzích systému Android
@@ -0,0 +1,8 @@
v4.20.0: OpenTracks
Změny:
- Umožnění změny časového pásma stop
- Zjednodušené rozhraní značek
Oprava chyby:
- Edge-2-edge: reakce na virtuální klávesnici
@@ -0,0 +1,8 @@
v4.20.0: OpenTracks
Changes:
- Allow to change timezone offset of tracks
- Simplified Marker UI
Bugfix:
- Edge-2-edge: react to virtual keyboard
@@ -0,0 +1,5 @@
v4.21.0: OpenTracks
Changes:
- Track list supports swipe-to-delete
- Re-implemented themes (for DynamicColor and OLED)
@@ -0,0 +1,4 @@
v4.21.1: OpenTracks
Bugfix:
- Fixed crash on export/import UI (introduced in v4.21.0)
@@ -0,0 +1,5 @@
v4.19.5: OpenTracks
Ceartú fabht:
- Taispeánadh deilbhín an lainseálaí róbheag uaireanta
- Deilbhín an rianaithe ar an leathanach sonraí ag baint úsáide as cineál gníomhaíochta logánaithe
@@ -0,0 +1,4 @@
v4.19.6: OpenTracks
Athruithe:
- Ba chóir go mbeadh Edge-2-edge ag obair anois ar gach leagan de Android
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+1 -2
View File
@@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -763,8 +763,8 @@ public class CustomContentProviderUtilsTest {
TrackPoint trackPoint = contentProviderUtils.createTrackPoint(cursorMock);
// then
assertEquals(longitude, trackPoint.getLongitude(), 0.01);
assertEquals(latitude, trackPoint.getLatitude(), 0.01);
assertEquals(latitude, trackPoint.getPosition().latitude(), 0.01);
assertEquals(longitude, trackPoint.getPosition().longitude(), 0.01);
assertEquals(time, trackPoint.getTime().toEpochMilli());
assertEquals(speed, trackPoint.getSpeed().toMPS(), 0.01);
assertEquals(HeartRate.of(75f), trackPoint.getHeartRate());
@@ -20,8 +20,8 @@ public class TrackPointAssert {
Assert.assertEquals("has location,", expected.hasLocation(), actual.hasLocation());
if (expected.hasLocation()) {
Assert.assertEquals("latitude", expected.getLatitude(), actual.getLatitude(), 0.001);
Assert.assertEquals("longitude", expected.getLongitude(), actual.getLongitude(), 0.001);
Assert.assertEquals("latitude", expected.getPosition().latitude(), actual.getPosition().latitude(), 0.001);
Assert.assertEquals("longitude", expected.getPosition().longitude(), actual.getPosition().longitude(), 0.001);
}
Assert.assertEquals("has altitude", expected.hasAltitude(), actual.hasAltitude());
+1 -1
View File
@@ -80,7 +80,7 @@ limitations under the License.
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/OpenTracksTheme">
android:theme="@style/DayNightDynamicTheme"> <!-- Default for AppCompatActivities -->
<activity
android:name=".publicapi.StartRecording"
@@ -37,9 +37,7 @@ public abstract class AbstractActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
if (PreferencesUtils.shouldApplyOledTheme()) {
setTheme(R.style.OpenTracksThemeOled);
}
PreferencesUtils.applyTheme(this);
EdgeToEdge.enable(this);
@@ -56,7 +54,7 @@ public abstract class AbstractActivity extends AppCompatActivity {
private void edge2edgeApplyInsets(View rootView) {
ViewCompat.setOnApplyWindowInsetsListener(rootView, (view, windowInsets) -> {
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.ime());
view.setPadding(insets.left, insets.top, insets.right, insets.bottom);
return WindowInsetsCompat.CONSUMED;
});
@@ -43,6 +43,7 @@ public abstract class AbstractTrackDeleteActivity extends AbstractActivity imple
ConfirmDeleteDialogFragment.showDialog(getSupportFragmentManager(), trackIds);
}
//TODO A callback is better.
@Override
public void onConfirmDeleteDone(Track.Id... trackIds) {
ArrayList<Track.Id> trackIdList = Arrays.stream(trackIds)
@@ -6,8 +6,6 @@ import android.content.Context;
import android.os.Build;
import android.util.Log;
import com.google.android.material.color.DynamicColors;
import java.lang.reflect.Method;
import de.dennisguse.opentracks.settings.PreferencesUtils;
@@ -34,11 +32,7 @@ public class Startup extends Application {
// Set default values of preferences on first start.
PreferencesUtils.resetPreferences(this, false);
PreferencesUtils.applyDefaultUnit();
PreferencesUtils.applyNightMode();
if (PreferencesUtils.shouldUseDynamicColors()) {
DynamicColors.applyToActivitiesIfAvailable(this);
}
PreferencesUtils.applyNightModeAndDynamicColors(this);
}
@Override
@@ -23,12 +23,14 @@ import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import java.time.ZoneOffset;
import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.databinding.TrackEditBinding;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
import de.dennisguse.opentracks.util.TrackUtils;
import de.dennisguse.opentracks.ui.ZoneOffsetAdapter;
/**
* An activity that let's the user see and edit the user editable track meta data such as track name, activity type, and track description.
@@ -68,19 +70,18 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
return;
}
viewBinding.fields.trackEditName.setText(track.getName());
viewBinding.fields.trackEditActivityType.setText(track.getActivityTypeLocalized());
viewBinding.trackEditName.setText(track.getName());
viewBinding.trackEditActivityTypeLocalized.setText(track.getActivityTypeLocalized());
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, ActivityType.getLocalizedStrings(this));
viewBinding.fields.trackEditActivityType.setAdapter(adapter);
viewBinding.fields.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> {
String localizedActivityType = (String) viewBinding.fields.trackEditActivityType.getAdapter().getItem(position);
viewBinding.trackEditActivityTypeLocalized.setAdapter(adapter);
viewBinding.trackEditActivityTypeLocalized.setOnItemClickListener((parent, view, position, id) -> {
String localizedActivityType = (String) viewBinding.trackEditActivityTypeLocalized.getAdapter().getItem(position);
setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType));
});
viewBinding.fields.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> {
viewBinding.trackEditActivityTypeLocalized.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
String localizedActivityType = viewBinding.fields.trackEditActivityType.getText().toString();
String localizedActivityType = viewBinding.trackEditActivityTypeLocalized.getText().toString();
setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType));
}
});
@@ -92,16 +93,23 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
if (activityType == null) {
activityType = track.getActivityType();
}
setActivityTypeIcon(activityType);
viewBinding.fields.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), this, viewBinding.fields.trackEditActivityType.getText().toString()));
viewBinding.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), this, viewBinding.trackEditActivityTypeLocalized.getText().toString()));
viewBinding.fields.trackEditDescription.setText(track.getDescription());
viewBinding.trackEditDescription.setText(track.getDescription());
final ArrayAdapter<ZoneOffset> zoneOffsetAdapter = new ZoneOffsetAdapter(this, android.R.layout.simple_dropdown_item_1line);
viewBinding.trackEditTimeOffset.setText(track.getZoneOffset().toString());
viewBinding.trackEditTimeOffset.setAdapter(zoneOffsetAdapter);
viewBinding.trackEditTimeOffset.setOnItemClickListener((parent, view, position, id) -> track.setZoneOffset(zoneOffsetAdapter.getItem(position)));
viewBinding.trackEditSave.setOnClickListener(v -> {
TrackUtils.updateTrack(TrackEditActivity.this, track, viewBinding.fields.trackEditName.getText().toString(),
viewBinding.fields.trackEditActivityType.getText().toString(), viewBinding.fields.trackEditDescription.getText().toString(),
contentProviderUtils);
track.setName(viewBinding.trackEditName.getText().toString());
track.setDescription(viewBinding.trackEditDescription.getText().toString());
track.setActivityTypeLocalizedAndUpdateActivityType(this, viewBinding.trackEditActivityTypeLocalized.getText().toString());
contentProviderUtils.updateTrack(track);
finish();
});
@@ -124,12 +132,12 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
private void setActivityTypeIcon(ActivityType activityType) {
this.activityType = activityType;
viewBinding.fields.trackEditActivityTypeIcon.setImageResource(activityType.getIconDrawableId());
viewBinding.trackEditActivityTypeIcon.setImageResource(activityType.getIconDrawableId());
}
@Override
public void onChooseActivityTypeDone(ActivityType activityType) {
setActivityTypeIcon(activityType);
viewBinding.fields.trackEditActivityType.setText(getString(activityType.getLocalizedStringId()));
viewBinding.trackEditActivityTypeLocalized.setText(getString(activityType.getLocalizedStringId()));
}
}
@@ -34,7 +34,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.button.MaterialButton;
@@ -60,6 +62,7 @@ import de.dennisguse.opentracks.ui.aggregatedStatistics.AggregatedStatisticsActi
import de.dennisguse.opentracks.ui.aggregatedStatistics.ConfirmDeleteDialogFragment;
import de.dennisguse.opentracks.ui.markers.MarkerListActivity;
import de.dennisguse.opentracks.ui.util.ActivityUtils;
import de.dennisguse.opentracks.ui.util.RecyclerViewSwipeDeleteCallback;
import de.dennisguse.opentracks.util.IntentDashboardUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.util.PermissionRequester;
@@ -168,6 +171,13 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
viewBinding.trackList.setLayoutManager(layoutManager);
viewBinding.trackList.setAdapter(adapter);
ItemTouchHelper itemTouchhelper = new ItemTouchHelper(new RecyclerViewSwipeDeleteCallback(this) {
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
TrackListActivity.this.deleteTracks(new Track.Id(viewHolder.getItemId()));
}
});
itemTouchhelper.attachToRecyclerView(viewBinding.trackList);
viewBinding.trackListFabAction.setOnClickListener((view) -> {
if (recordingStatus.isRecording()) {
Toast.makeText(TrackListActivity.this, getString(R.string.hold_to_stop), Toast.LENGTH_LONG).show();
@@ -306,6 +316,12 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
adapter.swapData(tracks);
}
@Override
public void onConfirmDeleteAbort(Track.Id... trackIds) {
// This is not nice, but it will happen rarely (as deletion is not a standard case).
adapter.notifyItemRangeChanged(0, adapter.getItemCount());
}
@Override
protected void onDeleteConfirmed() {
// Do nothing
@@ -49,7 +49,6 @@ import de.dennisguse.opentracks.ui.markers.MarkerListActivity;
import de.dennisguse.opentracks.ui.util.ActivityUtils;
import de.dennisguse.opentracks.util.IntentDashboardUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.util.TrackUtils;
/**
* An activity to show the track detail, record a new track or resumes an existing one.
@@ -327,7 +326,9 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
public void onChooseActivityTypeDone(ActivityType activityType) {
Track track = contentProviderUtils.getTrack(trackId);
String activityTypeLocalized = getString(activityType.getLocalizedStringId());
TrackUtils.updateTrack(this, track, null, activityTypeLocalized, null, contentProviderUtils);
track.setActivityTypeLocalizedAndUpdateActivityType(this, activityTypeLocalized);
contentProviderUtils.updateTrack(track);
}
private class CustomFragmentPagerAdapter extends FragmentStateAdapter {
@@ -22,7 +22,6 @@ import de.dennisguse.opentracks.ui.aggregatedStatistics.ConfirmDeleteDialogFragm
import de.dennisguse.opentracks.util.ExportUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.util.StringUtils;
import de.dennisguse.opentracks.util.TrackUtils;
public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller {
@@ -34,8 +33,6 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements
private Track.Id trackId;
private boolean isDiscarding = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -107,9 +104,11 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements
}
private void storeTrackMetaData(ContentProviderUtils contentProviderUtils, Track track) {
TrackUtils.updateTrack(TrackStoppedActivity.this, track, viewBinding.trackEditName.getText().toString(),
viewBinding.trackEditActivityType.getText().toString(), viewBinding.trackEditDescription.getText().toString(),
contentProviderUtils);
track.setName(viewBinding.trackEditName.getText().toString());
track.setDescription(viewBinding.trackEditDescription.getText().toString());
track.setActivityTypeLocalizedAndUpdateActivityType(this, viewBinding.trackEditActivityType.getText().toString());
contentProviderUtils.updateTrack(track);
}
@NonNull
@@ -144,7 +143,6 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements
@Override
protected void onDeleteConfirmed() {
isDiscarding = true;
viewBinding.loadingLayout.loadingText.setText(getString(R.string.track_discarding));
viewBinding.contentLinearLayout.setVisibility(View.GONE);
viewBinding.loadingLayout.loadingIndeterminate.setVisibility(View.VISIBLE);
@@ -784,8 +784,8 @@ public class ContentProviderUtils {
values.put(TrackPointsColumns.TYPE, trackPoint.getType().type_db);
if (trackPoint.hasLocation()) {
values.put(TrackPointsColumns.LONGITUDE, (int) (trackPoint.getLongitude() * 1E6));
values.put(TrackPointsColumns.LATITUDE, (int) (trackPoint.getLatitude() * 1E6));
values.put(TrackPointsColumns.LATITUDE, (int) (trackPoint.getPosition().latitude() * 1E6));
values.put(TrackPointsColumns.LONGITUDE, (int) (trackPoint.getPosition().longitude() * 1E6));
}
values.put(TrackPointsColumns.TIME, trackPoint.getTime().toEpochMilli());
if (trackPoint.hasAltitude()) {
@@ -129,10 +129,12 @@ public enum ActivityType {
.orElse(ActivityType.UNKNOWN);
}
@NonNull
public static ActivityType findByLocalizedString(Context context, String localizedActivityType) {
return findByLocalizedString(context.getResources(), localizedActivityType);
}
@NonNull
public static ActivityType findByLocalizedString(Resources resources, String localizedActivityType) {
return Arrays.stream(ActivityType.values())
.filter(it -> resources.getString(it.getLocalizedStringId()).equals(localizedActivityType))
@@ -132,14 +132,6 @@ public final class Marker {
return position;
}
public double getLatitude() {
return position.latitude();
}
public double getLongitude() {
return position.longitude();
}
public boolean hasAccuracy() {
return position.hasHorizontalAccuracy();
}
@@ -16,6 +16,7 @@
package de.dennisguse.opentracks.data.models;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
@@ -48,7 +49,7 @@ public class Track {
private ActivityType activityType;
private final ZoneOffset zoneOffset;
private ZoneOffset zoneOffset;
private TrackStatistics trackStatistics = new TrackStatistics();
@@ -58,7 +59,7 @@ public class Track {
}
public Track(@NonNull ZoneOffset zoneOffset) {
this.zoneOffset = zoneOffset;
setZoneOffset(zoneOffset);
}
/**
@@ -113,10 +114,19 @@ public class Track {
this.activityType = activityType;
}
public void setActivityTypeLocalizedAndUpdateActivityType(Context context, String activityTypeLocalized) {
setActivityTypeLocalized(activityTypeLocalized);
setActivityType(ActivityType.findByLocalizedString(context, activityTypeLocalized));
}
public ZoneOffset getZoneOffset() {
return zoneOffset;
}
public void setZoneOffset(@NonNull ZoneOffset zoneOffset) {
this.zoneOffset = zoneOffset;
}
public OffsetDateTime getStartTime() {
return trackStatistics
.getStartTime().atOffset(zoneOffset);
@@ -147,18 +147,6 @@ public class TrackPoint {
return position.hasLocation();
}
//TODO Should be double
@Deprecated //Use getPosition()
public Double getLatitude() {
return position.latitude();
}
//TODO Should be double
@Deprecated //Use getPosition()
public Double getLongitude() {
return position.longitude();
}
@NonNull
public Position getPosition() {
return position;
@@ -91,8 +91,8 @@ public class CSVTrackExporter implements TrackExporter {
List<Column> columns = List.of(
new Column("time", null),
new Column("trackpoint_type", t -> quote(t.getType().name())),
new Column("latitude", t -> t.hasLocation() ? COORDINATE_FORMAT.format(t.getLatitude()) : ""),
new Column("longitude", t -> t.hasLocation() ? COORDINATE_FORMAT.format(t.getLongitude()) : ""),
new Column("latitude", t -> t.hasLocation() ? COORDINATE_FORMAT.format(t.getPosition().latitude()) : ""),
new Column("longitude", t -> t.hasLocation() ? COORDINATE_FORMAT.format(t.getPosition().longitude()) : ""),
new Column("altitude", t -> t.hasAltitude() ? ALTITUDE_FORMAT.format(t.getAltitude().toM()) : ""),
new Column("accuracy_horizontal", t -> t.hasHorizontalAccuracy() ? DISTANCE_FORMAT.format(t.getHorizontalAccuracy().toM()) : ""),
new Column("accuracy_vertical", t -> t.hasVerticalAccuracy() ? DISTANCE_FORMAT.format(t.getVerticalAccuracy().toM()) : ""),
@@ -21,7 +21,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -95,8 +94,6 @@ public class ExportActivity extends AppCompatActivity implements ExportService.E
private int trackExportSkippedCount;
private int trackExportTotalCount;
boolean doubleBackToCancel = false;
private ExportActivityBinding viewBinding;
private ArrayList<String> trackErrors = new ArrayList<>();
@@ -214,19 +211,6 @@ public class ExportActivity extends AppCompatActivity implements ExportService.E
exportTasks.clear();
}
@Override
public void onBackPressed() {
if (doubleBackToCancel || getTotalDone() == trackExportTotalCount) {
super.onBackPressed();
return;
}
this.doubleBackToCancel = true;
Toast.makeText(this, getString(R.string.generic_click_twice_cancel), Toast.LENGTH_SHORT).show();
new Handler().postDelayed(() -> doubleBackToCancel = false, 2000);
}
private void createExportTasks(boolean allInOneFile) {
List<Track> tracks = contentProviderUtils.getTracks();
exportTasks = new ArrayList<>();
@@ -36,6 +36,7 @@ import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.TrackPointIterator;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Marker;
import de.dennisguse.opentracks.data.models.Position;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.data.models.TrackPoint;
import de.dennisguse.opentracks.stats.TrackStatistics;
@@ -253,7 +254,7 @@ public class GPXTrackExporter implements TrackExporter {
}
private void writeMarker(ZoneOffset zoneOffset, Marker marker) {
printWriter.println("<wpt " + formatLocation(marker.getLatitude(), marker.getLongitude()) + ">");
printWriter.println("<wpt " + formatLocation(marker.getPosition()) + ">");
if (marker.hasAltitude()) {
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(marker.getAltitude().toM()) + "</ele>");
}
@@ -311,7 +312,7 @@ public class GPXTrackExporter implements TrackExporter {
private Distance writeTrackPoint(ZoneOffset zoneOffset, TrackPoint trackPoint, List<TrackPoint> sensorPoints, Distance trackDistance) {
Distance cumulativeDistance;
printWriter.println("<trkpt " + formatLocation(trackPoint.getLatitude(), trackPoint.getLongitude()) + ">");
printWriter.println("<trkpt " + formatLocation(trackPoint.getPosition()) + ">");
if (trackPoint.hasAltitude()) {
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(trackPoint.getAltitude().toM()) + "</ele>");
@@ -395,7 +396,7 @@ public class GPXTrackExporter implements TrackExporter {
.orElse(null);
}
private String formatLocation(double latitude, double longitude) {
return "lat=\"" + COORDINATE_FORMAT.format(latitude) + "\" lon=\"" + COORDINATE_FORMAT.format(longitude) + "\"";
private String formatLocation(Position position) {
return "lat=\"" + COORDINATE_FORMAT.format(position.latitude()) + "\" lon=\"" + COORDINATE_FORMAT.format(position.longitude()) + "\"";
}
}
@@ -432,8 +432,8 @@ public class KMLTrackExporter implements TrackExporter {
printWriter.println("<name>" + StringUtils.formatCData(marker.getName()) + "</name>");
printWriter.println("<description>" + StringUtils.formatCData(marker.getDescription()) + "</description>");
printWriter.print("<Camera>");
printWriter.print("<longitude>" + marker.getLongitude() + "</longitude>");
printWriter.print("<latitude>" + marker.getLatitude() + "</latitude>");
printWriter.print("<longitude>" + marker.getPosition().longitude() + "</longitude>");
printWriter.print("<latitude>" + marker.getPosition().latitude() + "</latitude>");
printWriter.print("<altitude>20</altitude>");
printWriter.print("<tilt>90</tilt>");
printWriter.println("</Camera>");
@@ -20,9 +20,7 @@ import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
@@ -56,8 +54,6 @@ public class ImportActivity extends FragmentActivity {
private ImportActivityBinding viewBinding;
boolean doubleBackToCancel = false;
private ArrayList<Uri> documentUris = new ArrayList<>();
private boolean isDirectory;
@@ -122,21 +118,6 @@ public class ImportActivity extends FragmentActivity {
outState.putBoolean(BUNDLE_IS_DIRECTORY, isDirectory);
}
@Override
public void onBackPressed() {
if (doubleBackToCancel || (summary != null && getTotalDone() == summary.getTotalCount())) {
super.onBackPressed();
viewModel.cancel();
getViewModelStore().clear();
return;
}
this.doubleBackToCancel = true;
Toast.makeText(this, getString(R.string.generic_click_twice_cancel), Toast.LENGTH_SHORT).show();
new Handler().postDelayed(() -> doubleBackToCancel=false, 2000);
}
private void initViews() {
viewBinding.importProgressDone.setText("0");
viewBinding.importProgressTotal.setText("0");
@@ -178,10 +178,10 @@ public class TrackImporter {
if (current.hasLocation()) {
Instant time = current.getTime();
if (current.getLatitude() == 100) {
if (current.getPosition().latitude() == 100) {
//TODO Remove by 31st December 2021.
trackPoints.set(i, new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, time));
} else if (current.getLatitude() == 200) {
} else if (current.getPosition().latitude() == 200) {
//TODO Remove by 31st December 2021.
trackPoints.set(i, new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, time));
//TODO Delete location
@@ -10,7 +10,6 @@ import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.services.TrackRecordingService;
import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.util.IntentDashboardUtils;
import de.dennisguse.opentracks.util.TrackUtils;
public class StartRecording extends AbstractAPIActivity {
@@ -42,12 +41,12 @@ public class StartRecording extends AbstractAPIActivity {
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(this);
Track track = contentProviderUtils.getTrack(trackId);
TrackUtils.updateTrack(this, track,
bundle.getString(EXTRA_TRACK_NAME, null),
bundle.getString(EXTRA_TRACK_ACTIVITY_TYPE_LOCALIZED, null),
ActivityType.findBy(bundle.getString(EXTRA_TRACK_ACTIVITY_TYPE_ID, null)),
bundle.getString(EXTRA_TRACK_DESCRIPTION, null),
contentProviderUtils);
track.setName(bundle.getString(EXTRA_TRACK_NAME, ""));
track.setDescription(bundle.getString(EXTRA_TRACK_DESCRIPTION, ""));
track.setActivityType(ActivityType.findBy(bundle.getString(EXTRA_TRACK_ACTIVITY_TYPE_ID, null)));
track.setActivityTypeLocalized(bundle.getString(EXTRA_TRACK_ACTIVITY_TYPE_LOCALIZED, ""));
contentProviderUtils.updateTrack(track);
}
private void startDashboardAPI(@NonNull Track.Id trackId, @NonNull Bundle bundle) {
@@ -17,6 +17,7 @@
package de.dennisguse.opentracks.settings;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
@@ -30,6 +31,8 @@ import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;
import com.google.android.material.color.DynamicColors;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -338,11 +341,6 @@ public class PreferencesUtils {
return getBoolean(R.string.chart_display_heart_rate_key, DEFAULT);
}
public static boolean shouldUseDynamicColors() {
final boolean DEFAULT = resources.getBoolean(R.bool.settings_ui_dynamic_colors_default);
return getBoolean(R.string.settings_ui_dynamic_colors_key, DEFAULT);
}
public static boolean shouldVoiceAnnouncementOnDeviceSpeaker() {
final boolean DEFAULT = resources.getBoolean(R.bool.voice_on_device_speaker_default);
return getBoolean(R.string.voice_on_device_speaker_key, DEFAULT);
@@ -705,7 +703,7 @@ public class PreferencesUtils {
public static TrackFileFormat getExportTrackFileFormat() {
final String TRACKFILEFORMAT_NAME_DEFAULT = getString(R.string.export_trackfileformat_default, null);
String trackFileFormatName = getString(R.string.export_trackfileformat_key, TRACKFILEFORMAT_NAME_DEFAULT);
return Arrays.stream(TrackFileFormat.values())
return Arrays.stream(TrackFileFormat.values())
.filter(format -> format.getPreferenceId().equals(trackFileFormatName))
.findFirst().orElse(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES);
}
@@ -715,30 +713,62 @@ public class PreferencesUtils {
return getBoolean(R.string.import_prevent_reimport_key, defaultValue);
}
/**
* @return * {@link androidx.appcompat.app.AppCompatDelegate}.MODE_*
* * 3: Night OLED friendly
*/
private static String getUiMode() {
final String defaultValue = getKey(R.string.night_mode_default);
final String value = getString(R.string.night_mode_key, defaultValue);
return value;
record ThemeConfig(int themeResourceId, int dayNight, boolean dynamicColor) {
}
public static boolean shouldApplyOledTheme() {
return resources.getString(R.string.night_mode_night_oled_value)
.equals(getUiMode());
private static ThemeConfig getThemeMode() {
final String defaultValue = getKey(R.string.theme_default);
final String value = getString(R.string.theme_key, defaultValue);
switch (value) {
case "0" -> {
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, false);
}
case "1" -> {
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, true);
}
case "2" -> {
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_NO, false);
}
case "3" -> {
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_NO, true);
}
case "4" -> {
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_YES, false);
}
case "5" -> {
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_YES, true);
}
case "6" -> {
return new ThemeConfig(R.style.NightOledColorTheme, AppCompatDelegate.MODE_NIGHT_YES, false);
}
case "7" -> {
return new ThemeConfig(R.style.NightOledDynamicTheme, AppCompatDelegate.MODE_NIGHT_YES, true);
}
default -> {
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, false);
}
}
}
public static void applyTheme(Context context) {
context.setTheme(getThemeMode().themeResourceId());
}
public static void applyNightMode() {
String uiMode = getUiMode();
if (resources.getString(R.string.night_mode_night_oled_value)
.equals(uiMode)) {
return;
}
ThemeConfig themeConfig = getThemeMode();
AppCompatDelegate.setDefaultNightMode(Integer.parseInt(uiMode));
AppCompatDelegate.setDefaultNightMode(themeConfig.dayNight);
}
public static void applyNightModeAndDynamicColors(Application application) {
ThemeConfig themeConfig = getThemeMode();
applyNightMode();
if (application != null && themeConfig.dynamicColor)
DynamicColors.applyToActivitiesIfAvailable(application);
}
public static void resetPreferences(Context context, boolean readAgain) {
@@ -2,7 +2,6 @@ package de.dennisguse.opentracks.settings;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
@@ -15,7 +14,7 @@ import de.dennisguse.opentracks.R;
public class UserInterfaceSettingsFragment extends PreferenceFragmentCompat {
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> {
if (PreferencesUtils.isKey(R.string.night_mode_key, key)) {
if (PreferencesUtils.isKey(R.string.theme_key, key)) {
getActivity().runOnUiThread(() -> {
PreferencesUtils.applyNightMode();
Toast.makeText(getContext(), R.string.settings_theme_switch_restart, Toast.LENGTH_LONG).show();
@@ -33,9 +32,6 @@ public class UserInterfaceSettingsFragment extends PreferenceFragmentCompat {
startActivity(intent);
return true;
});
Preference dynamicColors = findPreference(getString(R.string.settings_ui_dynamic_colors_key));
dynamicColors.setEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU);
}
@Override
@@ -55,6 +55,7 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
this.recyclerView = recyclerView;
this.recordingStatus = recordingStatus;
this.unitSystem = unitSystem;
setHasStableIds(true);
}
public void setActionModeCallback(ActivityUtils.ContextualActionModeCallback actionModeCallback) {
@@ -76,6 +77,12 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
viewHolder.bind(cursor);
}
@Override
public long getItemId(int position) {
cursor.moveToPosition(position);
return cursor.getLong(cursor.getColumnIndexOrThrow(TracksColumns._ID));
}
@Override
public int getItemCount() {
if (cursor == null) {
@@ -163,7 +170,6 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
private final TrackListItemBinding viewBinding;
private final View view;
private Track.Id trackId;
@@ -171,10 +177,9 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
super(itemView);
viewBinding = TrackListItemBinding.bind(itemView);
view = itemView;
view.setOnClickListener(this);
view.setOnLongClickListener(this);
viewBinding.getRoot().setOnClickListener(this);
viewBinding.getRoot().setOnLongClickListener(this);
}
@@ -233,9 +238,10 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
public void setSelected(boolean isSelected) {
selection.put((int) getId(), isSelected);
view.setActivated(isSelected);
viewBinding.getRoot().setActivated(isSelected);
}
//TODO Check if this still required.
public long getId() {
return trackId.id();
}
@@ -244,7 +250,7 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
@Override
public void onClick(View v) {
if (selectionMode) {
setSelected(!view.isActivated());
setSelected(!viewBinding.getRoot().isActivated());
actionMode.invalidate();
return;
}
@@ -260,14 +266,14 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(
context,
new Pair<>(view.findViewById(R.id.track_list_item_icon), TrackRecordedActivity.VIEW_TRACK_ICON));
new Pair<>(viewBinding.getRoot().findViewById(R.id.track_list_item_icon), TrackRecordedActivity.VIEW_TRACK_ICON));
context.startActivity(newIntent, activityOptions.toBundle());
}
}
@Override
public boolean onLongClick(View v) {
setSelected(!view.isActivated());
setSelected(!viewBinding.getRoot().isActivated());
if (!selectionMode) {
actionMode = context.startSupportActionMode(TrackListAdapter.this);
} else {
@@ -0,0 +1,19 @@
package de.dennisguse.opentracks.ui;
import android.content.Context;
import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import java.time.ZoneOffset;
import java.util.stream.IntStream;
public class ZoneOffsetAdapter extends ArrayAdapter<ZoneOffset> {
public ZoneOffsetAdapter(@NonNull Context context, int resource) {
super(context, resource, IntStream.range(-12, +12)
.boxed()
.map(ZoneOffset::ofHours)
.toList());
}
}
@@ -75,7 +75,8 @@ public class ConfirmDeleteDialogFragment extends DialogFragment {
getActivity(),
titleId,
getString(messageId),
(dialog, which) -> caller.onConfirmDeleteDone(trackIds)
(dialog, which) -> caller.onConfirmDeleteDone(trackIds),
(dialog, which) -> caller.onConfirmDeleteAbort(trackIds)
);
}
@@ -86,6 +87,9 @@ public class ConfirmDeleteDialogFragment extends DialogFragment {
*/
public interface ConfirmDeleteCaller {
default void onConfirmDeleteAbort(Track.Id... trackIds) {
}
void onConfirmDeleteDone(Track.Id... trackIds);
}
}
@@ -71,13 +71,18 @@ public class DeleteMarkerDialogFragment extends DialogFragment {
int titleId = markerIds.length > 1 ? R.string.generic_delete_selected_confirm_title : R.string.marker_delete_one_confirm_title;
int messageId = markerIds.length > 1 ? R.string.marker_delete_multiple_confirm_message : R.string.marker_delete_one_confirm_message;
return DialogUtils.createConfirmationDialog(
fragmentActivity, titleId, getString(messageId), (dialog, which) -> new Thread(() -> {
fragmentActivity, titleId, getString(messageId),
(dialog, which) -> new Thread(() -> {
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(fragmentActivity);
for (Marker.Id markerId : markerIds) {
contentProviderUtils.deleteMarker(context, markerId);
}
caller.onMarkerDeleted();
}).start());
}
).start(),
(dialog, which) -> {
// None
});
}
/**
@@ -24,17 +24,15 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.util.ArrayList;
import java.util.List;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import de.dennisguse.opentracks.AbstractActivity;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.Marker;
import de.dennisguse.opentracks.data.tables.MarkerColumns;
import de.dennisguse.opentracks.databinding.MarkerDetailActivityBinding;
import de.dennisguse.opentracks.ui.markers.DeleteMarkerDialogFragment.DeleteMarkerCaller;
@@ -53,7 +51,7 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
private MarkerDetailActivityBinding viewBinding;
private List<Marker.Id> markerIds;
private Cursor cursor;
@Override
protected void onCreate(Bundle bundle) {
@@ -69,40 +67,29 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(this);
Marker marker = contentProviderUtils.getMarker(markerId);
markerIds = new ArrayList<>();
//TODO only load used data: ID + name
cursor = contentProviderUtils.getMarkerCursor(marker.getTrackId(), null, -1);
if (cursor == null) {
finish();
}
int markerIndex = -1;
//TODO Load only markerIds, not the whole marker
try (Cursor cursor = contentProviderUtils.getMarkerCursor(marker.getTrackId(), null, -1)) {
if (cursor != null && cursor.moveToFirst()) {
for (int i = 0; i < cursor.getCount(); i++) {
Marker currentMarker = contentProviderUtils.createMarker(cursor);
markerIds.add(currentMarker.getId());
if (markerId.equals(currentMarker.getId())) {
markerIndex = markerIds.size() - 1;
}
cursor.moveToNext();
if (cursor != null && cursor.moveToFirst()) {
while (markerIndex == -1 && cursor.moveToNext()) {
Marker.Id currentId = new Marker.Id(cursor.getLong(cursor.getColumnIndexOrThrow(MarkerColumns._ID)));
if (markerId.equals(currentId)) {
markerIndex = cursor.getPosition();
}
}
}
final MarkerDetailPagerAdapter markerAdapter = new MarkerDetailPagerAdapter(getSupportFragmentManager());
final MarkerDetailPagerAdapter markerAdapter = new MarkerDetailPagerAdapter(this);
viewBinding.makerDetailActivityViewPager.setAdapter(markerAdapter);
viewBinding.makerDetailActivityViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
viewBinding.makerDetailActivityViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
viewBinding.markerDetailToolbar.setTitle(markerAdapter.getPageTitle(position));
// viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(markerAdapter.getPageTitle(position)); TOOD
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
viewBinding.makerDetailActivityViewPager.setCurrentItem(markerIndex == -1 ? 0 : markerIndex);
@@ -117,37 +104,42 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
return viewBinding.getRoot();
}
@Override
protected void onDestroy() {
super.onDestroy();
viewBinding = null;
if (cursor != null) cursor.close();
cursor = null;
}
@Override
public void onMarkerDeleted() {
runOnUiThread(this::finish);
}
/**
* Marker detail pager adapter.
*
* @author Jimmy Shih
*/
private class MarkerDetailPagerAdapter extends FragmentStatePagerAdapter {
private class MarkerDetailPagerAdapter extends FragmentStateAdapter {
MarkerDetailPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
MarkerDetailPagerAdapter(@NonNull FragmentActivity fa) {
super(fa);
}
@Override
@NonNull
public Fragment getItem(int position) {
return MarkerDetailFragment.newInstance(markerIds.get(position));
public Fragment createFragment(int position) {
cursor.moveToPosition(position);
return MarkerDetailFragment.newInstance(new Marker.Id(cursor.getLong(cursor.getColumnIndexOrThrow(MarkerColumns._ID))));
}
@Override
public int getItemCount() {
return cursor.getCount();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return getString(R.string.marker_title, position + 1, getCount());
}
@Override
public int getCount() {
return markerIds.size();
cursor.moveToPosition(position);
return getString(R.string.marker_detail_title, position + 1, getItemCount(), cursor.getString(cursor.getColumnIndexOrThrow(MarkerColumns.NAME)));
}
}
}
@@ -18,7 +18,6 @@ package de.dennisguse.opentracks.ui.markers;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -26,22 +25,18 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import java.time.Duration;
import androidx.lifecycle.Lifecycle;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.Marker;
import de.dennisguse.opentracks.databinding.MarkerDetailFragmentBinding;
import de.dennisguse.opentracks.share.ShareUtils;
import de.dennisguse.opentracks.ui.util.ListItemUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.util.StringUtils;
@@ -55,43 +50,15 @@ public class MarkerDetailFragment extends Fragment {
private static final String TAG = MarkerDetailFragment.class.getSimpleName();
private static final String KEY_MARKER_ID = "markerId";
private static final Duration HIDE_TEXT_DELAY = Duration.ofSeconds(4);
private MenuItem shareMarkerImageMenuItem;
private ContentProviderUtils contentProviderUtils;
private Handler handler;
private Marker.Id markerId;
private Marker marker;
private MarkerDetailFragmentBinding viewBinding;
private final Runnable hideText = new Runnable() {
@Override
public void run() {
Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.fadeout);
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation anim) {
}
@Override
public void onAnimationRepeat(Animation anim) {
}
@Override
public void onAnimationEnd(Animation anim) {
viewBinding.markerDetailMarkerTextGradient.setVisibility(View.GONE);
viewBinding.markerDetailMarkerInfo.setVisibility(View.GONE);
}
});
viewBinding.markerDetailMarkerTextGradient.startAnimation(animation);
viewBinding.markerDetailMarkerInfo.startAnimation(animation);
}
};
public static MarkerDetailFragment newInstance(Marker.Id markerId) {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_MARKER_ID, markerId);
@@ -111,43 +78,70 @@ public class MarkerDetailFragment extends Fragment {
getParentFragmentManager().popBackStack();
return;
}
contentProviderUtils = new ContentProviderUtils(getActivity());
handler = new Handler();
setHasOptionsMenu(true);
contentProviderUtils = new ContentProviderUtils(getContext());
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewBinding = MarkerDetailFragmentBinding.inflate(inflater, container, false);
viewBinding.markerDetailMarkerPhoto.setOnClickListener(v -> {
handler.removeCallbacks(hideText);
int visibility = viewBinding.markerDetailMarkerInfo.getVisibility() == View.GONE ? View.VISIBLE : View.GONE;
viewBinding.markerDetailMarkerTextGradient.setVisibility(visibility);
viewBinding.markerDetailMarkerInfo.setVisibility(visibility);
if (visibility == View.VISIBLE) {
handler.postDelayed(hideText, HIDE_TEXT_DELAY.toMillis());
requireActivity().addMenuProvider(new MenuProvider() {
@Override
public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.marker_detail, menu);
shareMarkerImageMenuItem = menu.findItem(R.id.marker_detail_share);
updateMarker();
updateMenuItems();
}
});
@Override
public boolean onMenuItemSelected(@NonNull MenuItem item) {
FragmentActivity fragmentActivity = getActivity();
if (item.getItemId() == R.id.marker_detail_show_on_map) {
IntentUtils.showCoordinateOnMap(getContext(), marker);
return true;
}
if (item.getItemId() == R.id.marker_detail_edit) {
Intent intent = IntentUtils.newIntent(fragmentActivity, MarkerEditActivity.class)
.putExtra(MarkerEditActivity.EXTRA_MARKER_ID, markerId);
startActivity(intent);
return true;
}
if (item.getItemId() == R.id.marker_detail_share) {
if (marker.hasPhoto()) {
Intent intent = ShareUtils.newShareFileIntent(getContext(), marker.getId());
intent = Intent.createChooser(intent, null);
startActivity(intent);
}
return true;
}
if (item.getItemId() == R.id.marker_detail_delete) {
DeleteMarkerDialogFragment.showDialog(getChildFragmentManager(), markerId);
return true;
}
return false;
}
}, getViewLifecycleOwner(), Lifecycle.State.RESUMED);
return viewBinding.getRoot();
}
@Override
public void onResume() {
super.onResume();
// Need to update the marker in case returning after an edit
updateMarker(true);
updateMarker();
updateUi();
updateMenuItems();
}
@Override
public void onPause() {
super.onPause();
handler.removeCallbacks(hideText);
}
@Override
public void onDestroyView() {
super.onDestroyView();
@@ -166,97 +160,35 @@ public class MarkerDetailFragment extends Fragment {
super.setMenuVisibility(menuVisible);
// View pager caches the neighboring fragments in the resumed state.
// If becoming visible from the resumed state, update the UI to display the text above the image.
if (isResumed()) {
if (menuVisible) {
updateUi();
} else {
handler.removeCallbacks(hideText);
}
if (isResumed() && menuVisible) {
updateUi();
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.marker_detail, menu);
shareMarkerImageMenuItem = menu.findItem(R.id.marker_detail_share);
updateMarker(false);
updateMenuItems();
}
private void updateMenuItems() {
if (shareMarkerImageMenuItem != null)
shareMarkerImageMenuItem.setVisible(marker.hasPhoto());
if (shareMarkerImageMenuItem != null) { // MenuProvider might not yet been initialized.
// shareMarkerImageMenuItem.setEnabled(marker.hasPhoto());
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
FragmentActivity fragmentActivity = getActivity();
if (item.getItemId() == R.id.marker_detail_show_on_map) {
IntentUtils.showCoordinateOnMap(getContext(), marker);
return true;
}
if (item.getItemId() == R.id.marker_detail_edit) {
Intent intent = IntentUtils.newIntent(fragmentActivity, MarkerEditActivity.class)
.putExtra(MarkerEditActivity.EXTRA_MARKER_ID, markerId);
startActivity(intent);
return true;
}
if (item.getItemId() == R.id.marker_detail_share) {
if (marker.hasPhoto()) {
Intent intent = ShareUtils.newShareFileIntent(getContext(), marker.getId());
intent = Intent.createChooser(intent, null);
startActivity(intent);
}
return true;
}
if (item.getItemId() == R.id.marker_detail_delete) {
DeleteMarkerDialogFragment.showDialog(getChildFragmentManager(), markerId);
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateMarker(boolean refresh) {
if (refresh || marker == null) {
marker = contentProviderUtils.getMarker(markerId);
if (marker == null) {
Log.d(TAG, "marker is null");
getParentFragmentManager().popBackStack();
}
private void updateMarker() {
marker = contentProviderUtils.getMarker(markerId);
if (marker == null) {
Log.d(TAG, "marker is null");
getParentFragmentManager().popBackStack();
}
}
private void updateUi() {
boolean hasPhoto = marker.hasPhoto();
if (hasPhoto) {
handler.removeCallbacks(hideText);
if (marker.hasPhoto()) {
viewBinding.markerDetailMarkerPhoto.setImageURI(marker.getPhotoUrl());
handler.postDelayed(hideText, HIDE_TEXT_DELAY.toMillis());
} else {
viewBinding.markerDetailMarkerPhoto.setImageResource(MarkerUtils.ICON_ID);
viewBinding.markerDetailMarkerPhoto.setImageDrawable(MarkerUtils.getDefaultPhoto(getContext()));
}
ListItemUtils.setTextView(getActivity(), viewBinding.markerDetailMarkerName, marker.getName(), hasPhoto);
viewBinding.markerDetailMarkerCategory.setText(StringUtils.getCategory(marker.getCategory()));
viewBinding.markerDetailMarkerDescription.setText(marker.getDescription());
ListItemUtils.setTextView(getActivity(), viewBinding.markerDetailMarkerCategory, StringUtils.getCategory(marker.getCategory()), hasPhoto);
ListItemUtils.setTextView(getActivity(), viewBinding.markerDetailMarkerDescription, marker.getDescription(), hasPhoto);
setLocation(hasPhoto);
}
private void setLocation(boolean addShadow) {
String value = "[" + getString(R.string.stats_latitude) + " "
+ StringUtils.formatCoordinate(getContext(), marker.getLatitude()) + ", "
+ getString(R.string.stats_longitude) + " "
+ StringUtils.formatCoordinate(getContext(), marker.getLongitude()) + "]";
ListItemUtils.setTextView(getActivity(), viewBinding.markerDetailMarkerLocation, value, addShadow);
viewBinding.markerDetailMarkerLocation.setText(StringUtils.formatCoordinate(getContext(), marker.getPosition()));
}
}
@@ -164,7 +164,6 @@ public class MarkerListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
private final MarkerListItemBinding viewBinding;
private final View view;
private Marker marker;
@@ -172,23 +171,20 @@ public class MarkerListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
super(view);
viewBinding = MarkerListItemBinding.bind(view);
this.view = view;
view.setOnClickListener(this);
view.setOnLongClickListener(this);
viewBinding.getRoot().setOnClickListener(this);
viewBinding.getRoot().setOnLongClickListener(this);
}
public void bind(Marker marker) {
this.marker = marker;
viewBinding.markerListItemPhoto.setVisibility(marker.hasPhoto() ? View.VISIBLE : View.GONE);
viewBinding.markerListItemTextGradient.setVisibility(marker.hasPhoto() ? View.VISIBLE : View.GONE);
if (marker.hasPhoto()) {
int height = ThemeUtils.getPhotoHeight(context);
ViewGroup.LayoutParams params = viewBinding.markerListItemPhoto.getLayoutParams();
params.height = height;
viewBinding.markerListItemPhoto.setLayoutParams(params);
viewBinding.markerListItemTextGradient.setLayoutParams(params);
asyncLoadPhoto(viewBinding.markerListItemPhoto, marker.getPhotoUrl(), marker.getId());
}
@@ -208,7 +204,7 @@ public class MarkerListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
public void setSelected(boolean isSelected) {
selection.put((int) getId(), isSelected);
view.setActivated(isSelected);
viewBinding.getRoot().setActivated(isSelected);
}
public long getId() {
@@ -26,15 +26,13 @@ public class MarkerUtils {
private static final String TAG = FileUtils.class.getSimpleName();
static final int ICON_ID = R.drawable.ic_marker_orange_pushpin_with_shadow;
private static final String JPEG_EXTENSION = "jpeg";
private MarkerUtils() {
}
public static Drawable getDefaultPhoto(@NonNull Context context) {
return ContextCompat.getDrawable(context, ICON_ID);
return ContextCompat.getDrawable(context, R.drawable.ic_marker_show_24dp);
}
/**
@@ -42,12 +42,12 @@ public class DialogUtils {
* @param message the message
* @param okListener the listener when OK is clicked
*/
public static Dialog createConfirmationDialog(final Context context, int titleId, String message, DialogInterface.OnClickListener okListener) {
public static Dialog createConfirmationDialog(final Context context, int titleId, String message, DialogInterface.OnClickListener okListener, DialogInterface.OnClickListener cancelListener) {
return new AlertDialog.Builder(context)
.setCancelable(true)
.setIcon(R.drawable.ic_delete_forever_24dp)
.setMessage(message)
.setNegativeButton(android.R.string.cancel, null)
.setNegativeButton(android.R.string.cancel, cancelListener)
.setPositiveButton(android.R.string.ok, okListener)
.setTitle(titleId).create();
}
@@ -17,11 +17,8 @@
package de.dennisguse.opentracks.ui.util;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import java.time.Duration;
import java.time.Instant;
import java.time.OffsetDateTime;
@@ -89,29 +86,6 @@ public class ListItemUtils {
return timeDistanceText;
}
/**
* Sets a text view.
*
* @param context the context
* @param textView the text view
* @param value the value for the text view
* @param addShadow true to add shadow
*/
public static void setTextView(Context context, TextView textView, String value, boolean addShadow) {
if (value == null || value.length() == 0) {
textView.setVisibility(View.GONE);
return;
}
textView.setVisibility(View.VISIBLE);
textView.setText(value);
if (addShadow) {
textView.setShadowLayer(5, 0, 2, ContextCompat.getColor(context, android.R.color.black));
} else {
textView.setShadowLayer(0, 0, 0, 0);
}
}
public static void setDateAndTime(Context context, TextView dateView, TextView timeView, Instant time, ZoneOffset timeZone) {
OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(time, timeZone);
String dateContent = StringUtils.formatDateTodayRelative(context, offsetDateTime);
@@ -7,6 +7,8 @@ import android.util.TypedValue;
import androidx.core.content.ContextCompat;
import com.google.android.material.R;
public class ThemeUtils {
private ThemeUtils() {
@@ -18,7 +20,7 @@ public class ThemeUtils {
public static int getBackgroundColor(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(android.R.attr.colorBackground, typedValue, true);
theme.resolveAttribute(R.attr.colorSurface, typedValue, true);
return ContextCompat.getColor(context, typedValue.resourceId);
}
@@ -26,7 +28,7 @@ public class ThemeUtils {
public static int getTextColorPrimary(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
theme.resolveAttribute(R.attr.colorOnSurface, typedValue, true);
return ContextCompat.getColor(context, typedValue.resourceId);
}
@@ -34,20 +36,20 @@ public class ThemeUtils {
public static int getTextColorSecondary(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
theme.resolveAttribute(R.attr.colorSecondary, typedValue, true);
return ContextCompat.getColor(context, typedValue.resourceId);
}
public static int getFontSizeSmallInPx(Context context) {
TypedArray typedArray = context.obtainStyledAttributes(com.google.android.material.R.style.TextAppearance_MaterialComponents_Body2, new int[]{android.R.attr.textSize});
TypedArray typedArray = context.obtainStyledAttributes(R.style.TextAppearance_MaterialComponents_Body2, new int[]{android.R.attr.textSize});
int fontSize = typedArray.getDimensionPixelSize(0, 12);
typedArray.recycle();
return fontSize;
}
public static int getFontSizeMediumInPx(Context context) {
TypedArray typedArray = context.obtainStyledAttributes(com.google.android.material.R.style.TextAppearance_MaterialComponents_Body1, new int[]{android.R.attr.textSize});
TypedArray typedArray = context.obtainStyledAttributes(R.style.TextAppearance_MaterialComponents_Body1, new int[]{android.R.attr.textSize});
int fontSize = typedArray.getDimensionPixelSize(0, 15);
typedArray.recycle();
return fontSize;
@@ -50,23 +50,14 @@ public class IntentUtils {
return new Intent(context, cls).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
}
public static void showCoordinateOnMap(Context context, Marker marker) {
showCoordinateOnMap(context, marker.getLatitude(), marker.getLongitude(), marker.getName());
}
/**
* Send intent to show coordinates on a map (needs an another app).
*
* @param context the context
* @param latitude the latitude
* @param longitude the longitude
* @param label the label
*/
private static void showCoordinateOnMap(Context context, double latitude, double longitude, String label) {
public static void showCoordinateOnMap(Context context, Marker marker) {
//SEE https://developer.android.com/guide/components/intents-common.html#Maps
String uri = "geo:0,0?q=" + latitude + "," + longitude;
if (label != null && label.length() > 0) {
uri += "(" + label + ")";
String uri = "geo:0,0?q=" + marker.getPosition().latitude() + "," + marker.getPosition().longitude();
if (marker.getName() != null && !marker.getName().isEmpty()) {
uri += "(" + marker.getName() + ")";
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(uri));
@@ -45,6 +45,7 @@ import de.dennisguse.opentracks.data.models.Cadence;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.DistanceFormatter;
import de.dennisguse.opentracks.data.models.HeartRate;
import de.dennisguse.opentracks.data.models.Position;
import de.dennisguse.opentracks.data.models.Power;
import de.dennisguse.opentracks.settings.UnitSystem;
@@ -142,25 +143,8 @@ public class StringUtils {
return df.format(value);
}
/**
* Formats a coordinate
*
* @param context the context's object.
* @param coordinate the coordinate
*/
public static String formatCoordinate(Context context, double coordinate) {
return context.getString(R.string.location_coordinate, Location.convert(coordinate, Location.FORMAT_DEGREES));
}
/**
* Formats a complete coordinate (latitude, longitude)
*
* @param context the context's object.
* @param latitude the coordinate's latitude.
* @param longitude the coordinate's longitude.
*/
public static String formatCoordinate(Context context, double latitude, double longitude) {
return context.getString(R.string.location_latitude_longitude, Location.convert(latitude, Location.FORMAT_DEGREES), Location.convert(longitude, Location.FORMAT_DEGREES));
public static String formatCoordinate(Context context, Position position) {
return context.getString(R.string.location_latitude_longitude, Location.convert(position.latitude(), Location.FORMAT_DEGREES), Location.convert(position.longitude(), Location.FORMAT_DEGREES));
}
public static Pair<String, String> getHeartRateParts(Context context, HeartRate heartrate) {
@@ -1,65 +0,0 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package de.dennisguse.opentracks.util;
import android.content.Context;
import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Track;
/**
* Utilities for updating track.
*
* @author Jimmy Shih
*/
//TOOD Refactor ActivityType handling in here!
@Deprecated //TODO Refactor: all this should happen somewhere else (ContentProviderUtils?)
public class TrackUtils {
private TrackUtils() {
}
public static void updateTrack(Context context, Track track, String name, String activityTypeLocalized, String description, ContentProviderUtils contentProviderUtils) {
updateTrack(context, track, name, activityTypeLocalized, ActivityType.findByLocalizedString(context, activityTypeLocalized), description, contentProviderUtils);
}
public static void updateTrack(Context context, Track track, String name, String activityTypeLocalized, ActivityType activityType, String description, ContentProviderUtils contentProviderUtils) {
boolean update = false;
if (name != null) {
track.setName(name);
update = true;
}
if (activityTypeLocalized != null) {
track.setActivityTypeLocalized(activityTypeLocalized);
update = true;
}
if (activityType != null) {
track.setActivityType(activityType);
} else if (activityTypeLocalized != null) {
track.setActivityType(ActivityType.findByLocalizedString(context, activityTypeLocalized)
);
}
if (description != null) {
track.setDescription(description);
update = true;
}
if (update) {
contentProviderUtils.updateTrack(track);
}
}
}
@@ -265,7 +265,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder<St
TrackPoint latestTrackPoint = data.latestTrackPoint();
String value;
if (latestTrackPoint != null && latestTrackPoint.hasLocation()) {
value = StringUtils.formatCoordinate(getContext(), latestTrackPoint.getLatitude(), latestTrackPoint.getLongitude());
value = StringUtils.formatCoordinate(getContext(), latestTrackPoint.getPosition());
} else {
value = getContext().getString(R.string.value_unknown);
}
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_logo_color_108dp" />
<monochrome android:drawable="@drawable/ic_logo_color_108dp" />
</adaptive-icon>
+5 -2
View File
@@ -1,3 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_logo_color_24dp" />
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_logo_color_108dp" />
<monochrome android:drawable="@drawable/ic_logo_color_108dp" />
</adaptive-icon>
+2 -3
View File
@@ -1,7 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="108"
android:viewportHeight="108">
<group
@@ -10,7 +9,7 @@
android:translateX="22"
android:translateY="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M82.489,12.834C83.196,10.418 82.043,9.556 79.926,10.917L10.087,55.828c-2.117,1.361 -1.795,2.628 0.714,2.815L39.806,60.807c2.51,0.188 5.291,2.267 6.18,4.621l10.282,27.208c0.89,2.354 2.195,2.304 2.902,-0.111z" />
android:pathData="M85.133,20.59C85.731,18.546 84.756,17.817 82.965,18.968L23.874,56.967c-1.791,1.152 -1.519,2.224 0.604,2.382L49.019,61.18c2.124,0.159 4.477,1.918 5.229,3.91l8.7,23.021c0.753,1.992 1.857,1.949 2.455,-0.094z"
android:fillColor="#FFFFFF"></path>
</group>
</vector>
@@ -1,59 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="24.040403dp"
android:height="34dp"
android:viewportWidth="210"
android:viewportHeight="297">
<path
android:fillAlpha="0.49421525"
android:fillColor="#333333"
android:pathData="m108.528,213.298a56.035,7.006 5.281,0 0,-22.426 2.532,56.035 7.006,5.281 0,0 -0.234,0.177l-0.207,-0.024c-0.045,0.116 -0.075,0.231 -0.096,0.348a56.035,7.006 5.281,0 0,0.338 1.582c0.981,1.709 3.761,3.463 6.584,5.219l-22.744,15.5a67.065,11.557 4.228,0 0,-39.968 5.269,67.065 11.557,4.228 0,0 -0.729,0.576 67.065,11.557 4.228,0 0,-2.754 1.364,67.065 11.557,4.228 0,0 38.909,16.043l-32.177,27.065 52.228,-24.746a67.065,11.557 4.228,0 0,71.411 -3.819,67.065 11.557,4.228 0,0 0.728,-0.575 67.065,11.557 4.228,0 0,2.755 -1.364,67.065 11.557,4.228 0,0 -12.384,-10.598 40.034,5.073 5.25,0 0,0.056 -0.037,40.034 5.073,5.25 0,0 0.377,-0.343l22.452,-15.301c8.236,-0.652 17.656,-1.478 22.944,-3.01a56.035,7.006 5.281,0 0,2.655 -1.038,56.035 7.006,5.281 0,0 -46.084,-12.27 56.035,7.006 5.281,0 0,-41.636 -2.55z"
android:strokeWidth="0.138931"
android:strokeAlpha="0.265501"
android:strokeColor="#000000"
android:strokeLineCap="butt"
android:strokeLineJoin="miter" />
<path
android:pathData="M70.603,174.308 L33.024,288.947 94.567,183.195Z"
android:strokeWidth="0.264583"
android:strokeAlpha="0.265501"
android:strokeColor="#000000"
android:strokeLineCap="butt"
android:strokeLineJoin="miter">
<aapt:attr name="android:fillColor">
<gradient
android:endX="67.193245"
android:endY="217.31992"
android:startX="63.39815"
android:startY="215.52817"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FF898D8D"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#d45500"
android:fillType="evenOdd"
android:pathData="M26.293,132.603a39.974,70.319 112.028,1 0,130.371 52.747a39.974,70.319 112.028,1 0,-130.371 -52.747z"
android:strokeWidth="0.264583" />
<path
android:fillColor="#ff6600"
android:fillType="evenOdd"
android:pathData="M29.776,125.57a39.974,70.319 112.028,1 0,130.371 52.747a39.974,70.319 112.028,1 0,-130.371 -52.747z"
android:strokeWidth="0.264583" />
<path
android:fillColor="#d45500"
android:fillType="evenOdd"
android:pathData="m85.662,24.322c-0.891,8.35 2.928,17.133 6.825,25.924l-23.334,57.673 -0.731,1.806 0.249,0.101a42.43,17.361 22.028,0 0,33.304 30.101,42.43 17.361,22.028 0,0 44.865,1.526l0.139,0.056 0.245,-0.606a42.43,17.361 22.028,0 0,0.595 -1.156,42.43 17.361,22.028 0,0 0.377,-1.245l22.452,-55.493c9.29,-2.666 20.091,-6.136 24.764,-13.175z"
android:strokeWidth="0.264583" />
<path
android:fillColor="#ff6600"
android:fillType="evenOdd"
android:pathData="M86.103,23.766a23.967,59.409 112.028,1 0,110.145 44.564a23.967,59.409 112.028,1 0,-110.145 -44.564z"
android:strokeWidth="0.264583" />
</vector>
-22
View File
@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="90"
android:centerColor="@color/text_gradient_center"
android:endColor="@color/text_gradient_start"
android:startColor="@color/text_gradient_end" />
</shape>
@@ -36,7 +36,7 @@ limitations under the License.
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.viewpager.widget.ViewPager
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/maker_detail_activity_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
+23 -54
View File
@@ -13,10 +13,30 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
android:orientation="vertical"
android:paddingHorizontal="8dp">
<TextView
android:id="@+id/marker_detail_marker_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Marker Location" />
<TextView
android:id="@+id/marker_detail_marker_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Marker Category" />
<TextView
android:id="@+id/marker_detail_marker_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Marker Description" />
<ImageView
android:id="@+id/marker_detail_marker_photo"
@@ -24,55 +44,4 @@ limitations under the License.
android:layout_height="match_parent"
android:contentDescription="@string/image_photo_marker"
android:scaleType="fitCenter" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- A gradient on top of the text -->
<ImageView
android:id="@+id/marker_detail_marker_text_gradient"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha=".6"
android:contentDescription="@string/image_photo_marker"
android:src="@drawable/text_gradient" />
<LinearLayout
android:id="@+id/marker_detail_marker_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="80dp"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:id="@+id/marker_detail_marker_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?attr/textAppearanceBody1"
android:paddingTop="8dp"
tools:text="Marker Name" />
<TextView
android:id="@+id/marker_detail_marker_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?attr/textAppearanceBody2"
tools:text="Marker Category" />
<TextView
android:id="@+id/marker_detail_marker_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?attr/textAppearanceBody2"
tools:text="Marker Description" />
<TextView
android:id="@+id/marker_detail_marker_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?attr/textAppearanceBody2"
tools:text="Marker Location" />
</LinearLayout>
</FrameLayout>
</FrameLayout>
</LinearLayout>
+2 -2
View File
@@ -59,7 +59,6 @@ limitations under the License.
android:id="@+id/marker_edit_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_marker_orange_pushpin_with_shadow"
android:inputType="textCapSentences"
android:selectAllOnFocus="true" />
@@ -148,7 +147,8 @@ limitations under the License.
<Button
android:id="@+id/marker_edit_done"
style="@style/BottomButton"
android:layout_gravity="end" />
android:layout_gravity="end"
android:text="@string/generic_save" />
</LinearLayout>
</LinearLayout>
+2 -18
View File
@@ -18,23 +18,7 @@
app:layout_constraintBottom_toTopOf="@id/marker_list_item_bottom_line"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/avatars" />
<!-- A gradient on top of the text -->
<ImageView
android:id="@+id/marker_list_item_text_gradient"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha=".6"
android:contentDescription="@string/image_photo_marker"
android:src="@drawable/text_gradient"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/marker_list_item_bottom_line"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
app:layout_constraintTop_toTopOf="parent" />
<!-- Name -->
<TextView
@@ -84,7 +68,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="marker_list_item_photo,marker_list_item_text_gradient,marker_list_item_name,marker_list_item_date,marker_list_item_time_distance,marker_list_item_time" />
app:constraint_referenced_ids="marker_list_item_photo,marker_list_item_name,marker_list_item_date,marker_list_item_time_distance,marker_list_item_time" />
<!-- Bottom Line -->
<View
+95 -5
View File
@@ -14,18 +14,108 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
android:fitsSystemWindows="true"
android:orientation="vertical">
<include
android:id="@+id/fields"
layout="@layout/track_edit_fields" />
<ScrollView style="@style/ScrollView.WithBottomButtons">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<com.google.android.material.textfield.TextInputLayout
style="?attr/textInputOutlinedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:hint="@string/generic_name"
android:imeOptions="actionNext"
android:importantForAutofill="no">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/track_edit_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout
style="?attr/textInputOutlinedExposedDropdownMenuStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_weight="1"
android:imeOptions="actionNext"
android:importantForAutofill="no">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/track_edit_activity_type_localized"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:hint="@string/track_edit_activity_type_hint"
android:imeOptions="actionNext"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>
<ImageView
android:id="@+id/track_edit_activity_type_icon"
tools:src="@drawable/ic_activity_bike_24dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="bottom" />
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout
style="?attr/textInputOutlinedExposedDropdownMenuStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:imeOptions="actionNext"
android:importantForAutofill="no">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/track_edit_time_offset"
android:layout_width="match_parent"
android:inputType="none"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:hint="@string/track_edit_time_offset"
android:imeOptions="actionNext"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="?attr/textInputOutlinedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:hint="@string/generic_description"
android:imeOptions="actionNext"
android:importantForAutofill="no">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/track_edit_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>
<View style="@style/BottomButtonDivider" />
-84
View File
@@ -1,84 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/ScrollView.WithBottomButtons">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?attr/textInputOutlinedStyle"
android:hint="@string/generic_name"
android:imeOptions="actionNext"
android:importantForAutofill="no"
android:layout_marginBottom="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/track_edit_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
style="?attr/textInputOutlinedExposedDropdownMenuStyle"
android:imeOptions="actionNext"
android:importantForAutofill="no"
android:layout_marginBottom="16dp">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/track_edit_activity_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:hint="@string/track_edit_activity_type_hint"
android:imeOptions="actionNext"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>
<ImageView
android:id="@+id/track_edit_activity_type_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="bottom"
tools:src="@drawable/ic_activity_bike_24dp"/>
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?attr/textInputOutlinedStyle"
android:hint="@string/generic_description"
android:imeOptions="actionNext"
android:importantForAutofill="no"
android:layout_marginBottom="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/track_edit_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">حذف العلامة؟</string>
<string name="marker_delete_multiple_confirm_message">سيتم حذف العلامات التي تم تحديدها نهائيًا من الجهاز</string>
<string name="marker_name_format">مُحدد %1$d</string>
<string name="marker_title">%1$d‏ من‏ %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">نوع المُحدد (على سبيل المثال شلال)</string>
@@ -208,8 +207,6 @@ limitations under the License.
<string name="stats_altitude">الارتفاع</string>
<string name="stats_fastest_pace">أسرع إيقاع</string>
<string name="stats_gain">الاكتساب</string>
<string name="stats_latitude">خط العرض</string>
<string name="stats_longitude">خط الطول</string>
<string name="stats_max_speed">أقصى سرعة</string>
<string name="stats_moving_time">وقت التحرك</string>
<string name="stats_pace">الوتيرة</string>
-3
View File
@@ -117,7 +117,6 @@
<string name="marker_delete_one_confirm_title">Delete marker?</string>
<string name="marker_delete_multiple_confirm_message">The selected markers will be permanently deleted from the device</string>
<string name="marker_name_format">Marker %1$d</string>
<string name="marker_title">%1$d of %2$d</string>
<string name="marker_edit_marker_type">Marker type (e.g. waterfall)</string>
<string name="marker_list_empty_message">You don\'t have any markers</string>
<string name="menu_aggregated_statistics">Aggregated stats</string>
@@ -169,8 +168,6 @@
<string name="stats_altitude">Elevation</string>
<string name="stats_fastest_pace">Fastest pace</string>
<string name="stats_gain">Gain</string>
<string name="stats_latitude">Latitude</string>
<string name="stats_longitude">Longitude</string>
<string name="stats_max_speed">Max. speed</string>
<string name="stats_moving_time">Moving time</string>
<string name="stats_pace">Pace</string>
-3
View File
@@ -117,7 +117,6 @@
<string name="marker_delete_one_confirm_title">¿Eliminar marcador?</string>
<string name="marker_delete_multiple_confirm_message">Los marcadores seleccionados se eliminarán del dispositivo de forma permanente</string>
<string name="marker_name_format">Marcador %1$d</string>
<string name="marker_title">%1$d de %2$d</string>
<string name="marker_edit_marker_type">Tipo de marcador (p. ej., cascada)</string>
<string name="marker_list_empty_message">No tienes ningún marcador</string>
<string name="menu_aggregated_statistics">Estadíst. globales</string>
@@ -172,8 +171,6 @@
<string name="stats_altitude">Elevación</string>
<string name="stats_fastest_pace">Ritmo más rápido</string>
<string name="stats_gain">Aumento</string>
<string name="stats_latitude">Latitud</string>
<string name="stats_longitude">Longitud</string>
<string name="stats_max_speed">Velocidad máxima</string>
<string name="stats_moving_time">Tiempo en movimiento</string>
<string name="stats_pace">Ritmo</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Да се изтрие ли маркерът?</string>
<string name="marker_delete_multiple_confirm_message">Избраните маркери ще бъдат окончателно изтрити от устройството</string>
<string name="marker_name_format">Маркер %1$d</string>
<string name="marker_title">%1$d от %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Тип маркер (напр. водопад)</string>
@@ -208,8 +207,6 @@ limitations under the License.
<string name="stats_altitude">Надморска височина</string>
<string name="stats_fastest_pace">Най-бързо темпо</string>
<string name="stats_gain">Увеличаване</string>
<string name="stats_latitude">Географска ширина</string>
<string name="stats_longitude">Географска дължина</string>
<string name="stats_max_speed">Максимална скорост</string>
<string name="stats_moving_time">Време на движението</string>
<string name="stats_pace">Темпо</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Voleu suprimir el marcador?</string>
<string name="marker_delete_multiple_confirm_message">Els marcadors seleccionats se suprimiran permanentment del dispositiu</string>
<string name="marker_name_format">Marcador %1$d</string>
<string name="marker_title">%1$d de %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Tipus de marcador (p. ex. cascada)</string>
@@ -208,8 +207,6 @@ limitations under the License.
<string name="stats_altitude">Altitud</string>
<string name="stats_fastest_pace">Ritme més ràpid</string>
<string name="stats_gain">Augment</string>
<string name="stats_latitude">Latitud</string>
<string name="stats_longitude">Longitud</string>
<string name="stats_max_speed">Velocitat màxima</string>
<string name="stats_moving_time">Temps en moviment</string>
<string name="stats_pace">Ritme</string>
+3 -4
View File
@@ -147,7 +147,6 @@
<string name="marker_delete_one_confirm_title">Squassà a stantella ?</string>
<string name="marker_delete_multiple_confirm_message">E stantelle selezziunate seranu squassate ab’eternu da l’apparechju</string>
<string name="marker_name_format">Stantella %1$d</string>
<string name="marker_title">%1$d nant’à %2$d</string>
<string name="marker_list_empty_message">Ùn avete nisuna stantella</string>
<string name="menu_aggregated_statistics">Statistiche aggregate</string>
<string name="menu_edit">Mudificà</string>
@@ -460,7 +459,6 @@
<string name="settings_import_section">Impurtà</string>
<string name="settings_export_section">Espurtà</string>
<string name="settings_public_api_package_title">Nome di u pacchettu per l’API publica</string>
<string name="stats_latitude">Latitudine</string>
<string name="settings_public_api_enabled_summary_off">Solu OpenTracks pò lancià è piantà l’arregistramenti.</string>
<string name="settings_public_api_enabled_summary_on">D’altre appiecazioni installate ponu lancià o piantà l’arregistramenti.</string>
<string name="settings_prevent_reimport_tracks_title">Impedisce a reimpurtazione di tracciatu</string>
@@ -472,8 +470,6 @@
<string name="stats_average_moving_speed">Vitezza mediana in mossa</string>
<string name="stats_average_pace">Andatura mediana</string>
<string name="stats_average_speed">Vitezza mediana</string>
<string name="stats_coordinates">Latitudine è lungitudine</string>
<string name="stats_longitude">Lungitudine</string>
<string name="stats_max_speed">Vitezza massima</string>
<string name="stats_pace">Andatura</string>
<string name="stats_moving_time">Durata in mossa</string>
@@ -549,4 +545,7 @@
<string name="settings_recording_show_gps_disabled_warning_title">Avertimentu di disattivazione di u GPS</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Durante l’arregistramentu, un avertimentu hè affissatu s’è u GPS hè disattivatu.</string>
<string name="empty">viotu</string>
<string name="track_edit_time_offset">Sfarenza di u fusu orariu</string>
<string name="marker_detail_title">%1$d nant’à %2$d : %3$s</string>
<string name="stats_coordinates">Latitudine/Lungitudine</string>
</resources>
+2 -3
View File
@@ -175,7 +175,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Smazat značku?</string>
<string name="marker_delete_multiple_confirm_message">Vybrané značky budou trvale smazány ze zařízení</string>
<string name="marker_name_format">Značka %1$d</string>
<string name="marker_title">%1$d z %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Typ značky (např. vodopád)</string>
@@ -253,8 +252,6 @@ limitations under the License.
<string name="stats_altitude">Nadmořská výška</string>
<string name="stats_fastest_pace">Nejvyšší tempo</string>
<string name="stats_gain">Nárůst</string>
<string name="stats_latitude">Zeměpisná šířka</string>
<string name="stats_longitude">Zeměpisná délka</string>
<string name="stats_max_speed">Maximální rychlost</string>
<string name="stats_moving_time">Doba pohybu</string>
<string name="stats_pace">Tempo</string>
@@ -601,4 +598,6 @@ limitations under the License.
<string name="settings_chart_display_pace_or_speed_title">Zobrazit tempo nebo rychlost</string>
<string name="settings_recording_show_gps_disabled_warning_title">Varování o vypnuté poloze</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Během nahrávání zobrazit varování, pokud je vypnutá poloha.</string>
<string name="track_edit_time_offset">Posunutí časového pásma</string>
<string name="marker_detail_title">%1$d z %2$d: %3$s</string>
</resources>
-3
View File
@@ -191,7 +191,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Slet markøren\?</string>
<string name="marker_delete_multiple_confirm_message">De valgte markører slettes permanent fra enheden</string>
<string name="marker_name_format">Markør %1$d</string>
<string name="marker_title">%1$d af %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Markørtype (f.eks. vandfald)</string>
@@ -269,8 +268,6 @@ limitations under the License.
<string name="stats_altitude">Højde</string>
<string name="stats_fastest_pace">Hurtigste tempo</string>
<string name="stats_gain">Stigning</string>
<string name="stats_latitude">Breddegrad</string>
<string name="stats_longitude">Længdegrad</string>
<string name="stats_max_speed">Maks. hastighed</string>
<string name="stats_moving_time">Bevægelsestid</string>
<string name="stats_pace">Tempo</string>
+1 -3
View File
@@ -193,7 +193,6 @@ Meldet das GPS-Gerät ungenaue Daten (z.B. Standort, Geschwindigkeit, Höhe), ka
<string name="marker_delete_one_confirm_title">Markierung löschen?</string>
<string name="marker_delete_multiple_confirm_message">Die ausgewählten Markierungen werden endgültig vom Gerät gelöscht</string>
<string name="marker_name_format">%1$d. Markierung</string>
<string name="marker_title">%1$d von %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Art der Markierung, z. B. Wasserfall</string>
@@ -274,8 +273,6 @@ Meldet das GPS-Gerät ungenaue Daten (z.B. Standort, Geschwindigkeit, Höhe), ka
<string name="stats_altitude">Höhe</string>
<string name="stats_fastest_pace">Schnellstes Tempo</string>
<string name="stats_gain">Anstieg</string>
<string name="stats_latitude">Breitengrad</string>
<string name="stats_longitude">Längengrad</string>
<string name="stats_max_speed">Max. Geschwindigkeit</string>
<string name="stats_moving_time">Bewegungszeit</string>
<string name="stats_pace">Tempo</string>
@@ -654,4 +651,5 @@ Meldet das GPS-Gerät ungenaue Daten (z.B. Standort, Geschwindigkeit, Höhe), ka
<string name="settings_recording_show_gps_disabled_warning_title">Warnung „GPS deaktiviert“</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Während der Aufzeichnung eine Warnung anzeigen, wenn GPS deaktiviert ist.</string>
<string name="empty">leer</string>
<string name="track_edit_time_offset">Zeitzonenverschiebung</string>
</resources>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Διαγραφή δείκτη;</string>
<string name="marker_delete_multiple_confirm_message">Οι επιλεγμένοι δείκτες θα διαγραφούν οριστικά από τη συσκευή</string>
<string name="marker_name_format">Σήμανση %1$d</string>
<string name="marker_title">%1$d από %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Τύπος σήμανσης (π.χ. καταρράκτης)</string>
@@ -206,8 +205,6 @@ limitations under the License.
<string name="stats_altitude">Υψόμετρο</string>
<string name="stats_fastest_pace">Ταχύτερος ρυθμός</string>
<string name="stats_gain">Αύξηση</string>
<string name="stats_latitude">Γεωγραφικό πλάτος</string>
<string name="stats_longitude">Γεωγραφικό μήκος</string>
<string name="stats_max_speed">Μέγιστη ταχύτητα</string>
<string name="stats_moving_time">Διάρκεια κίνησης</string>
<string name="stats_pace">Ρυθμός</string>
-3
View File
@@ -191,7 +191,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">¿Eliminar marcador?</string>
<string name="marker_delete_multiple_confirm_message">Los marcadores seleccionados se eliminarán del dispositivo de forma permanente</string>
<string name="marker_name_format">Marcador %1$d</string>
<string name="marker_title">%1$d de %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Tipo de marcador (p. ej., cascada)</string>
@@ -269,8 +268,6 @@ limitations under the License.
<string name="stats_altitude">Elevación</string>
<string name="stats_fastest_pace">Ritmo más rápido</string>
<string name="stats_gain">Aumento</string>
<string name="stats_latitude">Latitud</string>
<string name="stats_longitude">Longitud</string>
<string name="stats_max_speed">Velocidad máxima</string>
<string name="stats_moving_time">Tiempo en movimiento</string>
<string name="stats_pace">Ritmo</string>
-3
View File
@@ -191,7 +191,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Kas kustutada märgis\?</string>
<string name="marker_delete_multiple_confirm_message">Valitud märgis kustutatakse seadmest jäädavalt</string>
<string name="marker_name_format">Märgis %1$d</string>
<string name="marker_title">%1$d/%2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Märgise tüüp (nt juga)</string>
@@ -269,8 +268,6 @@ limitations under the License.
<string name="stats_altitude">Kõrgus</string>
<string name="stats_fastest_pace">Kiireim tempo</string>
<string name="stats_gain">Saavutatud</string>
<string name="stats_latitude">Laiuskraad</string>
<string name="stats_longitude">Pikkuskraad</string>
<string name="stats_max_speed">Max kiirus</string>
<string name="stats_moving_time">Liikumisaeg</string>
<string name="stats_pace">Tempo</string>
-3
View File
@@ -193,7 +193,6 @@ GPS gailuak datu okerrak salatzen baditu (adibidez, kokapena, abiadura, kota), O
<string name="marker_delete_one_confirm_title">Markatzailea ezabatu nahi duzu?</string>
<string name="marker_delete_multiple_confirm_message">Hautatutako markatzaileak behin betiko ezabatuko dira gailutik</string>
<string name="marker_name_format">%1$d markatzailea</string>
<string name="marker_title">%1$d/%2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Markatzaile mota (adibidez, ur-jauzia)</string>
@@ -271,8 +270,6 @@ GPS gailuak datu okerrak salatzen baditu (adibidez, kokapena, abiadura, kota), O
<string name="stats_altitude">Altitudea</string>
<string name="stats_fastest_pace">Pauso-erritmorik bizkorrena</string>
<string name="stats_gain">Igoera</string>
<string name="stats_latitude">Latitudea</string>
<string name="stats_longitude">Longitudea</string>
<string name="stats_max_speed">Gehienezko abiadura</string>
<string name="stats_moving_time">Abian emandako denbora</string>
<string name="stats_pace">Pauso-erritmoa</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">نشانگر حذف شود؟</string>
<string name="marker_delete_multiple_confirm_message">نشانگرهای انتخاب شده برای همیشه از دستگاه حذف خواهد شد</string>
<string name="marker_name_format">نشانگر %1$d</string>
<string name="marker_title">%1$d از %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">نوع نشانگر (برای مثال آبشار)</string>
@@ -206,8 +205,6 @@ limitations under the License.
<string name="stats_altitude">ارتفاع</string>
<string name="stats_fastest_pace">سریع‌ترین تندی</string>
<string name="stats_gain">افزایش</string>
<string name="stats_latitude">عرض جغرافیایی</string>
<string name="stats_longitude">طول جغرافیایی</string>
<string name="stats_max_speed">حداکثر سرعت</string>
<string name="stats_moving_time">زمان حرکت</string>
<string name="stats_pace">تندی</string>
-3
View File
@@ -194,7 +194,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Poistetaanko merkki?</string>
<string name="marker_delete_multiple_confirm_message">Valitut merkit poistetaan laitteesta pysyvästi</string>
<string name="marker_name_format">Merkki %1$d</string>
<string name="marker_title">%1$d/%2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Merkin tyyppi (esim. vesiputous)</string>
@@ -274,8 +273,6 @@ limitations under the License.
<string name="stats_altitude">Korkeus</string>
<string name="stats_fastest_pace">Nopein vauhti</string>
<string name="stats_gain">Kaltevuus</string>
<string name="stats_latitude">Leveysaste</string>
<string name="stats_longitude">Pituusaste</string>
<string name="stats_max_speed">Enimmäisnopeus</string>
<string name="stats_moving_time">Liikkumisaika</string>
<string name="stats_pace">Vauhti</string>
-3
View File
@@ -117,7 +117,6 @@
<string name="marker_delete_one_confirm_title">Supprimer le repère?</string>
<string name="marker_delete_multiple_confirm_message">Les repères sélectionnés seront définitivement supprimés de l\'appareil</string>
<string name="marker_name_format">Repère %1$d</string>
<string name="marker_title">%1$d sur %2$d</string>
<string name="marker_edit_marker_type">Type de repère (p. ex. : cascade)</string>
<string name="marker_list_empty_message">Vous n\'avez aucun repère</string>
<string name="menu_aggregated_statistics">Statistiques cumulées</string>
@@ -168,8 +167,6 @@
<string name="stats_altitude">Élévation</string>
<string name="stats_fastest_pace">Allure la plus rapide</string>
<string name="stats_gain">Gain</string>
<string name="stats_latitude">Latitude</string>
<string name="stats_longitude">Longitude</string>
<string name="stats_max_speed">Vitesse maximale</string>
<string name="stats_moving_time">Durée de déplacement</string>
<string name="stats_pace">Allure</string>
-3
View File
@@ -117,7 +117,6 @@
<string name="marker_delete_one_confirm_title">Supprimer le repère ?</string>
<string name="marker_delete_multiple_confirm_message">Les repères sélectionnés vont être définitivement supprimés de l\'appareil.</string>
<string name="marker_name_format">Repère %1$d</string>
<string name="marker_title">%1$d sur %2$d</string>
<string name="marker_edit_marker_type">Type de repère (exemple : cascade)</string>
<string name="marker_list_empty_message">Vous n\'avez aucun repère.</string>
<string name="menu_aggregated_statistics">Statistiques cumulées</string>
@@ -170,8 +169,6 @@
<string name="stats_altitude">Altitude</string>
<string name="stats_fastest_pace">Allure la plus rapide</string>
<string name="stats_gain">Dénivelé positif</string>
<string name="stats_latitude">Latitude</string>
<string name="stats_longitude">Longitude</string>
<string name="stats_max_speed">Vitesse max.</string>
<string name="stats_moving_time">Durée en déplacement</string>
<string name="stats_pace">Allure</string>
+2 -3
View File
@@ -193,7 +193,6 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="marker_delete_one_confirm_title">Supprimer le repère ?</string>
<string name="marker_delete_multiple_confirm_message">Les repères sélectionnés vont être définitivement supprimés de l\'appareil</string>
<string name="marker_name_format">Repère %1$d</string>
<string name="marker_title">%1$d sur %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Type de repère (exemple : cascade)</string>
@@ -271,8 +270,6 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="stats_altitude">Altitude</string>
<string name="stats_fastest_pace">Allure la plus rapide</string>
<string name="stats_gain">Dénivelé positif</string>
<string name="stats_latitude">Latitude</string>
<string name="stats_longitude">Longitude</string>
<string name="stats_max_speed">Vitesse max</string>
<string name="stats_moving_time">Durée en déplacement</string>
<string name="stats_pace">Allure</string>
@@ -674,4 +671,6 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="settings_recording_show_gps_disabled_warning_title">Alerte GPS désactivée</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Pendant l\'enregistrement, afficher un avertissement si le GPS est désactivé.</string>
<string name="empty">vide</string>
<string name="marker_detail_title">%1$d de %2$d: %3$s</string>
<string name="track_edit_time_offset">Décalage de fuseau horaire</string>
</resources>
+1 -4
View File
@@ -163,7 +163,6 @@
<string name="marker_delete_one_confirm_title">Scrios an marcóir\?</string>
<string name="marker_delete_multiple_confirm_message">Scriosfar na marcóirí roghnaithe go buan ón bhfeiste</string>
<string name="marker_name_format">Marcóir %1$d</string>
<string name="marker_title">%1$d de %2$d</string>
<string name="marker_edit_marker_type">Cineál marcóra (m.sh. eas)</string>
<string name="menu_aggregated_statistics">Staitisticí comhiomlána</string>
<string name="menu_delete">Scrios</string>
@@ -269,7 +268,6 @@
<string name="stats_fastest_pace">An luas is tapúla</string>
<string name="stats_gain">Gnóthachan</string>
<string name="stats_loss">Caillteanas</string>
<string name="stats_latitude">Domhanleithead</string>
<string name="stats_moving_time">Am ag bogadh</string>
<string name="stats_pace">Luas</string>
<string name="stats_speed">Luas</string>
@@ -355,8 +353,6 @@
<string name="help_support_content">You can: \n a) spread the word about OpenTracks, \n b) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">propose features</a>, \nc) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">report bugs</a>, \n d) help in software development, \n e) buy in <a href="https://play.google.com/store/apps/details?id=de.dennisguse.opentracks.playstore">Google Play Store</a>, \n f) donate, and \n g) do whatever you think helps OpenTracks.</string>
<string name="settings_public_api_disabled_toast">Tá OpenTracks Public API díchumasaithe: is féidir é a chumasú sna socruithe.</string>
<string name="stats_altitude">Airde</string>
<string name="stats_coordinates">Domhanleithead/Domhanfhad</string>
<string name="stats_longitude">Domhanfhad</string>
<string name="stats_max_speed">Luas uasta</string>
<string name="stats_distance">Fad</string>
<string name="stats_split_interval">Eatramh scoilte</string>
@@ -552,4 +548,5 @@
<string name="settings_chart_display_heart_rate_title">Taispeáin ráta croí</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Agus tú ag taifeadadh, taispeáin rabhadh má tá GPS díchumasaithe.</string>
<string name="settings_recording_show_gps_disabled_warning_title">Rabhadh GPS díchumasaithe</string>
<string name="track_edit_time_offset">Fritháireamh Crios Ama</string>
</resources>
+3 -3
View File
@@ -181,7 +181,6 @@ Se o GPS informa sobre datos pouco precisos (ex.: localización, velocidade, ele
<string name="marker_delete_one_confirm_title">Eliminar o marcador?</string>
<string name="marker_delete_multiple_confirm_message">Os marcadores seleccionados eliminaranse permanentemente do dispositivo</string>
<string name="marker_name_format">Marcador %1$d</string>
<string name="marker_title">%1$d de %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Tipo de marcador (por exemplo, fervenza)</string>
@@ -263,8 +262,6 @@ Se o GPS informa sobre datos pouco precisos (ex.: localización, velocidade, ele
<string name="stats_altitude">Elevación</string>
<string name="stats_fastest_pace">Ritmo máis rápido</string>
<string name="stats_gain">Desnivel</string>
<string name="stats_latitude">Latitude</string>
<string name="stats_longitude">Lonxitude</string>
<string name="stats_max_speed">Velocidade máxima</string>
<string name="stats_moving_time">Tempo en movemento</string>
<string name="stats_pace">Ritmo</string>
@@ -601,4 +598,7 @@ Se o GPS informa sobre datos pouco precisos (ex.: localización, velocidade, ele
<string name="settings_charts_title">Gráficos</string>
<string name="settings_recording_show_gps_disabled_warning_title">Aviso do GPS desactivado</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Ao gravar, mostrar aviso se o GPS está desactivado.</string>
<string name="empty">baleiro</string>
<string name="marker_detail_title">%1$d de %2$d: %3$s</string>
<string name="track_edit_time_offset">Diferenza de Zona horaria</string>
</resources>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">मार्कर हटाएं?</string>
<string name="marker_delete_multiple_confirm_message">चयनित मार्कर उपकरण से स्थायी रूप से हटा दिए जाएंगे</string>
<string name="marker_name_format">मार्कर %1$d</string>
<string name="marker_title">%2$d में से %1$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">मार्कर प्रकार (उदा., झरना)</string>
@@ -206,8 +205,6 @@ limitations under the License.
<string name="stats_altitude">ऊंचाई</string>
<string name="stats_fastest_pace">सबसे तेज चाल</string>
<string name="stats_gain">वृद्धि</string>
<string name="stats_latitude">अक्षांश</string>
<string name="stats_longitude">देशांतर</string>
<string name="stats_max_speed">अधिकतम गति</string>
<string name="stats_moving_time">चलते रहने का समय</string>
<string name="stats_pace">चाल</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Želite li izbrisati oznaku?</string>
<string name="marker_delete_multiple_confirm_message">Odabrane oznake trajno će se izbrisati s uređaja</string>
<string name="marker_name_format">Oznaka %1$d</string>
<string name="marker_title">%1$d od %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Vrsta oznake (npr. vodopad)</string>
@@ -208,8 +207,6 @@ limitations under the License.
<string name="stats_altitude">Visina</string>
<string name="stats_fastest_pace">Najbrži tempo</string>
<string name="stats_gain">Povećanje</string>
<string name="stats_latitude">Geografska širina</string>
<string name="stats_longitude">Geografska duljina</string>
<string name="stats_max_speed">Maks. brzina</string>
<string name="stats_moving_time">Vrijeme kretanja</string>
<string name="stats_pace">Tempo</string>
+2 -3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Törli a jelölőt?</string>
<string name="marker_delete_multiple_confirm_message">A kiválasztott jelölők véglegesen törlődnek az eszközről</string>
<string name="marker_name_format">%1$d. jelölő</string>
<string name="marker_title">%1$d/%2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Jelölő típusa (pl. vízesés)</string>
@@ -208,8 +207,6 @@ limitations under the License.
<string name="stats_altitude">Magasság</string>
<string name="stats_fastest_pace">Leggyorsabb tempó</string>
<string name="stats_gain">Növekedés</string>
<string name="stats_latitude">Földrajzi szélesség</string>
<string name="stats_longitude">Földrajzi hosszúság</string>
<string name="stats_max_speed">Max. sebesség</string>
<string name="stats_moving_time">Mozgási idő</string>
<string name="stats_pace">Tempó</string>
@@ -596,4 +593,6 @@ limitations under the License.
<string name="empty">üres</string>
<string name="settings_recording_show_gps_disabled_warning_title">GPS letiltott figyelmeztetés</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Felvétel közben egy figyelmeztetés jelenik meg, ha a GPS ki van kapcsolva.</string>
<string name="track_edit_time_offset">Időzóna eltolódás</string>
<string name="marker_detail_title">%1$d %2$d-ból/ből %3$s</string>
</resources>
-3
View File
@@ -117,7 +117,6 @@
<string name="marker_delete_one_confirm_title">Hapus penanda?</string>
<string name="marker_delete_multiple_confirm_message">Penanda yang dipilih akan dihapus secara permanen dari perangkat</string>
<string name="marker_name_format">Penanda %1$d</string>
<string name="marker_title">%1$d dari %2$d</string>
<string name="marker_edit_marker_type">Jenis penanda (misal: air terjun)</string>
<string name="marker_list_empty_message">Anda tidak memiliki penanda</string>
<string name="menu_aggregated_statistics">Statistik agregat</string>
@@ -170,8 +169,6 @@
<string name="stats_altitude">Ketinggian</string>
<string name="stats_fastest_pace">Laju tercepat</string>
<string name="stats_gain">Perolehan</string>
<string name="stats_latitude">Lintang</string>
<string name="stats_longitude">Bujur</string>
<string name="stats_max_speed">Kecepatan maks</string>
<string name="stats_moving_time">Waktu pergerakan</string>
<string name="stats_pace">Laju</string>
-3
View File
@@ -179,7 +179,6 @@ Infatti, un\'applicazione deve supportare <i>ACTION_VIEW</i> con MIME <i>applica
<string name="marker_delete_one_confirm_title">Eliminare indicatore?</string>
<string name="marker_delete_multiple_confirm_message">Gli indicatori selezionati verranno eliminati definitivamente dal dispositivo</string>
<string name="marker_name_format">Indicatore %1$d</string>
<string name="marker_title">%1$d di %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Tipo di indicatore (ad es. cascata)</string>
@@ -246,8 +245,6 @@ Infatti, un\'applicazione deve supportare <i>ACTION_VIEW</i> con MIME <i>applica
<string name="stats_altitude">Altitudine</string>
<string name="stats_fastest_pace">Ritmo più veloce</string>
<string name="stats_gain">Salita</string>
<string name="stats_latitude">Latitudine</string>
<string name="stats_longitude">Longitude</string>
<string name="stats_max_speed">Velocità massima</string>
<string name="stats_moving_time">Tempo in movimento</string>
<string name="stats_pace">Ritmo</string>
-3
View File
@@ -117,7 +117,6 @@
<string name="marker_delete_one_confirm_title">למחוק את הסמן?</string>
<string name="marker_delete_multiple_confirm_message">הסמנים שנבחרו יימחקו לצמיתות מהמכשיר</string>
<string name="marker_name_format">סמן %1$d</string>
<string name="marker_title">%1$d מתוך %2$d משימות</string>
<string name="marker_edit_marker_type">סוג סמן (כגון מפל)</string>
<string name="marker_list_empty_message">אין לך סמנים</string>
<string name="menu_aggregated_statistics">סטטיסטיקה מצטברת</string>
@@ -168,8 +167,6 @@
<string name="stats_altitude">גובה</string>
<string name="stats_fastest_pace">הקצב המהיר ביותר</string>
<string name="stats_gain">תוספת</string>
<string name="stats_latitude">קו רוחב</string>
<string name="stats_longitude">קו אורך</string>
<string name="stats_max_speed">מהירות מקסימלית</string>
<string name="stats_moving_time">זמן תנועה</string>
<string name="stats_pace">קצב</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">マーカーを削除しますか?</string>
<string name="marker_delete_multiple_confirm_message">選択したマーカーが端末から完全に削除されます</string>
<string name="marker_name_format">マーカー%1$d</string>
<string name="marker_title">%1$d/%2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">マーカーの種類(例: 滝)</string>
@@ -206,8 +205,6 @@ limitations under the License.
<string name="stats_altitude">標高</string>
<string name="stats_fastest_pace">最速ペース</string>
<string name="stats_gain">増加</string>
<string name="stats_latitude">緯度</string>
<string name="stats_longitude">経度</string>
<string name="stats_max_speed">最大速度</string>
<string name="stats_moving_time">移動時間</string>
<string name="stats_pace">ペース</string>
-4
View File
@@ -205,7 +205,6 @@
<string name="marker_delete_one_confirm_title">ಮಾರ್ಕರ್ ಅಳಿಸುವುದೇ?</string>
<string name="marker_delete_multiple_confirm_message">ಆಯ್ಕೆಮಾಡಿದ ಗುರುತುಗಳನ್ನು ಸಾಧನದಿಂದ ಶಾಶ್ವತವಾಗಿ ಅಳಿಸಲಾಗುತ್ತದೆ</string>
<string name="marker_name_format">ಮಾರ್ಕರ್ %1$d</string>
<string name="marker_title">%2$d ರಲ್ಲಿ %1$d</string>
<string name="marker_edit_marker_type">ಮಾರ್ಕರ್ ಪ್ರಕಾರ (ಉದಾ. ಜಲಪಾತ)</string>
<string name="marker_list_empty_message">ನೀವು ಯಾವುದೇ ಮಾರ್ಕರ್‌ಗಳನ್ನು ಹೊಂದಿಲ್ಲ</string>
<string name="menu_aggregated_statistics">ಒಟ್ಟು ಅಂಕಿಅಂಶಗಳು</string>
@@ -348,9 +347,6 @@
<string name="stats_fastest_pace">ಅತಿ ವೇಗದ ಗತಿ</string>
<string name="stats_gain">ಗಳಿಕೆ</string>
<string name="stats_loss">ನಷ್ಟ</string>
<string name="stats_coordinates">ಅಕ್ಷಾಂಶ/ರೇಖಾಂಶ</string>
<string name="stats_latitude">ಅಕ್ಷಾಂಶ</string>
<string name="stats_longitude">ರೇಖಾಂಶ</string>
<string name="stats_max_speed">ಗರಿಷ್ಠ ವೇಗ</string>
<string name="stats_moving_time">ಚಲನೆಯ ಸಮಯ</string>
<string name="stats_pace">ಗತಿ</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">마커를 삭제하시겠습니까?</string>
<string name="marker_delete_multiple_confirm_message">선택한 마커가 기기에서 영구적으로 삭제됩니다.</string>
<string name="marker_name_format">아이콘 %1$d</string>
<string name="marker_title">%2$d개 중 %1$d개</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">아이콘 유형(예: 폭포)</string>
@@ -206,8 +205,6 @@ limitations under the License.
<string name="stats_altitude">고도</string>
<string name="stats_fastest_pace">최고 속도</string>
<string name="stats_gain">등락</string>
<string name="stats_latitude">위도</string>
<string name="stats_longitude">경도</string>
<string name="stats_max_speed">최고 속도</string>
<string name="stats_moving_time">이동 시간</string>
<string name="stats_pace">속도</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Ištrinti žymeklį?</string>
<string name="marker_delete_multiple_confirm_message">Pasirinkti žymekliai bus visam laikui ištrinti iš įrenginio</string>
<string name="marker_name_format">Žymeklis %1$d</string>
<string name="marker_title">%1$d iš %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Žymeklio tipas (pvz., krioklys)</string>
@@ -208,8 +207,6 @@ limitations under the License.
<string name="stats_altitude">Pakilimas</string>
<string name="stats_fastest_pace">Greičiausias tempas</string>
<string name="stats_gain">Pelnas</string>
<string name="stats_latitude">Platuma</string>
<string name="stats_longitude">Ilguma</string>
<string name="stats_max_speed">Maks. greitis</string>
<string name="stats_moving_time">Judėjimo trukmė</string>
<string name="stats_pace">Tempas</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Vai dzēst atzīmi?</string>
<string name="marker_delete_multiple_confirm_message">Atlasītās atzīmes tiks neatgriezeniski dzēstas no ierīces</string>
<string name="marker_name_format">Marķieris %1$d</string>
<string name="marker_title">%1$d no %2$d atzīmes(-ēm)</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Marķiera veids (piemēram, ūdenskritums)</string>
@@ -208,8 +207,6 @@ limitations under the License.
<string name="stats_altitude">Pacēlums</string>
<string name="stats_fastest_pace">Ātrākais temps</string>
<string name="stats_gain">Pieaugums</string>
<string name="stats_latitude">Platums</string>
<string name="stats_longitude">Garums</string>
<string name="stats_max_speed">Maks. ātrums</string>
<string name="stats_moving_time">Pārvietošanās laiks</string>
<string name="stats_pace">Temps</string>
-3
View File
@@ -117,7 +117,6 @@
<string name="marker_delete_one_confirm_title">Ștergeți marcatorul?</string>
<string name="marker_delete_multiple_confirm_message">Marcatorii selectați vor fi șterși definitiv de pe dispozitiv</string>
<string name="marker_name_format">Marcator %1$d</string>
<string name="marker_title">%1$d din %2$d</string>
<string name="marker_edit_marker_type">Tip de marcator (de exemplu: cascadă)</string>
<string name="marker_list_empty_message">Nu aveți niciun marcator</string>
<string name="menu_aggregated_statistics">Statistici cumulate</string>
@@ -168,8 +167,6 @@
<string name="stats_altitude">Altitudinea</string>
<string name="stats_fastest_pace">Cel mai rapid ritm</string>
<string name="stats_gain">Creștere</string>
<string name="stats_latitude">Latitudinea</string>
<string name="stats_longitude">Longitudinea</string>
<string name="stats_max_speed">Viteza maximă</string>
<string name="stats_moving_time">Durata deplasării</string>
<string name="stats_pace">Ritmul</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Padamkan penanda?</string>
<string name="marker_delete_multiple_confirm_message">Penanda yang dipilih akan dipadamkan terus dari peranti</string>
<string name="marker_name_format">Penanda %1$d</string>
<string name="marker_title">%1$d daripada %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Jenis penanda (mis. air terjun)</string>
@@ -207,8 +206,6 @@ limitations under the License.
<string name="stats_altitude">Ketinggian</string>
<string name="stats_fastest_pace">Langkah paling cepat</string>
<string name="stats_gain">Pertambahan</string>
<string name="stats_latitude">Latitud</string>
<string name="stats_longitude">Longitud</string>
<string name="stats_max_speed">Kelajuan maks</string>
<string name="stats_moving_time">Masa bergerak</string>
<string name="stats_pace">Langkah</string>
-3
View File
@@ -141,7 +141,6 @@ limitations under the License.
<string name="marker_delete_one_confirm_title">Slett markøren\?</string>
<string name="marker_delete_multiple_confirm_message">De valgte markørene blir slettet fra enheten for godt</string>
<string name="marker_name_format">Markør %1$d</string>
<string name="marker_title">%1$d av %2$d</string>
<!-- Marker Detail -->
<!-- Marker Edit -->
<string name="marker_edit_marker_type">Markørtype (f.eks. foss)</string>
@@ -206,8 +205,6 @@ limitations under the License.
<string name="stats_altitude">Høyde</string>
<string name="stats_fastest_pace">Raskeste tempo</string>
<string name="stats_gain">Total stigning</string>
<string name="stats_latitude">Breddegrad</string>
<string name="stats_longitude">Lengdegrad</string>
<string name="stats_max_speed">Maks. hastighet</string>
<string name="stats_moving_time">Forflytningstid</string>
<string name="stats_pace">Tempo</string>
@@ -1,38 +0,0 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="OpenTracksTheme" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Material3 tech documentation; https://github.com/material-components/material-components-android/blob/master/docs/components/ -->
<item name="colorPrimary">@color/opentracks</item>
<item name="colorSecondary">@color/opentracks</item>
<!-- Material3 https://github.com/material-components/material-components-android/issues/2828#issuecomment-1187563903 -->
<item name="switchPreferenceCompatStyle">@style/MaterialSwitchPreferenceCompat</item>
<item name="android:statusBarColor">@color/oled_friendly</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:navigationBarColor">@color/oled_friendly</item>
<item name="bottomAppBarStyle">@style/Widget.OpenTracks.BottomAppBar</item>
<item name="floatingActionButtonStyle">@style/Widget.OpenTracks.FloatingActionButton</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="SplashTheme" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_logo_color_108dp</item>
<item name="postSplashScreenTheme">@style/OpenTracksTheme</item>
</style>
<style name="Widget.OpenTracks.BottomAppBar" parent="Widget.Material3.BottomAppBar">
<item name="materialThemeOverlay">@style/ThemeOverlay.OpenTracks.BottomAppBar</item>
</style>
<style name="ThemeOverlay.OpenTracks.BottomAppBar" parent="">
<item name="colorPrimary">@color/oled_friendly</item>
</style>
</resources>

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