Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 23f47f10f8 | |||
| 251fa17487 | |||
| bae3373fe9 | |||
| 0a685a66e3 | |||
| 5ca9ca857a | |||
| d9dfa6d746 | |||
| 3a5220546e | |||
| 047d5c2340 | |||
| 725c21c0a1 | |||
| 7939e39fc1 | |||
| a133bd8f9e | |||
| 1f9790cba8 | |||
| a3ba1e1490 | |||
| accb30152f | |||
| dc7daa6e8c | |||
| 1d8e788d53 | |||
| 568b908b26 | |||
| 3ab63adb34 | |||
| 91692f345e | |||
| dbdb98a682 | |||
| df66cd5753 | |||
| 6e39dd37f8 | |||
| 7212f7be94 | |||
| 77fe494e6c | |||
| 2f491e8c10 | |||
| f4fe7b1ab3 | |||
| 7e444cbf31 | |||
| ed6ab9c53c | |||
| f91ca3154c | |||
| bbfab1b201 | |||
| 1f2e3bcf70 | |||
| d1f3791f97 | |||
| 490b95a001 | |||
| 12e6f03098 | |||
| d86f42e2e9 | |||
| 360d59d3de | |||
| b617420290 | |||
| 53b267150b | |||
| 0dfd55ed52 | |||
| daabd5381d | |||
| a842129e37 | |||
| e8b9c2bbc3 | |||
| e55924dae3 | |||
| e3a8143d58 | |||
| 30310bb874 | |||
| 9f377b172d |
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
||||
@@ -51,13 +51,19 @@ _OpenTracks_ is a sport tracking application that completely respects your priva
|
||||
__Only required permissions:__
|
||||
* _ACCESS_FINE_LOCATION_: required to use the GPS.
|
||||
|
||||
An overview of Bluetooth LE sensors that are known to work with OpenTracks is in [README_TESTED_SENSORS.md](README_TESTED_SENSORS.md).
|
||||
|
||||
_Please note:_
|
||||
_OpenTracks_ does not contain a _map_ (as this would required Internet access).
|
||||
To show your tracks on a map, a 3rd party application (e.g., [OsmAnd](https://play.google.com/store/apps/details?id=net.osmand) or [MAPS.ME](https://play.google.com/store/apps/details?id=com.mapswithme.maps.pro)) needs to be installed.
|
||||
|
||||
## Custom Dashboards
|
||||
## Custom Dashboards (incl. Map)
|
||||
As of v3.3.1 OpenTracks enables to use custom dashboards.
|
||||
The reference implementation is [OSMDashboard](https://github.com/OpenTracksApp/OSMDashboard), which presents an OpenStreetMap map (showing the current track, incl. updates).
|
||||
The developer documentation is in [README_API.md](README_API.md).
|
||||
|
||||
Alternatively, recorded tracks can be shared as KMZ/GPX to installed applications (e.g., [OsmAnd](https://play.google.com/store/apps/details?id=net.osmand) or [MAPS.ME](https://play.google.com/store/apps/details?id=com.mapswithme.maps.pro)).
|
||||
However, this is rather slow and does not provide updates while recording.
|
||||
|
||||
|
||||
## Screenshots
|
||||
<div>
|
||||
@@ -87,7 +93,7 @@ Rework of _OpenTracks_ included:
|
||||
* removing calorie estimation and activity estimation,
|
||||
* removing support for ANT+ and Classic Bluetooth,
|
||||
* adding support for Bluetooth LE heart rate sensors,
|
||||
* removing Protobuf (store sensor data in SQLite columns directly), and
|
||||
* removing Protobuf (store sensosensorr data in SQLite columns directly), and
|
||||
* removing Android Service API for other apps.
|
||||
|
||||
Artwork, logos and user interface remained more or less unchanged.
|
||||
|
||||
@@ -7,9 +7,6 @@ Although this might be (mostly) sufficient, it has some limitations.
|
||||
This include limited configurability (e.g., ordering of shown elements) and the lack of Internet access.
|
||||
In fact, the later is considered a feature but severely limits the implementation presenting a map (at least in an easy way).
|
||||
|
||||
_NOTE:_ for showing a track on a map a workaround was implemented in OpenTracks.
|
||||
Data could be exported as KMZ and presented in 3rd-party application (e.g., [OsmAnd](https://play.google.com/store/apps/details?id=net.osmand) or [MAPS.ME](https://play.google.com/store/apps/details?id=com.mapswithme.maps.pro)).
|
||||
|
||||
For the time being, the OpenTracks Data API can be used to implement mainly custom dashboards.
|
||||
|
||||
## Implementation
|
||||
@@ -0,0 +1,20 @@
|
||||
# Overview of tested Bluetooth LE sensors
|
||||
|
||||
## HRS: Heartrate Service
|
||||
* Decathlon|Geonaute|Kalenji Dual HRM Belt
|
||||
* Polar H7
|
||||
* Polar OH1
|
||||
Has updatable firmware that requires a user account at polar.com
|
||||
* Wahoo Tickr (Model: WFBTHR02)
|
||||
|
||||
## CSCP: Cycling Cadence and Speed Service
|
||||
Please note that the according to the specification these sensors _may_ provide speed as well as cadence.
|
||||
However, often only one value is provided.
|
||||
|
||||
### Speed
|
||||
* Wahoo Speed (Model: WFRPMSPD)
|
||||
|
||||
### Cadence
|
||||
* Wahoo Cadence (Model: WFPODCAD2)
|
||||
This sensor reports cadence data as speed.
|
||||
A workaround is in place.
|
||||
@@ -6,7 +6,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.2'
|
||||
classpath 'com.android.tools.build:gradle:4.0.0'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,25 +50,30 @@ def getVersionName = { ->
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
compileSdkVersion 30
|
||||
|
||||
defaultConfig {
|
||||
applicationId "de.dennisguse.opentracks"
|
||||
manifestPlaceholders = [
|
||||
applicationLogo: "@drawable/ic_logo_color_24dp",
|
||||
applicationLogo: "@mipmap/ic_launcher",
|
||||
applicationName: "@string/app_name"
|
||||
]
|
||||
|
||||
versionCode 3381
|
||||
versionCode 3427
|
||||
//versionCode getVersionCode() //Useful for debugging.
|
||||
versionName "v3.7.2"
|
||||
versionName "v3.7.5"
|
||||
|
||||
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
|
||||
|
||||
|
||||
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
targetSdkVersion 30
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -78,7 +83,7 @@ android {
|
||||
applicationIdSuffix ".debug"
|
||||
versionNameSuffix "-debug"
|
||||
manifestPlaceholders = [
|
||||
applicationLogo: "@drawable/ic_logo_black_24dp",
|
||||
applicationLogo: "@mipmap/ic_launcher_debug",
|
||||
applicationName: "OpenTracks (Debug)"
|
||||
]
|
||||
}
|
||||
@@ -100,8 +105,10 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.preference:preference:1.1.0'
|
||||
implementation 'androidx.preference:preference:1.1.1'
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
|
||||
|
||||
androidTestImplementation 'androidx.test:core:1.2.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
@@ -113,5 +120,4 @@ dependencies {
|
||||
|
||||
testImplementation 'androidx.test:core:1.2.0'
|
||||
testImplementation 'org.mockito:mockito-core:3.0.0'
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
}
|
||||
|
||||
@@ -9,23 +9,34 @@ from every activity showing a menu.
|
||||
endlegend
|
||||
|
||||
[*] --> TrackListActivity
|
||||
TrackListActivity --> TrackDetailActivity : Start recording
|
||||
TrackListActivity --> TrackRecordingActivity : Start recording
|
||||
TrackListActivity --> SearchListActivity
|
||||
TrackListActivity --> MarkerListActivity : Show all markers
|
||||
TrackListActivity --> TrackDetailActivity : Show track
|
||||
TrackListActivity --> TrackRecordedActivity : Show track
|
||||
TrackListActivity --> TrackDeleteActivity
|
||||
|
||||
SearchListActivity --> MarkerDetailActivity : Search result
|
||||
SearchListActivity --> TrackDetailActivity : Search result
|
||||
SearchListActivity --> TrackRecordedActivity : Search result
|
||||
|
||||
TrackDetailActivity --> TrackDeleteActivity
|
||||
TrackDetailActivity --> TrackEditActivity
|
||||
TrackDetailActivity --> MarkerListActivity
|
||||
TrackDetailActivity --> MarkerEditActivity : Add marker
|
||||
TrackDetailActivity --> CameraIntent : Add marker (with photo)
|
||||
TrackDetailActivity --> ShareFileIntent
|
||||
TrackDetailActivity --> DashboardIntent : Database cursor
|
||||
TrackDetailActivity --> TrackOnMapIntent : KMZ
|
||||
TrackRecordedActivity --> TrackDeleteActivity
|
||||
TrackRecordedActivity --> TrackEditActivity
|
||||
TrackRecordedActivity --> MarkerListActivity
|
||||
TrackRecordedActivity --> MarkerEditActivity : Add marker
|
||||
TrackRecordedActivity --> CameraIntent : Add marker (with photo)
|
||||
TrackRecordedActivity --> ShareFileIntent
|
||||
TrackRecordedActivity --> DashboardIntent : Database cursor
|
||||
TrackRecordedActivity --> TrackOnMapIntent : KMZ
|
||||
TrackRecordedActivity --> TrackRecordingActivity
|
||||
TrackRecordedActivity --> SettingsActivity
|
||||
TrackRecordedActivity --> TrackListActivity : Back button
|
||||
|
||||
TrackRecordingActivity --> TrackOnMapIntent
|
||||
TrackRecordingActivity --> MarkerEditActivity : Add marker
|
||||
TrackRecordingActivity --> MarkerListActivity
|
||||
TrackRecordingActivity --> TrackEditActivity
|
||||
TrackRecordingActivity --> SettingsActivity
|
||||
TrackRecordingActivity --> TrackRecordedActivity : Stop recording
|
||||
TrackRecordingActivity --> TrackListActivity : Back button
|
||||
|
||||
MarkerListActivity --> MarkerDetailActivity
|
||||
|
||||
@@ -37,4 +48,4 @@ SettingsActivity --> HelpActivity
|
||||
SettingsActivity --> ExportActivity
|
||||
SettingsActivity --> ImportActivity
|
||||
|
||||
@enduml
|
||||
@enduml
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
@startuml
|
||||
SensorManager --> ElevationSumManager
|
||||
LocationManager --> TrackRecordingService
|
||||
ElevationSumManager --> TrackRecordingService
|
||||
|
||||
TrackRecordingService --> TrackRecordingServiceConnection
|
||||
TrackRecordingService --> Database
|
||||
|
||||
Database --> CustomContentProvider
|
||||
CustomContentProvider --> TrackDataHub
|
||||
CustomContentProvider --> ShareContentProvider
|
||||
TrackDataHub --> StatisticsRecordingFragment : TrackPoints, TrackStatistics, Waypoints (push)
|
||||
TrackDataHub --> StatisticsRecordedFragment : TrackPoints, TrackStatistics, Waypoints (push)
|
||||
TrackDataHub --> ChartFragment --> ChartView
|
||||
|
||||
TrackRecordingServiceConnection --> StatisticsRecordingFragment : Sensor data (heartrate, cadence, elevation gain; pull 1s)
|
||||
TrackRecordingServiceConnection --> TrackController : Start time (pull, onStart)
|
||||
@enduml
|
||||
@@ -0,0 +1,7 @@
|
||||
v3.7.3: OpenTracks
|
||||
|
||||
Bugfix:
|
||||
- Fixed computation of cadence and speed (via Bluetooth LE sensor)
|
||||
|
||||
Developer:
|
||||
- Removed unused translations
|
||||
@@ -0,0 +1,12 @@
|
||||
v3.7.4: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Sharing/export format configurable
|
||||
|
||||
Bugfix:
|
||||
- Wheel diameter not stored correctly (for speed sensor)
|
||||
- Help: links are clickable
|
||||
|
||||
Developer:
|
||||
- Split TrackDetailActivity
|
||||
- StatsFragement successor uses ConstraintLayout
|
||||
@@ -0,0 +1,11 @@
|
||||
v3.7.5: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Added aggregated statistics summary (from main the screen's menu)
|
||||
- Dashboard API: pass "show on lock screen"- and "keep screen on"-setting
|
||||
- Updated translations
|
||||
- Import: be lenient with ISO8601 date format
|
||||
- Show track on map: file format can be selected and opening dashboard works on Android R (API 30+)
|
||||
|
||||
Bugfix:
|
||||
- App icon now correctly implemented
|
||||
@@ -1,6 +1,5 @@
|
||||
#Sun Apr 12 18:41:12 CEST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
||||
|
||||
@@ -82,6 +82,7 @@ esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
@@ -129,6 +130,7 @@ fi
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
@@ -154,19 +156,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,14 +177,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
@@ -1,100 +1,104 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
||||
@@ -11,7 +11,14 @@ import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
public class ShareContentProviderTest {
|
||||
|
||||
@Test
|
||||
public void testCreateandParseURI() {
|
||||
public void testCreateandParseURI_invalid() {
|
||||
Uri uri = Uri.parse("content://de.dennisguse.opentracks.debug.content/tracks/1");
|
||||
|
||||
Assert.assertArrayEquals(new long[]{}, ShareContentProvider.parseURI(uri));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateandParseURI_valid() {
|
||||
long[] trackIds = {1, 3, 5};
|
||||
Pair<Uri, String> shareURIandMIME = ShareContentProvider.createURI(trackIds, "TrackName", TrackFileFormat.KML_ONLY_TRACK);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import de.dennisguse.opentracks.util.UintUtils;
|
||||
public class SensorDataCyclingTest {
|
||||
|
||||
@Test
|
||||
public void compute_cadence() {
|
||||
public void compute_cadence_1() {
|
||||
// given
|
||||
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 1024); // 1s
|
||||
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 2048); // 2s
|
||||
@@ -24,6 +24,19 @@ public class SensorDataCyclingTest {
|
||||
Assert.assertEquals(60, current.getCadence_rpm(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compute_cadence_2() {
|
||||
// given
|
||||
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 6184);
|
||||
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 8016);
|
||||
|
||||
// when
|
||||
current.compute(previous);
|
||||
|
||||
// then
|
||||
Assert.assertEquals(33.53, current.getCadence_rpm(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compute_cadence_sameCount() {
|
||||
// given
|
||||
@@ -77,6 +90,19 @@ public class SensorDataCyclingTest {
|
||||
Assert.assertEquals(60, current.getCadence_rpm(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compute_speed() {
|
||||
// given
|
||||
SensorDataCycling.Speed previous = new SensorDataCycling.Speed("sensorAddress", "sensorName", 1, 6184);
|
||||
SensorDataCycling.Speed current = new SensorDataCycling.Speed("sensorAddress", "sensorName", 2, 8016);
|
||||
|
||||
// when
|
||||
current.compute(previous, 2150);
|
||||
|
||||
// then
|
||||
Assert.assertEquals(1.20, current.getSpeed_mps(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compute_speed_rollOverCount() {
|
||||
// given
|
||||
|
||||
@@ -97,7 +97,7 @@ public class ExportImportTest {
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
|
||||
TrackFileFormat trackFileFormat = TrackFileFormat.KML_WITH_TRACKDETAIL;
|
||||
TrackExporter trackExporter = trackFileFormat.newTrackExporter(context, new Track[]{track}, null);
|
||||
TrackExporter trackExporter = trackFileFormat.newTrackExporter(context, new Track[]{track});
|
||||
|
||||
// when
|
||||
// 1. export
|
||||
@@ -169,7 +169,7 @@ public class ExportImportTest {
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
|
||||
TrackFileFormat trackFileFormat = TrackFileFormat.GPX;
|
||||
TrackExporter trackExporter = trackFileFormat.newTrackExporter(context, new Track[]{track}, null);
|
||||
TrackExporter trackExporter = trackFileFormat.newTrackExporter(context, new Track[]{track});
|
||||
|
||||
// when
|
||||
// 1. export
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package de.dennisguse.opentracks.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class PreferencesUtilsTest {
|
||||
|
||||
private final Context context = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Test
|
||||
public void ExportTrackFileFormat_ok() {
|
||||
// given
|
||||
SharedPreferences.Editor editor = PreferencesUtils.getSharedPreferences(context).edit();
|
||||
editor.putString(context.getString(R.string.export_trackfileformat_key), TrackFileFormat.KMZ_WITH_TRACKDETAIL.name());
|
||||
editor.commit();
|
||||
|
||||
// when
|
||||
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context);
|
||||
|
||||
// then
|
||||
Assert.assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL, trackFileFormat);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ExportTrackFileFormat_invalid() {
|
||||
// given
|
||||
SharedPreferences.Editor editor = PreferencesUtils.getSharedPreferences(context).edit();
|
||||
editor.putString(context.getString(R.string.export_trackfileformat_key), "invalid");
|
||||
editor.commit();
|
||||
|
||||
// when
|
||||
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context);
|
||||
|
||||
// then
|
||||
Assert.assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA, trackFileFormat);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ExportTrackFileFormat_noValue() {
|
||||
// given
|
||||
SharedPreferences.Editor editor = PreferencesUtils.getSharedPreferences(context).edit();
|
||||
editor.clear();
|
||||
editor.commit();
|
||||
|
||||
// when
|
||||
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context);
|
||||
|
||||
// then
|
||||
Assert.assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA, trackFileFormat);
|
||||
}
|
||||
}
|
||||
@@ -128,6 +128,7 @@ public class StringUtilsTest {
|
||||
*/
|
||||
@Test
|
||||
public void testGetTime_timezone() {
|
||||
assertGetTime("2010-05-04T03:02:01", 2010, 5, 4, 3, 2, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01Z", 2010, 5, 4, 3, 2, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01+00:00", 2010, 5, 4, 3, 2, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01-00:00", 2010, 5, 4, 3, 2, 1, 0);
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
package de.dennisguse.opentracks.viewmodels;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class AggregatedStatisticsTest {
|
||||
|
||||
private final Context context = ApplicationProvider.getApplicationContext();
|
||||
|
||||
/**
|
||||
* Create a TrackStatistics object.
|
||||
*
|
||||
* @param totalDistance distance in meters.
|
||||
* @param totalTime total time in milliseconds.
|
||||
* @return TrackStatistics object.
|
||||
*/
|
||||
private static Track createTrack(Context context, long totalDistance, long totalTime, String category) {
|
||||
TrackStatistics statistics = new TrackStatistics();
|
||||
statistics.setStartTime_ms(1000L); // Resulting start time
|
||||
statistics.setStopTime_ms(1000L + totalTime);
|
||||
statistics.setTotalTime(totalTime);
|
||||
statistics.setMovingTime(totalTime);
|
||||
statistics.setTotalDistance(totalDistance);
|
||||
statistics.setTotalElevationGain(50.0);
|
||||
statistics.setMaxSpeed(50.0); // Resulting max speed
|
||||
statistics.setMaxElevation(1250.0);
|
||||
statistics.setMinElevation(1200.0); // Resulting min elevation
|
||||
|
||||
Track track = new Track();
|
||||
track.setIcon(TrackIconUtils.getIconValue(context, category));
|
||||
track.setCategory(category);
|
||||
track.setTrackStatistics(statistics);
|
||||
return track;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregate() {
|
||||
// given
|
||||
// 10km in 40 minutes.
|
||||
long totalDistance = 10000;
|
||||
long totalTime = 2400000;
|
||||
String biking = context.getString(R.string.activity_type_biking);
|
||||
Track track = createTrack(context, totalDistance, totalTime, biking);
|
||||
|
||||
// when
|
||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
||||
aggregatedStatistics.aggregate(track);
|
||||
|
||||
// then
|
||||
Assert.assertEquals(1, aggregatedStatistics.getCount());
|
||||
Assert.assertTrue(aggregatedStatistics.get(biking) != null);
|
||||
Assert.assertEquals(1, aggregatedStatistics.get(biking).getCountTracks());
|
||||
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime, statistics2.getMovingTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregate_mountainBiking() {
|
||||
// given
|
||||
// 10km in 40 minutes.
|
||||
long totalDistance = 10000;
|
||||
long totalTime = 2400000;
|
||||
String mountainBiking = context.getString(R.string.activity_type_mountain_biking);
|
||||
Track track = createTrack(context, totalDistance, totalTime, mountainBiking);
|
||||
|
||||
// when
|
||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
||||
aggregatedStatistics.aggregate(track);
|
||||
|
||||
// then
|
||||
Assert.assertTrue(aggregatedStatistics.get(mountainBiking) != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregate_trailRunning() {
|
||||
// given
|
||||
// 10km in 40 minutes.
|
||||
long totalDistance = 10000;
|
||||
long totalTime = 2400000;
|
||||
String trailRunning = context.getString(R.string.activity_type_trail_running);
|
||||
Track track = createTrack(context, totalDistance, totalTime, trailRunning);
|
||||
|
||||
// when
|
||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
||||
aggregatedStatistics.aggregate(track);
|
||||
|
||||
// then
|
||||
Assert.assertTrue(aggregatedStatistics.get(trailRunning) != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregate_twoBikingTracks() {
|
||||
// given
|
||||
// 10km in 40 minutes.
|
||||
long totalDistance = 10000;
|
||||
long totalTime = 2400000;
|
||||
String biking = context.getString(R.string.activity_type_biking);
|
||||
Track[] tracks = new Track[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
tracks[i] = createTrack(context, totalDistance, totalTime, biking);
|
||||
}
|
||||
|
||||
// when
|
||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
||||
aggregatedStatistics.aggregate(tracks[0]); // biking activity 1.
|
||||
aggregatedStatistics.aggregate(tracks[1]); // biking activity 2.
|
||||
|
||||
// then
|
||||
Assert.assertEquals(1, aggregatedStatistics.getCount());
|
||||
Assert.assertTrue(aggregatedStatistics.get(biking) != null);
|
||||
Assert.assertEquals(2, aggregatedStatistics.get(biking).getCountTracks());
|
||||
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime * 2L, statistics2.getMovingTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregate_threeDifferentTracks() {
|
||||
// given
|
||||
// 10km in 40 minutes.
|
||||
long totalDistance = 10000;
|
||||
|
||||
String biking = context.getString(R.string.activity_type_biking);
|
||||
String running = context.getString(R.string.activity_type_running);
|
||||
String walking = context.getString(R.string.activity_type_walking);
|
||||
long totalTime = 2400000;
|
||||
Track[] tracks = new Track[]{
|
||||
createTrack(context, totalDistance, totalTime, biking),
|
||||
createTrack(context, totalDistance, totalTime, running),
|
||||
createTrack(context, totalDistance, totalTime, walking)
|
||||
};
|
||||
|
||||
// when
|
||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
||||
aggregatedStatistics.aggregate(tracks[0]); // biking activity 1.
|
||||
aggregatedStatistics.aggregate(tracks[1]); // biking activity 2.
|
||||
aggregatedStatistics.aggregate(tracks[2]); // biking activity 3.
|
||||
|
||||
// then
|
||||
Assert.assertEquals(3, aggregatedStatistics.getCount());
|
||||
Assert.assertTrue(aggregatedStatistics.get(biking) != null);
|
||||
Assert.assertTrue(aggregatedStatistics.get(running) != null);
|
||||
Assert.assertTrue(aggregatedStatistics.get(walking) != null);
|
||||
Assert.assertEquals(1, aggregatedStatistics.get(biking).getCountTracks());
|
||||
Assert.assertEquals(1, aggregatedStatistics.get(running).getCountTracks());
|
||||
Assert.assertEquals(1, aggregatedStatistics.get(walking).getCountTracks());
|
||||
|
||||
{
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime, statistics2.getMovingTime());
|
||||
}
|
||||
|
||||
{
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(running).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime, statistics2.getMovingTime());
|
||||
}
|
||||
|
||||
{
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(walking).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime, statistics2.getMovingTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregate_severalTracksWithSeveralActivities() {
|
||||
// given
|
||||
// 10km in 40 minutes.
|
||||
long totalDistance = 10000;
|
||||
long totalTime = 2400000;
|
||||
String biking = context.getString(R.string.activity_type_biking);
|
||||
String running = context.getString(R.string.activity_type_running);
|
||||
String walking = context.getString(R.string.activity_type_walking);
|
||||
String driving = context.getString(R.string.activity_type_driving);
|
||||
Track[] tracks = new Track[]{
|
||||
createTrack(context, totalDistance, totalTime, biking),
|
||||
createTrack(context, totalDistance, totalTime, running),
|
||||
createTrack(context, totalDistance, totalTime, walking),
|
||||
createTrack(context, totalDistance, totalTime, biking),
|
||||
createTrack(context, totalDistance, totalTime, running),
|
||||
createTrack(context, totalDistance, totalTime, walking),
|
||||
createTrack(context, totalDistance, totalTime, biking),
|
||||
createTrack(context, totalDistance, totalTime, biking),
|
||||
createTrack(context, totalDistance, totalTime, biking),
|
||||
createTrack(context, totalDistance, totalTime, driving),
|
||||
};
|
||||
|
||||
|
||||
// when
|
||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
||||
for (Track track : tracks) {
|
||||
aggregatedStatistics.aggregate(track);
|
||||
|
||||
}
|
||||
|
||||
// then
|
||||
// 4 sports.
|
||||
Assert.assertEquals(4, aggregatedStatistics.getCount());
|
||||
|
||||
// There is a map for every sport.
|
||||
Assert.assertTrue(aggregatedStatistics.get(biking) != null);
|
||||
Assert.assertTrue(aggregatedStatistics.get(running) != null);
|
||||
Assert.assertTrue(aggregatedStatistics.get(walking) != null);
|
||||
Assert.assertTrue(aggregatedStatistics.get(driving) != null);
|
||||
|
||||
// Number of tracks by sport.
|
||||
Assert.assertEquals(5, aggregatedStatistics.get(biking).getCountTracks()); // Biking.
|
||||
Assert.assertEquals(2, aggregatedStatistics.get(running).getCountTracks()); // Running.
|
||||
Assert.assertEquals(2, aggregatedStatistics.get(walking).getCountTracks()); // Walking.
|
||||
Assert.assertEquals(1, aggregatedStatistics.get(driving).getCountTracks()); // Driving.
|
||||
|
||||
// Biking.
|
||||
{
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance * 5, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime * 5, statistics2.getMovingTime());
|
||||
}
|
||||
|
||||
// Running.
|
||||
{
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(running).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime * 2, statistics2.getMovingTime());
|
||||
}
|
||||
|
||||
// Walking.
|
||||
{
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(walking).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime * 2, statistics2.getMovingTime());
|
||||
}
|
||||
|
||||
// Driving.
|
||||
{
|
||||
TrackStatistics statistics2 = aggregatedStatistics.get(driving).getTrackStatistics();
|
||||
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
|
||||
Assert.assertEquals(totalTime, statistics2.getMovingTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,14 @@ limitations under the License.
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="de.dennisguse.opentracks"
|
||||
android:installLocation="auto">
|
||||
<!-- Permission to initialize services -->
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true"
|
||||
android:xlargeScreens="true" />
|
||||
|
||||
<application
|
||||
android:name=".Startup"
|
||||
android:allowBackup="false"
|
||||
@@ -79,7 +86,11 @@ limitations under the License.
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".TrackDetailActivity"
|
||||
android:name=".TrackRecordedActivity"
|
||||
android:screenOrientation="userPortrait" />
|
||||
|
||||
<activity
|
||||
android:name=".TrackRecordingActivity"
|
||||
android:screenOrientation="userPortrait" />
|
||||
|
||||
<activity android:name=".TrackEditActivity" />
|
||||
@@ -94,12 +105,30 @@ limitations under the License.
|
||||
android:value=".SearchListActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".AggregatedStatisticsActivity"
|
||||
android:screenOrientation="userPortrait"
|
||||
android:label="@string/menu_aggregated_statistics"/>
|
||||
|
||||
<activity
|
||||
android:name=".io.file.exporter.ExportActivity"
|
||||
android:theme="@style/ThemeCustomTransparent" />
|
||||
|
||||
<activity android:name=".settings.SettingsActivity" />
|
||||
|
||||
<activity android:name=".ShowOnMapProxyActivity$KMZ">
|
||||
<intent-filter android:label="@string/open_track_as_KMZ">
|
||||
<action android:name="Intent.OpenTracks-Dashboard" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".ShowOnMapProxyActivity$GPX">
|
||||
<intent-filter android:label="@string/open_track_as_GPX">
|
||||
<action android:name="Intent.OpenTracks-Dashboard" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name=".content.provider.ShareContentProvider"
|
||||
android:authorities="${applicationId}.content"
|
||||
@@ -124,12 +153,7 @@ limitations under the License.
|
||||
android:icon="@drawable/ic_logo_color_24dp"
|
||||
android:label="@string/recording_service" />
|
||||
</application>
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true"
|
||||
android:xlargeScreens="true" />
|
||||
|
||||
<!-- Permissions to record locations -->
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.gps"
|
||||
|
||||
@@ -2,11 +2,13 @@ package de.dennisguse.opentracks;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import de.dennisguse.opentracks.util.SystemUtils;
|
||||
import de.dennisguse.opentracks.util.ViewUtils;
|
||||
|
||||
public class AboutActivity extends AbstractActivity {
|
||||
|
||||
@@ -27,6 +29,8 @@ public class AboutActivity extends AbstractActivity {
|
||||
|
||||
TextView textURL = findViewById(R.id.about_app_url);
|
||||
textURL.setText(getString(R.string.about_url, getString(R.string.app_web_url)));
|
||||
|
||||
ViewUtils.makeClickableLinks((ViewGroup) findViewById(android.R.id.content));
|
||||
}
|
||||
|
||||
protected int getLayoutResId() {
|
||||
|
||||
@@ -26,7 +26,7 @@ import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
|
||||
/**
|
||||
* An abstract class for the following common tasks across
|
||||
* {@link TrackListActivity}, {@link TrackDetailActivity}, and
|
||||
* {@link TrackListActivity}, {@link TrackRecordedActivity}, and
|
||||
* {@link SearchListActivity}:
|
||||
* <p>
|
||||
* - share track <br>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package de.dennisguse.opentracks;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import de.dennisguse.opentracks.adapters.AggregatedStatisticsAdapter;
|
||||
import de.dennisguse.opentracks.viewmodels.AggregatedStatistics;
|
||||
import de.dennisguse.opentracks.viewmodels.AggregatedStatisticsModel;
|
||||
|
||||
public class AggregatedStatisticsActivity extends AbstractActivity {
|
||||
|
||||
private ListView listView;
|
||||
private AggregatedStatisticsAdapter adapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
listView = findViewById(R.id.aggregated_stats_list);
|
||||
|
||||
final AggregatedStatisticsModel viewModel = new ViewModelProvider(this).get(AggregatedStatisticsModel.class);
|
||||
viewModel.getAggregatedStats().observe(this, new Observer<AggregatedStatistics>() {
|
||||
@Override
|
||||
public void onChanged(AggregatedStatistics aggregatedStatistics) {
|
||||
if (aggregatedStatistics != null) {
|
||||
adapter = new AggregatedStatisticsAdapter(getApplicationContext(), aggregatedStatistics);
|
||||
listView.setAdapter(adapter);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutResId() {
|
||||
return R.layout.aggregated_stats;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,20 @@
|
||||
package de.dennisguse.opentracks;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import de.dennisguse.opentracks.util.ViewUtils;
|
||||
|
||||
public class HelpActivity extends AbstractActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ViewUtils.makeClickableLinks((ViewGroup) findViewById(android.R.id.content));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutResId() {
|
||||
return R.layout.help;
|
||||
|
||||
@@ -109,12 +109,7 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
|
||||
|
||||
@Override
|
||||
public void onDeleteMarkerDone() {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
runOnUiThread(this::finish);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -82,12 +82,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
|
||||
recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(MarkerListActivity.this);
|
||||
}
|
||||
if (key != null) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MarkerListActivity.this.invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
runOnUiThread(() -> MarkerListActivity.this.invalidateOptionsMenu());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -153,12 +153,7 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
||||
recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(SearchListActivity.this);
|
||||
}
|
||||
if (key != null) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
arrayAdapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
runOnUiThread(() -> arrayAdapter.notifyDataSetChanged());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -214,11 +209,11 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
||||
Map<String, Object> item = arrayAdapter.getItem(position);
|
||||
Long trackId = (Long) item.get(TRACK_ID_FIELD);
|
||||
Long markerId = (Long) item.get(MARKER_ID_FIELD);
|
||||
Intent intent = IntentUtils.newIntent(SearchListActivity.this, TrackDetailActivity.class);
|
||||
Intent intent = IntentUtils.newIntent(SearchListActivity.this, TrackRecordedActivity.class);
|
||||
if (markerId != null) {
|
||||
intent = intent.putExtra(TrackDetailActivity.EXTRA_MARKER_ID, markerId);
|
||||
intent = intent.putExtra(TrackRecordedActivity.EXTRA_MARKER_ID, markerId);
|
||||
} else {
|
||||
intent = intent.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, trackId);
|
||||
intent = intent.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
|
||||
}
|
||||
startActivity(intent);
|
||||
}
|
||||
@@ -346,12 +341,9 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
||||
final List<Map<String, Object>> displayResults = prepareResultsforDisplay(scoredResults);
|
||||
|
||||
// Use the UI thread to display the results
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
arrayAdapter.clear();
|
||||
arrayAdapter.addAll(displayResults);
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
arrayAdapter.clear();
|
||||
arrayAdapter.addAll(displayResults);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -448,12 +440,7 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
||||
|
||||
@Override
|
||||
public void onDeleteMarkerDone() {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleIntent(getIntent());
|
||||
}
|
||||
});
|
||||
runOnUiThread(() -> handleIntent(getIntent()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -463,11 +450,6 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
||||
|
||||
@Override
|
||||
protected void onDeleted() {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleIntent(getIntent());
|
||||
}
|
||||
});
|
||||
runOnUiThread(() -> handleIntent(getIntent()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package de.dennisguse.opentracks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TrackPointsColumns;
|
||||
import de.dennisguse.opentracks.content.provider.ShareContentProvider;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.util.IntentDashboardUtils;
|
||||
|
||||
/**
|
||||
* Used to convert IntentDashboardUtils.startDashboard-requests into {@link TrackFileFormat}.
|
||||
*/
|
||||
public abstract class ShowOnMapProxyActivity extends AppCompatActivity {
|
||||
|
||||
private TrackFileFormat trackFileFormat;
|
||||
|
||||
protected ShowOnMapProxyActivity(TrackFileFormat trackFileFormat) {
|
||||
this.trackFileFormat = trackFileFormat;
|
||||
}
|
||||
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
long[] trackIds = IntentDashboardUtils.extractTrackIdsFromIntent(getIntent());
|
||||
|
||||
showTrackTrackfileFormat(this, trackFileFormat, trackIds);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send intent to show tracks on a map (needs an another app) as KMZ.
|
||||
*
|
||||
* @param context the context
|
||||
* @param trackIds the track ids
|
||||
*/
|
||||
private static void showTrackTrackfileFormat(Context context, TrackFileFormat trackFileFormat, long[] trackIds) {
|
||||
if (trackIds.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(TrackPointsColumns.TRACKID, trackIds[0]);
|
||||
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, "SharingTrack", trackFileFormat);
|
||||
intent.setDataAndType(uriAndMime.first, uriAndMime.second);
|
||||
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
||||
context.startActivity(Intent.createChooser(intent, context.getString(R.string.open_track_as_trackfileformat, trackFileFormat.getExtension())));
|
||||
}
|
||||
|
||||
public static class KMZ extends ShowOnMapProxyActivity {
|
||||
public KMZ() {
|
||||
super(TrackFileFormat.KMZ_WITH_TRACKDETAIL);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GPX extends ShowOnMapProxyActivity {
|
||||
public GPX() {
|
||||
super(TrackFileFormat.GPX);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.dennisguse.opentracks;
|
||||
|
||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||
|
||||
/**
|
||||
* Interface for communication between activities that use {@link de.dennisguse.opentracks.content.TrackDataHub} and their fragments that need thi data hub.
|
||||
*/
|
||||
public interface TrackActivityDataHubInterface {
|
||||
TrackDataHub getTrackDataHub();
|
||||
}
|
||||
@@ -56,6 +56,7 @@ import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceInterface;
|
||||
import de.dennisguse.opentracks.settings.SettingsActivity;
|
||||
import de.dennisguse.opentracks.util.ActivityUtils;
|
||||
import de.dennisguse.opentracks.util.IntentDashboardUtils;
|
||||
import de.dennisguse.opentracks.util.IntentUtils;
|
||||
import de.dennisguse.opentracks.util.ListItemUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
@@ -143,14 +144,11 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
||||
recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(TrackListActivity.this);
|
||||
}
|
||||
if (key != null) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TrackListActivity.this.invalidateOptionsMenu();
|
||||
LoaderManager.getInstance(TrackListActivity.this).restartLoader(0, null, loaderCallbacks);
|
||||
boolean isRecording = PreferencesUtils.isRecording(recordingTrackId);
|
||||
trackController.update(isRecording, recordingTrackPaused);
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
TrackListActivity.this.invalidateOptionsMenu();
|
||||
LoaderManager.getInstance(TrackListActivity.this).restartLoader(0, null, loaderCallbacks);
|
||||
boolean isRecording = PreferencesUtils.isRecording(recordingTrackId);
|
||||
trackController.update(isRecording, recordingTrackPaused);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -174,15 +172,8 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
||||
private final Runnable bindChangedCallback = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
/*
|
||||
* After binding changes (e.g., becomes available), update the total time in trackController.
|
||||
*/
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
trackController.update(PreferencesUtils.isRecording(recordingTrackId), recordingTrackPaused);
|
||||
}
|
||||
});
|
||||
// After binding changes (e.g., becomes available), update the total time in trackController.
|
||||
runOnUiThread(() -> trackController.update(PreferencesUtils.isRecording(recordingTrackId), recordingTrackPaused));
|
||||
|
||||
if (!startGps) {
|
||||
return;
|
||||
@@ -205,8 +196,7 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
||||
if (!PreferencesUtils.isRecording(recordingTrackId)) {
|
||||
// Not recording -> Recording
|
||||
updateMenuItems(false, true);
|
||||
Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackDetailActivity.class)
|
||||
.putExtra(TrackDetailActivity.EXTRA_RECORDING_REQUEST, true);
|
||||
Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class);
|
||||
startActivity(newIntent);
|
||||
} else if (recordingTrackPaused) {
|
||||
// Paused -> Resume
|
||||
@@ -251,9 +241,17 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
||||
listView.setEmptyView(findViewById(R.id.track_list_empty_view));
|
||||
listView.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackDetailActivity.class)
|
||||
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, id);
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long trackId) {
|
||||
Intent newIntent;
|
||||
if (trackId == recordingTrackId) {
|
||||
// Is recording -> open record activity.
|
||||
newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class)
|
||||
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
|
||||
} else {
|
||||
// Not recording -> open detail activity.
|
||||
newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordedActivity.class)
|
||||
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
|
||||
}
|
||||
startActivity(newIntent);
|
||||
}
|
||||
});
|
||||
@@ -397,6 +395,10 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
||||
this.invalidateOptionsMenu();
|
||||
}
|
||||
return true;
|
||||
case R.id.track_list_aggregated_stats:
|
||||
intent = IntentUtils.newIntent(this, AggregatedStatisticsActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.track_list_markers:
|
||||
intent = IntentUtils.newIntent(this, MarkerListActivity.class);
|
||||
startActivity(intent);
|
||||
@@ -480,7 +482,7 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
||||
Intent intent;
|
||||
switch (itemId) {
|
||||
case R.id.list_context_menu_show_on_map:
|
||||
IntentUtils.showTrackOnMap(this, trackIds);
|
||||
IntentDashboardUtils.startDashboard(this, trackIds);
|
||||
return true;
|
||||
case R.id.list_context_menu_share:
|
||||
intent = IntentUtils.newShareFileIntent(this, trackIds);
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright 2008 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;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.fragments.ChartFragment;
|
||||
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
||||
import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment;
|
||||
import de.dennisguse.opentracks.fragments.StatisticsRecordedFragment;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||
import de.dennisguse.opentracks.settings.SettingsActivity;
|
||||
import de.dennisguse.opentracks.util.IntentDashboardUtils;
|
||||
import de.dennisguse.opentracks.util.IntentUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||
import de.dennisguse.opentracks.util.TrackUtils;
|
||||
|
||||
/**
|
||||
* An activity to show the track detail, record a new track or resumes an existing one.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TrackRecordedActivity extends AbstractListActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, ConfirmDeleteDialogFragment.ConfirmDeleteCaller, TrackActivityDataHubInterface {
|
||||
|
||||
public static final String EXTRA_TRACK_ID = "track_id";
|
||||
public static final String EXTRA_MARKER_ID = "marker_id";
|
||||
|
||||
private static final String TAG = TrackRecordedActivity.class.getSimpleName();
|
||||
|
||||
private static final String CURRENT_TAB_TAG_KEY = "current_tab_tag_key";
|
||||
|
||||
// The following are set in onCreate.
|
||||
private ContentProviderUtils contentProviderUtils;
|
||||
private TrackDataHub trackDataHub;
|
||||
private ViewPager pager;
|
||||
|
||||
// From intent.
|
||||
private long trackId;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
contentProviderUtils = new ContentProviderUtils(this);
|
||||
handleIntent(getIntent());
|
||||
|
||||
trackDataHub = new TrackDataHub(this);
|
||||
|
||||
FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager(), 1) {
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return new StatisticsRecordedFragment();
|
||||
case 1:
|
||||
return ChartFragment.newInstance(false);
|
||||
case 2:
|
||||
return ChartFragment.newInstance(true);
|
||||
default:
|
||||
throw new RuntimeException("There isn't Fragment associated with the position: " + position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return getString(R.string.track_detail_stats_tab);
|
||||
case 1:
|
||||
return getString(R.string.settings_chart_by_time);
|
||||
case 2:
|
||||
return getString(R.string.settings_chart_by_distance);
|
||||
}
|
||||
return "Unknown Tab";
|
||||
}
|
||||
};
|
||||
pager = findViewById(R.id.track_detail_activity_view_pager);
|
||||
pager.setAdapter(adapter);
|
||||
TabLayout tabs = findViewById(R.id.track_detail_activity_tablayout);
|
||||
tabs.setupWithViewPager(pager);
|
||||
if (savedInstanceState != null) {
|
||||
pager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
trackDataHub.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
// Update UI
|
||||
this.invalidateOptionsMenu();
|
||||
|
||||
if (trackId != -1L) {
|
||||
trackDataHub.loadTrack(trackId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
trackDataHub.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt(CURRENT_TAB_TAG_KEY, pager.getCurrentItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutResId() {
|
||||
return R.layout.track_detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
setIntent(intent);
|
||||
handleIntent(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.track_detail, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.track_detail_markers).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
menu.findItem(R.id.track_detail_resume_track).setVisible(!PreferencesUtils.isRecording(this));
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
setTitle(track != null ? track.getName() : "");
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
Intent intent;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.track_detail_share:
|
||||
intent = IntentUtils.newShareFileIntent(this, new long[]{trackId});
|
||||
intent = Intent.createChooser(intent, null);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.track_detail_menu_show_on_map:
|
||||
IntentDashboardUtils.startDashboard(this, trackId);
|
||||
return true;
|
||||
case R.id.track_detail_markers:
|
||||
intent = IntentUtils.newIntent(this, MarkerListActivity.class)
|
||||
.putExtra(MarkerListActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.track_detail_edit:
|
||||
intent = IntentUtils.newIntent(this, TrackEditActivity.class)
|
||||
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.track_detail_delete:
|
||||
deleteTracks(new long[]{trackId});
|
||||
return true;
|
||||
case R.id.track_detail_resume_track:
|
||||
Intent newIntent = IntentUtils.newIntent(TrackRecordedActivity.this, TrackRecordingActivity.class)
|
||||
.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(newIntent);
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
finish();
|
||||
return true;
|
||||
case R.id.track_detail_settings:
|
||||
intent = IntentUtils.newIntent(this, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TrackRecordingServiceConnection getTrackRecordingServiceConnection() {
|
||||
// Not needed.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeleted() {
|
||||
runOnUiThread(this::finish);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link TrackDataHub}.
|
||||
*/
|
||||
@Override
|
||||
public TrackDataHub getTrackDataHub() {
|
||||
return trackDataHub;
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent) {
|
||||
trackId = intent.getLongExtra(EXTRA_TRACK_ID, -1L);
|
||||
|
||||
long markerId = intent.getLongExtra(EXTRA_MARKER_ID, -1L);
|
||||
if (markerId != -1L) {
|
||||
// Use the trackId from the marker
|
||||
Waypoint waypoint = contentProviderUtils.getWaypoint(markerId);
|
||||
if (waypoint == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
trackId = waypoint.getTrackId();
|
||||
}
|
||||
|
||||
if (trackId == -1L) {
|
||||
Log.e(TAG, "TrackDetailActivity needs EXTRA_TRACK_ID.");
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public void chooseActivityType(String category) {
|
||||
ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), category);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChooseActivityTypeDone(String iconValue) {
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
String category = getString(TrackIconUtils.getIconActivityType(iconValue));
|
||||
TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* Copyright 2008 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;
|
||||
|
||||
import android.content.Intent;
|
||||
@@ -38,15 +22,14 @@ import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.fragments.ChartFragment;
|
||||
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
||||
import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment;
|
||||
import de.dennisguse.opentracks.fragments.StatsFragment;
|
||||
import de.dennisguse.opentracks.fragments.StatisticsRecordingFragment;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceInterface;
|
||||
import de.dennisguse.opentracks.settings.SettingsActivity;
|
||||
import de.dennisguse.opentracks.util.IntentDashboardUtils;
|
||||
import de.dennisguse.opentracks.util.IntentUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||
@@ -58,13 +41,11 @@ import de.dennisguse.opentracks.util.TrackUtils;
|
||||
* @author Leif Hendrik Wilden
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TrackDetailActivity extends AbstractListActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, ConfirmDeleteDialogFragment.ConfirmDeleteCaller {
|
||||
public class TrackRecordingActivity extends AbstractActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, TrackActivityDataHubInterface {
|
||||
|
||||
public static final String EXTRA_TRACK_ID = "track_id";
|
||||
public static final String EXTRA_MARKER_ID = "marker_id";
|
||||
public static final String EXTRA_RECORDING_REQUEST = "request_recording";
|
||||
|
||||
private static final String TAG = TrackDetailActivity.class.getSimpleName();
|
||||
private static final String TAG = TrackRecordingActivity.class.getSimpleName();
|
||||
|
||||
private static final String CURRENT_TAB_TAG_KEY = "current_tab_tag_key";
|
||||
|
||||
@@ -79,8 +60,6 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
// From intent
|
||||
private long trackId;
|
||||
|
||||
private boolean isRecordingRequest = false;
|
||||
|
||||
// Preferences
|
||||
private long recordingTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
|
||||
private boolean recordingTrackPaused;
|
||||
@@ -89,12 +68,7 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
@Override
|
||||
public void run() {
|
||||
// After binding changes (is available), update the total time in trackController.
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
trackController.update(isRecording(), recordingTrackPaused);
|
||||
}
|
||||
});
|
||||
runOnUiThread(() -> trackController.update(true, recordingTrackPaused));
|
||||
|
||||
if (recordingTrackId == -1L) {
|
||||
TrackRecordingServiceInterface service = trackRecordingServiceConnection.getServiceIfBound();
|
||||
@@ -102,9 +76,6 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
Log.d(TAG, "could not get TrackRecordingService");
|
||||
return;
|
||||
}
|
||||
if (!isRecordingRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Starts or resumes a track.
|
||||
int msg;
|
||||
@@ -121,12 +92,10 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
}
|
||||
|
||||
// A recording track is on.
|
||||
Toast.makeText(TrackDetailActivity.this, msg, Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(TrackRecordingActivity.this, msg, Toast.LENGTH_SHORT).show();
|
||||
trackDataHub.loadTrack(trackId);
|
||||
trackController.update(true, false);
|
||||
trackController.onResume(true, recordingTrackPaused);
|
||||
|
||||
isRecordingRequest = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -134,43 +103,37 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (PreferencesUtils.isKey(TrackDetailActivity.this, R.string.recording_track_id_key, key)) {
|
||||
recordingTrackId = PreferencesUtils.getRecordingTrackId(TrackDetailActivity.this);
|
||||
if (PreferencesUtils.isKey(TrackRecordingActivity.this, R.string.recording_track_id_key, key)) {
|
||||
recordingTrackId = PreferencesUtils.getRecordingTrackId(TrackRecordingActivity.this);
|
||||
setLockscreenPolicy();
|
||||
setScreenOnPolicy();
|
||||
}
|
||||
|
||||
if (PreferencesUtils.isKey(TrackDetailActivity.this, R.string.recording_track_paused_key, key)) {
|
||||
recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(TrackDetailActivity.this);
|
||||
if (PreferencesUtils.isKey(TrackRecordingActivity.this, R.string.recording_track_paused_key, key)) {
|
||||
recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(TrackRecordingActivity.this);
|
||||
setLockscreenPolicy();
|
||||
setScreenOnPolicy();
|
||||
}
|
||||
|
||||
if (PreferencesUtils.isKey(TrackDetailActivity.this, R.string.stats_show_on_lockscreen_while_recording_key, key)) {
|
||||
if (PreferencesUtils.isKey(TrackRecordingActivity.this, R.string.stats_show_on_lockscreen_while_recording_key, key)) {
|
||||
setLockscreenPolicy();
|
||||
}
|
||||
|
||||
if (PreferencesUtils.isKey(TrackDetailActivity.this, R.string.stats_keep_screen_on_while_recording_key, key)) {
|
||||
if (PreferencesUtils.isKey(TrackRecordingActivity.this, R.string.stats_keep_screen_on_while_recording_key, key)) {
|
||||
setScreenOnPolicy();
|
||||
}
|
||||
|
||||
if (key == null) return;
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TrackDetailActivity.this.invalidateOptionsMenu();
|
||||
boolean isRecording = isRecording();
|
||||
trackController.update(isRecording, recordingTrackPaused);
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
TrackRecordingActivity.this.invalidateOptionsMenu();
|
||||
trackController.update(true, recordingTrackPaused);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private MenuItem insertMarkerMenuItem;
|
||||
private MenuItem markerListMenuItem;
|
||||
private MenuItem shareMenuItem;
|
||||
private MenuItem resumeMenuItem;
|
||||
|
||||
private final OnClickListener recordListener = new OnClickListener() {
|
||||
@Override
|
||||
@@ -192,8 +155,13 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
private final OnClickListener stopListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
trackRecordingServiceConnection.stopRecording(TrackDetailActivity.this, true);
|
||||
trackRecordingServiceConnection.stopRecording(TrackRecordingActivity.this, true);
|
||||
Intent newIntent = IntentUtils.newIntent(TrackRecordingActivity.this, TrackRecordedActivity.class)
|
||||
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(newIntent);
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
updateMenuItems(true);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -220,12 +188,14 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return new StatisticsRecordingFragment();
|
||||
case 1:
|
||||
return ChartFragment.newInstance(false);
|
||||
case 2:
|
||||
return ChartFragment.newInstance(true);
|
||||
default: //0
|
||||
return new StatsFragment();
|
||||
default:
|
||||
throw new RuntimeException("There isn't Fragment associated with the position: " + position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +231,7 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
}
|
||||
|
||||
private void setLockscreenPolicy() {
|
||||
boolean showOnLockScreen = PreferencesUtils.shouldShowStatsOnLockscreen(TrackDetailActivity.this)
|
||||
boolean showOnLockScreen = PreferencesUtils.shouldShowStatsOnLockscreen(TrackRecordingActivity.this)
|
||||
&& PreferencesUtils.isRecording(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
@@ -274,7 +244,7 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
}
|
||||
|
||||
private void setScreenOnPolicy() {
|
||||
boolean keepScreenOn = PreferencesUtils.shouldKeepScreenOn(TrackDetailActivity.this)
|
||||
boolean keepScreenOn = PreferencesUtils.shouldKeepScreenOn(TrackRecordingActivity.this)
|
||||
&& PreferencesUtils.isRecording(this);
|
||||
|
||||
if (keepScreenOn) {
|
||||
@@ -304,10 +274,10 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
|
||||
if (trackId != -1L) {
|
||||
trackDataHub.loadTrack(trackId);
|
||||
trackController.onResume(isRecording(), recordingTrackPaused);
|
||||
} else {
|
||||
startRecording();
|
||||
trackController.onResume(true, recordingTrackPaused);
|
||||
}
|
||||
|
||||
startRecording();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -332,7 +302,7 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
|
||||
@Override
|
||||
protected int getLayoutResId() {
|
||||
return R.layout.track_detail;
|
||||
return R.layout.track_record;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -344,12 +314,10 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.track_detail, menu);
|
||||
getMenuInflater().inflate(R.menu.track_record, menu);
|
||||
|
||||
insertMarkerMenuItem = menu.findItem(R.id.track_detail_insert_marker);
|
||||
shareMenuItem = menu.findItem(R.id.track_detail_share);
|
||||
markerListMenuItem = menu.findItem(R.id.track_detail_markers);
|
||||
resumeMenuItem = menu.findItem(R.id.track_detail_resume_track);
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
@@ -370,13 +338,8 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
.putExtra(MarkerEditActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.track_detail_share:
|
||||
intent = IntentUtils.newShareFileIntent(this, new long[]{trackId});
|
||||
intent = Intent.createChooser(intent, null);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.track_detail_menu_show_on_map:
|
||||
IntentUtils.showTrackOnMap(this, new long[]{trackId});
|
||||
IntentDashboardUtils.startDashboard(this, trackId);
|
||||
return true;
|
||||
case R.id.track_detail_markers:
|
||||
intent = IntentUtils.newIntent(this, MarkerListActivity.class)
|
||||
@@ -388,13 +351,6 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.track_detail_delete:
|
||||
deleteTracks(new long[]{trackId});
|
||||
return true;
|
||||
case R.id.track_detail_resume_track:
|
||||
isRecordingRequest = true;
|
||||
startRecording();
|
||||
return true;
|
||||
case R.id.track_detail_settings:
|
||||
intent = IntentUtils.newIntent(this, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
@@ -404,58 +360,25 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TrackRecordingServiceConnection getTrackRecordingServiceConnection() {
|
||||
return trackRecordingServiceConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeleted() {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link TrackDataHub}.
|
||||
*/
|
||||
@Override
|
||||
public TrackDataHub getTrackDataHub() {
|
||||
return trackDataHub;
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent) {
|
||||
trackId = intent.getLongExtra(EXTRA_TRACK_ID, -1L);
|
||||
isRecordingRequest = intent.getBooleanExtra(EXTRA_RECORDING_REQUEST, false);
|
||||
long markerId = intent.getLongExtra(EXTRA_MARKER_ID, -1L);
|
||||
if (markerId != -1L) {
|
||||
// Use the trackId from the marker
|
||||
Waypoint waypoint = contentProviderUtils.getWaypoint(markerId);
|
||||
if (waypoint == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
trackId = waypoint.getTrackId();
|
||||
if (trackId == -1L) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (trackId == -1L) {
|
||||
return;
|
||||
}
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
if (track == null) {
|
||||
// Use the last track if markerId is not set
|
||||
if (markerId == -1L) {
|
||||
track = contentProviderUtils.getLastTrack();
|
||||
if (track != null) {
|
||||
trackId = track.getId();
|
||||
return;
|
||||
}
|
||||
track = contentProviderUtils.getLastTrack();
|
||||
if (track != null) {
|
||||
trackId = track.getId();
|
||||
return;
|
||||
}
|
||||
finish();
|
||||
}
|
||||
@@ -465,20 +388,9 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
* Updates the menu items.
|
||||
*/
|
||||
private void updateMenuItems(boolean isPaused) {
|
||||
insertMarkerMenuItem.setVisible(isRecording() && !isPaused);
|
||||
shareMenuItem.setVisible(!isRecording());
|
||||
markerListMenuItem.setShowAsAction(isRecording() ? MenuItem.SHOW_AS_ACTION_NEVER : MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
String title;
|
||||
if (isRecording()) {
|
||||
title = getString(isPaused ? R.string.generic_paused : R.string.generic_recording);
|
||||
resumeMenuItem.setVisible(false);
|
||||
} else {
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
title = track != null ? track.getName() : "";
|
||||
// Only visible if there aren't other tracks that is recording.
|
||||
resumeMenuItem.setVisible(recordingTrackId == -1L);
|
||||
}
|
||||
setTitle(title);
|
||||
insertMarkerMenuItem.setVisible(!isPaused);
|
||||
markerListMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||
setTitle(getString(isPaused ? R.string.generic_paused : R.string.generic_recording));
|
||||
}
|
||||
|
||||
public void chooseActivityType(String category) {
|
||||
@@ -492,10 +404,6 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
||||
TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils);
|
||||
}
|
||||
|
||||
private boolean isRecording() {
|
||||
return trackId == recordingTrackId;
|
||||
}
|
||||
|
||||
private void startRecording() {
|
||||
trackRecordingServiceConnection.startAndBind(this);
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
package de.dennisguse.opentracks.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.util.StringUtils;
|
||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||
import de.dennisguse.opentracks.viewmodels.AggregatedStatistics;
|
||||
|
||||
public class AggregatedStatisticsAdapter extends BaseAdapter {
|
||||
|
||||
private AggregatedStatistics aggregatedStatistics;
|
||||
private Context context;
|
||||
|
||||
public AggregatedStatisticsAdapter(Context context, AggregatedStatistics aggregatedStatistics) {
|
||||
this.context = context;
|
||||
this.aggregatedStatistics = aggregatedStatistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
if (aggregatedStatistics != null) {
|
||||
return aggregatedStatistics.getCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AggregatedStatistics.AggregatedStatistic getItem(int position) {
|
||||
return aggregatedStatistics.getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
// Not important because data are not database register but cooked data.
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
AggregatedStatistics.AggregatedStatistic aggregatedStats = getItem(position);
|
||||
ViewHolder viewHolder;
|
||||
|
||||
if (isSpeedSport(position)) {
|
||||
viewHolder = new ViewSpeedHolder();
|
||||
} else {
|
||||
viewHolder = new ViewPaceHolder();
|
||||
}
|
||||
|
||||
convertView = LayoutInflater.from(context).inflate(R.layout.aggregated_stats_list_item, parent, false);
|
||||
viewHolder.setValues(convertView, getIcon(position), getName(position), aggregatedStats);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private boolean isSpeedSport(int position) {
|
||||
String category = aggregatedStatistics.getSportName(position);
|
||||
return TrackIconUtils.isSpeedIcon(context, category);
|
||||
}
|
||||
|
||||
private int getIcon(int position) {
|
||||
String iconValue = TrackIconUtils.getIconValue(context, aggregatedStatistics.getSportName(position));
|
||||
return TrackIconUtils.getIconDrawable(iconValue);
|
||||
}
|
||||
|
||||
private String getName(int position) {
|
||||
return aggregatedStatistics.getSportName(position);
|
||||
}
|
||||
|
||||
private class ViewHolder {
|
||||
protected ImageView sportIcon;
|
||||
protected TextView typeLabel;
|
||||
protected TextView numTracks;
|
||||
protected TextView distance;
|
||||
protected TextView distanceUnit;
|
||||
protected TextView time;
|
||||
protected boolean metricsUnits;
|
||||
|
||||
public ViewHolder() {
|
||||
metricsUnits = PreferencesUtils.isMetricUnits(context);
|
||||
}
|
||||
|
||||
public void setValues(View view, int iconDrawable, String name, AggregatedStatistics.AggregatedStatistic aggregatedStats) {
|
||||
sportIcon = view.findViewById(R.id.aggregated_stats_sport_icon);
|
||||
typeLabel = view.findViewById(R.id.aggregated_stats_type_label);
|
||||
numTracks = view.findViewById(R.id.aggregated_stats_num_tracks);
|
||||
distance = view.findViewById(R.id.aggregated_stats_distance);
|
||||
distanceUnit = view.findViewById(R.id.aggregated_stats_distance_unit);
|
||||
time = view.findViewById(R.id.aggregated_stats_time);
|
||||
|
||||
sportIcon.setImageResource(iconDrawable);
|
||||
typeLabel.setText(name);
|
||||
numTracks.setText(StringUtils.valueInParentheses(String.valueOf(aggregatedStats.getCountTracks())));
|
||||
|
||||
Pair<String, String> parts = StringUtils.getDistanceParts(context, aggregatedStats.getTrackStatistics().getTotalDistance(), metricsUnits);
|
||||
distance.setText(parts.first);
|
||||
distanceUnit.setText(parts.second);
|
||||
|
||||
time.setText(StringUtils.formatElapsedTime(aggregatedStats.getTrackStatistics().getMovingTime()));
|
||||
}
|
||||
}
|
||||
|
||||
private class ViewSpeedHolder extends ViewHolder {
|
||||
private TextView avgSpeed;
|
||||
private TextView avgSpeedUnit;
|
||||
private TextView avgSpeedLabel;
|
||||
private TextView maxSpeed;
|
||||
private TextView maxSpeedUnit;
|
||||
private TextView maxSpeedLabel;
|
||||
|
||||
@Override
|
||||
public void setValues(View view, int iconDrawable, String name, AggregatedStatistics.AggregatedStatistic aggregatedStats) {
|
||||
super.setValues(view, iconDrawable, name, aggregatedStats);
|
||||
|
||||
avgSpeed = view.findViewById(R.id.aggregated_stats_avg_rate);
|
||||
avgSpeedUnit = view.findViewById(R.id.aggregated_stats_avg_rate_unit);
|
||||
avgSpeedLabel = view.findViewById(R.id.aggregated_stats_avg_rate_label);
|
||||
maxSpeed = view.findViewById(R.id.aggregated_stats_max_rate);
|
||||
maxSpeedUnit = view.findViewById(R.id.aggregated_stats_max_rate_unit);
|
||||
maxSpeedLabel = view.findViewById(R.id.aggregated_stats_max_rate_label);
|
||||
|
||||
{
|
||||
Pair<String, String> parts = StringUtils.getSpeedParts(context, aggregatedStats.getTrackStatistics().getAverageMovingSpeed(), metricsUnits, true);
|
||||
avgSpeed.setText(parts.first);
|
||||
avgSpeedUnit.setText(parts.second);
|
||||
avgSpeedLabel.setText(context.getString(R.string.stats_average_moving_speed));
|
||||
}
|
||||
|
||||
{
|
||||
Pair<String, String> parts = StringUtils.getSpeedParts(context, aggregatedStats.getTrackStatistics().getMaxSpeed(), metricsUnits, true);
|
||||
maxSpeed.setText(parts.first);
|
||||
maxSpeedUnit.setText(parts.second);
|
||||
maxSpeedLabel.setText(context.getString(R.string.stats_max_speed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ViewPaceHolder extends ViewHolder {
|
||||
private TextView avgPace;
|
||||
private TextView avgPaceUnit;
|
||||
private TextView avgPaceLabel;
|
||||
private TextView maxPace;
|
||||
private TextView maxPaceUnit;
|
||||
private TextView maxPaceLabel;
|
||||
|
||||
@Override
|
||||
public void setValues(View view, int iconDrawable, String name, AggregatedStatistics.AggregatedStatistic aggregatedStats) {
|
||||
super.setValues(view, iconDrawable, name, aggregatedStats);
|
||||
|
||||
avgPace = view.findViewById(R.id.aggregated_stats_avg_rate);
|
||||
avgPaceUnit = view.findViewById(R.id.aggregated_stats_avg_rate_unit);
|
||||
avgPaceLabel = view.findViewById(R.id.aggregated_stats_avg_rate_label);
|
||||
|
||||
maxPace = view.findViewById(R.id.aggregated_stats_max_rate);
|
||||
maxPaceUnit = view.findViewById(R.id.aggregated_stats_max_rate_unit);
|
||||
maxPaceLabel = view.findViewById(R.id.aggregated_stats_max_rate_label);
|
||||
|
||||
{
|
||||
Pair<String, String> parts = StringUtils.getSpeedParts(context, aggregatedStats.getTrackStatistics().getAverageMovingSpeed(), metricsUnits, false);
|
||||
avgPace.setText(parts.first);
|
||||
avgPaceUnit.setText(parts.second);
|
||||
avgPaceLabel.setText(R.string.stats_average_moving_pace);
|
||||
}
|
||||
|
||||
{
|
||||
Pair<String, String> parts = StringUtils.getSpeedParts(context, aggregatedStats.getTrackStatistics().getMaxSpeed(), metricsUnits, false);
|
||||
maxPace.setText(parts.first);
|
||||
maxPaceUnit.setText(parts.second);
|
||||
maxPaceLabel.setText(R.string.stats_fastest_pace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,12 +144,9 @@ public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeL
|
||||
|
||||
PreferencesUtils.register(context, this);
|
||||
onSharedPreferenceChanged(null, null);
|
||||
runInHandlerThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (started) {
|
||||
loadDataForAll();
|
||||
}
|
||||
runInHandlerThread(() -> {
|
||||
if (started) {
|
||||
loadDataForAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -178,16 +175,13 @@ public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeL
|
||||
}
|
||||
|
||||
public void loadTrack(final long trackId) {
|
||||
runInHandlerThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (trackId == selectedTrackId) {
|
||||
Log.i(TAG, "Not reloading track " + trackId);
|
||||
return;
|
||||
}
|
||||
selectedTrackId = trackId;
|
||||
loadDataForAll();
|
||||
runInHandlerThread(() -> {
|
||||
if (trackId == selectedTrackId) {
|
||||
Log.i(TAG, "Not reloading track " + trackId);
|
||||
return;
|
||||
}
|
||||
selectedTrackId = trackId;
|
||||
loadDataForAll();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -197,13 +191,10 @@ public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeL
|
||||
* @param trackDataListener the track data listener
|
||||
*/
|
||||
public void registerTrackDataListener(final TrackDataListener trackDataListener, final boolean tracksTable, final boolean waypointsTable, final boolean trackPointsTable_SampleIn, final boolean trackPointsTable_SampleOut) {
|
||||
runInHandlerThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
trackDataManager.registerTrackDataListener(trackDataListener, tracksTable, waypointsTable, trackPointsTable_SampleIn, trackPointsTable_SampleOut);
|
||||
if (started) {
|
||||
loadDataForListener(trackDataListener);
|
||||
}
|
||||
runInHandlerThread(() -> {
|
||||
trackDataManager.registerTrackDataListener(trackDataListener, tracksTable, waypointsTable, trackPointsTable_SampleIn, trackPointsTable_SampleOut);
|
||||
if (started) {
|
||||
loadDataForListener(trackDataListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -214,12 +205,7 @@ public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeL
|
||||
* @param trackDataListener the track data listener
|
||||
*/
|
||||
public void unregisterTrackDataListener(final TrackDataListener trackDataListener) {
|
||||
runInHandlerThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
trackDataManager.unregisterTrackDataListener(trackDataListener);
|
||||
}
|
||||
});
|
||||
runInHandlerThread(() -> trackDataManager.unregisterTrackDataListener(trackDataListener));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,15 +224,12 @@ public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeL
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, final String key) {
|
||||
runInHandlerThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (PreferencesUtils.isKey(context, R.string.recording_track_id_key, key)) {
|
||||
recordingTrackId = PreferencesUtils.getRecordingTrackId(context);
|
||||
}
|
||||
if (PreferencesUtils.isKey(context, R.string.recording_track_paused_key, key)) {
|
||||
recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(context);
|
||||
}
|
||||
runInHandlerThread(() -> {
|
||||
if (PreferencesUtils.isKey(context, R.string.recording_track_id_key, key)) {
|
||||
recordingTrackId = PreferencesUtils.getRecordingTrackId(context);
|
||||
}
|
||||
if (PreferencesUtils.isKey(context, R.string.recording_track_paused_key, key)) {
|
||||
recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -289,7 +272,7 @@ public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeL
|
||||
if (isOnlyListener) {
|
||||
resetSamplingState();
|
||||
}
|
||||
Set<TrackDataListener> sampledOutListeners = hasSampledOut ? trackDataListeners : Collections.<TrackDataListener>emptySet();
|
||||
Set<TrackDataListener> sampledOutListeners = hasSampledOut ? trackDataListeners : Collections.emptySet();
|
||||
notifyTrackPointsTableUpdate(isOnlyListener, trackDataListeners, sampledOutListeners);
|
||||
}
|
||||
|
||||
|
||||
@@ -910,5 +910,4 @@ public class ContentProviderUtils {
|
||||
public static String[] parseTrackIdsFromUri(Uri url) {
|
||||
return TextUtils.split(url.getLastPathSegment(), ID_SEPARATOR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public class ShareContentProvider extends CustomContentProvider implements ICont
|
||||
|
||||
static long[] parseURI(Uri uri) {
|
||||
List<String> uriPaths = uri.getPathSegments();
|
||||
if (uriPaths == null || uriPaths.size() < 2) {
|
||||
if (uriPaths == null || uriPaths.size() < 3) {
|
||||
Log.d(TAG, "URI does not contain any trackIds.");
|
||||
return new long[]{};
|
||||
}
|
||||
@@ -209,7 +209,7 @@ public class ShareContentProvider extends CustomContentProvider implements ICont
|
||||
tracks[i] = contentProviderUtils.getTrack(trackIds[i]);
|
||||
}
|
||||
|
||||
final TrackExporter trackExporter = getTrackFileFormat(uri).newTrackExporter(getContext(), tracks, null);
|
||||
final TrackExporter trackExporter = getTrackFileFormat(uri).newTrackExporter(getContext(), tracks);
|
||||
|
||||
PipeDataWriter pipeDataWriter = new PipeDataWriter<String>() {
|
||||
@Override
|
||||
|
||||
@@ -64,13 +64,13 @@ public final class SensorDataCycling {
|
||||
|
||||
public void compute(Cadence previous) {
|
||||
if (hasData() && previous != null && previous.hasData()) {
|
||||
long timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024 * UnitConversions.S_TO_MS;
|
||||
float timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
|
||||
if (timeDiff_ms <= 0) {
|
||||
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
|
||||
cadence_rpm = INVALID_VALUE_FLOAT;
|
||||
} else {
|
||||
long crankDiff = UintUtils.diff(crankRevolutionsCount, previous.crankRevolutionsCount, UintUtils.UINT32_MAX);
|
||||
float cadence_ms = crankDiff / (float) timeDiff_ms;
|
||||
float cadence_ms = crankDiff / timeDiff_ms;
|
||||
cadence_rpm = (float) (cadence_ms / UnitConversions.MS_TO_S / UnitConversions.S_TO_MIN);
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public final class SensorDataCycling {
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "cadence=" + getCadence_rpm() + "_" + getCrankRevolutionsTime();
|
||||
return "cadence=" + getCadence_rpm() + " time=" + getCrankRevolutionsTime() + " count=" + getCrankRevolutionsCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +125,7 @@ public final class SensorDataCycling {
|
||||
|
||||
public void compute(Speed previous, int wheel_circumference_mm) {
|
||||
if (hasData() && previous != null && previous.hasData()) {
|
||||
long timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024 * UnitConversions.S_TO_MS;
|
||||
float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
|
||||
if (timeDiff_ms <= 0) {
|
||||
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
|
||||
speed_mps = INVALID_VALUE_FLOAT;
|
||||
@@ -140,7 +140,7 @@ public final class SensorDataCycling {
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "speed=" + getSpeed_mps() + "_" + getWheelRevolutionsTime();
|
||||
return "speed=" + getSpeed_mps() + " time=" + getWheelRevolutionsTime() + " count=" + getWheelRevolutionsCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,9 +4,6 @@ import androidx.annotation.NonNull;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class SensorDataSet {
|
||||
|
||||
private SensorDataHeartRate heartRate;
|
||||
@@ -31,10 +28,6 @@ public final class SensorDataSet {
|
||||
}
|
||||
|
||||
public void set(SensorData data) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data instanceof SensorDataHeartRate) {
|
||||
this.heartRate = (SensorDataHeartRate) data;
|
||||
return;
|
||||
@@ -48,10 +41,6 @@ public final class SensorDataSet {
|
||||
this.cyclingSpeed = (SensorDataCycling.Speed) data;
|
||||
return;
|
||||
}
|
||||
if (data instanceof SensorDataCycling.CadenceAndSpeed) {
|
||||
set(((SensorDataCycling.CadenceAndSpeed) data).getCadence());
|
||||
set(((SensorDataCycling.CadenceAndSpeed) data).getSpeed());
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.TrackDetailActivity;
|
||||
import de.dennisguse.opentracks.TrackActivityDataHubInterface;
|
||||
import de.dennisguse.opentracks.chart.ChartPoint;
|
||||
import de.dennisguse.opentracks.chart.ChartView;
|
||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||
@@ -90,12 +90,9 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
boolean metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
||||
if (metricUnits != chartView.getMetricUnits()) {
|
||||
chartView.setMetricUnits(metricUnits);
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isResumed()) {
|
||||
chartView.requestLayout();
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
if (isResumed()) {
|
||||
chartView.requestLayout();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -106,12 +103,9 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
chartView.setReportSpeed(reportSpeed);
|
||||
chartView.applyReportSpeed();
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isResumed()) {
|
||||
chartView.requestLayout();
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
if (isResumed()) {
|
||||
chartView.requestLayout();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -214,12 +208,9 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
trackStatisticsUpdater = startTime != -1L ? new TrackStatisticsUpdater(startTime) : null;
|
||||
pendingPoints.clear();
|
||||
chartView.reset();
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isResumed()) {
|
||||
chartView.resetScroll();
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
if (isResumed()) {
|
||||
chartView.resetScroll();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -286,7 +277,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
* Needs to be synchronized because trackDataHub can be accessed by multiple threads.
|
||||
*/
|
||||
private synchronized void resumeTrackDataHub() {
|
||||
trackDataHub = ((TrackDetailActivity) getActivity()).getTrackDataHub();
|
||||
trackDataHub = ((TrackActivityDataHubInterface) getActivity()).getTrackDataHub();
|
||||
trackDataHub.registerTrackDataListener(this, true, true, true, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,15 +80,12 @@ public class DeleteMarkerDialogFragment extends DialogFragment {
|
||||
fragmentActivity, titleId, getString(messageId), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(fragmentActivity);
|
||||
for (long markerId : markerIds) {
|
||||
contentProviderUtils.deleteWaypoint(getContext(), markerId);
|
||||
}
|
||||
caller.onDeleteMarkerDone();
|
||||
new Thread(() -> {
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(fragmentActivity);
|
||||
for (long markerId : markerIds) {
|
||||
contentProviderUtils.deleteWaypoint(getContext(), markerId);
|
||||
}
|
||||
caller.onDeleteMarkerDone();
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,126 +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.fragments;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
|
||||
/**
|
||||
* A DialogFragment to select a file type, gpx, kml, etc.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class FileTypeDialogFragment extends DialogFragment {
|
||||
|
||||
private static final String FILE_TYPE_DIALOG_TAG = "fileType";
|
||||
private static final String KEY_TITLE_ID = "titleId";
|
||||
private static final String KEY_OPTION_ID = "optionId";
|
||||
|
||||
private FileTypeCaller caller;
|
||||
|
||||
public static void showDialog(FragmentManager fragmentManager, int titleId, int optionId) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(KEY_TITLE_ID, titleId);
|
||||
bundle.putInt(KEY_OPTION_ID, optionId);
|
||||
|
||||
FileTypeDialogFragment fileTypeDialogFragment = new FileTypeDialogFragment();
|
||||
fileTypeDialogFragment.setArguments(bundle);
|
||||
fileTypeDialogFragment.show(fragmentManager, FILE_TYPE_DIALOG_TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
try {
|
||||
caller = (FileTypeCaller) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(context + " must implement " + FileTypeCaller.class.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
int optionId = getArguments().getInt(KEY_OPTION_ID);
|
||||
final int titleId = getArguments().getInt(KEY_TITLE_ID);
|
||||
|
||||
final TrackFileFormat[] trackFileFormats = {TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES, TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA, TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA, TrackFileFormat.GPX};
|
||||
String[] choices = new String[trackFileFormats.length];
|
||||
for (int i = 0; i < choices.length; i++) {
|
||||
TrackFileFormat trackFileFormat = trackFileFormats[i];
|
||||
String trackFileFormatUpperCase = trackFileFormat.getExtension().toUpperCase(Locale.US); //ASCII upper case
|
||||
int photoMessageId = trackFileFormat.includesPhotos() ? R.string.export_with_photos : R.string.export_without_photos;
|
||||
String trackFileFormatDisplayName = String.format("%s (%s)", trackFileFormatUpperCase, getString(photoMessageId));
|
||||
choices[i] = getString(optionId, trackFileFormatDisplayName);
|
||||
}
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setNegativeButton(R.string.generic_cancel, new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
onDismissed();
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.generic_ok, new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
|
||||
caller.onFileTypeDone(trackFileFormats[position]);
|
||||
}
|
||||
})
|
||||
.setSingleChoiceItems(choices, 0, null)
|
||||
.setTitle(titleId)
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(@NonNull DialogInterface dialog) {
|
||||
onDismissed();
|
||||
}
|
||||
|
||||
private void onDismissed() {
|
||||
dismiss();
|
||||
caller.onDismissed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for caller of this dialog fragment.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public interface FileTypeCaller {
|
||||
|
||||
/**
|
||||
* Called when file type selection is done.
|
||||
*/
|
||||
void onFileTypeDone(TrackFileFormat trackFileFormat);
|
||||
|
||||
void onDismissed();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright 2008 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.fragments;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.util.Pair;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.TrackRecordedActivity;
|
||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||
import de.dennisguse.opentracks.content.TrackDataListener;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.util.StringUtils;
|
||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||
|
||||
/**
|
||||
* A fragment to display track statistics to the user.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class StatisticsRecordedFragment extends Fragment implements TrackDataListener {
|
||||
|
||||
private TrackStatistics trackStatistics = null;
|
||||
private String category = "";
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) {
|
||||
if (isResumed()) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if (isResumed()) {
|
||||
updateUI();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.statistics_recorded, container, false);
|
||||
}
|
||||
|
||||
/* Views */
|
||||
private TextView totalTimeValueView;
|
||||
private TextView distanceValue;
|
||||
private TextView distanceUnit;
|
||||
private View activityLabel;
|
||||
private Spinner activitySpinner;
|
||||
private TextView movingTimeValue;
|
||||
private TextView speedAvgLabel;
|
||||
private TextView speedAvgValue;
|
||||
private TextView speedAvgUnit;
|
||||
private TextView speedMaxLabel;
|
||||
private TextView speedMaxValue;
|
||||
private TextView speedMaxUnit;
|
||||
private TextView speedMovingLabel;
|
||||
private TextView speedMovingValue;
|
||||
private TextView speedMovingUnit;
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
totalTimeValueView = view.findViewById(R.id.stats_total_time_value);
|
||||
|
||||
distanceValue = view.findViewById(R.id.stats_distance_value);
|
||||
distanceUnit = view.findViewById(R.id.stats_distance_unit);
|
||||
|
||||
activityLabel = view.findViewById(R.id.stats_activity_type_label);
|
||||
activitySpinner = view.findViewById(R.id.stats_activity_type_icon);
|
||||
|
||||
movingTimeValue = view.findViewById(R.id.stats_moving_time_value);
|
||||
|
||||
speedAvgLabel = view.findViewById(R.id.stats_average_speed_label);
|
||||
speedAvgValue = view.findViewById(R.id.stats_average_speed_value);
|
||||
speedAvgUnit = view.findViewById(R.id.stats_average_speed_unit);
|
||||
|
||||
speedMaxLabel = view.findViewById(R.id.stats_max_speed_label);
|
||||
speedMaxValue = view.findViewById(R.id.stats_max_speed_value);
|
||||
speedMaxUnit = view.findViewById(R.id.stats_max_speed_unit);
|
||||
|
||||
speedMovingLabel = view.findViewById(R.id.stats_moving_speed_label);
|
||||
speedMovingValue = view.findViewById(R.id.stats_moving_speed_value);
|
||||
speedMovingUnit = view.findViewById(R.id.stats_moving_speed_unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
Spinner activityTypeIcon = getView().findViewById(R.id.stats_activity_type_icon);
|
||||
activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(getActivity(), ""));
|
||||
activityTypeIcon.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
((TrackRecordedActivity) getActivity()).chooseActivityType(category);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
activityTypeIcon.setOnKeyListener(new View.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
|
||||
((TrackRecordedActivity) getActivity()).chooseActivityType(category);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
PreferencesUtils.register(getContext(), sharedPreferenceChangeListener);
|
||||
|
||||
TrackDataHub trackDataHub = ((TrackRecordedActivity) getActivity()).getTrackDataHub();
|
||||
trackDataHub.registerTrackDataListener(this, true, false, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
PreferencesUtils.unregister(getContext(), sharedPreferenceChangeListener);
|
||||
|
||||
TrackDataHub trackDataHub = ((TrackRecordedActivity) getActivity()).getTrackDataHub();
|
||||
trackDataHub.unregisterTrackDataListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
||||
totalTimeValueView = null;
|
||||
|
||||
distanceValue = null;
|
||||
distanceUnit = null;
|
||||
|
||||
activityLabel = null;
|
||||
activitySpinner = null;
|
||||
|
||||
movingTimeValue = null;
|
||||
|
||||
speedAvgLabel = null;
|
||||
speedAvgValue = null;
|
||||
speedAvgUnit = null;
|
||||
|
||||
speedMaxLabel = null;
|
||||
speedMaxValue = null;
|
||||
speedMaxUnit = null;
|
||||
|
||||
speedMovingLabel = null;
|
||||
speedMovingValue = null;
|
||||
speedMovingUnit = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackUpdated(final Track track) {
|
||||
if (isResumed()) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if (isResumed()) {
|
||||
trackStatistics = track != null ? track.getTrackStatistics() : null;
|
||||
category = track != null ? track.getCategory() : "";
|
||||
updateUI();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTrackPoints() {
|
||||
// We don't care.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSampledInTrackPoint(TrackPoint trackPoint) {
|
||||
// We don't care.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSampledOutTrackPoint(TrackPoint trackPoint) {
|
||||
// We don't care.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewTrackPointsDone() {
|
||||
// We don't care.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWaypoints() {
|
||||
// We don't care.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewWaypoint(Waypoint wpt) {
|
||||
// We don't care.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewWaypointsDone() {
|
||||
// We don't care.
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
String trackIconValue = TrackIconUtils.getIconValue(getContext(), category);
|
||||
|
||||
boolean metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
||||
boolean reportSpeed = PreferencesUtils.isReportSpeed(getContext(), category);
|
||||
|
||||
// Set total distance
|
||||
{
|
||||
double totalDistance = trackStatistics == null ? Double.NaN : trackStatistics.getTotalDistance();
|
||||
Pair<String, String> parts = StringUtils.getDistanceParts(getContext(), totalDistance, metricUnits);
|
||||
|
||||
distanceValue.setText(parts.first);
|
||||
distanceUnit.setText(parts.second);
|
||||
}
|
||||
|
||||
// Set activity type
|
||||
{
|
||||
activityLabel.setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
|
||||
|
||||
activitySpinner.setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
|
||||
activitySpinner.setEnabled(false);
|
||||
if (trackIconValue != null) {
|
||||
TrackIconUtils.setIconSpinner(activitySpinner, trackIconValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Set time and start datetime
|
||||
if (trackStatistics != null) {
|
||||
movingTimeValue.setText(StringUtils.formatElapsedTime(trackStatistics.getMovingTime()));
|
||||
totalTimeValueView.setText(StringUtils.formatElapsedTime(trackStatistics.getTotalTime()));
|
||||
}
|
||||
|
||||
// Set average speed/pace
|
||||
{
|
||||
double speed = trackStatistics != null ? trackStatistics.getAverageSpeed() : Double.NaN;
|
||||
speedAvgLabel.setText(reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
|
||||
|
||||
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
||||
speedAvgValue.setText(parts.first);
|
||||
speedAvgUnit.setText(parts.second);
|
||||
}
|
||||
|
||||
// Set max speed/pace
|
||||
{
|
||||
double speed = trackStatistics == null ? Double.NaN : trackStatistics.getMaxSpeed();
|
||||
|
||||
speedMaxLabel.setText(reportSpeed ? R.string.stats_max_speed : R.string.stats_fastest_pace);
|
||||
|
||||
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
||||
speedMaxValue.setText(parts.first);
|
||||
speedMaxUnit.setText(parts.second);
|
||||
}
|
||||
|
||||
// Set moving speed/pace
|
||||
{
|
||||
double speed = trackStatistics != null ? trackStatistics.getAverageMovingSpeed() : Double.NaN;
|
||||
|
||||
speedMovingLabel.setText(reportSpeed ? R.string.stats_average_moving_speed : R.string.stats_average_moving_pace);
|
||||
|
||||
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
||||
speedMovingValue.setText(parts.first);
|
||||
speedMovingUnit.setText(parts.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* Copyright 2008 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.fragments;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
@@ -31,15 +15,18 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.TrackDetailActivity;
|
||||
import de.dennisguse.opentracks.TrackRecordingActivity;
|
||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||
import de.dennisguse.opentracks.content.TrackDataListener;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataHeartRate;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceInterface;
|
||||
@@ -57,9 +44,9 @@ import de.dennisguse.opentracks.util.UnitConversions;
|
||||
* @author Sandor Dornbush
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
public class StatisticsRecordingFragment extends Fragment implements TrackDataListener {
|
||||
|
||||
private static final String STATS_FRAGMENT_TAG = StatsFragment.class.getSimpleName();
|
||||
private static final String TAG = StatisticsRecordingFragment.class.getSimpleName();
|
||||
|
||||
private static final long UI_UPDATE_INTERVAL = UnitConversions.ONE_SECOND_MS;
|
||||
|
||||
@@ -81,12 +68,9 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) {
|
||||
if (isResumed()) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isResumed()) {
|
||||
updateUI();
|
||||
}
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if (isResumed()) {
|
||||
updateUI();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -109,14 +93,15 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.stats, container, false);
|
||||
return inflater.inflate(R.layout.statistics_recording, container, false);
|
||||
}
|
||||
|
||||
/* Views */
|
||||
private View heartRateContainer;
|
||||
private View sensorHorizontalLine;
|
||||
private Group heartRateGroup;
|
||||
private TextView heartRateValueView;
|
||||
private TextView heartRateSensorView;
|
||||
private View cadenceContainer;
|
||||
private Group cadenceGroup;
|
||||
private TextView cadenceValueView;
|
||||
private TextView cadenceSensorView;
|
||||
|
||||
@@ -147,16 +132,13 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
private TextView speedMovingLabel;
|
||||
private TextView speedMovingValue;
|
||||
private TextView speedMovingUnit;
|
||||
private View elevationSeparator;
|
||||
private View elevationContainer;
|
||||
private View speedContainer;
|
||||
private Group elevationGroup;
|
||||
private TextView speedLabel;
|
||||
private TextView speedValue;
|
||||
private TextView speedUnit;
|
||||
private TextView elevationValue;
|
||||
private TextView elevationUnit;
|
||||
private View coordinateSeparator;
|
||||
private View coordinateContainer;
|
||||
private Group coordinateGroup;
|
||||
private TextView latitudeValue;
|
||||
private TextView longitudeValue;
|
||||
|
||||
@@ -164,11 +146,13 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
heartRateContainer = view.findViewById(R.id.stats_sensor_heart_rate_container);
|
||||
sensorHorizontalLine = view.findViewById(R.id.stats_sensor_horizontal_line);
|
||||
|
||||
heartRateGroup = view.findViewById(R.id.stats_sensor_heart_rate_group);
|
||||
heartRateValueView = view.findViewById(R.id.stats_sensor_heart_rate_value);
|
||||
heartRateSensorView = view.findViewById(R.id.stats_sensor_heart_rate_sensor_value);
|
||||
|
||||
cadenceContainer = view.findViewById(R.id.stats_sensor_cadence_container);
|
||||
cadenceGroup = view.findViewById(R.id.stats_sensor_cadence_group);
|
||||
cadenceValueView = view.findViewById(R.id.stats_sensor_cadence_value);
|
||||
cadenceSensorView = view.findViewById(R.id.stats_sensor_cadence_sensor_value);
|
||||
|
||||
@@ -194,10 +178,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
speedMovingValue = view.findViewById(R.id.stats_moving_speed_value);
|
||||
speedMovingUnit = view.findViewById(R.id.stats_moving_speed_unit);
|
||||
|
||||
elevationSeparator = view.findViewById(R.id.stats_elevation_separator);
|
||||
elevationContainer = view.findViewById(R.id.stats_elevation_container);
|
||||
elevationGroup = view.findViewById(R.id.stats_elevation_current_group);
|
||||
|
||||
speedContainer = view.findViewById(R.id.stats_speed);
|
||||
speedLabel = view.findViewById(R.id.stats_speed_label);
|
||||
speedValue = view.findViewById(R.id.stats_speed_value);
|
||||
speedUnit = view.findViewById(R.id.stats_speed_unit);
|
||||
@@ -205,8 +187,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
elevationValue = view.findViewById(R.id.stats_elevation_current_value);
|
||||
elevationUnit = view.findViewById(R.id.stats_elevation_current_unit);
|
||||
|
||||
coordinateSeparator = view.findViewById(R.id.stats_coordinate_separator);
|
||||
coordinateContainer = view.findViewById(R.id.stats_coordinate_container);
|
||||
coordinateGroup = view.findViewById(R.id.stats_coordinate_group);
|
||||
|
||||
latitudeValue = view.findViewById(R.id.stats_latitude_value);
|
||||
longitudeValue = view.findViewById(R.id.stats_longitude_value);
|
||||
@@ -226,7 +207,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
((TrackDetailActivity) getActivity()).chooseActivityType(category);
|
||||
((TrackRecordingActivity) getActivity()).chooseActivityType(category);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -235,7 +216,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
|
||||
((TrackDetailActivity) getActivity()).chooseActivityType(category);
|
||||
((TrackRecordingActivity) getActivity()).chooseActivityType(category);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -275,10 +256,12 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
heartRateContainer = null;
|
||||
sensorHorizontalLine = null;
|
||||
|
||||
heartRateGroup = null;
|
||||
heartRateValueView = null;
|
||||
heartRateSensorView = null;
|
||||
cadenceContainer = null;
|
||||
cadenceGroup = null;
|
||||
cadenceValueView = null;
|
||||
cadenceSensorView = null;
|
||||
|
||||
@@ -304,10 +287,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
speedMovingValue = null;
|
||||
speedMovingUnit = null;
|
||||
|
||||
elevationSeparator = null;
|
||||
elevationContainer = null;
|
||||
elevationGroup = null;
|
||||
|
||||
speedContainer = null;
|
||||
speedLabel = null;
|
||||
speedValue = null;
|
||||
speedUnit = null;
|
||||
@@ -315,8 +296,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
elevationValue = null;
|
||||
elevationUnit = null;
|
||||
|
||||
coordinateSeparator = null;
|
||||
coordinateContainer = null;
|
||||
coordinateGroup = null;
|
||||
|
||||
latitudeValue = null;
|
||||
longitudeValue = null;
|
||||
@@ -325,14 +305,11 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
@Override
|
||||
public void onTrackUpdated(final Track track) {
|
||||
if (isResumed()) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isResumed()) {
|
||||
lastTrackStatistics = track != null ? track.getTrackStatistics() : null;
|
||||
category = track != null ? track.getCategory() : "";
|
||||
updateUI();
|
||||
}
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if (isResumed()) {
|
||||
lastTrackStatistics = track != null ? track.getTrackStatistics() : null;
|
||||
category = track != null ? track.getCategory() : "";
|
||||
updateUI();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -356,24 +333,21 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
@Override
|
||||
public void onNewTrackPointsDone() {
|
||||
if (isResumed()) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isResumed()) {
|
||||
if (!isSelectedTrackRecording() || isSelectedTrackPaused()) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if (isResumed()) {
|
||||
if (!isSelectedTrackRecording() || isSelectedTrackPaused()) {
|
||||
lastTrackPoint = null;
|
||||
}
|
||||
|
||||
if (lastTrackPoint != null) {
|
||||
boolean hasFix = !LocationUtils.isLocationOld(lastTrackPoint.getLocation());
|
||||
boolean hasGoodFix = TrackPointUtils.fulfillsAccuracy(lastTrackPoint, recordingGpsAccuracy);
|
||||
|
||||
if (!hasFix || !hasGoodFix) {
|
||||
lastTrackPoint = null;
|
||||
}
|
||||
|
||||
if (lastTrackPoint != null) {
|
||||
boolean hasFix = !LocationUtils.isLocationOld(lastTrackPoint.getLocation());
|
||||
boolean hasGoodFix = TrackPointUtils.fulfillsAccuracy(lastTrackPoint, recordingGpsAccuracy);
|
||||
|
||||
if (!hasFix || !hasGoodFix) {
|
||||
lastTrackPoint = null;
|
||||
}
|
||||
}
|
||||
setLocationValues();
|
||||
}
|
||||
setLocationValues();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -399,7 +373,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
* Needs to be synchronized because trackDataHub can be accessed by multiple threads.
|
||||
*/
|
||||
private synchronized void resumeTrackDataHub() {
|
||||
trackDataHub = ((TrackDetailActivity) getActivity()).getTrackDataHub();
|
||||
trackDataHub = ((TrackRecordingActivity) getActivity()).getTrackDataHub();
|
||||
trackDataHub.registerTrackDataListener(this, true, false, true, true);
|
||||
}
|
||||
|
||||
@@ -442,65 +416,79 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
|
||||
SensorDataSet sensorDataSet = null;
|
||||
if (trackRecordingService == null) {
|
||||
Log.d(STATS_FRAGMENT_TAG, "Cannot get the track recording service.");
|
||||
Log.d(TAG, "Cannot get the track recording service.");
|
||||
} else {
|
||||
sensorDataSet = trackRecordingService.getSensorData();
|
||||
}
|
||||
|
||||
setHeartRateSensorData(sensorDataSet, isSelectedTrackRecording());
|
||||
setCadenceSensorData(sensorDataSet, isSelectedTrackRecording());
|
||||
setHeartRateSensorData(sensorDataSet);
|
||||
setCadenceSensorData(sensorDataSet);
|
||||
setSpeedSensorData(sensorDataSet, isSelectedTrackRecording());
|
||||
}
|
||||
|
||||
private void setHeartRateSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
||||
private void setHeartRateSensorData(SensorDataSet sensorDataSet) {
|
||||
int isVisible = View.VISIBLE;
|
||||
if (!isRecording || PreferencesUtils.isBluetoothHeartRateSensorAddressNone(getContext())) {
|
||||
isVisible = View.INVISIBLE;
|
||||
if (PreferencesUtils.isBluetoothHeartRateSensorAddressNone(getContext())) {
|
||||
isVisible = View.GONE;
|
||||
}
|
||||
heartRateContainer.setVisibility(isVisible);
|
||||
heartRateGroup.setVisibility(isVisible);
|
||||
setVisibilitySensorHorizontalLine();
|
||||
|
||||
if (isRecording) {
|
||||
String sensorValue = getContext().getString(R.string.value_unknown);
|
||||
String sensorName = getContext().getString(R.string.value_unknown);
|
||||
if (sensorDataSet != null && sensorDataSet.getHeartRate() != null) {
|
||||
sensorName = sensorDataSet.getHeartRate().getSensorName();
|
||||
if (sensorDataSet.getHeartRate().hasHeartRate_bpm() && sensorDataSet.getHeartRate().isRecent()) {
|
||||
sensorValue = StringUtils.formatDecimal(sensorDataSet.getHeartRate().getHeartRate_bpm(), 0);
|
||||
}
|
||||
String sensorValue = getContext().getString(R.string.value_unknown);
|
||||
String sensorName = getContext().getString(R.string.value_unknown);
|
||||
if (sensorDataSet != null && sensorDataSet.getHeartRate() != null) {
|
||||
SensorDataHeartRate data = sensorDataSet.getHeartRate();
|
||||
|
||||
sensorName = data.getSensorName();
|
||||
if (data.hasHeartRate_bpm() && data.isRecent()) {
|
||||
sensorValue = StringUtils.formatDecimal(data.getHeartRate_bpm(), 0);
|
||||
}
|
||||
|
||||
heartRateSensorView.setText(sensorName);
|
||||
heartRateValueView.setText(sensorValue);
|
||||
}
|
||||
|
||||
heartRateSensorView.setText(sensorName);
|
||||
heartRateValueView.setText(sensorValue);
|
||||
}
|
||||
|
||||
private void setCadenceSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
||||
private void setCadenceSensorData(SensorDataSet sensorDataSet) {
|
||||
int isVisible = View.VISIBLE;
|
||||
if (!isRecording || PreferencesUtils.isBluetoothCyclingCadenceSensorAddressNone(getContext())) {
|
||||
isVisible = View.INVISIBLE;
|
||||
if (PreferencesUtils.isBluetoothCyclingCadenceSensorAddressNone(getContext())) {
|
||||
isVisible = View.GONE;
|
||||
}
|
||||
cadenceContainer.setVisibility(isVisible);
|
||||
cadenceGroup.setVisibility(isVisible);
|
||||
setVisibilitySensorHorizontalLine();
|
||||
|
||||
if (isRecording) {
|
||||
String sensorValue = getContext().getString(R.string.value_unknown);
|
||||
String sensorName = getContext().getString(R.string.value_unknown);
|
||||
if (sensorDataSet != null && sensorDataSet.getCyclingCadence() != null) {
|
||||
sensorName = sensorDataSet.getCyclingCadence().getSensorName();
|
||||
if (sensorDataSet.getCyclingCadence().hasCadence_rpm() && sensorDataSet.getCyclingCadence().isRecent()) {
|
||||
sensorValue = StringUtils.formatDecimal(sensorDataSet.getCyclingCadence().getCadence_rpm(), 0);
|
||||
}
|
||||
String sensorValue = getContext().getString(R.string.value_unknown);
|
||||
String sensorName = getContext().getString(R.string.value_unknown);
|
||||
if (sensorDataSet != null && sensorDataSet.getCyclingCadence() != null) {
|
||||
SensorDataCycling.Cadence data = sensorDataSet.getCyclingCadence();
|
||||
sensorName = data.getSensorName();
|
||||
|
||||
if (data.hasCadence_rpm() && data.isRecent()) {
|
||||
sensorValue = StringUtils.formatDecimal(data.getCadence_rpm(), 0);
|
||||
}
|
||||
|
||||
cadenceSensorView.setText(sensorName);
|
||||
cadenceValueView.setText(sensorValue);
|
||||
}
|
||||
|
||||
cadenceSensorView.setText(sensorName);
|
||||
cadenceValueView.setText(sensorValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* If cadence and hear rate groups are invisible then sensor horizontal line hast to be invisible too.
|
||||
*/
|
||||
private void setVisibilitySensorHorizontalLine() {
|
||||
if (cadenceGroup.getVisibility() != View.VISIBLE && heartRateGroup.getVisibility() != View.VISIBLE) {
|
||||
sensorHorizontalLine.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setSpeedSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
||||
if (isRecording) {
|
||||
if (sensorDataSet != null && sensorDataSet.getCyclingSpeed() != null) {
|
||||
if (sensorDataSet.getCyclingSpeed().hasSpeed_mps() && sensorDataSet.getCyclingSpeed().isRecent()) {
|
||||
setSpeed(sensorDataSet.getCyclingSpeed().getSpeed_mps());
|
||||
SensorDataCycling.Speed data = sensorDataSet.getCyclingSpeed();
|
||||
|
||||
if (data.hasSpeed_mps() && data.isRecent()) {
|
||||
setSpeed(data.getSpeed_mps());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -574,7 +562,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
// Make elevation visible?
|
||||
{
|
||||
boolean showElevation = PreferencesUtils.isShowStatsElevation(getContext());
|
||||
elevationSeparator.setVisibility(showElevation ? View.VISIBLE : View.GONE);
|
||||
elevationGroup.setVisibility(showElevation ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,18 +591,14 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
|
||||
private void setLocationValues() {
|
||||
boolean metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
||||
boolean isRecording = isSelectedTrackRecording();
|
||||
|
||||
// Set speed/pace
|
||||
speedContainer.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
|
||||
if (isRecording) {
|
||||
double speed = lastTrackPoint != null && lastTrackPoint.hasSpeed() ? lastTrackPoint.getSpeed() : Double.NaN;
|
||||
setSpeed(speed);
|
||||
}
|
||||
double speed = lastTrackPoint != null && lastTrackPoint.hasSpeed() ? lastTrackPoint.getSpeed() : Double.NaN;
|
||||
setSpeed(speed);
|
||||
|
||||
// Set elevation
|
||||
boolean showElevation = isRecording && PreferencesUtils.isShowStatsElevation(getContext());
|
||||
elevationContainer.setVisibility(showElevation ? View.VISIBLE : View.GONE);
|
||||
boolean showElevation = PreferencesUtils.isShowStatsElevation(getContext());
|
||||
elevationGroup.setVisibility(showElevation ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (showElevation) {
|
||||
double altitude = lastTrackPoint != null && lastTrackPoint.hasAltitude() ? lastTrackPoint.getAltitude() : Double.NaN;
|
||||
@@ -625,10 +609,9 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
}
|
||||
|
||||
// Set coordinate
|
||||
boolean showCoordinate = isRecording && PreferencesUtils.isStatsShowCoordinate(getContext());
|
||||
boolean showCoordinate = PreferencesUtils.isStatsShowCoordinate(getContext());
|
||||
|
||||
coordinateSeparator.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
|
||||
coordinateContainer.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
|
||||
coordinateGroup.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
|
||||
if (showCoordinate) {
|
||||
double latitude = lastTrackPoint != null ? lastTrackPoint.getLatitude() : Double.NaN;
|
||||
String latitudeText = Double.isNaN(latitude) || Double.isInfinite(latitude) ? getContext().getString(R.string.value_unknown) : StringUtils.formatCoordinate(latitude);
|
||||
@@ -12,7 +12,6 @@ import de.dennisguse.opentracks.io.file.exporter.GpxTrackWriter;
|
||||
import de.dennisguse.opentracks.io.file.exporter.KmlTrackWriter;
|
||||
import de.dennisguse.opentracks.io.file.exporter.KmzTrackExporter;
|
||||
import de.dennisguse.opentracks.io.file.exporter.TrackExporter;
|
||||
import de.dennisguse.opentracks.io.file.exporter.TrackExporterListener;
|
||||
import de.dennisguse.opentracks.io.file.exporter.TrackWriter;
|
||||
|
||||
/**
|
||||
@@ -74,8 +73,8 @@ public enum TrackFileFormat {
|
||||
return new KmlTrackWriter(context, multiple, false, false, exportPhotos);
|
||||
}
|
||||
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks, TrackExporterListener trackExporterListener) {
|
||||
return newKmzTrackExporter(context, this.newTrackWriter(context, tracks.length > 1), tracks, trackExporterListener, exportPhotos);
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks) {
|
||||
return newKmzTrackExporter(context, this.newTrackWriter(context, tracks.length > 1), tracks, exportPhotos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,8 +100,8 @@ public enum TrackFileFormat {
|
||||
return new KmlTrackWriter(context, multiple, true, false, exportPhotos);
|
||||
}
|
||||
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks, TrackExporterListener trackExporterListener) {
|
||||
return newKmzTrackExporter(context, this.newTrackWriter(context, tracks.length > 1), tracks, trackExporterListener, exportPhotos);
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks) {
|
||||
return newKmzTrackExporter(context, this.newTrackWriter(context, tracks.length > 1), tracks, exportPhotos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,8 +133,8 @@ public enum TrackFileFormat {
|
||||
return MIME_KMZ;
|
||||
}
|
||||
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks, TrackExporterListener trackExporterListener) {
|
||||
return newKmzTrackExporter(context, this.newTrackWriter(context, tracks.length > 1), tracks, trackExporterListener, exportPhotos);
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks) {
|
||||
return newKmzTrackExporter(context, this.newTrackWriter(context, tracks.length > 1), tracks, exportPhotos);
|
||||
}
|
||||
|
||||
public String getExtension() {
|
||||
@@ -163,8 +162,8 @@ public enum TrackFileFormat {
|
||||
return MIME_KMZ;
|
||||
}
|
||||
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks, TrackExporterListener trackExporterListener) {
|
||||
return newKmzTrackExporter(context, newTrackWriter(context, tracks.length > 1), tracks, trackExporterListener, exportPhotos);
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks) {
|
||||
return newKmzTrackExporter(context, newTrackWriter(context, tracks.length > 1), tracks, exportPhotos);
|
||||
}
|
||||
|
||||
public String getExtension() {
|
||||
@@ -197,10 +196,10 @@ public enum TrackFileFormat {
|
||||
|
||||
private static final String MIME_KML = "application/vnd.google-earth.kml+xml";
|
||||
|
||||
private static TrackExporter newKmzTrackExporter(Context context, TrackWriter trackWriter, Track[] tracks, TrackExporterListener trackExporterListener, boolean exportPhotos) {
|
||||
private static TrackExporter newKmzTrackExporter(Context context, TrackWriter trackWriter, Track[] tracks, boolean exportPhotos) {
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||
|
||||
FileTrackExporter fileTrackExporter = new FileTrackExporter(contentProviderUtils, trackWriter, tracks, trackExporterListener);
|
||||
FileTrackExporter fileTrackExporter = new FileTrackExporter(contentProviderUtils, trackWriter, tracks);
|
||||
|
||||
return new KmzTrackExporter(contentProviderUtils, fileTrackExporter, tracks, exportPhotos);
|
||||
}
|
||||
@@ -210,10 +209,10 @@ public enum TrackFileFormat {
|
||||
*/
|
||||
public abstract String getMimeType();
|
||||
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks, TrackExporterListener trackExporterListener) {
|
||||
public TrackExporter newTrackExporter(Context context, Track[] tracks) {
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||
TrackWriter trackWriter = newTrackWriter(context, tracks.length > 1);
|
||||
return new FileTrackExporter(contentProviderUtils, trackWriter, tracks, trackExporterListener);
|
||||
return new FileTrackExporter(contentProviderUtils, trackWriter, tracks);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,17 +30,17 @@ import androidx.documentfile.provider.DocumentFile;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.fragments.FileTypeDialogFragment;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.util.DialogUtils;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
|
||||
/**
|
||||
* An activity for saving tracks to the external storage.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class ExportActivity extends FragmentActivity implements FileTypeDialogFragment.FileTypeCaller {
|
||||
public class ExportActivity extends FragmentActivity {
|
||||
|
||||
private static final int DIRECTORY_PICKER_REQUEST_CODE = 6;
|
||||
|
||||
@@ -55,8 +55,6 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
private int processedTrackCount;
|
||||
private int totalTrackCount;
|
||||
|
||||
private Uri directoryUri;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -71,36 +69,24 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
super.onActivityResult(requestCode, resultCode, resultData);
|
||||
if (requestCode == DIRECTORY_PICKER_REQUEST_CODE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
directoryUri = resultData.getData();
|
||||
fileTypeDialogStart();
|
||||
Uri directoryUri = resultData.getData();
|
||||
DocumentFile pickedDirectory = DocumentFile.fromTreeUri(this, directoryUri);
|
||||
DocumentFile exportDirectory = pickedDirectory.findFile(FileUtils.EXPORT_DIR);
|
||||
if (exportDirectory == null) {
|
||||
exportDirectory = pickedDirectory.createDirectory(FileUtils.EXPORT_DIR);
|
||||
}
|
||||
|
||||
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(this);
|
||||
|
||||
directoryDisplayName = FileUtils.getPath(exportDirectory);
|
||||
exportAsyncTask = new ExportAsyncTask(this, trackFileFormat, exportDirectory);
|
||||
exportAsyncTask.execute();
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fileTypeDialogStart() {
|
||||
FileTypeDialogFragment.showDialog(getSupportFragmentManager(), R.string.export_all_title, R.string.export_all_option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileTypeDone(TrackFileFormat trackFileFormat) {
|
||||
DocumentFile pickedDirectory = DocumentFile.fromTreeUri(this, directoryUri);
|
||||
DocumentFile exportDirectory = pickedDirectory.findFile(FileUtils.EXPORT_DIR);
|
||||
if (exportDirectory == null) {
|
||||
exportDirectory = pickedDirectory.createDirectory(FileUtils.EXPORT_DIR);
|
||||
}
|
||||
|
||||
directoryDisplayName = FileUtils.getPath(exportDirectory);
|
||||
exportAsyncTask = new ExportAsyncTask(this, trackFileFormat, exportDirectory);
|
||||
exportAsyncTask.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissed() {
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
@@ -112,7 +98,7 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
exportAsyncTask.cancel(true);
|
||||
dialog.dismiss();
|
||||
onDismissed();
|
||||
finish();
|
||||
}
|
||||
}, directoryDisplayName);
|
||||
return progressDialog;
|
||||
@@ -138,13 +124,13 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
dialog.dismiss();
|
||||
onDismissed();
|
||||
finish();
|
||||
}
|
||||
}).setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int arg1) {
|
||||
dialog.dismiss();
|
||||
onDismissed();
|
||||
finish();
|
||||
}
|
||||
}).setTitle(titleId);
|
||||
return builder.create();
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package de.dennisguse.opentracks.io.file.exporter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
@@ -45,13 +44,10 @@ class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
private static final String TAG = ExportAsyncTask.class.getSimpleName();
|
||||
private final TrackFileFormat trackFileFormat;
|
||||
private final DocumentFile directory;
|
||||
private final Context context;
|
||||
private final ContentProviderUtils contentProviderUtils;
|
||||
private ExportActivity exportActivity;
|
||||
private WakeLock wakeLock;
|
||||
|
||||
private boolean completed = false;
|
||||
|
||||
private int processedTrackCount = 0;
|
||||
private int totalTrackCount = 0;
|
||||
|
||||
@@ -66,8 +62,7 @@ class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
this.exportActivity = exportActivity;
|
||||
this.trackFileFormat = trackFileFormat;
|
||||
this.directory = directory;
|
||||
context = exportActivity.getApplicationContext();
|
||||
contentProviderUtils = new ContentProviderUtils(context);
|
||||
contentProviderUtils = new ContentProviderUtils(exportActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,7 +94,6 @@ class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
completed = true;
|
||||
if (exportActivity != null) {
|
||||
exportActivity.onAsyncTaskCompleted(processedTrackCount, totalTrackCount);
|
||||
}
|
||||
@@ -107,7 +101,6 @@ class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
@Override
|
||||
protected void onCancelled() {
|
||||
completed = true;
|
||||
if (exportActivity != null) {
|
||||
exportActivity.onAsyncTaskCompleted(processedTrackCount, totalTrackCount);
|
||||
}
|
||||
@@ -119,17 +112,7 @@ class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
* @param track the track
|
||||
*/
|
||||
private Boolean exportTrack(Track track) {
|
||||
TrackExporterListener trackExporterListener = new TrackExporterListener() {
|
||||
@Override
|
||||
public void onProgressUpdate(int number, int max) {
|
||||
//Update the progress dialog once every 500 points.
|
||||
if (number % 500 == 0) {
|
||||
publishProgress(number, max);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TrackExporter trackExporter = trackFileFormat.newTrackExporter(context, new Track[]{track}, trackExporterListener);
|
||||
TrackExporter trackExporter = trackFileFormat.newTrackExporter(exportActivity, new Track[]{track});
|
||||
|
||||
String fileName = track.getId() + "." + trackFileFormat.getExtension();
|
||||
|
||||
@@ -139,8 +122,8 @@ class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
file = directory.createFile(trackFileFormat.getMimeType(), fileName);
|
||||
}
|
||||
|
||||
try (OutputStream outputStream = context.getContentResolver().openOutputStream(file.getUri())) {
|
||||
if (trackExporter.writeTrack(context, outputStream)) {
|
||||
try (OutputStream outputStream = exportActivity.getContentResolver().openOutputStream(file.getUri())) {
|
||||
if (trackExporter.writeTrack(exportActivity, outputStream)) {
|
||||
return true;
|
||||
} else {
|
||||
if (!file.delete()) {
|
||||
@@ -167,6 +150,7 @@ class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
return false;
|
||||
}
|
||||
totalTrackCount = cursor.getCount();
|
||||
|
||||
for (int i = 0; i < totalTrackCount; i++) {
|
||||
if (isCancelled()) {
|
||||
return false;
|
||||
|
||||
@@ -44,7 +44,6 @@ public class FileTrackExporter implements TrackExporter {
|
||||
private final ContentProviderUtils contentProviderUtils;
|
||||
private final Track[] tracks;
|
||||
private final TrackWriter trackWriter;
|
||||
private final TrackExporterListener trackExporterListener;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -52,13 +51,11 @@ public class FileTrackExporter implements TrackExporter {
|
||||
* @param contentProviderUtils the content provider utils
|
||||
* @param trackWriter the track writer
|
||||
* @param tracks the tracks
|
||||
* @param trackExporterListener the track export listener
|
||||
*/
|
||||
public FileTrackExporter(ContentProviderUtils contentProviderUtils, TrackWriter trackWriter, Track[] tracks, TrackExporterListener trackExporterListener) {
|
||||
public FileTrackExporter(ContentProviderUtils contentProviderUtils, TrackWriter trackWriter, Track[] tracks) {
|
||||
this.contentProviderUtils = contentProviderUtils;
|
||||
this.tracks = tracks;
|
||||
this.trackWriter = trackWriter;
|
||||
this.trackExporterListener = trackExporterListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,9 +155,6 @@ public class FileTrackExporter implements TrackExporter {
|
||||
|
||||
// Write the current trackPoint
|
||||
trackWriter.writeTrackPoint(trackPoint);
|
||||
if (trackExporterListener != null) {
|
||||
trackExporterListener.onProgressUpdate(locationNumber, trackPointIterator.getCount());
|
||||
}
|
||||
} else {
|
||||
if (wroteSegment) {
|
||||
trackWriter.writeCloseSegment();
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.io.file.exporter;
|
||||
|
||||
/**
|
||||
* Listener for {@link TrackExporter} progress.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public interface TrackExporterListener {
|
||||
|
||||
/**
|
||||
* Called to update progress.
|
||||
*
|
||||
* @param number the number of {@link de.dennisguse.opentracks.content.data.TrackPoint}s written
|
||||
* @param max the maximum number of {@link de.dennisguse.opentracks.content.data.TrackPoint}s in a {@link de.dennisguse.opentracks.content.data.Track}, for calculation of
|
||||
* completion percentage
|
||||
*/
|
||||
void onProgressUpdate(int number, int max);
|
||||
}
|
||||
@@ -424,7 +424,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
} else {
|
||||
try {
|
||||
timeValue = StringUtils.parseTime(time);
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (Exception e) {
|
||||
throw new SAXException(createErrorMessage(String.format(Locale.US, "Unable to parse time: %s", time)), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,17 +30,17 @@ import androidx.documentfile.provider.DocumentFile;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.fragments.FileTypeDialogFragment;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.util.DialogUtils;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
|
||||
/**
|
||||
* An activity to import files from the external storage.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class ImportActivity extends FragmentActivity implements FileTypeDialogFragment.FileTypeCaller {
|
||||
public class ImportActivity extends FragmentActivity {
|
||||
|
||||
private static final int DIRECTORY_PICKER_REQUEST_CODE = 6;
|
||||
|
||||
@@ -55,8 +55,6 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
private int importedTrackCount;
|
||||
private int totalTrackCount;
|
||||
|
||||
private Uri directoryUri;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -72,34 +70,20 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
super.onActivityResult(requestCode, resultCode, resultData);
|
||||
if (requestCode == DIRECTORY_PICKER_REQUEST_CODE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
directoryUri = resultData.getData();
|
||||
fileTypeDialogStart();
|
||||
Uri directoryUri = resultData.getData();
|
||||
DocumentFile pickedDirectory = DocumentFile.fromTreeUri(this, directoryUri);
|
||||
|
||||
directoryDisplayName = FileUtils.getPath(pickedDirectory);
|
||||
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(this);
|
||||
|
||||
importAsyncTask = new ImportAsyncTask(this, trackFileFormat, pickedDirectory);
|
||||
importAsyncTask.execute();
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void fileTypeDialogStart() {
|
||||
FileTypeDialogFragment.showDialog(getSupportFragmentManager(), R.string.import_selection_title, R.string.import_selection_option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileTypeDone(TrackFileFormat trackFileFormat) {
|
||||
DocumentFile pickedDirectory = DocumentFile.fromTreeUri(this, directoryUri);
|
||||
|
||||
directoryDisplayName = FileUtils.getPath(pickedDirectory);
|
||||
|
||||
importAsyncTask = new ImportAsyncTask(this, trackFileFormat, pickedDirectory);
|
||||
importAsyncTask.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissed() {
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
@@ -110,7 +94,7 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
importAsyncTask.cancel(true);
|
||||
dialog.dismiss();
|
||||
onDismissed();
|
||||
finish();
|
||||
}
|
||||
}, directoryDisplayName);
|
||||
return progressDialog;
|
||||
@@ -140,13 +124,13 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialogInterface) {
|
||||
dialogInterface.dismiss();
|
||||
onDismissed();
|
||||
finish();
|
||||
}
|
||||
}).setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int which) {
|
||||
dialogInterface.dismiss();
|
||||
onDismissed();
|
||||
finish();
|
||||
}
|
||||
}).setTitle(titleId).create();
|
||||
default:
|
||||
|
||||
@@ -41,8 +41,8 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.TrackDetailActivity;
|
||||
import de.dennisguse.opentracks.TrackListActivity;
|
||||
import de.dennisguse.opentracks.TrackRecordingActivity;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||
@@ -150,12 +150,7 @@ public class TrackRecordingService extends Service {
|
||||
if (locationExecutorService == null || locationExecutorService.isShutdown() || locationExecutorService.isTerminated()) {
|
||||
return;
|
||||
}
|
||||
locationExecutorService.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onLocationChangedAsync(location);
|
||||
}
|
||||
});
|
||||
locationExecutorService.submit(() -> onLocationChangedAsync(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -743,10 +738,10 @@ public class TrackRecordingService extends Service {
|
||||
|
||||
private void showNotification(boolean isGpsStarted) {
|
||||
if (isRecording()) {
|
||||
Intent intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
|
||||
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, recordingTrackId);
|
||||
Intent intent = IntentUtils.newIntent(this, TrackRecordingActivity.class)
|
||||
.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, recordingTrackId);
|
||||
PendingIntent pendingIntent = TaskStackBuilder.create(this)
|
||||
.addParentStack(TrackDetailActivity.class)
|
||||
.addParentStack(TrackRecordingActivity.class)
|
||||
.addNextIntent(intent)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
|
||||
@@ -51,12 +51,14 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
|
||||
|
||||
private TrackRecordingServiceInterface trackRecordingService;
|
||||
|
||||
public TrackRecordingServiceConnection() {
|
||||
callback = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param callback the callback to invoke when the service binding changes
|
||||
*/
|
||||
public TrackRecordingServiceConnection(Runnable callback) {
|
||||
public TrackRecordingServiceConnection(@NonNull Runnable callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorData;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
import de.dennisguse.opentracks.util.BluetoothUtils;
|
||||
@@ -31,11 +32,11 @@ import de.dennisguse.opentracks.util.UnitConversions;
|
||||
|
||||
/**
|
||||
* Bluetooth LE sensor manager: manages connections to Bluetooth LE sensors.
|
||||
*
|
||||
* <p>
|
||||
* Note: should only be instantiated once.
|
||||
*
|
||||
* <p>
|
||||
* TODO: listen for Bluetooth enabled/disabled events.
|
||||
*
|
||||
* <p>
|
||||
* TODO: In case, a cycling (Cadence and Speed) sensor reports both values, testing is required.
|
||||
* We establish two GATT separate GATT connections (as if two different sensors were used).
|
||||
* However, it is not clear if this is allowed.
|
||||
@@ -148,20 +149,25 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onChanged(de.dennisguse.opentracks.content.sensor.SensorData sensorData) {
|
||||
public synchronized void onChanged(SensorData sensorData) {
|
||||
if (sensorData instanceof SensorDataCycling.Cadence) {
|
||||
if (sensorData.equals(sensorDataSet.getCyclingCadence())) {
|
||||
SensorDataCycling.Cadence previous = sensorDataSet.getCyclingCadence();
|
||||
Log.d(TAG, "previous " + previous + "; current" + sensorData);
|
||||
|
||||
if (sensorData.equals(previous)) {
|
||||
Log.d(TAG, "onChanged: cadence data repeated.");
|
||||
return;
|
||||
}
|
||||
((SensorDataCycling.Cadence) sensorData).compute(sensorDataSet.getCyclingCadence());
|
||||
((SensorDataCycling.Cadence) sensorData).compute(previous);
|
||||
}
|
||||
if (sensorData instanceof SensorDataCycling.Speed) {
|
||||
if (sensorData.equals(sensorDataSet.getCyclingSpeed())) {
|
||||
SensorDataCycling.Speed previous = sensorDataSet.getCyclingSpeed();
|
||||
Log.d(TAG, "previous " + previous + "; current" + sensorData);
|
||||
if (sensorData.equals(previous)) {
|
||||
Log.d(TAG, "onChanged: speed data repeated.");
|
||||
return;
|
||||
}
|
||||
((SensorDataCycling.Speed) sensorData).compute(sensorDataSet.getCyclingSpeed(), PreferencesUtils.getWheelCircumference(context));
|
||||
((SensorDataCycling.Speed) sensorData).compute(previous, PreferencesUtils.getWheelCircumference(context));
|
||||
}
|
||||
|
||||
sensorDataSet.set(sensorData);
|
||||
|
||||
@@ -11,8 +11,11 @@ import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.settings.bluetooth.BluetoothLeCyclingCadenceAndSpeedPreference;
|
||||
import de.dennisguse.opentracks.settings.bluetooth.BluetoothLeHeartRatePreference;
|
||||
import de.dennisguse.opentracks.settings.bluetooth.BluetoothLeSensorPreference;
|
||||
@@ -57,20 +60,10 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (PreferencesUtils.isKey(getActivity(), R.string.recording_track_id_key, key)) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateReset();
|
||||
}
|
||||
});
|
||||
getActivity().runOnUiThread(() -> updateReset());
|
||||
}
|
||||
if (PreferencesUtils.isKey(getActivity(), R.string.stats_units_key, key)) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateUnits();
|
||||
}
|
||||
});
|
||||
getActivity().runOnUiThread(() -> updateUnits());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -89,6 +82,8 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
||||
|
||||
setPreferencesFromResource(R.xml.settings, rootKey);
|
||||
}
|
||||
|
||||
setExportTrackFileFormatOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,5 +167,24 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
||||
|
||||
HackUtils.invalidatePreference(statsRatePreferences);
|
||||
}
|
||||
|
||||
|
||||
private void setExportTrackFileFormatOptions() {
|
||||
final TrackFileFormat[] trackFileFormats = {TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES, TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA, TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA, TrackFileFormat.GPX};
|
||||
String[] entries = new String[trackFileFormats.length];
|
||||
String[] entryValues = new String[trackFileFormats.length];
|
||||
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
TrackFileFormat trackFileFormat = trackFileFormats[i];
|
||||
String trackFileFormatUpperCase = trackFileFormat.getExtension().toUpperCase(Locale.US); //ASCII upper case
|
||||
int photoMessageId = trackFileFormat.includesPhotos() ? R.string.export_with_photos : R.string.export_without_photos;
|
||||
entries[i] = String.format("%s (%s)", trackFileFormatUpperCase, getString(photoMessageId));
|
||||
entryValues[i] = trackFileFormat.name();
|
||||
}
|
||||
|
||||
ListPreference listPreference = findPreference(getString(R.string.export_trackfileformat_key));
|
||||
listPreference.setEntries(entries);
|
||||
listPreference.setEntryValues(entryValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,13 +61,10 @@ public class BluetoothUtils {
|
||||
final Object mutex = new Object();
|
||||
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
adapters.add(BluetoothAdapter.getDefaultAdapter());
|
||||
synchronized (mutex) {
|
||||
mutex.notify();
|
||||
}
|
||||
handler.post(() -> {
|
||||
adapters.add(BluetoothAdapter.getDefaultAdapter());
|
||||
synchronized (mutex) {
|
||||
mutex.notify();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TrackPointsColumns;
|
||||
@@ -21,32 +23,61 @@ public class IntentDashboardUtils {
|
||||
|
||||
private static final String ACTION_DASHBOARD_PAYLOAD = ACTION_DASHBOARD + ".Payload";
|
||||
|
||||
private static final String EXTRAS_SHOULD_KEEP_SCREEN_ON = "EXTRAS_SHOULD_KEEP_SCREEN_ON";
|
||||
private static final String EXTRAS_SHOW_WHEN_LOCKED = "EXTRAS_SHOULD_KEEP_SCREEN_ON";
|
||||
|
||||
private static int TRACK_URI_INDEX = 0;
|
||||
private static int TRACKPOINTS_URI_INDEX = 1;
|
||||
|
||||
private IntentDashboardUtils() {
|
||||
}
|
||||
|
||||
public static boolean startDashboard(Context context, long[] trackIds) {
|
||||
ArrayList<Uri> uris = new ArrayList<>();
|
||||
/**
|
||||
* Send intent to show tracks on a map (needs an another app) as resource URIs.
|
||||
*
|
||||
* @param context the context
|
||||
* @param trackIds the track ids
|
||||
*/
|
||||
public static void startDashboard(Context context, long[] trackIds) {
|
||||
if (trackIds.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String trackIdList = ContentProviderUtils.formatIdListForUri(trackIds);
|
||||
|
||||
uris.add(0, Uri.withAppendedPath(TracksColumns.CONTENT_URI, trackIdList));
|
||||
uris.add(1, Uri.withAppendedPath(TrackPointsColumns.CONTENT_URI_BY_TRACKID, trackIdList));
|
||||
ArrayList<Uri> uris = new ArrayList<>();
|
||||
uris.add(TRACK_URI_INDEX, Uri.withAppendedPath(TracksColumns.CONTENT_URI, trackIdList));
|
||||
uris.add(TRACKPOINTS_URI_INDEX, Uri.withAppendedPath(TrackPointsColumns.CONTENT_URI_BY_TRACKID, trackIdList));
|
||||
|
||||
Intent intent = new Intent(ACTION_DASHBOARD);
|
||||
intent.putParcelableArrayListExtra(ACTION_DASHBOARD_PAYLOAD, uris);
|
||||
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(EXTRAS_SHOULD_KEEP_SCREEN_ON, PreferencesUtils.shouldKeepScreenOn(context));
|
||||
intent.putExtra(EXTRAS_SHOW_WHEN_LOCKED, PreferencesUtils.shouldShowStatsOnLockscreen(context));
|
||||
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
ClipData clipData = ClipData.newRawUri(null, uris.get(0));
|
||||
clipData.addItem(new ClipData.Item(uris.get(1)));
|
||||
ClipData clipData = ClipData.newRawUri(null, uris.get(TRACK_URI_INDEX));
|
||||
clipData.addItem(new ClipData.Item(uris.get(TRACKPOINTS_URI_INDEX)));
|
||||
intent.setClipData(clipData);
|
||||
|
||||
if (intent.resolveActivity(context.getPackageManager()) != null) {
|
||||
context.startActivity(Intent.createChooser(intent, null));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void startDashboard(Context context, long trackId) {
|
||||
startDashboard(context, new long[]{trackId});
|
||||
}
|
||||
|
||||
public static long[] extractTrackIdsFromIntent(@NonNull Intent intent) {
|
||||
final ArrayList<Uri> uris = intent.getParcelableArrayListExtra(ACTION_DASHBOARD_PAYLOAD);
|
||||
final Uri tracksUri = uris.get(TRACK_URI_INDEX);
|
||||
|
||||
String[] trackIdsString = ContentProviderUtils.parseTrackIdsFromUri(tracksUri);
|
||||
long[] trackIds = new long[trackIdsString.length];
|
||||
for (int i = 0; i < trackIdsString.length; i++) {
|
||||
trackIds[i] = Long.parseLong(trackIdsString[i]);
|
||||
}
|
||||
|
||||
return trackIds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
|
||||
package de.dennisguse.opentracks.util;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
@@ -35,11 +33,9 @@ import java.util.Date;
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.content.DescriptionGenerator;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.TrackPointsColumns;
|
||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.content.provider.ShareContentProvider;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
|
||||
/**
|
||||
* Utilities for creating intents.
|
||||
@@ -92,9 +88,10 @@ public class IntentUtils {
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
if (track == null) {
|
||||
Log.e(TAG, "TrackId " + trackId + " could not be resolved.");
|
||||
continue;
|
||||
}
|
||||
|
||||
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(new long[]{trackId}, track.getName(), TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES);
|
||||
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(new long[]{trackId}, track.getName(), PreferencesUtils.getExportTrackFileFormat(context));
|
||||
uris.add(uriAndMime.first);
|
||||
mime = uriAndMime.second;
|
||||
}
|
||||
@@ -152,42 +149,11 @@ public class IntentUtils {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(uri));
|
||||
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(context, context.getString(R.string.app_not_installed_show_on_map), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
context.startActivity(Intent.createChooser(intent, null));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send intent to show tracks on a map (needs an another app).
|
||||
*
|
||||
* @param context the context
|
||||
* @param trackIds the track ids
|
||||
*/
|
||||
public static void showTrackOnMap(Context context, long[] trackIds) {
|
||||
if (trackIds.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IntentDashboardUtils.startDashboard(context, trackIds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(TrackPointsColumns.TRACKID, trackIds[0]);
|
||||
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, "SharingTrack", TrackFileFormat.KMZ_WITH_TRACKDETAIL);
|
||||
intent.setDataAndType(uriAndMime.first, uriAndMime.second);
|
||||
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (intent.resolveActivity(context.getPackageManager()) != null) {
|
||||
context.startActivity(intent);
|
||||
} else {
|
||||
Toast.makeText(context, context.getString(R.string.app_not_installed_show_on_map), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a take picture request to the camera app.
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
|
||||
/**
|
||||
* Utilities to access preferences stored in {@link SharedPreferences}.
|
||||
@@ -320,6 +321,16 @@ public class PreferencesUtils {
|
||||
return getInt(context, R.string.recording_gps_accuracy_key, RECORDING_GPS_ACCURACY);
|
||||
}
|
||||
|
||||
public static TrackFileFormat getExportTrackFileFormat(Context context) {
|
||||
final String TRACKFILEFORMAT_NAME_DEFAULT = getString(context, R.string.export_trackfileformat_default, null);
|
||||
String trackFileFormatName = getString(context, R.string.export_trackfileformat_key, TRACKFILEFORMAT_NAME_DEFAULT);
|
||||
try {
|
||||
return TrackFileFormat.valueOf(trackFileFormatName);
|
||||
} catch (Exception e) {
|
||||
return TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isRecording(Context context) {
|
||||
long recordingTrackId = getRecordingTrackId(context);
|
||||
return isRecording(recordingTrackId);
|
||||
|
||||
@@ -20,12 +20,16 @@ import android.location.Location;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Date;
|
||||
@@ -44,6 +48,8 @@ import de.dennisguse.opentracks.R;
|
||||
*/
|
||||
public class StringUtils {
|
||||
|
||||
private static final String TAG = StringUtils.class.getSimpleName();
|
||||
|
||||
private static final String COORDINATE_DEGREE = "\u00B0";
|
||||
|
||||
//TODO Remove when upgrading to API level 26+.
|
||||
@@ -280,22 +286,27 @@ public class StringUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time, in milliseconds, from an XML date time string as defined at http://www.w3.org/TR/xmlschema-2/#dateTime
|
||||
* Gets the time, in milliseconds, from an XML date time string (ISO8601) as defined at http://www.w3.org/TR/xmlschema-2/#dateTime
|
||||
* Let's be lenient: if timezone information is not provided, UTC will be used.
|
||||
*
|
||||
* @param xmlDateTime the XML date time string
|
||||
*/
|
||||
public static long parseTime(String xmlDateTime) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
try {
|
||||
TemporalAccessor t = DateTimeFormatter.ISO_DATE_TIME.parse(xmlDateTime);
|
||||
TemporalAccessor t = DateTimeFormatter.ISO_DATE_TIME.parseBest(xmlDateTime, ZonedDateTime::from, LocalDateTime::from);
|
||||
if (t instanceof LocalDateTime) {
|
||||
Log.w(TAG, "Date does not contain timezone information: using UTC.");
|
||||
t = ((LocalDateTime) t).atZone(ZoneOffset.UTC);
|
||||
}
|
||||
return Instant.from(t).toEpochMilli();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("Invalid XML dateTime value: " + e);
|
||||
Log.e(TAG, "Invalid XML dateTime value");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Remove the following when upgrading to API level 26+.
|
||||
//ATTENTION: The following code does not require a time zone (+01 or Z); while ISO_DATE_TIME requires this!
|
||||
|
||||
// Parse the date time base
|
||||
ParsePosition position = new ParsePosition(0);
|
||||
@@ -415,4 +426,8 @@ public class StringUtils {
|
||||
}
|
||||
return new Pair<>(value, unit);
|
||||
}
|
||||
|
||||
public static String valueInParentheses(String text) {
|
||||
return "(" + text + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class UintUtils {
|
||||
if (a < 0 || b < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (a > UINT_MAX && b > UINT_MAX) {
|
||||
if (a > UINT_MAX || b > UINT_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package de.dennisguse.opentracks.util;
|
||||
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class ViewUtils {
|
||||
|
||||
private ViewUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses all childs of {@link View} recursively and makes links within {@link TextView}s clickable.
|
||||
*/
|
||||
public static void makeClickableLinks(ViewGroup view) {
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < view.getChildCount(); i++) {
|
||||
final View child = view.getChildAt(i);
|
||||
if (child instanceof ViewGroup) {
|
||||
makeClickableLinks((ViewGroup) child);
|
||||
} else if (child instanceof TextView) {
|
||||
((TextView) child).setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package de.dennisguse.opentracks.viewmodels;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||
|
||||
public class AggregatedStatistics {
|
||||
|
||||
private HashMap<String, AggregatedStatistic> aggregatedStatistics = new HashMap<>();
|
||||
|
||||
public void aggregate(List<Track> tracks) {
|
||||
for (Track track : tracks) {
|
||||
aggregate(track);
|
||||
}
|
||||
}
|
||||
|
||||
public void aggregate(Track track) {
|
||||
String category = track.getCategory();
|
||||
if (aggregatedStatistics.containsKey(category)) {
|
||||
aggregatedStatistics.get(category).add(track.getTrackStatistics());
|
||||
} else {
|
||||
aggregatedStatistics.put(category, new AggregatedStatistic(track.getTrackStatistics()));
|
||||
}
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return aggregatedStatistics.size();
|
||||
}
|
||||
|
||||
public String getSportName(int position) {
|
||||
return getKey(position);
|
||||
}
|
||||
|
||||
public AggregatedStatistic get(String category) {
|
||||
return aggregatedStatistics.get(category);
|
||||
}
|
||||
|
||||
private String getKey(int position) {
|
||||
return (new ArrayList<>(aggregatedStatistics.keySet())).get(position);
|
||||
}
|
||||
|
||||
public AggregatedStatistic getItem(int position) {
|
||||
return (new ArrayList<>(aggregatedStatistics.values())).get(position);
|
||||
}
|
||||
|
||||
public static class AggregatedStatistic {
|
||||
private TrackStatistics trackStatistics;
|
||||
private int countTracks;
|
||||
|
||||
public AggregatedStatistic(TrackStatistics trackStatistics) {
|
||||
this.trackStatistics = trackStatistics;
|
||||
this.countTracks = 1;
|
||||
}
|
||||
|
||||
public TrackStatistics getTrackStatistics() {
|
||||
return trackStatistics;
|
||||
}
|
||||
|
||||
public int getCountTracks() {
|
||||
return countTracks;
|
||||
}
|
||||
|
||||
void add(TrackStatistics statistics) {
|
||||
trackStatistics.merge(statistics);
|
||||
countTracks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package de.dennisguse.opentracks.viewmodels;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||
|
||||
public class AggregatedStatisticsModel extends AndroidViewModel {
|
||||
|
||||
private MutableLiveData<AggregatedStatistics> aggregatedStats;
|
||||
|
||||
public AggregatedStatisticsModel(@NonNull Application application) {
|
||||
super(application);
|
||||
}
|
||||
|
||||
public LiveData<AggregatedStatistics> getAggregatedStats() {
|
||||
if (aggregatedStats == null) {
|
||||
aggregatedStats = new MutableLiveData<>();
|
||||
loadAggregatedStats();
|
||||
}
|
||||
return aggregatedStats;
|
||||
}
|
||||
|
||||
private void loadAggregatedStats() {
|
||||
new Thread(() -> {
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getApplication().getApplicationContext());
|
||||
List<Track> tracks = contentProviderUtils.getAllTracks();
|
||||
|
||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
||||
aggregatedStatistics.aggregate(tracks);
|
||||
|
||||
aggregatedStats.postValue(aggregatedStatistics);
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
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" />
|
||||
</vector>
|
||||
@@ -0,0 +1,33 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<group
|
||||
android:scaleX="0.56"
|
||||
android:scaleY="0.56"
|
||||
android:translateX="23.76"
|
||||
android:translateY="23.76">
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
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:strokeColor="#f69123">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startY="80.33152"
|
||||
android:startX="38.773293"
|
||||
android:endY="19.211866"
|
||||
android:endX="84.4913"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:offset="0"
|
||||
android:color="#FFFBB22F" />
|
||||
<item
|
||||
android:offset="1"
|
||||
android:color="#FFF58820" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM9,17L7,17v-7h2v7zM13,17h-2L11,7h2v10zM17,17h-2v-4h2v4z"/>
|
||||
</vector>
|
||||
@@ -6,82 +6,95 @@
|
||||
|
||||
<include layout="@layout/toolbar" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="239dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_logo_color_24dp" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
style="@style/TextLarge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/app_name"
|
||||
android:textSize="24sp" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<View style="@style/StatsHorizontalLine" />
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="239dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_logo_color_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/about_text_description"
|
||||
style="@style/TextMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="12dp" />
|
||||
<TextView
|
||||
style="@style/TextLarge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/app_name"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<View style="@style/StatsHorizontalLine" />
|
||||
<View style="@style/StatsHorizontalLine" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/about_text_version_name"
|
||||
style="@style/TextSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="6dp" />
|
||||
<TextView
|
||||
android:id="@+id/about_text_description"
|
||||
style="@style/TextMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="12dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/about_text_version_code"
|
||||
style="@style/TextSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="6dp" />
|
||||
<View style="@style/StatsHorizontalLine" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/about_app_url"
|
||||
style="@style/TextSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:gravity="center"
|
||||
android:padding="6dp" />
|
||||
<TextView
|
||||
android:id="@+id/about_text_version_name"
|
||||
style="@style/TextSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="6dp" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:gravity="center"
|
||||
android:padding="6dp"
|
||||
android:text="@string/about_history" />
|
||||
<TextView
|
||||
android:id="@+id/about_text_version_code"
|
||||
style="@style/TextSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="6dp" />
|
||||
|
||||
<View style="@style/StatsHorizontalLine" />
|
||||
<TextView
|
||||
android:id="@+id/about_app_url"
|
||||
style="@style/TextSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:gravity="center"
|
||||
android:padding="6dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="12dp"
|
||||
android:text="@string/about_libraries" />
|
||||
<TextView
|
||||
style="@style/TextSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="6dp"
|
||||
android:linksClickable="true"
|
||||
android:text="@string/about_history" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:gravity="center"
|
||||
android:text="@string/third_party_libraries" />
|
||||
<View style="@style/StatsHorizontalLine" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="12dp"
|
||||
android:text="@string/about_libraries" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:linksClickable="true"
|
||||
android:text="@string/third_party_libraries" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/toolbar" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/aggregated_stats_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1.0" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="24dp">
|
||||
|
||||
<!-- Guidelines -->
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_begin="8dp" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_end="8dp" />
|
||||
|
||||
<!-- Icon and sport name -->
|
||||
<ImageView
|
||||
android:id="@+id/aggregated_stats_sport_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintLeft_toLeftOf="@id/guideline1"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_activity_bike_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_type_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginBottom="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_sport_icon"
|
||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_sport_icon"
|
||||
app:layout_constraintTop_toTopOf="@+id/aggregated_stats_sport_icon"
|
||||
tools:text="@string/activity_type_cycling"
|
||||
android:layout_marginLeft="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_num_tracks"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginBottom="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_type_label"
|
||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_type_label"
|
||||
app:layout_constraintTop_toTopOf="@+id/aggregated_stats_type_label"
|
||||
tools:text="(1)"
|
||||
android:layout_marginLeft="4dp" />
|
||||
|
||||
<!-- Distance -->
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_distance"
|
||||
style="@style/StatsLargeValue"
|
||||
app:layout_constraintLeft_toLeftOf="@id/guideline1"
|
||||
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_sport_icon"
|
||||
tools:text="100000"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_distance_unit"
|
||||
style="@style/StatsUnit"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_distance"
|
||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_distance"
|
||||
tools:text="km" />
|
||||
|
||||
<!-- Time -->
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_time"
|
||||
style="@style/StatsLargeValue"
|
||||
app:layout_constraintRight_toRightOf="@id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_sport_icon"
|
||||
tools:text="00:00:00"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp" />
|
||||
|
||||
<!-- Avg. rate -->
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_avg_rate"
|
||||
style="@style/StatsSmallValue"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintTop_toBottomOf="@id/aggregated_stats_distance"
|
||||
app:layout_constraintLeft_toRightOf="@id/guideline1"
|
||||
app:layout_constraintRight_toLeftOf="@+id/aggregated_stats_avg_rate_unit"
|
||||
android:layout_marginTop="24dp"
|
||||
tools:text="30" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_avg_rate_unit"
|
||||
style="@style/StatsUnit"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_avg_rate"
|
||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_avg_rate"
|
||||
app:layout_constraintRight_toRightOf="@id/guideline2"
|
||||
tools:text="km/h" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_avg_rate_label"
|
||||
style="@style/StatsTinyLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_avg_rate"
|
||||
app:layout_constraintLeft_toRightOf="@id/guideline1"
|
||||
app:layout_constraintRight_toRightOf="@id/guideline2"
|
||||
tools:text="@string/stats_average_moving_speed" />
|
||||
|
||||
<!-- Max. rate -->
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_max_rate"
|
||||
style="@style/StatsSmallValue"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintTop_toBottomOf="@id/aggregated_stats_time"
|
||||
app:layout_constraintLeft_toRightOf="@id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/aggregated_stats_max_rate_unit"
|
||||
android:layout_marginTop="24dp"
|
||||
tools:text="70" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_max_rate_unit"
|
||||
style="@style/StatsUnit"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_max_rate"
|
||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_max_rate"
|
||||
app:layout_constraintRight_toLeftOf="@id/guideline3"
|
||||
tools:text="km/h" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aggregated_stats_max_rate_label"
|
||||
style="@style/StatsTinyLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_max_rate"
|
||||
app:layout_constraintLeft_toRightOf="@id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@id/guideline3"
|
||||
tools:text="@string/stats_max_speed" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,213 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/StatsScrollView">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- Guidelines -->
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_begin="8dp" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_end="8dp" />
|
||||
|
||||
<!-- Distance -->
|
||||
<TextView
|
||||
android:id="@+id/stats_distance_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_distance"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_distance_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_distance_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_distance_label"
|
||||
tools:text="100" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_distance_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_distance_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
tools:text="km" />
|
||||
|
||||
<!-- Activity Type -->
|
||||
<TextView
|
||||
android:id="@+id/stats_activity_type_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/track_edit_activity_type_hint"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/stats_activity_type_icon"
|
||||
style="@style/StatsLargeValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
||||
app:layout_constraintTop_toTopOf="@+id/stats_distance_value" />
|
||||
|
||||
<!-- Total time -->
|
||||
<TextView
|
||||
android:id="@+id/stats_total_time_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_total_time"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_distance_value" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_total_time_value"
|
||||
style="@style/StatsLargeValue"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_total_time_label"
|
||||
tools:text="00:00:00" />
|
||||
|
||||
<!-- Moving time -->
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_time_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_moving_time"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toTopOf="@+id/stats_total_time_label"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_total_time_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_time_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_time_label"
|
||||
tools:text="00:00:00" />
|
||||
|
||||
<!-- Horizontal line -->
|
||||
<View
|
||||
android:id="@+id/stats_speed_horizontal_line"
|
||||
style="@style/StatsHorizontalLine"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_time_value" />
|
||||
|
||||
<!-- Average speed/pace -->
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
||||
tools:text="Avg. Speed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_average_speed_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_average_speed_label"
|
||||
tools:text="30.00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_average_speed_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_average_speed_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
tools:text="km/h" />
|
||||
|
||||
<!-- Speed max -->
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
||||
tools:text="Max. Speed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_max_speed_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_max_speed_label"
|
||||
tools:text="30.00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_max_speed_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_max_speed_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
tools:text="km/h" />
|
||||
|
||||
<!-- Moving speed max -->
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
||||
tools:text="Max. Moving Speed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_moving_speed_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_speed_label"
|
||||
tools:text="30.00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_moving_speed_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_moving_speed_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
tools:text="km/h" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
@@ -0,0 +1,430 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/StatsScrollView">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- Guidelines -->
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_begin="8dp" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_end="8dp" />
|
||||
|
||||
<!-- Distance -->
|
||||
<TextView
|
||||
android:id="@+id/stats_distance_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_distance"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_distance_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_distance_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_distance_label"
|
||||
tools:text="100" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_distance_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_distance_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
tools:text="km" />
|
||||
|
||||
<!-- Activity Type -->
|
||||
<TextView
|
||||
android:id="@+id/stats_activity_type_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/track_edit_activity_type_hint"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/stats_activity_type_icon"
|
||||
style="@style/StatsLargeValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
||||
app:layout_constraintTop_toTopOf="@+id/stats_distance_value" />
|
||||
|
||||
<!-- Total time -->
|
||||
<TextView
|
||||
android:id="@+id/stats_total_time_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_total_time"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_distance_value" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_total_time_value"
|
||||
style="@style/StatsLargeValue"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_total_time_label"
|
||||
tools:text="00:00:00" />
|
||||
|
||||
<!-- Moving time -->
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_time_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_moving_time"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toTopOf="@+id/stats_total_time_label"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_total_time_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_time_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_time_label"
|
||||
tools:text="00:00:00" />
|
||||
|
||||
<!-- Horizontal line -->
|
||||
<View
|
||||
android:id="@+id/stats_speed_horizontal_line"
|
||||
style="@style/StatsHorizontalLine"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_time_value" />
|
||||
|
||||
<!-- Speed/pace -->
|
||||
<TextView
|
||||
android:id="@+id/stats_speed_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
||||
tools:text="Speed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_speed_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_speed_label"
|
||||
tools:text="30.00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_speed_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_speed_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_speed_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
tools:text="km/h" />
|
||||
|
||||
<!-- Average speed/pace -->
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
||||
tools:text="Avg. Speed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_average_speed_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_average_speed_label"
|
||||
tools:text="30.00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_average_speed_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_average_speed_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
tools:text="km/h" />
|
||||
|
||||
<!-- Speed max -->
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
||||
tools:text="Max. Speed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_max_speed_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_max_speed_label"
|
||||
tools:text="30.00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_max_speed_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_max_speed_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
tools:text="km/h" />
|
||||
|
||||
<!-- Moving speed max -->
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
||||
tools:text="Max. Moving Speed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_moving_speed_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_speed_label"
|
||||
tools:text="30.00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_moving_speed_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_moving_speed_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
tools:text="km/h" />
|
||||
|
||||
<!-- Horizontal line -->
|
||||
<View
|
||||
android:id="@+id/stats_elevation_horizontal_line"
|
||||
style="@style/StatsHorizontalLine"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_speed_value" />
|
||||
|
||||
<!-- Current elevation -->
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/stats_elevation_current_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="stats_elevation_current_label,stats_elevation_current_value,stats_elevation_current_unit,stats_elevation_horizontal_line" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_elevation_current_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
android:text="@string/stats_elevation"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_elevation_horizontal_line" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_elevation_current_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/stats_elevation_current_unit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_current_label"
|
||||
tools:text="100" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_elevation_current_unit"
|
||||
style="@style/StatsUnit"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/stats_elevation_current_value"
|
||||
app:layout_constraintLeft_toRightOf="@+id/stats_elevation_current_value"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
tools:text="m" />
|
||||
|
||||
<!-- Coordinate group -->
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/stats_coordinate_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="stats_latitude_label,stats_latitude_value,stats_longitude_label,stats_longitude_value,stats_coordinate_horizontal_line" />
|
||||
|
||||
<!-- Horizontal line -->
|
||||
<View
|
||||
android:id="@+id/stats_coordinate_horizontal_line"
|
||||
style="@style/StatsHorizontalLine"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_current_value" />
|
||||
|
||||
<!-- Latitude -->
|
||||
<TextView
|
||||
android:id="@+id/stats_latitude_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
android:text="@string/stats_latitude"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_coordinate_horizontal_line" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_latitude_value"
|
||||
style="@style/StatsSmallValue"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_latitude_label"
|
||||
tools:text="0.834937848" />
|
||||
|
||||
<!-- Longitude -->
|
||||
<TextView
|
||||
android:id="@+id/stats_longitude_label"
|
||||
style="@style/StatsSmallLabel"
|
||||
android:text="@string/stats_longitude"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_coordinate_horizontal_line" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_longitude_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_longitude_label"
|
||||
tools:text="0.834937848" />
|
||||
|
||||
<!-- Horizontal line -->
|
||||
<View
|
||||
android:id="@+id/stats_sensor_horizontal_line"
|
||||
style="@style/StatsHorizontalLine"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_latitude_value" />
|
||||
|
||||
<!-- Heart rate -->
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/stats_sensor_heart_rate_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="stats_sensor_heart_rate_label,stats_sensor_heart_rate_sensor_value,stats_sensor_heart_rate_value,stats_sensor_heart_rate_unit" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_heart_rate_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/sensor_state_heart_rate"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_sensor_horizontal_line" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_heart_rate_sensor_value"
|
||||
style="@style/StatsTinyValue"
|
||||
android:text="@string/value_unknown"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_heart_rate_label"
|
||||
tools:text="90" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_heart_rate_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_heart_rate_sensor_value"
|
||||
tools:text="90" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_heart_rate_unit"
|
||||
style="@style/StatsUnit"
|
||||
android:text="@string/sensor_unit_beats_per_minute"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_heart_rate_value" />
|
||||
|
||||
<!-- Cadence -->
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/stats_sensor_cadence_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="stats_sensor_cadence_label,stats_sensor_cadence_sensor_value,stats_sensor_cadence_value,stats_sensor_cadence_unit" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_cadence_label"
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/sensor_state_cadence"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_sensor_horizontal_line" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_cadence_sensor_value"
|
||||
style="@style/StatsTinyValue"
|
||||
android:text="@string/value_unknown"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_cadence_label"
|
||||
tools:text="90" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_cadence_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_cadence_sensor_value"
|
||||
tools:text="90" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_cadence_unit"
|
||||
style="@style/StatsUnit"
|
||||
android:text="@string/sensor_unit_rounds_per_minute"
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_cadence_value" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
@@ -1,332 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2010 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.
|
||||
-->
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/StatsScrollView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Distance and activity type -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<!-- Distance -->
|
||||
<LinearLayout style="@style/StatsLargeItemContainer">
|
||||
|
||||
<TextView
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_distance" />
|
||||
|
||||
<LinearLayout style="@style/StatsLargeValueContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_distance_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_distance_unit"
|
||||
style="@style/StatsUnit" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Activity type -->
|
||||
<include
|
||||
android:id="@+id/stats_activity_type"
|
||||
layout="@layout/stats_activity_type" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Total time and moving time -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- Total time -->
|
||||
<LinearLayout style="@style/StatsLargeItemContainer">
|
||||
|
||||
<TextView
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_total_time" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_total_time_value"
|
||||
style="@style/StatsLargeValue" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Moving time -->
|
||||
<LinearLayout style="@style/StatsLargeItemContainer">
|
||||
|
||||
<TextView
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/stats_moving_time" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_time_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Horizontal line -->
|
||||
<View style="@style/StatsHorizontalLine" />
|
||||
|
||||
<!-- Speed/pace and average -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- Speed/pace -->
|
||||
<LinearLayout
|
||||
android:id="@+id/stats_speed"
|
||||
style="@style/StatsSmallItemContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_speed_label"
|
||||
style="@style/StatsSmallLabel" />
|
||||
|
||||
<LinearLayout style="@style/StatsSmallValueContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_speed_unit"
|
||||
style="@style/StatsUnit" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Average -->
|
||||
<LinearLayout style="@style/StatsSmallItemContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_label"
|
||||
style="@style/StatsSmallLabel" />
|
||||
|
||||
<LinearLayout style="@style/StatsSmallValueContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_average_speed_unit"
|
||||
style="@style/StatsUnit" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Speed max and moving -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- Speed max -->
|
||||
<LinearLayout style="@style/StatsSmallItemContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_label"
|
||||
style="@style/StatsSmallLabel" />
|
||||
|
||||
<LinearLayout style="@style/StatsSmallValueContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_max_speed_unit"
|
||||
style="@style/StatsUnit" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Speed moving -->
|
||||
<LinearLayout style="@style/StatsSmallItemContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_label"
|
||||
style="@style/StatsSmallLabel" />
|
||||
|
||||
<LinearLayout style="@style/StatsSmallValueContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_moving_speed_unit"
|
||||
style="@style/StatsUnit" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/stats_elevation_separator"
|
||||
style="@style/StatsHorizontalLine" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/stats_elevation_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout style="@style/StatsSmallGroupContainer">
|
||||
<!-- This is a placeholder -->
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Elevation -->
|
||||
<LinearLayout style="@style/StatsSmallGroupContainer">
|
||||
|
||||
<TextView
|
||||
style="@style/StatsSmallLabel"
|
||||
android:text="@string/stats_elevation" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<!-- Current elevation -->
|
||||
<LinearLayout
|
||||
style="@style/StatsSmallValueContainer"
|
||||
android:layout_gravity="start|bottom">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_elevation_current_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_elevation_current_unit"
|
||||
style="@style/StatsUnit" />
|
||||
</LinearLayout>
|
||||
</TableLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Horizontal line -->
|
||||
<View
|
||||
android:id="@+id/stats_coordinate_separator"
|
||||
style="@style/StatsHorizontalLine" />
|
||||
|
||||
<!-- Latitude and longitude -->
|
||||
<LinearLayout
|
||||
android:id="@+id/stats_coordinate_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout style="@style/StatsSmallItemContainer">
|
||||
|
||||
<TextView
|
||||
style="@style/StatsSmallLabel"
|
||||
android:text="@string/stats_latitude" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_latitude_value"
|
||||
style="@style/StatsSmallValue" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout style="@style/StatsSmallItemContainer">
|
||||
|
||||
<TextView
|
||||
style="@style/StatsSmallLabel"
|
||||
android:text="@string/stats_longitude" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_longitude_value"
|
||||
style="@style/StatsSmallValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/stats_sensor_separator"
|
||||
style="@style/StatsHorizontalLine" />
|
||||
|
||||
<!-- Sensor data -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/stats_sensor_heart_rate_container"
|
||||
style="@style/StatsLargeItemContainer">
|
||||
|
||||
<TextView
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/sensor_state_heart_rate" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_heart_rate_sensor_value"
|
||||
style="@style/StatsTinyValue"
|
||||
android:text="@string/value_unknown" />
|
||||
|
||||
<LinearLayout style="@style/StatsLargeValueContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_heart_rate_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
<TextView
|
||||
style="@style/StatsUnit"
|
||||
android:text="@string/sensor_unit_beats_per_minute" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/stats_sensor_cadence_container"
|
||||
style="@style/StatsLargeItemContainer">
|
||||
|
||||
<TextView
|
||||
style="@style/StatsLargeLabel"
|
||||
android:text="@string/sensor_state_cadence" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_cadence_sensor_value"
|
||||
style="@style/StatsTinyValue"
|
||||
android:text="@string/value_unknown" />
|
||||
|
||||
<LinearLayout style="@style/StatsLargeValueContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_sensor_cadence_value"
|
||||
style="@style/StatsLargeValue"
|
||||
android:value="@string/value_unknown" />
|
||||
|
||||
<TextView
|
||||
style="@style/StatsUnit"
|
||||
android:text="@string/sensor_unit_rounds_per_minute" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
@@ -32,6 +32,4 @@ limitations under the License.
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<include layout="@layout/track_controller" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/toolbar" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/track_detail_activity_tablayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabIndicatorColor="@color/holo_orange_dark" />
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/track_detail_activity_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<include layout="@layout/track_controller" />
|
||||
</LinearLayout>
|
||||
@@ -15,12 +15,6 @@ limitations under the License.
|
||||
-->
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/track_detail_insert_marker"
|
||||
android:icon="@drawable/ic_marker_add_24dp"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom"
|
||||
android:title="@string/menu_insert_marker" />
|
||||
<item
|
||||
android:id="@+id/track_detail_menu_show_on_map"
|
||||
android:icon="@drawable/ic_map_24dp"
|
||||
|
||||
@@ -28,6 +28,11 @@ limitations under the License.
|
||||
android:title="@string/menu_start_gps"
|
||||
android:visible="false"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/track_list_aggregated_stats"
|
||||
android:icon="@drawable/ic_statistics_24dp"
|
||||
android:title="@string/menu_aggregated_statistics"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/track_list_markers"
|
||||
android:icon="@drawable/ic_marker_show_24dp"
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2011 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.
|
||||
-->
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/track_detail_insert_marker"
|
||||
android:icon="@drawable/ic_marker_add_24dp"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom"
|
||||
android:title="@string/menu_insert_marker" />
|
||||
<item
|
||||
android:id="@+id/track_detail_menu_show_on_map"
|
||||
android:icon="@drawable/ic_map_24dp"
|
||||
app:showAsAction="ifRoom"
|
||||
android:title="@string/menu_show_on_map" />
|
||||
<item
|
||||
android:id="@+id/track_detail_markers"
|
||||
android:icon="@drawable/ic_marker_show_24dp"
|
||||
android:orderInCategory="5"
|
||||
app:showAsAction="ifRoom"
|
||||
android:title="@string/menu_markers" />
|
||||
<item
|
||||
android:id="@+id/track_detail_edit"
|
||||
android:icon="@drawable/ic_edit_24dp"
|
||||
android:orderInCategory="9"
|
||||
android:title="@string/menu_edit" />
|
||||
<item
|
||||
android:id="@+id/track_detail_settings"
|
||||
android:icon="@drawable/ic_settings_24dp"
|
||||
android:orderInCategory="13"
|
||||
android:title="@string/menu_settings" />
|
||||
</menu>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?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" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_debug_background" />
|
||||
<foreground android:drawable="@drawable/ic_logo_color_108dp" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
@@ -133,13 +133,9 @@
|
||||
<string name="generic_yes">نعم</string>
|
||||
<string name="gps_location_access">\"الدخول إلى الموقع\"</string>
|
||||
<string name="gps_disabled">نظام تحديد المواقع العالمي (GPS) غير ممكّن. انقر هنا للانتقال إلى %1$s. اضغط على زر الرجوع للعودة.</string>
|
||||
<string name="gps_disabled_location_mode">حدد وضع تحديد الموقع بدقة عالية. انقر هنا للانتقال إلى %1$s. اضغط على زر الرجوع للعودة.</string>
|
||||
<string name="gps_disabled_my_location">لا يمكن تحديد الموقع الحالي. تستطيع تمكين مصادر أكثر للموقع على %1$s وتأكد من أنك في مكان مفتوح. حاول مرة أخرى في وقت لاحق.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">لا يمكن تحديد الموقع الحالي. يمكنك تحديد وضع تحديد الموقع بدقة عالية على %1$s وتأكد من أنك في مكان مفتوح. حاول مرة أخرى في وقت لاحق.</string>
|
||||
<string name="gps_not_found">لم يتم العثور على نظام تحديد المواقع (GPS) على الجهاز</string>
|
||||
<string name="gps_starting">بدء نظام تحديد المواقع العالمي (GPS)</string>
|
||||
<string name="gps_starting_error">تعذر تشغيل نظام تحديد المواقع العالمي (GPS)</string>
|
||||
<string name="gps_stopping">جارٍ إيقاف نظام تحديد المواقع العالمي (GPS)</string>
|
||||
<string name="gps_wait_for_better_signal">في انتظار إشارة أفضل لنظام تحديد المواقع العالمي (GPS)</string>
|
||||
<string name="gps_wait_for_signal">في انتظار إشارة نظام تحديد المواقع العالمي (GPS)</string>
|
||||
<string name="image_application">تطبيق</string>
|
||||
@@ -178,20 +174,13 @@
|
||||
<string name="marker_list_empty_message">ليس لديك أية علامات</string>
|
||||
<string name="menu_aggregated_statistics">الإحصاءات المجمعة</string>
|
||||
<string name="menu_delete">حذف</string>
|
||||
<string name="menu_delete_all">حذف الكل</string>
|
||||
<string name="menu_edit">تعديل</string>
|
||||
<string name="menu_export">تصدير</string>
|
||||
<string name="menu_export_all">تصدير جميع المسارات</string>
|
||||
<string name="menu_feedback">تعليقات</string>
|
||||
<string name="menu_help">مساعدة</string>
|
||||
<string name="menu_help_feedback">المساعدة والتعليقات</string>
|
||||
<string name="menu_help_forum">منتدى المساعدة</string>
|
||||
<string name="menu_import_all">استيراد جميع المسارات</string>
|
||||
<string name="menu_insert_marker">إدراج مُحدد</string>
|
||||
<string name="menu_insert_photo">جارٍ إدراج الصورة</string>
|
||||
<string name="menu_map">الخريطة</string>
|
||||
<string name="menu_markers">العلامات</string>
|
||||
<string name="menu_play">تشغيل</string>
|
||||
<string name="menu_search">بحث</string>
|
||||
<string name="menu_select_all">تحديد الكل</string>
|
||||
<string name="menu_sensor_state">حالة المستشعر</string>
|
||||
@@ -208,19 +197,14 @@
|
||||
<string name="search_global_description">المسارات والمحددات</string>
|
||||
<string name="search_list_empty_message">لم يطابق بحثك أي مسارات أو علامات</string>
|
||||
<string name="search_list_marker_track_location">في المسار ‘%1$s’.</string>
|
||||
<string name="search_voice_prompt">انطق اسم مسار أو علامة</string>
|
||||
<string name="sensor_state_battery">مستوى شحن البطارية</string>
|
||||
<string name="sensor_state_cadence">الإيقاع</string>
|
||||
<string name="sensor_state_cadence_value">%1$d دورة في الدقيقة</string>
|
||||
<string name="sensor_state_connected">متصل</string>
|
||||
<string name="sensor_state_connecting">اتصال</string>
|
||||
<string name="sensor_state_disconnected">غير متصل</string>
|
||||
<string name="sensor_state_heart_rate">معدل ضربات القلب</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d نبضة في الدقيقة</string>
|
||||
<string name="sensor_state_last_sensor_time">آخر وقت للمستشعر</string>
|
||||
<string name="sensor_state_power">الطاقة</string>
|
||||
<string name="sensor_state_power_value">%1$d واط</string>
|
||||
<string name="sensor_state_sending">إرسال</string>
|
||||
<string name="settings_not_while_recording">غير متاح أثناء تسجيل مسار</string>
|
||||
<string name="settings_show">إظهار</string>
|
||||
<string name="settings_advanced">خيارات متقدمة</string>
|
||||
@@ -249,22 +233,13 @@
|
||||
<string name="settings_reset_confirm_title">إعادة التعيين الآن؟</string>
|
||||
<string name="settings_reset_done">لقد تمت إعادة جميع الإعدادات إلى القيم الافتراضية</string>
|
||||
<string name="settings_sensor">المستشعر</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">إعادة ضبط إيقاع الدراجة</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">إعادة ضبط الدراجة المجمعة</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">إعادة ضبط معدل نبضات القلب</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">إعادة تعيين لوحة القدم</string>
|
||||
<string name="settings_sensor_bluetooth">البلوتوث</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">اقتران البلوتوث</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">فتح إعدادات بلوتوث في Android لإقران الجهاز</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">مستشعر بلوتوث</string>
|
||||
<string name="settings_sensor_connected">تم التوصيل بـ %1$s</string>
|
||||
<string name="settings_stats_coordinate">خط العرض/خط الطول</string>
|
||||
<string name="settings_stats_rate_title">المعدل المفضل</string>
|
||||
<string name="settings_stats_units_imperial">وحدات القياس البريطانية (ميل، قدم)</string>
|
||||
<string name="settings_stats_units_metric">وحدات القياس المترية (كم، م)</string>
|
||||
<string name="settings_stats_units_title">الوحدات المفضلة</string>
|
||||
<string name="share_track_emails_hint">عناوين البريد الإلكتروني</string>
|
||||
<string name="share_track_picker_title">حدد تطبيقًا</string>
|
||||
<string name="share_track_share_file">مشاركة ملف مسار</string>
|
||||
<string name="share_track_share_file_body">أعتقد أنك قد تكون مهتمًا بهذا المسار.\n\nلعرض هذا المسار، استخدام برنامج Google Earth أو غيره من البرامج تصميم الخرائط.\n\n%1$s</string>
|
||||
<string name="share_track_subject">أريد مشاركة مسار معك</string>
|
||||
@@ -299,9 +274,6 @@
|
||||
<string name="track_edit_activity_type_hint">نوع النشاط</string>
|
||||
<string name="track_edit_new_track_title">مسار جديد</string>
|
||||
<string name="track_list_empty_message">بدء تسجيل مغامرتك التالية هنا</string>
|
||||
<string name="track_list_record_error">يتعذر بدء التسجيل. ليس هناك إشارة بنظام تحديد المواقع العالمي (GPS). حاول مرة أخرى.</string>
|
||||
<string name="track_list_record_success">جارٍ الآن تسجيل مسار جديد</string>
|
||||
<string name="track_widget_config_title">تهيئة عناصر الأداة</string>
|
||||
<string name="tracks_few">%1$d مسارات</string>
|
||||
<string name="tracks_many">%1$d مسارًا</string>
|
||||
<string name="tracks_one">1 مسار</string>
|
||||
@@ -327,10 +299,8 @@
|
||||
<string name="value_integer_feet">%1$d قدم</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d قدم (إشارة نظام تحديد المواقع ممتازة)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d قدم (موصى به)</string>
|
||||
<string name="value_integer_kilobyte">%1$d كيلوبايت</string>
|
||||
<string name="value_integer_kilometer">%1$d كم</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d كم/ساعة</string>
|
||||
<string name="value_integer_megabyte">%1$d ميغابايت</string>
|
||||
<string name="value_integer_meter">%1$d م</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d م (إشارة نظام تحديد المواقع ممتازة)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d م (إشارة نظام تحديد المواقع سيئة)</string>
|
||||
@@ -340,7 +310,6 @@
|
||||
<string name="value_integer_minute">%1$d دقيقة</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d ث</string>
|
||||
<string name="value_never">مطلقًا</string>
|
||||
<string name="value_none">لا شيء</string>
|
||||
<string name="value_off">إيقاف</string>
|
||||
<string name="value_smallest">الأصغر</string>
|
||||
|
||||
@@ -133,13 +133,9 @@
|
||||
<string name="generic_yes">Yes</string>
|
||||
<string name="gps_location_access">\'Location access\'</string>
|
||||
<string name="gps_disabled">GPS not enabled. Tap here to go to %1$s. Press the back button to return.</string>
|
||||
<string name="gps_disabled_location_mode">Select high-accuracy location mode. Tap here to go to %1$s. Press the back button to return.</string>
|
||||
<string name="gps_disabled_my_location">Current location cannot be determined. Enable more location sources at %1$s and make sure the sky is visible. Try again later.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">Current location cannot be determined. Select the high-accuracy location mode at %1$s and make sure the sky is visible. Try again later.</string>
|
||||
<string name="gps_not_found">No GPS found on the device</string>
|
||||
<string name="gps_starting">Starting GPS</string>
|
||||
<string name="gps_starting_error">Unable to start GPS</string>
|
||||
<string name="gps_stopping">Stopping GPS</string>
|
||||
<string name="gps_wait_for_better_signal">Waiting for a better GPS signal</string>
|
||||
<string name="gps_wait_for_signal">Waiting for GPS signal</string>
|
||||
<string name="image_application">Application</string>
|
||||
@@ -178,20 +174,13 @@
|
||||
<string name="marker_list_empty_message">You don\'t have any markers</string>
|
||||
<string name="menu_aggregated_statistics">Aggregated stats</string>
|
||||
<string name="menu_delete">Delete</string>
|
||||
<string name="menu_delete_all">Delete all</string>
|
||||
<string name="menu_edit">Edit</string>
|
||||
<string name="menu_export">Export</string>
|
||||
<string name="menu_export_all">Export all</string>
|
||||
<string name="menu_feedback">Feedback</string>
|
||||
<string name="menu_help">Help</string>
|
||||
<string name="menu_help_feedback">Help & feedback</string>
|
||||
<string name="menu_help_forum">Help forum</string>
|
||||
<string name="menu_import_all">Import all</string>
|
||||
<string name="menu_insert_marker">Insert marker</string>
|
||||
<string name="menu_insert_photo">Insert photo</string>
|
||||
<string name="menu_map">Map</string>
|
||||
<string name="menu_markers">Markers</string>
|
||||
<string name="menu_play">Play</string>
|
||||
<string name="menu_search">Search</string>
|
||||
<string name="menu_select_all">Select all</string>
|
||||
<string name="menu_sensor_state">Sensor state</string>
|
||||
@@ -208,19 +197,14 @@
|
||||
<string name="search_global_description">Tracks and markers</string>
|
||||
<string name="search_list_empty_message">No tracks or markers matched your search</string>
|
||||
<string name="search_list_marker_track_location">In track ‘%1$s’.</string>
|
||||
<string name="search_voice_prompt">Say the name of a track or marker</string>
|
||||
<string name="sensor_state_battery">Battery level</string>
|
||||
<string name="sensor_state_cadence">Cadence</string>
|
||||
<string name="sensor_state_cadence_value">%1$d rpm</string>
|
||||
<string name="sensor_state_connected">Connected</string>
|
||||
<string name="sensor_state_connecting">Connecting</string>
|
||||
<string name="sensor_state_disconnected">Disconnected</string>
|
||||
<string name="sensor_state_heart_rate">Heart rate</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d bpm</string>
|
||||
<string name="sensor_state_last_sensor_time">Last sensor time</string>
|
||||
<string name="sensor_state_power">Power</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">Sending</string>
|
||||
<string name="settings_not_while_recording">Not available while recording a track</string>
|
||||
<string name="settings_show">Show</string>
|
||||
<string name="settings_advanced">Advanced</string>
|
||||
@@ -249,22 +233,13 @@
|
||||
<string name="settings_reset_confirm_title">Reset now?</string>
|
||||
<string name="settings_reset_done">All settings have been reverted to default values</string>
|
||||
<string name="settings_sensor">Sensor</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Reset bike cadence</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Reset combined bike</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Reset heart rate</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Reset foot pod</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Bluetooth pairing</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Open Android\'s Bluetooth settings to pair a sensor</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Bluetooth sensor</string>
|
||||
<string name="settings_sensor_connected">Connected to %1$s</string>
|
||||
<string name="settings_stats_coordinate">Latitude/Longitude</string>
|
||||
<string name="settings_stats_rate_title">Preferred rate</string>
|
||||
<string name="settings_stats_units_imperial">Imperial (miles, ft)</string>
|
||||
<string name="settings_stats_units_metric">Metric (km, m)</string>
|
||||
<string name="settings_stats_units_title">Preferred units</string>
|
||||
<string name="share_track_emails_hint">Email addresses</string>
|
||||
<string name="share_track_picker_title">Select an application</string>
|
||||
<string name="share_track_share_file">Share track file</string>
|
||||
<string name="share_track_share_file_body">I think you might be interested in this track.\n\nTo view this track, use Google Earth or other
|
||||
mapping software.\n\n%1$s</string>
|
||||
@@ -300,9 +275,6 @@
|
||||
<string name="track_edit_activity_type_hint">Activity type</string>
|
||||
<string name="track_edit_new_track_title">New Track</string>
|
||||
<string name="track_list_empty_message">Start recording your next adventure here</string>
|
||||
<string name="track_list_record_error">Unable to start recording. No GPS signal. Try again.</string>
|
||||
<string name="track_list_record_success">Now recording a new track</string>
|
||||
<string name="track_widget_config_title">Configure Widget Items</string>
|
||||
<string name="tracks_few">%1$d tracks</string>
|
||||
<string name="tracks_many">%1$d tracks</string>
|
||||
<string name="tracks_one">1 track</string>
|
||||
@@ -328,10 +300,8 @@
|
||||
<string name="value_integer_feet">%1$d ft</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d ft (excellent GPS)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d ft (recommended)</string>
|
||||
<string name="value_integer_kilobyte">%1$d kB</string>
|
||||
<string name="value_integer_kilometer">%1$d km</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d km/h</string>
|
||||
<string name="value_integer_megabyte">%1$d MB</string>
|
||||
<string name="value_integer_meter">%1$d m</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d m (excellent GPS)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d m (poor GPS)</string>
|
||||
@@ -341,7 +311,6 @@
|
||||
<string name="value_integer_minute">%1$d min</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d s</string>
|
||||
<string name="value_never">Never</string>
|
||||
<string name="value_none">None</string>
|
||||
<string name="value_off">Off</string>
|
||||
<string name="value_smallest">Smallest</string>
|
||||
|
||||
@@ -133,13 +133,9 @@
|
||||
<string name="generic_yes">Sí</string>
|
||||
<string name="gps_location_access">“Acceso a ubicaciones”</string>
|
||||
<string name="gps_disabled">El GPS no está habilitado. Puntea aquí para ir a %1$s. Para volver, presiona el botón Atrás.</string>
|
||||
<string name="gps_disabled_location_mode">Selecciona el modo de ubicación de alta precisión. Toca aquí para acceder a %1$s. Para volver a la pantalla anterior, presiona el botón Atrás.</string>
|
||||
<string name="gps_disabled_my_location">No se puede determinar la ubicación actual. Habilita más fuentes de ubicación en %1$s y asegúrate de que se pueda ver el cielo. Vuelve a intentarlo más tarde.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">No se puede determinar la ubicación actual. Selecciona el modo de ubicación de alta precisión en %1$s y asegúrate de que se pueda ver el cielo. Vuelve a intentarlo más tarde.</string>
|
||||
<string name="gps_not_found">No se encontró ningún GPS en el dispositivo.</string>
|
||||
<string name="gps_starting">Iniciando GPS</string>
|
||||
<string name="gps_starting_error">No se puede iniciar el GPS.</string>
|
||||
<string name="gps_stopping">Deteniendo GPS</string>
|
||||
<string name="gps_wait_for_better_signal">Esperando una mejor señal de GPS</string>
|
||||
<string name="gps_wait_for_signal">Esperando señal de GPS</string>
|
||||
<string name="image_application">Aplicación</string>
|
||||
@@ -178,21 +174,14 @@
|
||||
<string name="marker_list_empty_message">No tienes ningún marcador.</string>
|
||||
<string name="menu_aggregated_statistics">Estadíst. globales</string>
|
||||
<string name="menu_delete">Eliminar</string>
|
||||
<string name="menu_delete_all">Eliminar todos</string>
|
||||
<string name="menu_edit">Editar</string>
|
||||
<string name="menu_export">Exportar</string>
|
||||
<string name="menu_export_all">Exportar todo</string>
|
||||
<string name="menu_feedback">Comentarios</string>
|
||||
<string name="menu_help">Ayuda</string>
|
||||
<string name="menu_help_feedback">Ayuda y comentarios</string>
|
||||
<string name="menu_help_forum">Foro de ayuda</string>
|
||||
<string name="menu_import_all">Importar todo</string>
|
||||
<string name="menu_insert_marker">Insertar marcador</string>
|
||||
<string name="menu_insert_photo">Insertar foto</string>
|
||||
<string name="menu_insert_gallery_img">Insertar imagen de galería</string>
|
||||
<string name="menu_map">Mapa</string>
|
||||
<string name="menu_markers">Marcadores</string>
|
||||
<string name="menu_play">Reproducir</string>
|
||||
<string name="menu_search">Buscar</string>
|
||||
<string name="menu_select_all">Seleccionar todo</string>
|
||||
<string name="menu_sensor_state">Estado del sensor</string>
|
||||
@@ -210,19 +199,14 @@
|
||||
<string name="search_global_description">Recorridos y marcadores</string>
|
||||
<string name="search_list_empty_message">No hay rutas ni marcadores que coincidan con tu búsqueda.</string>
|
||||
<string name="search_list_marker_track_location">En el recorrido “%1$s”</string>
|
||||
<string name="search_voice_prompt">Di el nombre de la ruta o del marcador.</string>
|
||||
<string name="sensor_state_battery">Nivel de la batería</string>
|
||||
<string name="sensor_state_cadence">Cadencia</string>
|
||||
<string name="sensor_state_cadence_value">%1$d rpm</string>
|
||||
<string name="sensor_state_connected">Conectado</string>
|
||||
<string name="sensor_state_connecting">Conectándose</string>
|
||||
<string name="sensor_state_disconnected">Desconectado</string>
|
||||
<string name="sensor_state_heart_rate">Frecuencia cardíaca</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d bpm</string>
|
||||
<string name="sensor_state_last_sensor_time">Última hora del sensor</string>
|
||||
<string name="sensor_state_power">Potencia</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">Enviando</string>
|
||||
<string name="settings_not_while_recording">No está disponible durante la grabación de un recorrido.</string>
|
||||
<string name="settings_show">Mostrar</string>
|
||||
<string name="settings_advanced">Opciones avanzadas</string>
|
||||
@@ -251,22 +235,13 @@
|
||||
<string name="settings_reset_confirm_title">¿Restablecer ahora?</string>
|
||||
<string name="settings_reset_done">Se restablecieron los valores predeterminados de todas las opciones de configuración.</string>
|
||||
<string name="settings_sensor">Sensor</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Rest. cad. de bicicleta</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Rest. bicicleta comb.</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Restablecer frecuencia cardíaca</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Restablecer podómetro</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Vinculación Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Se abre la configuración de Bluetooth de Android para vincular un sensor.</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Sensor de Bluetooth</string>
|
||||
<string name="settings_sensor_connected">Conectado a %1$s</string>
|
||||
<string name="settings_stats_coordinate">Latitud/longitud</string>
|
||||
<string name="settings_stats_rate_title">Tasa preferida</string>
|
||||
<string name="settings_stats_units_imperial">Imperiales (millas, pies)</string>
|
||||
<string name="settings_stats_units_metric">Métricas (km, m)</string>
|
||||
<string name="settings_stats_units_title">Unidades preferidas</string>
|
||||
<string name="share_track_emails_hint">Direcciones de correo electrónico</string>
|
||||
<string name="share_track_picker_title">Seleccione una aplicación</string>
|
||||
<string name="share_track_share_file">Compartir el archivo del recorrido</string>
|
||||
<string name="share_track_share_file_body">Creo que este recorrido podría interesarte.\n\nPara ver este recorrido, usa Google Earth u otro software de mapas.\n\n%1$s</string>
|
||||
<string name="share_track_subject">Me gustaría compartir un recorrido contigo</string>
|
||||
@@ -302,9 +277,6 @@
|
||||
<string name="track_edit_activity_type_hint">Tipo de actividad</string>
|
||||
<string name="track_edit_new_track_title">Nuevo recorrido</string>
|
||||
<string name="track_list_empty_message">Comienza a grabar aquí tu próxima aventura.</string>
|
||||
<string name="track_list_record_error">No se puede iniciar la grabación. No se recibe señal de GPS. Vuelve a intentarlo.</string>
|
||||
<string name="track_list_record_success">Grabando una nueva ruta</string>
|
||||
<string name="track_widget_config_title">Configurar elementos de widget</string>
|
||||
<string name="tracks_few">%1$d recorridos</string>
|
||||
<string name="tracks_many">%1$d recorridos</string>
|
||||
<string name="tracks_one">1 recorrido</string>
|
||||
@@ -330,10 +302,8 @@
|
||||
<string name="value_integer_feet">%1$d pies</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d pies (señal de GPS excelente)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d pies (recomendado)</string>
|
||||
<string name="value_integer_kilobyte">%1$d KB</string>
|
||||
<string name="value_integer_kilometer">%1$d km</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d km/h</string>
|
||||
<string name="value_integer_megabyte">%1$d MB</string>
|
||||
<string name="value_integer_meter">%1$d m</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d m (señal de GPS excelente)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d m (señal de GPS deficiente)</string>
|
||||
@@ -343,7 +313,6 @@
|
||||
<string name="value_integer_minute">%1$d min.</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d s</string>
|
||||
<string name="value_never">Nunca</string>
|
||||
<string name="value_none">Ninguno</string>
|
||||
<string name="value_off">Desactivado</string>
|
||||
<string name="value_smallest">Menor</string>
|
||||
|
||||
@@ -133,13 +133,9 @@
|
||||
<string name="generic_yes">Да</string>
|
||||
<string name="gps_location_access">„Достъп до местоположението“</string>
|
||||
<string name="gps_disabled">GPS не е активиран. Докоснете тук, за да отидете на %1$s. Натиснете бутона за назад, за да се върнете.</string>
|
||||
<string name="gps_disabled_location_mode">Изберете режима за висока точност на местоположението. Докоснете тук, за да отидете в/ъв %1$s. Натиснете бутона за назад, за да се върнете.</string>
|
||||
<string name="gps_disabled_my_location">Текущото местоположение не може да бъде определено. Активирайте още източници на местоположение от %1$s и се уверете, че небето се вижда. Опитайте отново по-късно.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">Текущото местоположение не може да бъде определено. Изберете режима за висока точност на местоположението от %1$s и се уверете, че небето се вижда. Опитайте отново по-късно.</string>
|
||||
<string name="gps_not_found">Няма намерен GPS на устройството.</string>
|
||||
<string name="gps_starting">GPS се включва.</string>
|
||||
<string name="gps_starting_error">GPS не може да стартира.</string>
|
||||
<string name="gps_stopping">GPS се изключва.</string>
|
||||
<string name="gps_wait_for_better_signal">Изчаква се по-добър сигнал за GPS.</string>
|
||||
<string name="gps_wait_for_signal">Изчаква се сигнал за GPS.</string>
|
||||
<string name="image_application">Приложение</string>
|
||||
@@ -179,20 +175,13 @@
|
||||
<string name="marker_list_empty_message">Нямате маркери.</string>
|
||||
<string name="menu_aggregated_statistics">Събрани статист. данни</string>
|
||||
<string name="menu_delete">Изтриване</string>
|
||||
<string name="menu_delete_all">Изтриване на всички</string>
|
||||
<string name="menu_edit">Редактиране</string>
|
||||
<string name="menu_export">Експортиране</string>
|
||||
<string name="menu_export_all">Експорт. на всички</string>
|
||||
<string name="menu_feedback">Отзиви</string>
|
||||
<string name="menu_help">Помощ</string>
|
||||
<string name="menu_help_feedback">Помощ и отзиви</string>
|
||||
<string name="menu_help_forum">Помощен форум</string>
|
||||
<string name="menu_import_all">Импорт. на всички</string>
|
||||
<string name="menu_insert_marker">Вмъкване на маркер</string>
|
||||
<string name="menu_insert_photo">Вмъкване на снимка</string>
|
||||
<string name="menu_map">Карта</string>
|
||||
<string name="menu_markers">Маркери</string>
|
||||
<string name="menu_play">Старт</string>
|
||||
<string name="menu_search">Търсене</string>
|
||||
<string name="menu_select_all">Избиране на всички</string>
|
||||
<string name="menu_sensor_state">Състояние на сензора</string>
|
||||
@@ -209,19 +198,14 @@
|
||||
<string name="search_global_description">Маршрути и маркери</string>
|
||||
<string name="search_list_empty_message">Няма маршрути или маркери, отговарящи на търсените от вас.</string>
|
||||
<string name="search_list_marker_track_location">В маршрут „%1$s“.</string>
|
||||
<string name="search_voice_prompt">Произнесете името на маршрут или маркер.</string>
|
||||
<string name="sensor_state_battery">Ниво на батерията</string>
|
||||
<string name="sensor_state_cadence">Такт</string>
|
||||
<string name="sensor_state_cadence_value">%1$d об/мин</string>
|
||||
<string name="sensor_state_connected">Свързано</string>
|
||||
<string name="sensor_state_connecting">Свързва се</string>
|
||||
<string name="sensor_state_disconnected">Изключено</string>
|
||||
<string name="sensor_state_heart_rate">Сърдечен ритъм</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d уд/мин</string>
|
||||
<string name="sensor_state_last_sensor_time">Последно използване на сензора</string>
|
||||
<string name="sensor_state_power">Захранване</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">Изпраща се</string>
|
||||
<string name="settings_not_while_recording">Не е налице при записване на маршрут.</string>
|
||||
<string name="settings_show">Показване</string>
|
||||
<string name="settings_advanced">Разширени</string>
|
||||
@@ -250,22 +234,13 @@
|
||||
<string name="settings_reset_confirm_title">Да се зададе ли повторно сега?</string>
|
||||
<string name="settings_reset_done">Всички настройки са възстановени до стойностите по подразбиране.</string>
|
||||
<string name="settings_sensor">Сензор</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Нулиране на велос. каданс</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Нулиране на сензорите</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Повторно задаване на пулса</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Повторно задаване на крачкомер</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Сдвояване чрез Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Отваря настройките за Bluetooth на Android, за да се сдвои сензор</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Bluetooth сензор</string>
|
||||
<string name="settings_sensor_connected">Свързан с %1$s</string>
|
||||
<string name="settings_stats_coordinate">Ширина и дължина</string>
|
||||
<string name="settings_stats_rate_title">Предпочитана мярка</string>
|
||||
<string name="settings_stats_units_imperial">Имперски (мил, фт)</string>
|
||||
<string name="settings_stats_units_metric">Метрични (км, м)</string>
|
||||
<string name="settings_stats_units_title">Предпочитани единици</string>
|
||||
<string name="share_track_emails_hint">Имейл адреси</string>
|
||||
<string name="share_track_picker_title">Избор на приложение</string>
|
||||
<string name="share_track_share_file">Споделяне на файл с маршрут</string>
|
||||
<string name="share_track_share_file_body">Мисля, че този маршрут може да Ви заинтересува.\n\nЗа да го видите, използвайте Google Земя или друг
|
||||
картографски софтуер.\n\n%1$s</string>
|
||||
@@ -301,9 +276,6 @@
|
||||
<string name="track_edit_activity_type_hint">Тип дейност</string>
|
||||
<string name="track_edit_new_track_title">Нов маршрут</string>
|
||||
<string name="track_list_empty_message">Започнете да записвате следващото си приключение тук.</string>
|
||||
<string name="track_list_record_error">Записът не може да стартира. Няма сигнал за GPS. Опитайте отново.</string>
|
||||
<string name="track_list_record_success">В момента се записва нов маршрут.</string>
|
||||
<string name="track_widget_config_title">Конфигуриране на елементите на приспособления</string>
|
||||
<string name="tracks_few">%1$d маршрута</string>
|
||||
<string name="tracks_many">%1$d маршрута</string>
|
||||
<string name="tracks_one">1 маршрут</string>
|
||||
@@ -329,10 +301,8 @@
|
||||
<string name="value_integer_feet">%1$d фт</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d фт (отличен GPS)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d фт (препоръчително)</string>
|
||||
<string name="value_integer_kilobyte">%1$d КБ</string>
|
||||
<string name="value_integer_kilometer">%1$d км</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d км/ч</string>
|
||||
<string name="value_integer_megabyte">%1$d МБ</string>
|
||||
<string name="value_integer_meter">%1$d м</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d м (отличен GPS)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d м (слаб GPS)</string>
|
||||
@@ -342,7 +312,6 @@
|
||||
<string name="value_integer_minute">%1$d мин</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d сек</string>
|
||||
<string name="value_never">Никога</string>
|
||||
<string name="value_none">Никоя</string>
|
||||
<string name="value_off">Изключено</string>
|
||||
<string name="value_smallest">Най-малката</string>
|
||||
|
||||
@@ -133,15 +133,10 @@
|
||||
<string name="generic_yes">Sí</string>
|
||||
<string name="gps_location_access">\"Accés a la ubicació\"</string>
|
||||
<string name="gps_disabled">El GPS no està activat. Premeu aquí per anar a %1$s. Premeu el botó Enrere per tornar.</string>
|
||||
<string name="gps_disabled_location_mode">Seleccioneu el mode d\'ubicació d\'alta precisió. Toqueu aquí per anar a %1$s. Premeu el botó de retorn per anar enrere.</string>
|
||||
<string name="gps_disabled_my_location">No es pot determinar la ubicació actual. Activeu més fonts d\'ubicació a %1$s i assegureu-vos que
|
||||
es vegi el cel. Torneu-ho a provar més tard.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">No es pot determinar la ubicació actual. Seleccioneu el mode d\'ubicació d\'alta precisió a %1$s i assegureu-vos que
|
||||
es vegi el cel. Torneu-ho a provar més tard.</string>
|
||||
<string name="gps_not_found">No s\'ha trobat el GPS al dispositiu.</string>
|
||||
<string name="gps_starting">El GPS s\'està iniciant.</string>
|
||||
<string name="gps_starting_error">El GPS no es pot iniciar.</string>
|
||||
<string name="gps_stopping">El GPS s\'està aturant.</string>
|
||||
<string name="gps_wait_for_better_signal">S\'està esperant un senyal GPS de millor qualitat.</string>
|
||||
<string name="gps_wait_for_signal">S\'està esperant el senyal GPS.</string>
|
||||
<string name="image_application">Aplicació</string>
|
||||
@@ -181,20 +176,13 @@ es vegi el cel. Torneu-ho a provar més tard.</string>
|
||||
<string name="marker_list_empty_message">No teniu cap marcador.</string>
|
||||
<string name="menu_aggregated_statistics">Estadístiques globals</string>
|
||||
<string name="menu_delete">Suprimeix</string>
|
||||
<string name="menu_delete_all">Suprimeix-les totes</string>
|
||||
<string name="menu_edit">Edita</string>
|
||||
<string name="menu_export">Exporta</string>
|
||||
<string name="menu_export_all">Exporta-ho tot</string>
|
||||
<string name="menu_feedback">Comentaris</string>
|
||||
<string name="menu_help">ajuda</string>
|
||||
<string name="menu_help_feedback">Ajuda i comentaris</string>
|
||||
<string name="menu_help_forum">Fòrum d\'ajuda</string>
|
||||
<string name="menu_import_all">Importa-ho tot</string>
|
||||
<string name="menu_insert_marker">Insereix un marcador</string>
|
||||
<string name="menu_insert_photo">Insereix una foto</string>
|
||||
<string name="menu_map">Mapa</string>
|
||||
<string name="menu_markers">Marcadors</string>
|
||||
<string name="menu_play">Reprodueix</string>
|
||||
<string name="menu_search">Cerca</string>
|
||||
<string name="menu_select_all">Selecciona-ho tot</string>
|
||||
<string name="menu_sensor_state">Estat del sensor</string>
|
||||
@@ -211,19 +199,14 @@ es vegi el cel. Torneu-ho a provar més tard.</string>
|
||||
<string name="search_global_description">Pistes i marcadors</string>
|
||||
<string name="search_list_empty_message">No hi ha cap ruta ni marcador que coincideixi amb els criteris de cerca.</string>
|
||||
<string name="search_list_marker_track_location">A la ruta \"%1$s\".</string>
|
||||
<string name="search_voice_prompt">Digueu el nom d\'una ruta o d\'un marcador.</string>
|
||||
<string name="sensor_state_battery">Nivell de la bateria</string>
|
||||
<string name="sensor_state_cadence">Cadència</string>
|
||||
<string name="sensor_state_cadence_value">%1$d rpm</string>
|
||||
<string name="sensor_state_connected">Connectat</string>
|
||||
<string name="sensor_state_connecting">S\'està connectant</string>
|
||||
<string name="sensor_state_disconnected">Desconnectat</string>
|
||||
<string name="sensor_state_heart_rate">Freqüència cardíaca</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d ppm</string>
|
||||
<string name="sensor_state_last_sensor_time">Darrera hora del sensor</string>
|
||||
<string name="sensor_state_power">Potència</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">S\'està enviant</string>
|
||||
<string name="settings_not_while_recording">No està disponible durant l\'enregistrament d\'una ruta.</string>
|
||||
<string name="settings_show">Mostra\'n més</string>
|
||||
<string name="settings_advanced">Avançades</string>
|
||||
@@ -252,22 +235,13 @@ es vegi el cel. Torneu-ho a provar més tard.</string>
|
||||
<string name="settings_reset_confirm_title">Voleu restablir-ho ara?</string>
|
||||
<string name="settings_reset_done">S\'ha recuperat la configuració predeterminada.</string>
|
||||
<string name="settings_sensor">Sensor</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Restableix cadència bici</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Restableix bicicleta combinada</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Reinicia el pulsòmetre</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Reinicia el podòmetre</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Sincronització de Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Obre la configuració de Bluetooth d\'Android per a la sincronització d\'un sensor.</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Sensor de Bluetooth</string>
|
||||
<string name="settings_sensor_connected">Connectat a %1$s</string>
|
||||
<string name="settings_stats_coordinate">Latitud/Longitud:</string>
|
||||
<string name="settings_stats_rate_title">Mesura preferida</string>
|
||||
<string name="settings_stats_units_imperial">Sistema anglosaxó (milles, peus)</string>
|
||||
<string name="settings_stats_units_metric">Sistema mètric (km, m)</string>
|
||||
<string name="settings_stats_units_title">Unitats preferides</string>
|
||||
<string name="share_track_emails_hint">Adreces electròniques</string>
|
||||
<string name="share_track_picker_title">Seleccioneu una aplicació</string>
|
||||
<string name="share_track_share_file">Comparteix el fitxer de la pista</string>
|
||||
<string name="share_track_share_file_body">Crec que aquesta ruta et podria interessar.\n\nLa pots veure amb Google Earth o qualsevol altre programari de mapatge.\n\n%1$s</string>
|
||||
<string name="share_track_subject">Vull compartir una ruta amb tu</string>
|
||||
@@ -302,9 +276,6 @@ es vegi el cel. Torneu-ho a provar més tard.</string>
|
||||
<string name="track_edit_activity_type_hint">Tipus d\'activitat</string>
|
||||
<string name="track_edit_new_track_title">Nova ruta</string>
|
||||
<string name="track_list_empty_message">Comenceu a enregistrar aquí la vostra pròxima aventura.</string>
|
||||
<string name="track_list_record_error">No es pot iniciar l\'enregistrament. No hi ha senyal del GPS. Torneu-ho a provar.</string>
|
||||
<string name="track_list_record_success">S\'està enregistrant una ruta nova</string>
|
||||
<string name="track_widget_config_title">Configuració d\'elements del widget</string>
|
||||
<string name="tracks_few">%1$d rutes</string>
|
||||
<string name="tracks_many">%1$d rutes</string>
|
||||
<string name="tracks_one">1 ruta</string>
|
||||
@@ -330,10 +301,8 @@ es vegi el cel. Torneu-ho a provar més tard.</string>
|
||||
<string name="value_integer_feet">%1$d peus</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d peus (senyal de GPS excel·lent)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d peus (recomanat)</string>
|
||||
<string name="value_integer_kilobyte">%1$d KB</string>
|
||||
<string name="value_integer_kilometer">%1$d km</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d km/h</string>
|
||||
<string name="value_integer_megabyte">%1$d MB</string>
|
||||
<string name="value_integer_meter">%1$d m</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d m (GPS amb bona senyal)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d m (GPS amb poca senyal)</string>
|
||||
@@ -343,7 +312,6 @@ es vegi el cel. Torneu-ho a provar més tard.</string>
|
||||
<string name="value_integer_minute">%1$d min</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d s</string>
|
||||
<string name="value_never">Mai</string>
|
||||
<string name="value_none">Cap</string>
|
||||
<string name="value_off">Desactivat</string>
|
||||
<string name="value_smallest">Més petit</string>
|
||||
|
||||
@@ -1,5 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2010 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.
|
||||
-->
|
||||
<resources>
|
||||
<string name="about_preference_title">O OpenTracks</string>
|
||||
<string name="about_description"><i> OpenTracks </i> je sportovní sledovací aplikace, která zcela respektuje vaše soukromí.</string>
|
||||
<string name="about_url">Webová stránka projektu: <a href="%1$s">%1$s</a></string>
|
||||
<string name="about_version_name">Název verze: %1$s</string>
|
||||
<string name="about_version_code">Kód verze: %1$d</string>
|
||||
<string name="about_history">OpenTracks je vidlička <a href="https://code.google.com/archive/p/mytracks/"> <i> MyTracks Google </i> </a> (v roce 2016 ukončena).</string>
|
||||
<string name="about_libraries">Knihovny</string>
|
||||
<!-- Help -->
|
||||
<string name="help_feature_title">OpenTracks má následující funkce:</string>
|
||||
<string name="help_feature_content">
|
||||
* vytvářet GPS stopy \ n
|
||||
* použijte snímač srdeční frekvence (pouze Bluetooth LE) \ n
|
||||
* hlasová oznámení (podle času nebo vzdálenosti) \ n
|
||||
* vytvářejte značky (včetně obrázků) \ n
|
||||
* funguje zcela offline \ n
|
||||
* zobrazit skladby na mapě (viz níže)</string>
|
||||
|
||||
<string name="help_track_map_title">Jak ukázat skladbu na mapě?</string>
|
||||
<string name="help_track_map_content">
|
||||
Použijte malou ikonu mapy.\n
|
||||
a) (živé aktualizace) Nainstalujte <a href="https://github.com/OpenTracksApp/OSMDashboard">OSMDashboard</a>.
|
||||
Poskytuje online nebo offline mapy prostřednictvím <a href="https://www.openstreetmap.org">OpenStreetMap</a>.\n
|
||||
Ve skutečnosti je OSMDashboard samostatná aplikace, která má přístup (dočasně) pouze k datům stop, které se bud(ou) zobrazovat.\n
|
||||
b) Prostřednictvím „normální“ mapové aplikace (např. <a href="http://osmand.net/">OsmAnd</a> a <a href="https://maps.me/">MAPS.ME</a>).
|
||||
Tyto aplikace musí podporovat formát souboru KMZ (pouze umístění a časová razítka).
|
||||
Ve skutečnosti musí aplikace podporovat <i>ACTION_VIEW</i> pomocí MIME <i>application/vnd.google-earth.kmz</i>.</string>
|
||||
|
||||
<string name="help_storage_pictures_title">Jak ukládá OpenTracks obrázky pořízené jako značky?</string>
|
||||
<string name="help_storage_pictures_content">Jsou uloženy v interním úložišti aplikace (tj. Přístupné pouze v rámci OpenTracks).</string>
|
||||
|
||||
<string name="help_track_export_title">Jak mohu exportovat / sdílet zaznamenané stopy?</string>
|
||||
<string name="help_track_export_content">
|
||||
Skladby lze exportovat z Nastavení jako KMZ, KML nebo GPX.
|
||||
KMZ / KML všechna data; Pouze umístění GPX.
|
||||
Skladby sdílené pomocí ikony sdílení <i> </i> jsou sdíleny jako KMZ.</string>
|
||||
|
||||
<string name="help_data_google_play_services_title">Vyžaduje služba OpenTracks / používá službu Google Play?</string>
|
||||
|
||||
<string name="help_recording_title">Jak OpenTracks zaznamenává data?</string>
|
||||
<string name="help_recording_content">
|
||||
OpenTracks používá GPS senzor zařízení k nepřetržitému zaznamenávání polohy.
|
||||
Pokud zařízení GPS hlásí nepřesná data (např. Polohu, rychlost, nadmořskou výšku), OpenTracks s tím nemůže nic udělat.</string>
|
||||
|
||||
<string name="help_data_storage_title">Jak OpenTracks ukládá data senzorů?</string>
|
||||
<string name="help_data_storage_content">
|
||||
Data senzoru se ukládají na zaznamenané místo.
|
||||
Pokud jde o snímač srdeční frekvence, znamená to, že na každé místo je uloženo pouze <i> jedno </i> měření srdeční frekvence.
|
||||
Pokud stojíte v klidu nebo jste uvnitř, nebudou zaznamenána žádná data ze senzorů (ale budou zobrazena).</string>
|
||||
|
||||
<string name="help_gps_troubleshooting_title">OpenTracks nezaznamenává místa?</string>
|
||||
<string name="help_gps_troubleshooting_content">
|
||||
Co můžete udělat: \ n
|
||||
a) zkontrolujte, zda je GPS povoleno, \ n
|
||||
b) zlepšit příjem GPS (např. jít venku), \ n
|
||||
c) zkontrolujte, zda používáte aplikaci <a href="https://f-droid.org/en/packages/com.android.gpstest.osmdroid/"> GPSTest </a> a \ n
|
||||
d) deaktivujte úsporu energie. \ n
|
||||
\ n
|
||||
Pokud všechno nepomůže, nahláste chybu.</string>
|
||||
|
||||
<string name="help_support_title">Jak mohu podporovat OpenTracks?</string>
|
||||
<string name="help_support_content">
|
||||
Můžete: \ n
|
||||
a) šířit slovo o OpenTracks, \ n
|
||||
b) <a href="https://github.com/OpenTracksApp/OpenTracks/issues"> navrhnout funkce </a>, \ n
|
||||
c) <a href="https://github.com/OpenTracksApp/OpenTracks/issues"> nahlaste chyby </a>, \ n
|
||||
d) pomoc při vývoji softwaru, \ n
|
||||
e) nakupujte v <a href="https://play.google.com/store/apps/details?id=de.dennisguse.opentracks.playstore"> Obchod Google Play </a>, \ n
|
||||
f) darovat, a \ n
|
||||
g) udělejte, co si myslíte, že pomůže OpenTracks.</string>
|
||||
|
||||
<!-- Activity Type -->
|
||||
<string name="activity_type_airplane">letadlo</string>
|
||||
<string name="activity_type_atv">terénní auta</string>
|
||||
<string name="activity_type_biking">cyklistika</string>
|
||||
@@ -66,6 +151,8 @@
|
||||
<string name="activity_type_walking">chůze</string>
|
||||
<string name="activity_type_water_skiing">vodní lyžování</string>
|
||||
<string name="activity_type_wind_surfing">windsurfing</string>
|
||||
<string name="app_not_installed_show_on_map">Nainstalujte prosím aplikaci, která podporuje prezentaci mapových dat.</string>
|
||||
<!-- Description -->
|
||||
<string name="description_activity_type">Typ aktivity: %1$s</string>
|
||||
<string name="description_average_moving_pace_in_minute">Průměrné tempo pohybu: %1$s min/km (%2$s min/míli)</string>
|
||||
<string name="description_average_moving_speed">Průměrná rychlost přesunu: %1$.2f km/h (%2$.1f mil/h)</string>
|
||||
@@ -93,6 +180,7 @@
|
||||
<string name="description_sensor_cadence">Tempo šlapání (ot./min)</string>
|
||||
<string name="description_sensor_heart_rate">Srdeční frekvence (údery/min)</string>
|
||||
<string name="description_sensor_power">Výkon (W)</string>
|
||||
<string name="description_default_speed_or_pace">Podle typu činnosti</string>
|
||||
<string name="description_speed_imperial">Rychlost (míle/h)</string>
|
||||
<string name="description_speed_metric">Rychlost (km/h)</string>
|
||||
<string name="description_time">Doba</string>
|
||||
@@ -100,19 +188,25 @@
|
||||
<string name="description_total_time">Celková doba: %1$s</string>
|
||||
<string name="description_track_point">Bod</string>
|
||||
<string name="description_track_segment">Segment</string>
|
||||
<!-- Export -->
|
||||
<string name="export_all_option">Vše ve formátu %1$s</string>
|
||||
<string name="export_all_title">Export do externího úložiště</string>
|
||||
<string name="export_with_photos">s fotkami</string>
|
||||
<string name="export_without_photos">bez fotografií</string>
|
||||
<string name="export_error">Trasy byly exportovány do složky %3$s (%1$d z %2$s).</string>
|
||||
<string name="export_option">jako %1$s do složky %2$s</string>
|
||||
<string name="export_progress_message">Exportování do složky %1$s…</string>
|
||||
<string name="export_success">Trasy (celkem %1$s) byly exportovány do složky %2$s.</string>
|
||||
<string name="export_title">Export do…</string>
|
||||
<!-- External Storage -->
|
||||
<!-- Files -->
|
||||
<string name="files_few">%1$d soubory</string>
|
||||
<string name="files_many">%1$d souborů</string>
|
||||
<string name="files_one">1 soubor</string>
|
||||
<string name="files_other">%1$d souborů</string>
|
||||
<string name="files_two">2 soubory</string>
|
||||
<string name="files_zero">0 souborů</string>
|
||||
<!-- Generic -->
|
||||
<string name="generic_add">Přidat</string>
|
||||
<string name="generic_cancel">Zrušit</string>
|
||||
<string name="generic_delete_all_confirm_title">Smazat vše?</string>
|
||||
@@ -131,17 +225,15 @@
|
||||
<string name="generic_success_title">Úspěch</string>
|
||||
<string name="generic_tracks">Trasy</string>
|
||||
<string name="generic_yes">Ano</string>
|
||||
<!-- Gps -->
|
||||
<string name="gps_location_access">Přístup k poloze</string>
|
||||
<string name="gps_disabled">Systém GPS není zapnutý. Klepnutím sem přejdete na možnost %1$s. Stisknutím tlačítka Zpět se vrátíte.</string>
|
||||
<string name="gps_disabled_location_mode">Vyberte režim vysoké přesnosti určování polohy. Klepnutím sem přejdete do části %1$s. Stisknutím tlačítka Zpět se vrátíte.</string>
|
||||
<string name="gps_disabled_my_location">Aktuální polohu nelze určit. V části %1$s aktivujte další zdroje pro zjišťování polohy a ujistěte se, že vidíte oblohu. Zkuste to znovu později.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">Aktuální polohu nelze určit. V části %1$s vyberte režim vysoké přesnosti určování polohy a ujistěte se, že vidíte oblohu. Zkuste to znovu později.</string>
|
||||
<string name="gps_not_found">Zařízení neobsahuje GPS</string>
|
||||
<string name="gps_starting">Spouštění GPS</string>
|
||||
<string name="gps_starting_error">GPS nelze spustit</string>
|
||||
<string name="gps_stopping">Zastavování GPS</string>
|
||||
<string name="gps_wait_for_better_signal">Čekání na lepší signál GPS</string>
|
||||
<string name="gps_wait_for_signal">Čekání na signál GPS</string>
|
||||
<!-- Image -->
|
||||
<string name="image_application">Aplikace</string>
|
||||
<string name="image_arrow">Šipka</string>
|
||||
<string name="image_marker">Značka</string>
|
||||
@@ -152,6 +244,7 @@
|
||||
<string name="image_record">Zaznamenat</string>
|
||||
<string name="image_stop">Ukončit</string>
|
||||
<string name="image_track">Trasa</string>
|
||||
<!-- Import -->
|
||||
<string name="import_error">Trasy byly importovány ze složky %3$s (%1$d z %2$s).</string>
|
||||
<string name="import_no_directory">Složka %1$s neexistuje.</string>
|
||||
<string name="import_no_file">Nebyly nalezeny žádné soubory, které by bylo možné importovat. Připojte zařízení k počítači a umístěte soubory, které chcete importovat, do složky %1$s.</string>
|
||||
@@ -160,9 +253,11 @@
|
||||
<string name="import_selection_option">Všechny soubory %1$s</string>
|
||||
<string name="import_selection_title">Import z externího úložiště</string>
|
||||
<string name="import_success">Trasy (celkem %1$s) byly importovány ze složky %2$s.</string>
|
||||
<!-- Marker -->
|
||||
<string name="marker_add_error">Značku nelze vložit. Signál GPS není dostupný. Zkuste to znovu.</string>
|
||||
<string name="marker_add_success">Značka byla vložena.</string>
|
||||
<string name="marker_add_canceled">Zrušeno, značky nebyly přidány.</string>
|
||||
<string name="marker_add_photo_canceled">Zrušeno, nebyla přidána žádná značka</string>
|
||||
<string name="marker_delete_all_confirm_message">Všechny značky této trasy budou trvale smazány ze zařízení.</string>
|
||||
<string name="marker_delete_one_confirm_message">Značka bude trvale smazána ze zařízení.</string>
|
||||
<string name="marker_delete_one_confirm_title">Smazat značku?</string>
|
||||
@@ -172,26 +267,24 @@
|
||||
<string name="marker_name_format">Značka %1$d</string>
|
||||
<string name="marker_split_name_format">Dělicí značka %1$d</string>
|
||||
<string name="marker_title">%1$d z %2$d</string>
|
||||
<!-- Marker Detail -->
|
||||
<string name="marker_detail_statistics_title">Od poslední dělicí značky:</string>
|
||||
<!-- Marker Edit -->
|
||||
<string name="marker_edit_marker_type">Typ značky (například vodopád…)</string>
|
||||
<string name="marker_edit_marker_type_hint">Typ značky</string>
|
||||
<!-- Marker List -->
|
||||
<string name="marker_list_empty_message">Nemáte žádné značky.</string>
|
||||
<!-- Menu -->
|
||||
<string name="menu_aggregated_statistics">Souhrnná statistika</string>
|
||||
<string name="menu_delete">Smazat</string>
|
||||
<string name="menu_delete_all">Smazat vše</string>
|
||||
<string name="menu_edit">Upravit</string>
|
||||
<string name="menu_export">Exportovat</string>
|
||||
<string name="menu_export_all">Exportovat vše</string>
|
||||
<string name="menu_feedback">Zpětná vazba</string>
|
||||
<string name="menu_help">Nápověda</string>
|
||||
<string name="menu_help_feedback">Nápověda a názory</string>
|
||||
<string name="menu_help_forum">Fórum nápovědy</string>
|
||||
<string name="menu_import_all">Importovat vše</string>
|
||||
<string name="menu_insert_marker">Vložit značku</string>
|
||||
<string name="menu_insert_photo">Vložit fotku</string>
|
||||
<string name="menu_map">Mapa</string>
|
||||
<string name="menu_insert_gallery_img">Vložte obrázek galerie</string>
|
||||
<string name="menu_markers">Značky</string>
|
||||
<string name="menu_play">Přehrát</string>
|
||||
<string name="menu_search">Vyhledat</string>
|
||||
<string name="menu_select_all">Vybrat vše</string>
|
||||
<string name="menu_sensor_state">Stav senzoru</string>
|
||||
@@ -203,30 +296,41 @@
|
||||
<string name="menu_stop_gps">Ukončit GPS</string>
|
||||
<string name="menu_view_photo">Zobrazit fotku</string>
|
||||
<string name="menu_voice_frequency">Frekvence oznámení</string>
|
||||
<string name="menu_resume_track">Obnovit skladbu</string>
|
||||
<!-- OpenTracks -->
|
||||
<string name="app_name">OpenTracks</string>
|
||||
<string name="recording_service">Služba pro záznam</string>
|
||||
<!-- Permission -->
|
||||
<string name="permission_gps_failed">OpenTracks vyžaduje povolení k používání GPS.</string>
|
||||
<!-- Search -->
|
||||
<string name="search_global_description">Trasy a značky</string>
|
||||
<string name="search_list_empty_message">Vyhledávacímu dotazu neodpovídají žádné trasy ani značky.</string>
|
||||
<string name="search_list_marker_track_location">Na trase %1$s</string>
|
||||
<string name="search_voice_prompt">Vyslovte název trasy nebo značky.</string>
|
||||
<!-- Sensor State -->
|
||||
<string name="sensor_state_battery">Stav baterie</string>
|
||||
<string name="sensor_state_cadence">Frekvence šlapání</string>
|
||||
<string name="sensor_state_cadence_value">%1$d ot./min</string>
|
||||
<string name="sensor_state_connected">Připojeno</string>
|
||||
<string name="sensor_state_connecting">Připojování</string>
|
||||
<string name="sensor_state_disconnected">Odpojeno</string>
|
||||
<string name="sensor_state_heart_rate">Srdeční frekvence</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d úderů/min</string>
|
||||
<string name="sensor_state_last_sensor_time">Poslední čas senzoru</string>
|
||||
<string name="sensor_state_power">Napájení</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">Odesílání</string>
|
||||
<string name="sensor_not_known">Senzor %1$s není znám. Zkontrolujte nastavení.</string>
|
||||
<string name="sensor_could_not_scan">Nelze vyhledat zařízení Bluetooth (chyba %1$i).</string>
|
||||
<string name="bluetooth_disabled">Aktivujte prosím Bluetooth.</string>
|
||||
<string name="settings_not_while_recording">Při záznamu trasy není tato funkce dostupná.</string>
|
||||
<string name="settings_show">Zobrazit</string>
|
||||
<!-- Settings Advanced -->
|
||||
<string name="settings_advanced">Pokročilé</string>
|
||||
<!-- Settings Chart -->
|
||||
<string name="settings_chart_by_distance">Podle vzdálenosti</string>
|
||||
<string name="settings_chart_by_time">Podle doby</string>
|
||||
<string name="settings_chart_x_axis">Osa X</string>
|
||||
<!-- Settings Recording -->
|
||||
<string name="settings_recording_show_on_lockscreen_while_recording_title">Zobrazit statistiky na obrazovce uzamčení</string>
|
||||
<string name="settings_recording_show_on_lockscreen_while_recording_summary">Během nahrávání zobrazte statistiky bez odemknutí zařízení.</string>
|
||||
<string name="settings_recording_keep_screen_on_while_recording_title">Nechte obrazovku zapnutou</string>
|
||||
<string name="settings_recording_keep_screen_on_while_recording_summary">Během nahrávání udržujte obrazovku zapnutou.</string>
|
||||
<string name="settings_recording">Záznam</string>
|
||||
<string name="settings_recording_auto_resume_track_timeout_always_summary">Po restartu vždy pokračovat v záznamu</string>
|
||||
<string name="settings_recording_auto_resume_track_timeout_never_summary">Po restartu nikdy nepokračovat v záznamu</string>
|
||||
@@ -244,30 +348,32 @@
|
||||
<string name="settings_recording_track_name_date_local_option">Datum (místní)</string>
|
||||
<string name="settings_recording_track_name_number_option">Číslo</string>
|
||||
<string name="settings_recording_track_name_title">Výchozí název trasy</string>
|
||||
<!-- Settings Reset -->
|
||||
<string name="settings_reset">Resetovat</string>
|
||||
<string name="settings_reset_confirm_message">Všechna nastavení budou obnovena na výchozí hodnoty.</string>
|
||||
<string name="settings_reset_confirm_title">Resetovat nyní?</string>
|
||||
<string name="settings_reset_done">Všechna nastavení byla obnovena na výchozí hodnoty.</string>
|
||||
<string name="settings_error_initial_values_restored">Litujeme, ale došlo k chybě. Všechna nastavení byla vrácena na výchozí hodnoty.</string>
|
||||
<!-- Settings Sensor -->
|
||||
<string name="settings_sensor">Senzor</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Resetovat tempo šlapání</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Resetovat údaje o kole</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Resetovat tepovou frekvenci</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Resetovat krokoměr</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Párování zařízení Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Otevřete v Androidu nastavení Bluetooth a spárujte senzor.</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Senzor Bluetooth</string>
|
||||
<string name="settings_sensor_connected">Připojeno k senzoru %1$s</string>
|
||||
<string name="settings_sensor_connecting">Připojeno k senzoru %1$s</string>
|
||||
<string name="settings_sensor_disconnected">Odpojeno od %1$s</string>
|
||||
|
||||
<string name="settings_sensor_wheel_circumference">Velikost kola (ETRTO)</string>
|
||||
|
||||
<!-- Settings Stats -->
|
||||
<string name="settings_stats_coordinate">Zeměpisná šířka/délka</string>
|
||||
<string name="settings_stats_rate_title">Preferovaná rychlost</string>
|
||||
<string name="settings_stats_units_imperial">Imperiální jednotky (míle, stopy)</string>
|
||||
<string name="settings_stats_units_metric">Metrické jednotky (km, m)</string>
|
||||
<string name="settings_stats_units_title">Preferované jednotky</string>
|
||||
<string name="share_track_emails_hint">E-mailové adresy</string>
|
||||
<string name="share_track_picker_title">Zvolte aplikaci</string>
|
||||
<!-- Share Track -->
|
||||
<string name="share_track_share_file">Sdílet soubor trasy</string>
|
||||
<string name="share_track_share_file_body">Možná by vás mohla zajímat tato trasa.\n\nChcete-li ji zobrazit, použijte Google Earth nebo jiný mapový software.\n\n%1$s</string>
|
||||
<string name="share_track_subject">Chci s vámi sdílet trasu</string>
|
||||
<!-- Stats -->
|
||||
<string name="stats_average_moving_pace">Průměrné tempo pohybu</string>
|
||||
<string name="stats_average_moving_speed">Průměrná rychlost pohybu</string>
|
||||
<string name="stats_average_pace">Průměrné tempo</string>
|
||||
@@ -286,28 +392,36 @@
|
||||
<string name="stats_speed">Rychlost</string>
|
||||
<string name="stats_distance">Vzdálenost</string>
|
||||
<string name="stats_total_time">Celková doba</string>
|
||||
<!-- Track -->
|
||||
<string name="track_name_format">Trasa %1$d</string>
|
||||
<string name="track_record_notification">Záznam trasy…</string>
|
||||
<string name="track_recording_notification_accuracy">Přesnost polohy: %1$s</string>
|
||||
<string name="track_markers">Značky na trase %1$s</string>
|
||||
<!-- Track Delete -->
|
||||
<string name="track_delete_one_confirm_message">Trasa a související značky budou trvale smazány ze zařízení.</string>
|
||||
<string name="track_delete_one_confirm_title">Smazat trasu?</string>
|
||||
<string name="track_delete_multiple_confirm_message">Vybrané trasy a jejich značky budou trvale smazány ze zařízení.</string>
|
||||
<string name="track_delete_progress_message">Mazání…</string>
|
||||
<!-- Track Detail -->
|
||||
<string name="track_detail_chart_tab">Graf</string>
|
||||
<string name="track_detail_stats_tab">Statistika</string>
|
||||
<string name="track_detail_record_success">Zaznamenávání nové trasy</string>
|
||||
<string name="track_detail_resume_success">Nyní se obnovuje skladba</string>
|
||||
<!-- Track Edit -->
|
||||
<string name="track_edit_activity_type">Typ aktivity (například chůze…)</string>
|
||||
<string name="track_edit_activity_type_hint">Typ aktivity</string>
|
||||
<string name="track_edit_new_track_title">Nová trasa</string>
|
||||
<!-- Track List -->
|
||||
<string name="track_list_empty_message">Zde zaznamenejte příští výpravu</string>
|
||||
<string name="track_list_record_error">Záznam nelze spustit. Signál GPS není dostupný. Zkuste to znovu.</string>
|
||||
<string name="track_list_record_success">Zaznamenávání nové trasy</string>
|
||||
<string name="track_widget_config_title">Konfigurace widgetů</string>
|
||||
<!-- Track Widget -->
|
||||
<!-- Tracks -->
|
||||
<string name="tracks_few">%1$d trasy</string>
|
||||
<string name="tracks_many">%1$d tras</string>
|
||||
<string name="tracks_one">1 trasa</string>
|
||||
<string name="tracks_other">%1$d tras</string>
|
||||
<string name="tracks_two">2 trasy</string>
|
||||
<string name="tracks_zero">0 tras</string>
|
||||
<!-- Unit -->
|
||||
<string name="unit_feet">stop</string>
|
||||
<string name="unit_kilometer">km</string>
|
||||
<string name="unit_kilometer_per_hour">km/h</string>
|
||||
@@ -316,6 +430,7 @@
|
||||
<string name="unit_mile_per_hour">mil/h</string>
|
||||
<string name="unit_minute_per_kilometer">min/km</string>
|
||||
<string name="unit_minute_per_mile">min/míle</string>
|
||||
<!-- Value -->
|
||||
<string name="value_adapt_accuracy">Přizpůsobit na přesnost</string>
|
||||
<string name="value_adapt_battery_life">Přizpůsobit výdrži baterie</string>
|
||||
<string name="value_always">Vždy</string>
|
||||
@@ -327,10 +442,8 @@
|
||||
<string name="value_integer_feet">%1$d stop</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d stop (vynikající signál GPS)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d stop (doporučeno)</string>
|
||||
<string name="value_integer_kilobyte">%1$d kB</string>
|
||||
<string name="value_integer_kilometer">%1$d km</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d km/h</string>
|
||||
<string name="value_integer_megabyte">%1$d MB</string>
|
||||
<string name="value_integer_meter">%1$d m</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d m (vynikající signál GPS)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d m (špatný signál GPS)</string>
|
||||
@@ -340,11 +453,11 @@
|
||||
<string name="value_integer_minute">%1$d min</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d s</string>
|
||||
<string name="value_never">Nikdy</string>
|
||||
<string name="value_none">Žádné</string>
|
||||
<string name="value_off">Vypnuto</string>
|
||||
<string name="value_smallest">Nejmenší</string>
|
||||
<string name="value_smallest_recommended">Nejnižší hodnota (doporučeno)</string>
|
||||
<!-- Voice -->
|
||||
<string name="voice_hours_few">%1$d hodiny</string>
|
||||
<string name="voice_hours_many">%1$d hodin</string>
|
||||
<string name="voice_hours_one">1 hodina</string>
|
||||
@@ -391,6 +504,7 @@
|
||||
<string name="voice_total_distance_miles_two">celková vzdálenost 2 míle</string>
|
||||
<string name="voice_total_distance_miles_zero">celková vzdálenost 0 mil</string>
|
||||
<string name="voice_total_distance_zero">Celková vzdálenost Mých tras je nulová.</string>
|
||||
<!-- Waypoint Type -->
|
||||
<string name="waypoint_type_atm">Bankomat</string>
|
||||
<string name="waypoint_type_bank">banka</string>
|
||||
<string name="waypoint_type_bar">bar</string>
|
||||
@@ -442,4 +556,7 @@
|
||||
<string name="waypoint_type_waterfall">vodopád</string>
|
||||
<string name="waypoint_type_water_fountain">kašna</string>
|
||||
<string name="waypoint_type_waypoint">navigační bod</string>
|
||||
<!-- Share image -->
|
||||
<string name="share_image_subject">Chtěl bych s vámi sdílet obrázek</string>
|
||||
<string name="share_image_body">Myslím, že by vás mohl tento obrázek zajímat.</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,5 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2010 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.
|
||||
-->
|
||||
<resources>
|
||||
<string name="about_preference_title">Om OpenTracks</string>
|
||||
<string name="about_description"><i> OpenTracks </i> er en sportssporingsapplikation, der fuldt ud respekterer dit privatliv.</string>
|
||||
<string name="about_url">Projektwebside: <a href="%1$s">%1$s</a></string>
|
||||
<string name="about_version_name">Versionsnavn: %1$s</string>
|
||||
<string name="about_version_code">Versionskode: %1$d</string>
|
||||
<string name="about_history">OpenTracks er en gaffel fra <a href="https://code.google.com/archive/p/mytracks/"> <i> Googles MyTracks </i> </a> (afviklet i 2016).</string>
|
||||
<string name="about_libraries">Biblioteker</string>
|
||||
<!-- Help -->
|
||||
<string name="help_feature_title">OpenTracks har følgende funktioner:</string>
|
||||
<string name="help_feature_content">
|
||||
* Opret GPS-spor \n
|
||||
* Brug en pulssensor (kun Bluetooth LE) \n
|
||||
* stemmemeddelelser (efter tid eller afstand) \n
|
||||
* Opret markører (inkl. billeder) \n
|
||||
* fungerer helt offline \n
|
||||
* vis spor på et kort (se nedenfor)</string>
|
||||
|
||||
<string name="help_track_map_title">Hvordan viser man et spor på et kort?</string>
|
||||
<string name="help_track_map_content">
|
||||
Brug det lille kortikon. \n
|
||||
a)
|
||||
(liveopdateringer) Installer <a href="https://github.com/OpenTracksApp/OSMDashboard">OSMDashboard</a>.
|
||||
Det giver online eller offline kort via <a href="https://www.openstreetmap.org">OpenStreetMap</a>.\n
|
||||
Faktisk er OSMDashboard en separat app, der kun kan få adgang til (midlertidigt) adgang til dataene fra spor (e), der skal vises.\n
|
||||
b) Via et normalt kortprogram (f.eks. <a href="http://osmand.net/">OsmAnd</a> og <a href="https://maps.me/">MAPS.ME</a>).
|
||||
Disse app skal understøtte KMZ-filformatet (kun placeringer og tidsstempler).
|
||||
Faktisk skal en app understøtte <i>ACTION_VIEW</i> med MIME <i>application/vnd.google-earth.kmz</i>.</string>
|
||||
|
||||
<string name="help_storage_pictures_title">Hvordan gemmer OpenTracks billeder, der blev taget som markører?</string>
|
||||
<string name="help_storage_pictures_content">Disse gemmes i appens interne lager (dvs. kun tilgængelig inden for OpenTracks).</string>
|
||||
|
||||
<string name="help_track_export_title">Hvordan kan jeg eksportere / dele indspillede numre?</string>
|
||||
<string name="help_track_export_content">
|
||||
Spor kan eksporteres fra indstillingerne som KMZ, KML eller GPX.
|
||||
KMZ / KML alle data; GPX kun placeringer.
|
||||
Spor, der deles via <i>delingsikonet</i> deles som KMZ.</string>
|
||||
|
||||
<string name="help_data_google_play_services_title">Kræver/bruger OpenTracks Google Play Service?</string>
|
||||
|
||||
<string name="help_recording_title">Hvordan registrerer OpenTracks data?</string>
|
||||
<string name="help_recording_content">
|
||||
OpenTracks bruger enhedens GPS-sensor til at registrere placeringen kontinuerligt.
|
||||
Hvis GPS-enheden rapporterer unøjagtige data (f.eks. Placering, hastighed, højde), kan OpenTracks ikke gøre noget ved det.</string>
|
||||
|
||||
<string name="help_data_storage_title">Hvordan gemmer OpenTracks sensordata?</string>
|
||||
<string name="help_data_storage_content">
|
||||
Sensordata gemmes pr. Optaget placering.
|
||||
Med hensyn til en pulssensor betyder det, at der kun er <i> en </i> måling af hjertefrekvensen lagret pr. Placering.
|
||||
Hvis du står stille eller er indendørs, registreres ingen sensordata (men de vil blive vist).</string>
|
||||
|
||||
<string name="help_gps_troubleshooting_title">OpenTracks optager ikke placeringer?</string>
|
||||
<string name="help_gps_troubleshooting_content">
|
||||
Hvad du kan gøre:\n
|
||||
a) Kontroller, om GPS er aktiveret,\n
|
||||
b) forbedre GPS-modtagelse (f.eks. gå udendørs), \n
|
||||
c) Kontroller, om du har appen <a href="https://f-droid.org/en/packages/com.android.gpstest.osmdroid/"> GPSTest </a> og \n
|
||||
d) deaktiver strømbesparelse. \n
|
||||
\n
|
||||
Hvis alt ikke hjælper, skal du rapportere en fejl.</string>
|
||||
|
||||
<string name="help_support_title">Hvordan kan jeg støtte OpenTracks?</string>
|
||||
<string name="help_support_content">
|
||||
Du kan: \n
|
||||
a) sprede ordet om OpenTracks, \n
|
||||
b) <a href="https://github.com/OpenTracksApp/OpenTracks/issues"> foreslå funktioner </a>, \n
|
||||
c) <a href="https://github.com/OpenTracksApp/OpenTracks/issues"> rapportfejl </a>, \n
|
||||
d) hjælp til softwareudvikling, \n
|
||||
e) køb i <a href="https://play.google.com/store/apps/details?id=de.dennisguse.opentracks.playstore"> Google Play Store </a>, \n
|
||||
f) donere, og \n
|
||||
g) gør hvad du synes hjælper OpenTracks.</string>
|
||||
|
||||
<!-- Activity Type -->
|
||||
<string name="activity_type_airplane">fly</string>
|
||||
<string name="activity_type_atv">Terrængående køretøj</string>
|
||||
<string name="activity_type_biking">cykling</string>
|
||||
@@ -66,6 +152,8 @@
|
||||
<string name="activity_type_walking">til fods</string>
|
||||
<string name="activity_type_water_skiing">vandski</string>
|
||||
<string name="activity_type_wind_surfing">windsurfing</string>
|
||||
<string name="app_not_installed_show_on_map">Installer venligst en app, der understøtter præsentation af kortdata.</string>
|
||||
<!-- Description -->
|
||||
<string name="description_activity_type">Aktivitetstype: %1$s</string>
|
||||
<string name="description_average_moving_pace_in_minute">Gennemsnitsfart: %1$s min./km (%2$s min./mil)</string>
|
||||
<string name="description_average_moving_speed">Gennemsnitlig bevægelseshastighed: %1$.2f km/t (%2$.1f mil/t)</string>
|
||||
@@ -93,6 +181,7 @@
|
||||
<string name="description_sensor_cadence">Kadence (omdr./min.)</string>
|
||||
<string name="description_sensor_heart_rate">Puls (slag/min.)</string>
|
||||
<string name="description_sensor_power">Effekt (W)</string>
|
||||
<string name="description_default_speed_or_pace">Efter aktivitetstype</string>
|
||||
<string name="description_speed_imperial">Hastighed (mil/t)</string>
|
||||
<string name="description_speed_metric">Hastighed (km/t)</string>
|
||||
<string name="description_time">Tid</string>
|
||||
@@ -100,19 +189,25 @@
|
||||
<string name="description_total_time">Samlet tid: %1$s</string>
|
||||
<string name="description_track_point">Punkt</string>
|
||||
<string name="description_track_segment">Segment</string>
|
||||
<!-- Export -->
|
||||
<string name="export_all_option">Alle som %1$s</string>
|
||||
<string name="export_all_title">Eksportér til eksternt lager</string>
|
||||
<string name="export_with_photos">med fotos</string>
|
||||
<string name="export_without_photos">uden fotos</string>
|
||||
<string name="export_error">%1$d af %2$s blev eksporteret til %3$s</string>
|
||||
<string name="export_option">som %1$s til %2$s</string>
|
||||
<string name="export_progress_message">Eksporterer til %1$s…</string>
|
||||
<string name="export_success">%1$s blev eksporteret til %2$s</string>
|
||||
<string name="export_title">Eksportér til…</string>
|
||||
<!-- External Storage -->
|
||||
<!-- Files -->
|
||||
<string name="files_few">%1$d filer</string>
|
||||
<string name="files_many">%1$d filer</string>
|
||||
<string name="files_one">1 fil</string>
|
||||
<string name="files_other">%1$d filer</string>
|
||||
<string name="files_two">2 filer</string>
|
||||
<string name="files_zero">0 filer</string>
|
||||
<!-- Generic -->
|
||||
<string name="generic_add">Tilføj</string>
|
||||
<string name="generic_cancel">Annuller</string>
|
||||
<string name="generic_delete_all_confirm_title">Skal alle slettes?</string>
|
||||
@@ -131,19 +226,16 @@
|
||||
<string name="generic_success_title">Gennemført</string>
|
||||
<string name="generic_tracks">Ruter</string>
|
||||
<string name="generic_yes">Ja</string>
|
||||
<!-- Gps -->
|
||||
<string name="gps_location_access">\"Placeringsadgang\"</string>
|
||||
<string name="gps_disabled">GPS er ikke aktiveret. Tryk her for at gå til %1$s. Tryk på knappen Tilbage for at vende tilbage.</string>
|
||||
<string name="gps_disabled_location_mode">Vælg placeringstilstanden Høj nøjagtighed. Tryk her for at gå til %1$s. Tryk på knappen igen for at vende tilbage.</string>
|
||||
<string name="gps_disabled_my_location">Den aktuelle placering kan ikke bestemmes. Aktivér flere placeringskilder i %1$s, og sørg for, at
|
||||
himlen er synlig. Prøv igen senere.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">Den aktuelle placering kan ikke bestemmes. Aktivér flere placeringskilder i %1$s, og sørg
|
||||
for, at himlen er synlig. Prøv igen senere.</string>
|
||||
<string name="gps_not_found">Der blev ikke fundet nogen GPS på enheden</string>
|
||||
<string name="gps_starting">Starter GPS</string>
|
||||
<string name="gps_starting_error">GPS kunne ikke startes</string>
|
||||
<string name="gps_stopping">Stopper GPS</string>
|
||||
<string name="gps_wait_for_better_signal">Venter på et bedre GPS-signal</string>
|
||||
<string name="gps_wait_for_signal">Venter på GPS-signal</string>
|
||||
<!-- Image -->
|
||||
<string name="image_application">Applikation</string>
|
||||
<string name="image_arrow">Pil</string>
|
||||
<string name="image_marker">Markør</string>
|
||||
@@ -154,6 +246,7 @@
|
||||
<string name="image_record">Registrer</string>
|
||||
<string name="image_stop">Stop</string>
|
||||
<string name="image_track">Rute</string>
|
||||
<!-- Import -->
|
||||
<string name="import_error">%1$d af %2$s er importeret fra %3$s</string>
|
||||
<string name="import_no_directory">%1$s findes ikke</string>
|
||||
<string name="import_no_file">Der var ingen filer at importere. Slut din enhed til din computer, og placer filer, der skal
|
||||
@@ -163,9 +256,11 @@
|
||||
<string name="import_selection_option">Alle %1$s</string>
|
||||
<string name="import_selection_title">Importér fra eksternt lager</string>
|
||||
<string name="import_success">%1$s er importeret fra %2$s</string>
|
||||
<!-- Marker -->
|
||||
<string name="marker_add_error">En markør kan ikke indsættes. Intet GPS-signal. Prøv igen.</string>
|
||||
<string name="marker_add_success">Der blev indsat en markør</string>
|
||||
<string name="marker_add_canceled">Annulleret, ingen markør blev tilføjet</string>
|
||||
<string name="marker_add_photo_canceled">Annulleret, ingen fotomarkering tilføjet</string>
|
||||
<string name="marker_delete_all_confirm_message">Alle markører for denne rute slettes permanent fra enheden</string>
|
||||
<string name="marker_delete_one_confirm_message">Markøren slettes permanent fra enheden</string>
|
||||
<string name="marker_delete_one_confirm_title">Vil du slette markøren?</string>
|
||||
@@ -175,26 +270,24 @@
|
||||
<string name="marker_name_format">Markør %1$d</string>
|
||||
<string name="marker_split_name_format">Deling %1$d</string>
|
||||
<string name="marker_title">%1$d af %2$d</string>
|
||||
<!-- Marker Detail -->
|
||||
<string name="marker_detail_statistics_title">Siden sidste delte markør:</string>
|
||||
<!-- Marker Edit -->
|
||||
<string name="marker_edit_marker_type">Markørtype (f.eks. vandfald)</string>
|
||||
<string name="marker_edit_marker_type_hint">Markørtype</string>
|
||||
<!-- Marker List -->
|
||||
<string name="marker_list_empty_message">Du har ingen markører</string>
|
||||
<!-- Menu -->
|
||||
<string name="menu_aggregated_statistics">Samlet statistik</string>
|
||||
<string name="menu_delete">Slet</string>
|
||||
<string name="menu_delete_all">Slet alle</string>
|
||||
<string name="menu_edit">Rediger</string>
|
||||
<string name="menu_export">Eksportér</string>
|
||||
<string name="menu_export_all">Eksportér alle</string>
|
||||
<string name="menu_feedback">Feedback</string>
|
||||
<string name="menu_help">Hjælp</string>
|
||||
<string name="menu_help_feedback">Hjælp og feedback</string>
|
||||
<string name="menu_help_forum">Hjælpeforum</string>
|
||||
<string name="menu_import_all">Importér alle</string>
|
||||
<string name="menu_insert_marker">Indsæt markør</string>
|
||||
<string name="menu_insert_photo">Indsæt billede</string>
|
||||
<string name="menu_map">Kort</string>
|
||||
<string name="menu_insert_gallery_img">Indsæt galleribillede</string>
|
||||
<string name="menu_markers">Markører</string>
|
||||
<string name="menu_play">Afspil</string>
|
||||
<string name="menu_search">Søg</string>
|
||||
<string name="menu_select_all">Vælg alle</string>
|
||||
<string name="menu_sensor_state">Sensortilstand</string>
|
||||
@@ -206,30 +299,41 @@
|
||||
<string name="menu_stop_gps">Stop GPS</string>
|
||||
<string name="menu_view_photo">Se billede</string>
|
||||
<string name="menu_voice_frequency">Stemmefrekvens</string>
|
||||
<string name="menu_resume_track">Genoptag sporet</string>
|
||||
<!-- OpenTracks -->
|
||||
<string name="app_name">OpenTracks</string>
|
||||
<string name="recording_service">Registreringstjeneste</string>
|
||||
<!-- Permission -->
|
||||
<string name="permission_gps_failed">OpenTracks kræver tilladelse til at bruge GPS.</string>
|
||||
<!-- Search -->
|
||||
<string name="search_global_description">Ruter og markører</string>
|
||||
<string name="search_list_empty_message">Ingen ruter eller markører matchede din søgning</string>
|
||||
<string name="search_list_marker_track_location">I ruten \"%1$s\".</string>
|
||||
<string name="search_voice_prompt">Sig navnet på en rute eller markør</string>
|
||||
<!-- Sensor State -->
|
||||
<string name="sensor_state_battery">Batteriniveau</string>
|
||||
<string name="sensor_state_cadence">Kadence</string>
|
||||
<string name="sensor_state_cadence_value">%1$d omdr/min</string>
|
||||
<string name="sensor_state_connected">Tilsluttet</string>
|
||||
<string name="sensor_state_connecting">Opretter forbindelse</string>
|
||||
<string name="sensor_state_disconnected">Afbrudt</string>
|
||||
<string name="sensor_state_heart_rate">Puls</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d slag per minut</string>
|
||||
<string name="sensor_state_last_sensor_time">Sidste sensortid</string>
|
||||
<string name="sensor_state_power">Strøm</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">Sender</string>
|
||||
<string name="sensor_not_known">Sensor %1$s er ukendt. Kontroller indstillingerne.</string>
|
||||
<string name="sensor_could_not_scan">Kunne ikke scanne efter Bluetooth-enheder (fejl %1$i).</string>
|
||||
<string name="bluetooth_disabled">Aktivér Bluetooth.</string>
|
||||
<string name="settings_not_while_recording">Ikke tilgængelig ved registrering af rute</string>
|
||||
<string name="settings_show">Vis</string>
|
||||
<!-- Settings Advanced -->
|
||||
<string name="settings_advanced">Avanceret</string>
|
||||
<!-- Settings Chart -->
|
||||
<string name="settings_chart_by_distance">Efter afstand</string>
|
||||
<string name="settings_chart_by_time">Efter tid</string>
|
||||
<string name="settings_chart_x_axis">X-akse</string>
|
||||
<!-- Settings Recording -->
|
||||
<string name="settings_recording_show_on_lockscreen_while_recording_title">Vis statistik på låseskærm</string>
|
||||
<string name="settings_recording_show_on_lockscreen_while_recording_summary">Vis statistik, mens du optager, uden at låse enheden op.</string>
|
||||
<string name="settings_recording_keep_screen_on_while_recording_title">Hold skærmen tændt</string>
|
||||
<string name="settings_recording_keep_screen_on_while_recording_summary">Hold skærmen tændt, mens du optager.</string>
|
||||
<string name="settings_recording">Registrering</string>
|
||||
<string name="settings_recording_auto_resume_track_timeout_always_summary">Genoptag altid en registrering efter en genstart</string>
|
||||
<string name="settings_recording_auto_resume_track_timeout_never_summary">Genoptag altid en registrering efter en genstart</string>
|
||||
@@ -247,31 +351,33 @@
|
||||
<string name="settings_recording_track_name_date_local_option">Dato (lokal)</string>
|
||||
<string name="settings_recording_track_name_number_option">Nummer</string>
|
||||
<string name="settings_recording_track_name_title">Standardnavn på spor</string>
|
||||
<!-- Settings Reset -->
|
||||
<string name="settings_reset">Nulstil</string>
|
||||
<string name="settings_reset_confirm_message">Alle indstillinger vil blive ændret til standardværdierne..</string>
|
||||
<string name="settings_reset_confirm_title">Vil du nulstille nu?</string>
|
||||
<string name="settings_reset_done">Alle indstillinger er blevet gendannet til standardværdierne</string>
|
||||
<string name="settings_error_initial_values_restored">Beklager, men der opstod en fejl. Alle indstillinger er vendt tilbage til standardværdierne.</string>
|
||||
<!-- Settings Sensor -->
|
||||
<string name="settings_sensor">Sensor</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Nulstil cykelkadence</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Nulstil kombineret cykel</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Nulstil puls</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Nulstil fodsensor</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Bluetooth-parring</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Åbn indstillinger for Bluetooth i Android for at parre en sensor</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Bluetooth-sensor</string>
|
||||
<string name="settings_sensor_connected">Tilsluttet %1$s</string>
|
||||
<string name="settings_sensor_connecting">Tilsluttet %1$s</string>
|
||||
<string name="settings_sensor_disconnected">Frakoblet %1$s</string>
|
||||
|
||||
<string name="settings_sensor_wheel_circumference">Hjulstørrelse (ETRTO)</string>
|
||||
|
||||
<!-- Settings Stats -->
|
||||
<string name="settings_stats_coordinate">Breddegrad/længdegrad</string>
|
||||
<string name="settings_stats_rate_title">Foretrukkenfartenhed</string>
|
||||
<string name="settings_stats_units_imperial">Britisk (mil, ft)</string>
|
||||
<string name="settings_stats_units_metric">Metrisk (km, m)</string>
|
||||
<string name="settings_stats_units_title">Foretrukne enheder</string>
|
||||
<string name="share_track_emails_hint">E-mailadresser</string>
|
||||
<string name="share_track_picker_title">Vælg en applikation</string>
|
||||
<!-- Share Track -->
|
||||
<string name="share_track_share_file">Del rutefil</string>
|
||||
<string name="share_track_share_file_body">Du kunne måske være interesseret i denne rute.\n\nDu kan bruge Google Earth eller anden
|
||||
kortlægningssoftware til at se ruten.\n\n%1$s</string>
|
||||
<string name="share_track_subject">Jeg vil gerne dele en rute med dig</string>
|
||||
<!-- Stats -->
|
||||
<string name="stats_average_moving_pace">Gns. bevægelsestempo</string>
|
||||
<string name="stats_average_moving_speed">Gns. bevægelseshastighed</string>
|
||||
<string name="stats_average_pace">Gns. tempo</string>
|
||||
@@ -290,28 +396,36 @@
|
||||
<string name="stats_speed">Hastighed</string>
|
||||
<string name="stats_distance">Afstand</string>
|
||||
<string name="stats_total_time">Samlet tid</string>
|
||||
<!-- Track -->
|
||||
<string name="track_name_format">Rute %1$d</string>
|
||||
<string name="track_record_notification">Registrerer din rute…</string>
|
||||
<string name="track_recording_notification_accuracy">Placeringsnøjagtighed: %1$s</string>
|
||||
<string name="track_markers">Markører på %1$s</string>
|
||||
<!-- Track Delete -->
|
||||
<string name="track_delete_one_confirm_message">Ruten og de tilhørende markører slettes permanent fra enheden.</string>
|
||||
<string name="track_delete_one_confirm_title">Vil du slette ruten?</string>
|
||||
<string name="track_delete_multiple_confirm_message">De valgte ruter og tilhørende markører slettes permanent fra enheden.</string>
|
||||
<string name="track_delete_progress_message">Sletter…</string>
|
||||
<!-- Track Detail -->
|
||||
<string name="track_detail_chart_tab">Diagram</string>
|
||||
<string name="track_detail_stats_tab">Statistik</string>
|
||||
<string name="track_detail_record_success">Registrerer en ny rute</string>
|
||||
<string name="track_detail_resume_success">Genoptager nu sporet</string>
|
||||
<!-- Track Edit -->
|
||||
<string name="track_edit_activity_type">Aktivitetstype (f.eks. vandretur)</string>
|
||||
<string name="track_edit_activity_type_hint">Aktivitetstype</string>
|
||||
<string name="track_edit_new_track_title">Ny rute</string>
|
||||
<!-- Track List -->
|
||||
<string name="track_list_empty_message">Her kan du gå i gang med at registrere dit næste eventyr</string>
|
||||
<string name="track_list_record_error">Registreringen kan ikke startes. Intet GPS-signal. Prøv igen.</string>
|
||||
<string name="track_list_record_success">Registrerer en ny rute</string>
|
||||
<string name="track_widget_config_title">Konfigurer widget-elementer</string>
|
||||
<!-- Track Widget -->
|
||||
<!-- Tracks -->
|
||||
<string name="tracks_few">%1$d ruter</string>
|
||||
<string name="tracks_many">%1$d ruter</string>
|
||||
<string name="tracks_one">1 rute</string>
|
||||
<string name="tracks_other">%1$d ruter</string>
|
||||
<string name="tracks_two">2 ruter</string>
|
||||
<string name="tracks_zero">0 ruter</string>
|
||||
<!-- Unit -->
|
||||
<string name="unit_feet">fod</string>
|
||||
<string name="unit_kilometer">km</string>
|
||||
<string name="unit_kilometer_per_hour">km/t</string>
|
||||
@@ -320,6 +434,7 @@
|
||||
<string name="unit_mile_per_hour">mil/t</string>
|
||||
<string name="unit_minute_per_kilometer">min./km</string>
|
||||
<string name="unit_minute_per_mile">min./mil</string>
|
||||
<!-- Value -->
|
||||
<string name="value_adapt_accuracy">Juster nøjagtighed</string>
|
||||
<string name="value_adapt_battery_life">Tilpas til batterilevetid</string>
|
||||
<string name="value_always">Altid</string>
|
||||
@@ -331,10 +446,8 @@
|
||||
<string name="value_integer_feet">%1$d fod</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d fod (fremragende GPS)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d fod (anbefales)</string>
|
||||
<string name="value_integer_kilobyte">%1$d kB</string>
|
||||
<string name="value_integer_kilometer">%1$d km</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d km/t</string>
|
||||
<string name="value_integer_megabyte">%1$d MB</string>
|
||||
<string name="value_integer_meter">%1$d m</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d m (fremragende GPS)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d m (dårlig GPS)</string>
|
||||
@@ -344,11 +457,11 @@
|
||||
<string name="value_integer_minute">%1$d min.</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d sek.</string>
|
||||
<string name="value_never">Aldrig</string>
|
||||
<string name="value_none">Ingen</string>
|
||||
<string name="value_off">Fra</string>
|
||||
<string name="value_smallest">Mindste</string>
|
||||
<string name="value_smallest_recommended">Mindst (anbefalet)</string>
|
||||
<!-- Voice -->
|
||||
<string name="voice_hours_few">%1$d timer</string>
|
||||
<string name="voice_hours_many">%1$d timer</string>
|
||||
<string name="voice_hours_one">1 time</string>
|
||||
@@ -395,6 +508,7 @@
|
||||
<string name="voice_total_distance_miles_two">afstand i alt 2 mil</string>
|
||||
<string name="voice_total_distance_miles_zero">afstand i alt 0 mil</string>
|
||||
<string name="voice_total_distance_zero">Afstand i alt i OpenTracks er nul.</string>
|
||||
<!-- Waypoint Type -->
|
||||
<string name="waypoint_type_atm">Pengeautomat</string>
|
||||
<string name="waypoint_type_bank">bank</string>
|
||||
<string name="waypoint_type_bar">bar</string>
|
||||
@@ -446,4 +560,7 @@
|
||||
<string name="waypoint_type_waterfall">vandfald</string>
|
||||
<string name="waypoint_type_water_fountain">springvand</string>
|
||||
<string name="waypoint_type_waypoint">vejpunkt</string>
|
||||
<!-- Share image -->
|
||||
<string name="share_image_subject">Jeg vil gerne dele et billede med dig</string>
|
||||
<string name="share_image_body">Jeg tror, du måske er interesseret i dette billede.</string>
|
||||
</resources>
|
||||
|
||||
@@ -36,7 +36,7 @@ limitations under the License.
|
||||
Verwende das kleine Kartensymbol.\n
|
||||
a)
|
||||
(Live-Aktualisierungen) Installiere <a href="https://github.com/OpenTracksApp/OSMDashboard">OSMDashboard</a>.
|
||||
OSMDashboard stellt Online- oder Offline-Karten über <a href="https://www.openstreetmap.org">OpenStreetmap</a>.\n zur Verfügung.
|
||||
OSMDashboard stellt Online- oder Offline-Karten über <a href="https://www.openstreetmap.org">OpenStreetMap</a>.\n zur Verfügung.
|
||||
Eigentlich ist OSMDashboard eine separate App, die nur (vorübergehend) auf die Daten der anzuzeigenden Strecke(n) zugreifen kann.
|
||||
|
||||
\n
|
||||
@@ -232,13 +232,9 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<!-- Gps -->
|
||||
<string name="gps_location_access">\"Standortzugriff\"</string>
|
||||
<string name="gps_disabled">GPS ist nicht aktiviert. Tippen Sie hier, um zu %1$s wechseln. Drücken Sie \"Zurück\", um zurückzugehen.</string>
|
||||
<string name="gps_disabled_location_mode">Wählen Sie den Standortmodus für hohe Genauigkeit aus. Tippen Sie hier, um \"%1$s\" zu öffnen. Tippen Sie auf \"Zurück\", um zu dieser Ansicht zurückzukehren.</string>
|
||||
<string name="gps_disabled_my_location">Der aktuelle Standort kann nicht ermittelt werden. Aktivieren Sie mehr Standortquellen unter \"%1$s\" und vergewissern Sie sich, dass der Himmel sichtbar ist. Bitte versuchen Sie es später erneut.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">Der aktuelle Standort kann nicht ermittelt werden. Aktivieren Sie den Standortmodus für hohe Genauigkeit unter \"%1$s\" und vergewissern Sie sich, dass der Himmel sichtbar ist. Bitte versuchen Sie es später erneut.</string>
|
||||
<string name="gps_not_found">Das Gerät sendet kein GPS-Signal.</string>
|
||||
<string name="gps_starting">GPS wird gestartet.</string>
|
||||
<string name="gps_starting_error">GPS kann nicht gestartet werden.</string>
|
||||
<string name="gps_stopping">GPS wird beendet.</string>
|
||||
<string name="gps_wait_for_better_signal">Warten auf besseres GPS-Signal</string>
|
||||
<string name="gps_wait_for_signal">Warten auf GPS-Signal</string>
|
||||
<!-- Image -->
|
||||
@@ -286,21 +282,14 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<!-- Menu -->
|
||||
<string name="menu_aggregated_statistics">Gesammelte Statistiken</string>
|
||||
<string name="menu_delete">Löschen</string>
|
||||
<string name="menu_delete_all">Alle löschen</string>
|
||||
<string name="menu_edit">Bearbeiten</string>
|
||||
<string name="menu_export">Exportieren</string>
|
||||
<string name="menu_export_all">Alle exportieren</string>
|
||||
<string name="menu_feedback">Feedback</string>
|
||||
<string name="menu_help">Hilfe</string>
|
||||
<string name="menu_help_feedback">Hilfe & Feedback</string>
|
||||
<string name="menu_help_forum">Hilfeforum</string>
|
||||
<string name="menu_import_all">Alle importieren</string>
|
||||
<string name="menu_insert_marker">Markierung einfügen</string>
|
||||
<string name="menu_insert_photo">Foto einfügen</string>
|
||||
<string name="menu_insert_gallery_img">Galerie Bild einfügen</string>
|
||||
<string name="menu_map">Karte</string>
|
||||
<string name="menu_markers">Markierungen</string>
|
||||
<string name="menu_play">Wiedergeben</string>
|
||||
<string name="menu_search">Suche</string>
|
||||
<string name="menu_select_all">Alle auswählen</string>
|
||||
<string name="menu_sensor_state">Sensorstatus</string>
|
||||
@@ -322,27 +311,23 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="search_global_description">Tracks und Markierungen</string>
|
||||
<string name="search_list_empty_message">Keine Tracks oder Markierungen gefunden, die Ihrer Suchanfrage entsprechen</string>
|
||||
<string name="search_list_marker_track_location">Im Track \"%1$s\".</string>
|
||||
<string name="search_voice_prompt">Sprechen Sie den Namen eines Tracks oder einer Markierung.</string>
|
||||
<!-- Sensor State -->
|
||||
<string name="sensor_state_battery">Akkustatus</string>
|
||||
<string name="sensor_state_cadence">Trittfrequenz</string>
|
||||
<string name="sensor_state_cadence_value">%1$d Umdrehungen pro Minute</string>
|
||||
<string name="sensor_state_connected">Verbunden</string>
|
||||
<string name="sensor_state_connecting">Verbindung wird hergestellt…</string>
|
||||
<string name="sensor_state_disconnected">Nicht verbunden</string>
|
||||
<string name="sensor_state_heart_rate">Herzfrequenz</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d Schläge pro Minute</string>
|
||||
<string name="sensor_state_last_sensor_time">Letzte Sensorzeit</string>
|
||||
<string name="sensor_state_power">Leistung</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">Wird gesendet</string>
|
||||
<string name="sensor_not_known">Sensor %1$s ist unbekannt. Bitte überprüfe die Einstellungen.</string>
|
||||
<string name="sensor_could_not_scan">Konnte nicht nach Bluetooth-Geräten scannen (Fehler %1$i).</string>
|
||||
<string name="bluetooth_disabled">Bitte Bluetooth aktivieren.</string><!-- Settings -->
|
||||
<string name="bluetooth_disabled">Bitte Bluetooth aktivieren.</string>
|
||||
<string name="settings_not_while_recording">Während der Aufzeichnung eines Tracks nicht verfügbar</string>
|
||||
<string name="settings_show">Anzeigen</string>
|
||||
<!-- Settings Advanced -->
|
||||
<string name="settings_advanced">Erweitert</string>
|
||||
<string name="settings_default_trackfileformat">Dateiformat für export/teilen</string>
|
||||
<!-- Settings Chart -->
|
||||
<string name="settings_chart_by_distance">Nach Strecke</string>
|
||||
<string name="settings_chart_by_time">Nach Zeit</string>
|
||||
@@ -377,16 +362,9 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="settings_error_initial_values_restored">Entschuldigung, es ist ein Fehler aufgetreten. Alle Einstellungen wurden auf die Standardwerte zurückgesetzt.</string>
|
||||
<!-- Settings Sensor -->
|
||||
<string name="settings_sensor">Sensor</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Trittfrequenz zurücksetzen</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Radsensoren zurücksetzen</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Herzfrequenz zurücksetzen</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Laufsensor zurücksetzen</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Bluetooth-Pairing</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Die Bluetooth-Einstellungen von Android öffnen, um ein Sensor-Pairing vorzunehmen</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Bluetooth-Sensor</string>
|
||||
<string name="settings_sensor_connecting">Verbunden mit %1$s</string>
|
||||
<string name="settings_sensor_connected">Verbunden mit %1$s</string>
|
||||
<string name="settings_sensor_disconnected">Verbindung getrennt von %1$s</string>
|
||||
|
||||
<string name="settings_sensor_wheel_circumference">Reifengröße (ETRTO)</string>
|
||||
@@ -398,16 +376,14 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="settings_stats_units_metric">Metrisch (km, m)</string>
|
||||
<string name="settings_stats_units_title">Bevorzugte Einheiten</string>
|
||||
<!-- Share Track -->
|
||||
<string name="share_track_emails_hint">E-Mail-Adressen</string>
|
||||
<string name="share_track_picker_title">App auswählen</string>
|
||||
<string name="share_track_share_file">Track-Datei teilen</string>
|
||||
<string name="share_track_share_file_body">Dieser Track könnte dich interessieren.\n\nDu kannst ihn dir mit Google Earth oder einer anderen Kartierungssoftware ansehen.\n\n%1$s</string>
|
||||
<string name="share_track_subject">Ich möchte einen Track mit dir teilen</string>
|
||||
<!-- Stats -->
|
||||
<string name="stats_average_moving_pace">Durchschnittl. Bewegungstempo</string>
|
||||
<string name="stats_average_moving_speed">Durchschnittl. Bewegungsgeschwindigkeit</string>
|
||||
<string name="stats_average_pace">Durchschnittstempo</string>
|
||||
<string name="stats_average_speed">Durchschnittsgeschwindigkeit</string>
|
||||
<string name="stats_average_moving_pace">Durchschnitt\n(Bewegung)</string>
|
||||
<string name="stats_average_moving_speed">Durchschnitt\n(Bewegung)</string>
|
||||
<string name="stats_average_pace">Durchschnitt</string>
|
||||
<string name="stats_average_speed">Durchschnitt</string>
|
||||
<string name="stats_elevation">Höhe</string>
|
||||
<string name="stats_fastest_pace">Schnellstes Tempo</string>
|
||||
<string name="stats_gain">Anstieg</string>
|
||||
@@ -415,7 +391,7 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="stats_latitude">Breitengrad</string>
|
||||
<string name="stats_longitude">Längengrad</string>
|
||||
<string name="stats_max">Max.</string>
|
||||
<string name="stats_max_speed">Höchstgeschwin-digkeit</string>
|
||||
<string name="stats_max_speed">Max.</string>
|
||||
<string name="stats_min">Min.</string>
|
||||
<string name="stats_moving_time">Bewegungszeit</string>
|
||||
<string name="stats_pace">Tempo</string>
|
||||
@@ -443,10 +419,7 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="track_edit_new_track_title">Neuer Track</string>
|
||||
<!-- Track List -->
|
||||
<string name="track_list_empty_message">Zeichnen Sie Ihr nächstes Abenteuer hier auf.</string>
|
||||
<string name="track_list_record_error">Die Aufzeichnung kann nicht gestartet werden, da kein GPS-Signal verfügbar ist. Bitte versuchen Sie es erneut.</string>
|
||||
<string name="track_list_record_success">Neuer Track wird aufgezeichnet</string>
|
||||
<!-- Track Widget -->
|
||||
<string name="track_widget_config_title">Widget-Elemente konfigurieren</string>
|
||||
<!-- Tracks -->
|
||||
<string name="tracks_few">%1$d Tracks</string>
|
||||
<string name="tracks_many">%1$d Tracks</string>
|
||||
@@ -475,10 +448,8 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="value_integer_feet">%1$d Fuß</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d Fuß (ausgezeichnetes GPS-Signal)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d Fuß (empfohlen)</string>
|
||||
<string name="value_integer_kilobyte">%1$d KB</string>
|
||||
<string name="value_integer_kilometer">%1$d km</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d km/h</string>
|
||||
<string name="value_integer_megabyte">%1$d MB</string>
|
||||
<string name="value_integer_meter">%1$d m</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d m (ausgezeichnetes GPS-Signal)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d m (schlechtes GPS-Signal)</string>
|
||||
@@ -488,7 +459,6 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="value_integer_minute">%1$d min</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d s</string>
|
||||
<string name="value_never">Nie</string>
|
||||
<string name="value_none">Keine</string>
|
||||
<string name="value_off">Aus</string>
|
||||
<string name="value_smallest">Kleinster</string>
|
||||
|
||||
@@ -133,13 +133,9 @@
|
||||
<string name="generic_yes">Ναι</string>
|
||||
<string name="gps_location_access">\'Πρόσβαση τοποθεσίας\'</string>
|
||||
<string name="gps_disabled">Το GPS δεν είναι ενεργοποιημένο. Πατήστε εδώ για να μεταβείτε στο %1$s. Πατήστε το κουμπί \"Πίσω\" για να επιστρέψετε.</string>
|
||||
<string name="gps_disabled_location_mode">Επιλέξτε τη λειτουργία θέσης υψηλής ακρίβειας. Πατήστε εδώ για να μεταβείτε στο μενού %1$s . Πατήστε το κουμπί Πίσω για να επιστρέψετε.</string>
|
||||
<string name="gps_disabled_my_location">Η τρέχουσα τοποθεσία δεν μπορεί να προσδιοριστεί. Ενεργοποιήστε περισσότερες πηγές εντοπισμού στο μενού %1$s και βεβαιωθείτε ότι ο ουρανός είναι καθαρός. Δοκιμάστε ξανά αργότερα.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">Η τρέχουσα θέση δεν μπορεί να προσδιοριστεί. Επιλέξτε τη λειτουργία θέσης υψηλής ακρίβειας στο μενού %1$s και βεβαιωθείτε ότι ο ουρανός είναι καθαρός. Δοκιμάστε ξανά αργότερα.</string>
|
||||
<string name="gps_not_found">Δε βρέθηκε GPS στη συσκευή</string>
|
||||
<string name="gps_starting">Εκκίνηση GPS</string>
|
||||
<string name="gps_starting_error">Δεν είναι δυνατή η εκκίνηση του GPS</string>
|
||||
<string name="gps_stopping">Διακοπή λειτουργίας GPS</string>
|
||||
<string name="gps_wait_for_better_signal">Αναμονή για καλύτερο σήμα GPS</string>
|
||||
<string name="gps_wait_for_signal">Αναμονή για σήμα GPS</string>
|
||||
<string name="image_application">Εφαρμογή</string>
|
||||
@@ -179,20 +175,13 @@
|
||||
<string name="marker_list_empty_message">Δεν έχετε κανένα δείκτη</string>
|
||||
<string name="menu_aggregated_statistics">Στατιστικά</string>
|
||||
<string name="menu_delete">Διαγραφή</string>
|
||||
<string name="menu_delete_all">Διαγραφή όλων</string>
|
||||
<string name="menu_edit">Επεξεργασία</string>
|
||||
<string name="menu_export">Εξαγωγή</string>
|
||||
<string name="menu_export_all">Εξαγωγή όλων</string>
|
||||
<string name="menu_feedback">Σχόλια</string>
|
||||
<string name="menu_help">Bοήθεια</string>
|
||||
<string name="menu_help_feedback">Βοήθεια και σχόλια</string>
|
||||
<string name="menu_help_forum">Φόρουμ βοήθειας</string>
|
||||
<string name="menu_import_all">Εισαγωγή όλων</string>
|
||||
<string name="menu_insert_marker">Εισαγωγή σήμανσης</string>
|
||||
<string name="menu_insert_photo">Εισαγωγή φωτογραφίας</string>
|
||||
<string name="menu_map">Χάρτης</string>
|
||||
<string name="menu_markers">Δείκτες</string>
|
||||
<string name="menu_play">Αναπαραγωγή</string>
|
||||
<string name="menu_search">Αναζήτηση</string>
|
||||
<string name="menu_select_all">Επιλογή όλων</string>
|
||||
<string name="menu_sensor_state">Κατάσταση αισθητήρα</string>
|
||||
@@ -209,19 +198,14 @@
|
||||
<string name="search_global_description">Ίχνη και σημάνσεις</string>
|
||||
<string name="search_list_empty_message">Δεν υπάρχουν διαδρομές ή δείκτες που να ταιριάζουν στην αναζήτησή σας</string>
|
||||
<string name="search_list_marker_track_location">Στο ίχνος \"%1$s\".</string>
|
||||
<string name="search_voice_prompt">Εκφωνείστε το όνομα μιας διαδρομής ή δείκτη</string>
|
||||
<string name="sensor_state_battery">Στάθμη μπαταρίας</string>
|
||||
<string name="sensor_state_cadence">Ρυθμός</string>
|
||||
<string name="sensor_state_cadence_value">%1$d rpm</string>
|
||||
<string name="sensor_state_connected">Συνδέθηκε</string>
|
||||
<string name="sensor_state_connecting">Σύνδεση</string>
|
||||
<string name="sensor_state_disconnected">Αποσυνδεδεμένος</string>
|
||||
<string name="sensor_state_heart_rate">Καρδιακοί παλμοί</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d bpm</string>
|
||||
<string name="sensor_state_last_sensor_time">Χρόνος τελευταίου αισθητήρα</string>
|
||||
<string name="sensor_state_power">Ισχύς</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">Αποστολή</string>
|
||||
<string name="settings_not_while_recording">Η επιλογή δεν είναι διαθέσιμη κατά την εγγραφή ίχνους</string>
|
||||
<string name="settings_show">Εμφάνιση</string>
|
||||
<string name="settings_advanced">Προηγμένες</string>
|
||||
@@ -250,22 +234,13 @@
|
||||
<string name="settings_reset_confirm_title">Επαναφορά τώρα;</string>
|
||||
<string name="settings_reset_done">Όλες οι ρυθμίσεις έχουν επανέλθει στις προεπιλεγμένες τιμές</string>
|
||||
<string name="settings_sensor">Αισθητήρας</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Επαναφορά ρυθμού ποδηλασίας</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Επαναφορά συνδυασμού ποδηλασίας</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Επαναφορά καρδιακού ρυθμού</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Επαναφορά μετρητή ταχύτητας</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Ζεύξη Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Άνοιγμα των ρυθμίσεων Bluetooth του Android για ζεύξη με αισθητήρα</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Αισθητήρας Bluetooth</string>
|
||||
<string name="settings_sensor_connected">Έγινε σύνδεση με %1$s</string>
|
||||
<string name="settings_stats_coordinate">Πλάτος/Μήκος</string>
|
||||
<string name="settings_stats_rate_title">Προτιμώμενος ρυθμός</string>
|
||||
<string name="settings_stats_units_imperial">Αγγλοσαξονικό (μίλια, πόδια)</string>
|
||||
<string name="settings_stats_units_metric">Μετρικό (χλμ, μέτρα)</string>
|
||||
<string name="settings_stats_units_title">Προτιμώμενες μονάδες</string>
|
||||
<string name="share_track_emails_hint">Διευθύνσεις ηλεκτρονικού ταχυδρομείου</string>
|
||||
<string name="share_track_picker_title">Επιλογή εφαρμογής</string>
|
||||
<string name="share_track_share_file">Κοινή χρήση αρχείου ίχνους</string>
|
||||
<string name="share_track_share_file_body">Νομίζω ότι μπορεί να σε ενδιαφέρει αυτό το ίχνος.\n\nΓια να δεις αυτό το ίχνος, χρησιμοποίησε το Google Earth ή άλλο λογισμικό χαρτογράφησης.\n\n%1$s</string>
|
||||
<string name="share_track_subject">Θα ήθελα να μοιραστώ μία διαδρομή μαζί σου</string>
|
||||
@@ -300,9 +275,6 @@
|
||||
<string name="track_edit_activity_type_hint">Τύπος δραστηριότητας</string>
|
||||
<string name="track_edit_new_track_title">Νέο ίχνος</string>
|
||||
<string name="track_list_empty_message">Ξεκινήστε την εγγραφή της επόμενης περιπέτειάς σας εδώ</string>
|
||||
<string name="track_list_record_error">Δεν είναι δυνατή η έναρξη της εγγραφής. Δεν υπάρχει σήμα GPS. Δοκιμάστε ξανά.</string>
|
||||
<string name="track_list_record_success">Εγγραφή νέας διαδρομής σε εξέλιξη</string>
|
||||
<string name="track_widget_config_title">Διαμόρφωση στοιχείων γραφικού στοιχείου</string>
|
||||
<string name="tracks_few">%1$d ίχνη</string>
|
||||
<string name="tracks_many">%1$d ίχνη</string>
|
||||
<string name="tracks_one">1 ίχνος</string>
|
||||
@@ -328,10 +300,8 @@
|
||||
<string name="value_integer_feet">%1$d πόδια</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d πόδια (τέλειο σήμα GPS)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d ft (συνιστάται)</string>
|
||||
<string name="value_integer_kilobyte">%1$d kB</string>
|
||||
<string name="value_integer_kilometer">%1$d χιλιόμετρα</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d χλμ/ώρα</string>
|
||||
<string name="value_integer_megabyte">%1$d MB</string>
|
||||
<string name="value_integer_meter">%1$d μέτρα</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d μέτρα (τέλειο σήμα GPS)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d μέτρα (χαμηλό σήμα GPS)</string>
|
||||
@@ -341,7 +311,6 @@
|
||||
<string name="value_integer_minute">%1$d λεπ.</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d δευτ</string>
|
||||
<string name="value_never">Ποτέ</string>
|
||||
<string name="value_none">Καμία</string>
|
||||
<string name="value_off">Απενεργοποιημένο</string>
|
||||
<string name="value_smallest">Μικρότερη</string>
|
||||
|
||||
@@ -1,5 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2010 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.
|
||||
-->
|
||||
<resources>
|
||||
<string name="about_preference_title">Acerca de OpenTracks</string>
|
||||
<string name="about_description"><i>OpenTracks</i> es una aplicación de seguimiento deportivo que respeta completamente su privacidad.</string>
|
||||
<string name="about_url">Página web del proyecto: <a href="%1$s">%1$s</a></string>
|
||||
<string name="about_version_name">Nombre de la versión: %1$s</string>
|
||||
<string name="about_version_code">Código de la versión: %1$d</string>
|
||||
<string name="about_history">OpenTracks es una bifurcación de <a href="https://code.google.com/archive/p/mytracks/"><i>MyTracks </i></a> de Google (descontinuado en 2016).</string>
|
||||
<string name="about_libraries">Bibliotecas</string>
|
||||
<!-- Help -->
|
||||
<string name="help_feature_title">OpenTracks tiene las siguientes características:</string>
|
||||
<string name="help_feature_content">
|
||||
* crear un seguimiento GPS *
|
||||
* usa un sensor de ritmo cardíaco (sólo Bluetooth LE) *
|
||||
* anuncios de voz (por tiempo o distancia)*
|
||||
* crear marcadores (incluyendo imágenes) *
|
||||
* funciona completamente fuera de línea *
|
||||
* mostrar las pistas en un mapa (ver abajo)</string>
|
||||
|
||||
<string name="help_track_map_title">¿Cómo mostrar una pista en un mapa?</string>
|
||||
<string name="help_track_map_content">
|
||||
Usa el icono del mapa pequeño.
|
||||
a)
|
||||
(actualizaciones en vivo) Instalar <a href="https://github.com/OpenTracksApp/OSMDashboard">OSMDashboard</a>.
|
||||
Proporciona mapas en línea o fuera de línea a través de <a href="https://www.openstreetmap.org">OpenStreetMap</a>.\n
|
||||
En realidad, OSMDashboard es una aplicación independiente que sólo puede acceder (temporalmente) a los datos de las pist(as) que se van a mostrar.
|
||||
|
||||
\n
|
||||
b)
|
||||
A través de una aplicación de mapas normal (por ejemplo, <a href="http://osmand.net/">OsmAnd</a> y <a href="https://maps.me/">MAPS.ME</a>).
|
||||
Estas aplicaciones necesitan soportar el formato de archivo KMZ (sólo las ubicaciones y las marcas de tiempo).
|
||||
De hecho, una aplicación necesita soportar <i>ACTION_VIEW</i> con MIME <i>application/vnd.google-earth.kmz</i>.</string>
|
||||
|
||||
<string name="help_storage_pictures_title">¿Cómo almacena OpenTracks las fotos que fueron tomadas como marcadores?</string>
|
||||
<string name="help_storage_pictures_content">Estos se almacenan en el almacenamiento interno de la aplicación (es decir, sólo accesible dentro de OpenTracks).</string>
|
||||
|
||||
<string name="help_track_export_title">¿Cómo puedo exportar/compartir las pistas grabadas?</string>
|
||||
<string name="help_track_export_content">
|
||||
Las pistas pueden ser exportadas desde los ajustes como KMZ, KML o GPX.
|
||||
KMZ/KML todos los datos; GPX sólo las ubicaciones.
|
||||
Las pistas compartidas a través del <i> icono de compartir </i> se comparten como KMZ.</string>
|
||||
|
||||
<string name="help_data_google_play_services_title">¿Requiere OpenTracks usar el servicio de Google Play?</string>
|
||||
|
||||
<string name="help_recording_title">¿Cómo registra OpenTracks los datos?</string>
|
||||
<string name="help_recording_content">
|
||||
OpenTracks utiliza el sensor GPS del dispositivo para registrar la ubicación de forma continua.
|
||||
Si el dispositivo GPS reporta datos inexactos (por ejemplo, ubicación, velocidad, elevación), OpenTracks no puede hacer nada al respecto.</string>
|
||||
|
||||
<string name="help_data_storage_title">¿Cómo almacena OpenTracks los datos de los sensores?</string>
|
||||
<string name="help_data_storage_content">
|
||||
Los datos de los sensores se almacenan por cada ubicación registrada.
|
||||
En términos de un sensor de frecuencia cardíaca, esto significa que sólo <i>uno</i> la medición de la frecuencia cardíaca se almacena por ubicación.
|
||||
Si está parado o en el interior, no se registrarán los datos del sensor (pero se mostrarán).</string>
|
||||
|
||||
<string name="help_gps_troubleshooting_title">OpenTracks no está grabando las localizaciones?</string>
|
||||
<string name="help_gps_troubleshooting_content">
|
||||
Lo que puedes hacer...
|
||||
a) Comprobar si el GPS está activado.
|
||||
b) mejorar la recepción del GPS (por ejemplo, ir al exterior),\n
|
||||
c) comprueba si con <a href="https://f-droid.org/en/packages/com.android.gpstest.osmdroid/">GPSTest</a> app, y\n
|
||||
d) desactivar el ahorro de energía.
|
||||
\n
|
||||
Si todo no ayuda, por favor informe de un error.</string>
|
||||
|
||||
<string name="help_support_title">¿Cómo puedo apoyar OpenTracks?</string>
|
||||
<string name="help_support_content">
|
||||
Puedes...
|
||||
a) difundir la palabra sobre OpenTracks,...
|
||||
b) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">proponer características</a>,\n
|
||||
c) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">report bugs</a>,\n
|
||||
d) ayudar en el desarrollo de software,\n
|
||||
e) comprar en <a href="https://play.google.com/store/apps/details?id=de.dennisguse.opentracks.playstore">Google Play Store</a>,\n
|
||||
f) donar, y
|
||||
g) haz lo que creas que ayude a OpenTracks.</string>
|
||||
|
||||
<!-- Activity Type -->
|
||||
<string name="activity_type_airplane">avión</string>
|
||||
<string name="activity_type_atv">vehículos todoterreno</string>
|
||||
<string name="activity_type_biking">ciclismo</string>
|
||||
@@ -66,6 +155,8 @@
|
||||
<string name="activity_type_walking">recorrido a pie</string>
|
||||
<string name="activity_type_water_skiing">esquí acuático</string>
|
||||
<string name="activity_type_wind_surfing">windsurf</string>
|
||||
<string name="app_not_installed_show_on_map">Por favor, instale una aplicación que soporte la presentación de datos de mapas.</string>
|
||||
<!-- Description -->
|
||||
<string name="description_activity_type">Tipo de actividad: %1$s</string>
|
||||
<string name="description_average_moving_pace_in_minute">Ritmo de movimiento medio: %1$s min/km (%2$s min/mi)</string>
|
||||
<string name="description_average_moving_speed">Velocidad de movimiento media: %1$.2f km/h (%2$.1f mi/h)</string>
|
||||
@@ -93,6 +184,7 @@
|
||||
<string name="description_sensor_cadence">Cadencia (rpm)</string>
|
||||
<string name="description_sensor_heart_rate">Frecuencia cardíaca (bpm)</string>
|
||||
<string name="description_sensor_power">Potencia (W)</string>
|
||||
<string name="description_default_speed_or_pace">Por la clase de actividad</string>
|
||||
<string name="description_speed_imperial">Velocidad (mi/h)</string>
|
||||
<string name="description_speed_metric">Velocidad (km / h)</string>
|
||||
<string name="description_time">Tiempo</string>
|
||||
@@ -100,6 +192,7 @@
|
||||
<string name="description_total_time">Tiempo total: %1$s</string>
|
||||
<string name="description_track_point">Punto</string>
|
||||
<string name="description_track_segment">Segmento</string>
|
||||
<!-- Export -->
|
||||
<string name="export_all_option">Todo como %1$s</string>
|
||||
<string name="export_all_title">Exportar a unidad de almacenamiento externa</string>
|
||||
<string name="export_with_photos">con fotos</string>
|
||||
@@ -109,12 +202,15 @@
|
||||
<string name="export_progress_message">Exportando a %1$s…</string>
|
||||
<string name="export_success">Se exportaron %1$s a %2$s</string>
|
||||
<string name="export_title">Exportar a…</string>
|
||||
<!-- External Storage -->
|
||||
<!-- Files -->
|
||||
<string name="files_few">%1$d archivos</string>
|
||||
<string name="files_many">%1$d archivos</string>
|
||||
<string name="files_one">1 archivo</string>
|
||||
<string name="files_other">%1$d archivos</string>
|
||||
<string name="files_two">2 archivos</string>
|
||||
<string name="files_zero">0 archivos</string>
|
||||
<!-- Generic -->
|
||||
<string name="generic_add">Añadir</string>
|
||||
<string name="generic_cancel">Cancelar</string>
|
||||
<string name="generic_delete_all_confirm_title">¿Eliminar todo?</string>
|
||||
@@ -133,17 +229,15 @@
|
||||
<string name="generic_success_title">Correcto</string>
|
||||
<string name="generic_tracks">Rutas</string>
|
||||
<string name="generic_yes">Sí</string>
|
||||
<!-- Gps -->
|
||||
<string name="gps_location_access">\"Acceso a la ubicación\"</string>
|
||||
<string name="gps_disabled">El GPS no está habilitado. Toca aquí para ir a %1$s. Pulsa el botón Atrás para volver.</string>
|
||||
<string name="gps_disabled_location_mode">Selecciona el modo de ubicación de alta precisión. Toca aquí para acceder a %1$s. Para volver a la pantalla anterior, pulsa el botón atrás.</string>
|
||||
<string name="gps_disabled_my_location">No se puede determinar la ubicación actual. Habilita más fuentes de ubicación en %1$s y asegúrate de que se pueda ver el cielo. Vuelve a intentarlo más tarde.</string>
|
||||
<string name="gps_disabled_my_location_location_mode">No se puede determinar la ubicación actual. Selecciona el modo de ubicación de alta precisión en %1$s y asegúrate de que se pueda ver el cielo. Vuelve a intentarlo más tarde.</string>
|
||||
<string name="gps_not_found">No se ha encontrado ningún GPS en el dispositivo</string>
|
||||
<string name="gps_starting">Iniciando GPS</string>
|
||||
<string name="gps_starting_error">No se ha podido iniciar el GPS</string>
|
||||
<string name="gps_stopping">Deteniendo GPS</string>
|
||||
<string name="gps_wait_for_better_signal">Esperando una mejor señal de GPS</string>
|
||||
<string name="gps_wait_for_signal">Esperando señal de GPS</string>
|
||||
<!-- Image -->
|
||||
<string name="image_application">Aplicación</string>
|
||||
<string name="image_arrow">Flecha</string>
|
||||
<string name="image_marker">Marcador</string>
|
||||
@@ -154,6 +248,7 @@
|
||||
<string name="image_record">Grabar</string>
|
||||
<string name="image_stop">Detener</string>
|
||||
<string name="image_track">Ruta</string>
|
||||
<!-- Import -->
|
||||
<string name="import_error">Se importaron %1$d de %2$s desde %3$s</string>
|
||||
<string name="import_no_directory">%1$s no existe</string>
|
||||
<string name="import_no_file">No hay archivos que importar. Conecta tu dispositivo al ordenador y coloca los archivos que quieras
|
||||
@@ -163,6 +258,7 @@
|
||||
<string name="import_selection_option">Todos los archivos %1$s</string>
|
||||
<string name="import_selection_title">Importar desde la unidad de almacenamiento externa</string>
|
||||
<string name="import_success">Se importaron %1$s desde %2$s</string>
|
||||
<!-- Marker -->
|
||||
<string name="marker_add_error">No se puede insertar el marcador. No se recibe señal de GPS. Inténtalo de nuevo.</string>
|
||||
<string name="marker_add_success">Se ha insertado un marcador</string>
|
||||
<string name="marker_add_canceled">Cancelado, no se ha añadido ningún marcador</string>
|
||||
@@ -176,27 +272,24 @@
|
||||
<string name="marker_name_format">Marcador %1$d</string>
|
||||
<string name="marker_split_name_format">Dividir %1$d</string>
|
||||
<string name="marker_title">%1$d de %2$d</string>
|
||||
<!-- Marker Detail -->
|
||||
<string name="marker_detail_statistics_title">Desde el último marcador de división:</string>
|
||||
<!-- Marker Edit -->
|
||||
<string name="marker_edit_marker_type">Tipo de marcador (p. ej., cascada…)</string>
|
||||
<string name="marker_edit_marker_type_hint">Tipo de marcador</string>
|
||||
<!-- Marker List -->
|
||||
<string name="marker_list_empty_message">No tienes ningún marcador</string>
|
||||
<!-- Menu -->
|
||||
<string name="menu_aggregated_statistics">Estadísticas globales</string>
|
||||
<string name="menu_delete">Eliminar</string>
|
||||
<string name="menu_delete_all">Eliminar todo</string>
|
||||
<string name="menu_edit">Editar</string>
|
||||
<string name="menu_export">Exportar</string>
|
||||
<string name="menu_export_all">Exportar todo</string>
|
||||
<string name="menu_feedback">Enviar comentarios</string>
|
||||
<string name="menu_help">Ayuda</string>
|
||||
<string name="menu_help_feedback">Ayuda y opiniones</string>
|
||||
<string name="menu_help_forum">Foro de ayuda</string>
|
||||
<string name="menu_import_all">Importar todo</string>
|
||||
<string name="menu_insert_marker">Insertar marcador</string>
|
||||
<string name="menu_insert_photo">Insertar foto</string>
|
||||
<string name="menu_insert_gallery_img">Insertar imagen de galería</string>
|
||||
<string name="menu_map">Mapa</string>
|
||||
<string name="menu_markers">Marcadores</string>
|
||||
<string name="menu_play">Reproducir</string>
|
||||
<string name="menu_search">Buscar</string>
|
||||
<string name="menu_select_all">Seleccionar todo</string>
|
||||
<string name="menu_sensor_state">Estado de los sensores</string>
|
||||
@@ -209,30 +302,40 @@
|
||||
<string name="menu_view_photo">Ver foto</string>
|
||||
<string name="menu_voice_frequency">Frecuencia de voz</string>
|
||||
<string name="menu_resume_track">Reanudar ruta</string>
|
||||
<!-- OpenTracks -->
|
||||
<string name="app_name">OpenTracks</string>
|
||||
<string name="recording_service">Servicio de grabación</string>
|
||||
<!-- Permission -->
|
||||
<string name="permission_gps_failed">OpenTracks requiere permiso para usar el GPS.</string>
|
||||
<!-- Search -->
|
||||
<string name="search_global_description">Recorridos y marcadores</string>
|
||||
<string name="search_list_empty_message">No hay rutas ni marcadores que coincidan con tu búsqueda</string>
|
||||
<string name="search_list_marker_track_location">En la ruta \"%1$s\"</string>
|
||||
<string name="search_voice_prompt">Di el nombre de la ruta o del marcador</string>
|
||||
<!-- Sensor State -->
|
||||
<string name="sensor_state_battery">Nivel de batería</string>
|
||||
<string name="sensor_state_cadence">Cadencia</string>
|
||||
<string name="sensor_state_cadence_value">%1$d rpm</string>
|
||||
<string name="sensor_state_connected">Conectado</string>
|
||||
<string name="sensor_state_connecting">Conectando</string>
|
||||
<string name="sensor_state_disconnected">Desconectado</string>
|
||||
<string name="sensor_state_heart_rate">Frecuencia cardíaca</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d bpm</string>
|
||||
<string name="sensor_state_last_sensor_time">Último envío de datos del sensor</string>
|
||||
<string name="sensor_state_power">Potencia</string>
|
||||
<string name="sensor_state_power_value">%1$d W</string>
|
||||
<string name="sensor_state_sending">Enviando</string>
|
||||
<string name="sensor_not_known">Sensor %1$s es desconocido. Por favor, compruebe la configuración.</string>
|
||||
<string name="sensor_could_not_scan">No se pudieron buscar dispositivos Bluetooth (error %1$i).</string>
|
||||
<string name="bluetooth_disabled">Por favor, activa el Bluetooth.</string>
|
||||
<string name="settings_not_while_recording">No disponible mientras se graba una ruta</string>
|
||||
<string name="settings_show">Mostrar</string>
|
||||
<!-- Settings Advanced -->
|
||||
<string name="settings_advanced">Avanzado</string>
|
||||
<!-- Settings Chart -->
|
||||
<string name="settings_chart_by_distance">Por distancia</string>
|
||||
<string name="settings_chart_by_time">Por tiempo</string>
|
||||
<string name="settings_chart_x_axis">Eje X</string>
|
||||
<!-- Settings Recording -->
|
||||
<string name="settings_recording_show_on_lockscreen_while_recording_title">Mostrar las estadísticas en la pantalla de bloqueo</string>
|
||||
<string name="settings_recording_show_on_lockscreen_while_recording_summary">Mientras graba, muestre las estadísticas sin desbloquear el dispositivo.</string>
|
||||
<string name="settings_recording_keep_screen_on_while_recording_title">Mantén la pantalla encendida</string>
|
||||
<string name="settings_recording_keep_screen_on_while_recording_summary">Mientras graba, mantenga la pantalla encendida.</string>
|
||||
<string name="settings_recording">Grabación</string>
|
||||
<string name="settings_recording_auto_resume_track_timeout_always_summary">Reanudar siempre una grabación después de reiniciar</string>
|
||||
<string name="settings_recording_auto_resume_track_timeout_never_summary">No reanudar nunca una grabación después de reiniciar</string>
|
||||
@@ -250,30 +353,32 @@
|
||||
<string name="settings_recording_track_name_date_local_option">Fecha (local)</string>
|
||||
<string name="settings_recording_track_name_number_option">Número</string>
|
||||
<string name="settings_recording_track_name_title">Nombre de la ruta</string>
|
||||
<!-- Settings Reset -->
|
||||
<string name="settings_reset">Restablecer</string>
|
||||
<string name="settings_reset_confirm_message">Todos los ajustes volverán a los valores predeterminados.</string>
|
||||
<string name="settings_reset_confirm_title">¿Restablecer ahora?</string>
|
||||
<string name="settings_reset_done">Se han restablecido los valores predeterminados de todas las opciones de configuración</string>
|
||||
<string name="settings_error_initial_values_restored">Lo siento, pero ha habido un error. Todos los ajustes se han vuelto a los valores predeterminados.</string>
|
||||
<!-- Settings Sensor -->
|
||||
<string name="settings_sensor">Sensor</string>
|
||||
<string name="settings_sensor_ant_reset_bike_cadence_sensor">Restablecer cadencia de bicicleta</string>
|
||||
<string name="settings_sensor_ant_reset_combined_bike_sensor">Restablecer bicicleta combinada</string>
|
||||
<string name="settings_sensor_ant_reset_heart_rate_monitor">Restablecer pulso</string>
|
||||
<string name="settings_sensor_ant_reset_speed_distance_monitor">Restablecer podómetro</string>
|
||||
<string name="settings_sensor_bluetooth">Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing">Sincronización de Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_pairing_summary">Esta opción permite abrir los ajustes de Bluetooth de Android para sincronizar un sensor.</string>
|
||||
<string name="settings_sensor_bluetooth_sensor">Sensor Bluetooth</string>
|
||||
<string name="settings_sensor_connected">Conectado a %1$s</string>
|
||||
<string name="settings_sensor_connecting">Conectado a %1$s</string>
|
||||
<string name="settings_sensor_disconnected">Desconectado de %1$s</string>
|
||||
|
||||
<string name="settings_sensor_wheel_circumference">Tamaño de la rueda (ETRTO)</string>
|
||||
|
||||
<!-- Settings Stats -->
|
||||
<string name="settings_stats_coordinate">Latitud/Longitud</string>
|
||||
<string name="settings_stats_rate_title">Ritmo preferido</string>
|
||||
<string name="settings_stats_units_imperial">Imperiales (millas, pies)</string>
|
||||
<string name="settings_stats_units_metric">Métricas (km, m)</string>
|
||||
<string name="settings_stats_units_title">Unidades preferidas</string>
|
||||
<string name="share_track_emails_hint">Direcciones de correo electrónico</string>
|
||||
<string name="share_track_picker_title">Selecciona una aplicación</string>
|
||||
<!-- Share Track -->
|
||||
<string name="share_track_share_file">Compartir el archivo de la ruta</string>
|
||||
<string name="share_track_share_file_body">Creo que esta ruta te podría interesar.\n\nPara ver esta ruta, usa Google Earth u otro software de mapas.\n\n%1$s</string>
|
||||
<string name="share_track_subject">Me gustaría compartir una ruta contigo</string>
|
||||
<!-- Stats -->
|
||||
<string name="stats_average_moving_pace">Ritmo de movimiento medio</string>
|
||||
<string name="stats_average_moving_speed">Velocidad de movimiento media</string>
|
||||
<string name="stats_average_pace">Ritmo medio</string>
|
||||
@@ -292,29 +397,36 @@
|
||||
<string name="stats_speed">Velocidad</string>
|
||||
<string name="stats_distance">Distancia</string>
|
||||
<string name="stats_total_time">Tiempo total</string>
|
||||
<!-- Track -->
|
||||
<string name="track_name_format">Ruta %1$d</string>
|
||||
<string name="track_record_notification">Grabando tu ruta…</string>
|
||||
<string name="track_recording_notification_accuracy">Precisión de la localización: %1$s</string>
|
||||
<string name="track_markers">Marcadores de %1$s</string>
|
||||
<!-- Track Delete -->
|
||||
<string name="track_delete_one_confirm_message">La ruta y sus marcadores se eliminarán de forma permanente del dispositivo.</string>
|
||||
<string name="track_delete_one_confirm_title">¿Eliminar ruta?</string>
|
||||
<string name="track_delete_multiple_confirm_message">Las rutas seleccionadas y sus marcadores se eliminarán de forma permanente del dispositivo.</string>
|
||||
<string name="track_delete_progress_message">Eliminando…</string>
|
||||
<!-- Track Detail -->
|
||||
<string name="track_detail_chart_tab">Gráfico</string>
|
||||
<string name="track_detail_stats_tab">Estadísticas</string>
|
||||
<string name="track_detail_record_success">Grabando una nueva ruta</string>
|
||||
<string name="track_detail_resume_success">Ahora reanudando la pista</string>
|
||||
<!-- Track Edit -->
|
||||
<string name="track_edit_activity_type">Tipo de actividad (p. ej., senderismo…)</string>
|
||||
<string name="track_edit_activity_type_hint">Tipo de actividad</string>
|
||||
<string name="track_edit_new_track_title">Nueva pista</string>
|
||||
<!-- Track List -->
|
||||
<string name="track_list_empty_message">Empieza a grabar aquí tu próxima aventura</string>
|
||||
<string name="track_list_record_error">No se puede iniciar la grabación. No se recibe señal de GPS. Inténtalo de nuevo.</string>
|
||||
<string name="track_list_record_success">Grabando una nueva ruta</string>
|
||||
<string name="track_widget_config_title">Configurar elementos de widget</string>
|
||||
<!-- Track Widget -->
|
||||
<!-- Tracks -->
|
||||
<string name="tracks_few">%1$d rutas</string>
|
||||
<string name="tracks_many">%1$d rutas</string>
|
||||
<string name="tracks_one">1 ruta</string>
|
||||
<string name="tracks_other">%1$d rutas</string>
|
||||
<string name="tracks_two">2 rutas</string>
|
||||
<string name="tracks_zero">0 ruta</string>
|
||||
<!-- Unit -->
|
||||
<string name="unit_feet">pies</string>
|
||||
<string name="unit_kilometer">km</string>
|
||||
<string name="unit_kilometer_per_hour">km/h</string>
|
||||
@@ -323,6 +435,7 @@
|
||||
<string name="unit_mile_per_hour">millas/h</string>
|
||||
<string name="unit_minute_per_kilometer">min/km</string>
|
||||
<string name="unit_minute_per_mile">min/milla</string>
|
||||
<!-- Value -->
|
||||
<string name="value_adapt_accuracy">Adaptar para obtener valores exactos</string>
|
||||
<string name="value_adapt_battery_life">Adaptar a la duración de la batería</string>
|
||||
<string name="value_always">Siempre</string>
|
||||
@@ -334,10 +447,8 @@
|
||||
<string name="value_integer_feet">%1$d pies</string>
|
||||
<string name="value_integer_feet_excellent_gps">%1$d pies (señal de GPS excelente)</string>
|
||||
<string name="value_integer_feet_recommended">%1$d pies (recomendado)</string>
|
||||
<string name="value_integer_kilobyte">%1$d KB</string>
|
||||
<string name="value_integer_kilometer">%1$d km</string>
|
||||
<string name="value_integer_kilometer_hour">%1$d km/h</string>
|
||||
<string name="value_integer_megabyte">%1$d MB</string>
|
||||
<string name="value_integer_meter">%1$d m</string>
|
||||
<string name="value_integer_meter_excellent_gps">%1$d m (señal de GPS excelente)</string>
|
||||
<string name="value_integer_meter_poor_gps">%1$d m (señal de GPS débil)</string>
|
||||
@@ -347,11 +458,11 @@
|
||||
<string name="value_integer_minute">%1$d min</string>
|
||||
<string name="value_integer_percent">%1$d %%</string>
|
||||
<string name="value_integer_second">%1$d s</string>
|
||||
<string name="value_never">Nunca</string>
|
||||
<string name="value_none">Ninguna</string>
|
||||
<string name="value_off">No</string>
|
||||
<string name="value_smallest">Menor</string>
|
||||
<string name="value_smallest_recommended">Mínimo (recomendado)</string>
|
||||
<!-- Voice -->
|
||||
<string name="voice_hours_few">%1$d horas</string>
|
||||
<string name="voice_hours_many">%1$d horas</string>
|
||||
<string name="voice_hours_one">1 hora</string>
|
||||
@@ -398,6 +509,7 @@
|
||||
<string name="voice_total_distance_miles_two">distancia total de 2 millas</string>
|
||||
<string name="voice_total_distance_miles_zero">distancia total de 0 millas</string>
|
||||
<string name="voice_total_distance_zero">La distancia total de OpenTracks es igual a cero.</string>
|
||||
<!-- Waypoint Type -->
|
||||
<string name="waypoint_type_atm">cajero automático</string>
|
||||
<string name="waypoint_type_bank">banco</string>
|
||||
<string name="waypoint_type_bar">bar</string>
|
||||
|
||||