forked from upstream-mirrors/OpenTracks
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b09d640844 | |||
| a039f1a00c | |||
| 3df5c06c20 | |||
| 2904c65a01 | |||
| 4977789004 | |||
| 95e6448cba | |||
| a66c1b9407 | |||
| 9d55ac261f | |||
| dbd3e2fc5c | |||
| 713e454e44 | |||
| f0616fc043 | |||
| 75ed3120bd | |||
| b22e41cf66 | |||
| d1f003c0ce | |||
| 6ef80ade98 | |||
| e49d9fbd83 | |||
| c7738b1cb2 | |||
| 713f5c7708 | |||
| b9a36d1b3c | |||
| 34e89ea3f9 | |||
| 50a0e37086 | |||
| 11ac6b7279 | |||
| aadb79bf7d | |||
| da6b26644e | |||
| b264655d75 | |||
| 1ea9c0b216 | |||
| 8040edac7a | |||
| 037c79a1c5 | |||
| bc46f7447e | |||
| 6e88a448b1 | |||
| 2dac8d3ea6 | |||
| 0844c48d25 | |||
| 9607fda962 | |||
| 77ed28a8e2 | |||
| 4283e6d316 | |||
| ee030f32f5 | |||
| fb25055f3e | |||
| 9cdf87b998 | |||
| e9217b5327 | |||
| b4cb606499 | |||
| d1975685bc | |||
| 8cd9dda1f5 | |||
| c072967dd1 | |||
| 94e91d2063 | |||
| 796fa216f6 |
@@ -13,7 +13,7 @@ jobs:
|
||||
image: 'ubuntu:android-24.04'
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
image: 'ubuntu:android-24.04'
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
||||
@@ -123,4 +123,5 @@ Tested with:
|
||||
|
||||
Currently supported measurements:
|
||||
|
||||
* Human power
|
||||
* Human power
|
||||
* Cadence
|
||||
|
||||
+8
-7
@@ -33,7 +33,7 @@ android {
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
compileSdk = 36
|
||||
compileSdk = 37
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
@@ -47,13 +47,13 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'de.dennisguse.opentracks'
|
||||
versionCode 6653
|
||||
versionName "v4.27.0"
|
||||
versionCode 6698
|
||||
versionName "v4.28.0"
|
||||
|
||||
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
|
||||
|
||||
minSdk = 26
|
||||
targetSdk = 36
|
||||
targetSdk = 37
|
||||
|
||||
testInstrumentationRunner 'de.dennisguse.opentracks.TestRunner'
|
||||
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||
@@ -149,13 +149,14 @@ dependencies {
|
||||
implementation 'androidx.preference:preference:1.2.1'
|
||||
implementation 'androidx.documentfile:documentfile:1.1.0'
|
||||
implementation 'androidx.gridlayout:gridlayout:1.1.0'
|
||||
implementation 'com.google.android.material:material:1.13.0'
|
||||
implementation 'com.google.android.material:material:1.14.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
|
||||
implementation 'androidx.core:core:1.18.0'
|
||||
implementation 'androidx.core:core:1.19.0'
|
||||
implementation 'androidx.core:core-splashscreen:1.2.0'
|
||||
implementation 'androidx.mediarouter:mediarouter:1.8.1'
|
||||
implementation 'androidx.core:core-location-altitude:1.0.0-rc01'
|
||||
implementation 'androidx.core:core-location-altitude:1.0.0'
|
||||
implementation 'androidx.work:work-runtime:2.11.2'
|
||||
implementation 'androidx.health.connect:connect-client:1.1.0'
|
||||
|
||||
androidTestImplementation 'androidx.test:core:1.7.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
v4.27.1: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Support for Bosch Smart System eBikes (cadence, human power)
|
||||
- Add activity "gravel biking"
|
||||
|
||||
Bugfix:
|
||||
- While recording: TrackRecordingService would not restart correctly if killed by Android
|
||||
|
||||
Developer:
|
||||
- TargetSDK 37
|
||||
@@ -0,0 +1,5 @@
|
||||
v4.27.2: OpenTracks
|
||||
|
||||
Bugfix:
|
||||
- Not all valid timezone offsets could be set
|
||||
- Fixed race condition for IDLE trackpoints
|
||||
@@ -0,0 +1,10 @@
|
||||
v4.28.0: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Support for exporting to Health Connect
|
||||
|
||||
Bugfix:
|
||||
- Dashboard API: when sharing multiple tracks, the currently recorded one wasn't updated
|
||||
- Configuration setting for announcement of lap power wasn't stored correctly (only some languages affected)
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
v3.0.1: OpenTracks
|
||||
|
||||
Cambios:
|
||||
- Compartir marcadores
|
||||
- Configuración reestructurada
|
||||
- Se ha eliminado el botón «Atrás» de la barra de acciones
|
||||
- Exportación: se ha eliminado la opción de configuración del tamaño de las fotos
|
||||
- Exportación: ahora se puede seleccionar el formato KML
|
||||
|
||||
Correcciones de errores:
|
||||
- El directorio de exportación es ahora /OpenTracks/
|
||||
- El modo horizontal ya no provoca fallos
|
||||
- Se ha corregido la exportación a KML/KMZ
|
||||
|
||||
Desarrollador:
|
||||
- Las pruebas son ejecutables (pero muchas fallan)
|
||||
- Se ha habilitado la integración continua con TravisCI (sin pruebas)
|
||||
@@ -0,0 +1,14 @@
|
||||
v4.27.0: OpenTracks
|
||||
|
||||
Cambios:
|
||||
- Sensor: potencia de la bicicleta eléctrica Bosch
|
||||
- Sensores: se incluyen los dispositivos Bluetooth ya emparejados (como la bicicleta eléctrica Bosch)
|
||||
- Barómetro: se aplica la frecuencia de muestreo
|
||||
|
||||
Corrección de errores:
|
||||
- API del panel de control: no se proporcionaba la actualización
|
||||
- No se podía activar el GPS con el Bluetooth desactivado
|
||||
|
||||
Desarrollador:
|
||||
- Se ha eliminado Mockito
|
||||
- Pruebas de la interfaz de usuario: menos inestables
|
||||
@@ -0,0 +1,5 @@
|
||||
v4.26.2: OpenTracks
|
||||
|
||||
Correzioni:
|
||||
- Il GPS via Bluetooth non è (ancora) supportato
|
||||
- Il tipo di altitudine (EGM2008) non viene mostrato
|
||||
@@ -1,11 +1,22 @@
|
||||
OpenTracks é um aplicativo de rastreamento de esportes que respeita totalmente a sua privacidade.
|
||||
Um companheiro de rastreamento esportivo que respeita sua privacidade.
|
||||
|
||||
Características:
|
||||
* Rastreamento de esportes: monitore seu esporte e atividades ao ar livre
|
||||
* Fotos e marcadores: marque locais interessantes durante o rastreamento
|
||||
* Ganho e perda de altitude: via sensor barométrico
|
||||
* Altitude mostrada no EGM2008 (acima do nível médio do mar); exportado como WGS84
|
||||
* Anúncios de voz
|
||||
* Suporta sensores Bluetooth LE: frequência cardíaca, velocidade e distância (ciclismo), cadência (ciclismo) e medidor de potência (ciclismo)
|
||||
* Exportar dados: exporte trilhas como KMZ (incluindo fotos), KML, ou GPX
|
||||
* Sem acesso à Internet: a Internet não é usada
|
||||
Esportes e atividades ao ar livre garantem felicidade, habilidades e confiança.
|
||||
|
||||
Valoriza sua saúde acompanhando os seus treinos.
|
||||
Grava enquanto você corre ou caminha e te entrega um computador de bicicleta com uma tela maior para o ciclismo.
|
||||
Marca locais interessantes durante o percurso com fotos.
|
||||
Deixa estatísticas registradas em grande detalhe para analises.
|
||||
Compartilha apenas os dados que você quer que outros tenham.
|
||||
|
||||
* Anúncios por voz.
|
||||
* Suporte para sensores Bluetooth LE: frequência cardíaca, velocidade e distância (ciclismo), cadência (ciclismo) e medição de potência (ciclismo).
|
||||
* Ganhos e perdas de altitude: via sensor barométrico.
|
||||
* Altitudes exibidas em EGM2008 (acima do nível médio do mar); exportado como WGS84.
|
||||
* Exporta os dados de rastreio como KMZ (inclusive fotos), KML ou GPX.
|
||||
* Sem acesso à internet ou permissões extra.
|
||||
* Tema claro e escuro, respeitando as configurações do sistema.
|
||||
* Sem propagandas.
|
||||
|
||||
Software Livre / Código Aberto
|
||||
Significa que você pode usar, estudar, mudar e compartilhar o código.
|
||||
Licença Apache 2.0
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>OpenTracks: Privacy Policy</h1>
|
||||
|
||||
<p>
|
||||
OpenTracks does only store data on the local device that is relevant for tracking your sport exercise.
|
||||
Stored data is not transmitted from the app itself to a third party.
|
||||
|
||||
Data is stored by OpenTracks until:
|
||||
1. the user deletes the recorded track or
|
||||
2. the user uninstalls OpenTracks
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
+19
@@ -96,6 +96,25 @@ public class SensorDataCyclingTest {
|
||||
assertNull(current.getAggregatedValue(Instant.MIN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compute_cadence_directCadence_withoutPrevious() {
|
||||
AggregatorCyclingCadence current = new AggregatorCyclingCadence("", "");
|
||||
|
||||
current.add(Instant.MIN, new CyclingCadenceBluetooth.DirectCadenceData(Cadence.of(92)));
|
||||
|
||||
assertEquals(92, current.getAggregatedValue(Instant.MIN).getRPM(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compute_cadence_directCadence_winsOverCrankData() {
|
||||
AggregatorCyclingCadence current = new AggregatorCyclingCadence("", "");
|
||||
|
||||
current.add(Instant.MIN, new CyclingCadenceBluetooth.CrankData(1L, 1024));
|
||||
current.add(Instant.MIN, new CyclingCadenceBluetooth.DirectCadenceData(Cadence.of(92)));
|
||||
|
||||
assertEquals(92, current.getAggregatedValue(Instant.MIN).getRPM(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compute_speed() {
|
||||
AggregatorCyclingDistanceSpeed current = new AggregatorCyclingDistanceSpeed("", "");
|
||||
|
||||
+36
@@ -2,6 +2,7 @@ package de.dennisguse.opentracks.services;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -93,6 +94,41 @@ public class TrackRecordingServiceRecordingTest {
|
||||
service = startService();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@Test
|
||||
public void reCreate_not_recording() {
|
||||
// given
|
||||
TrackIdStorage.unset(context);
|
||||
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
// when
|
||||
service.onStartCommand(null, 0, 1);
|
||||
|
||||
// then
|
||||
assertFalse(service.isRecording());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@Test
|
||||
public void reCreate_recording() {
|
||||
// given
|
||||
assertFalse(service.isRecording());
|
||||
Track.Id trackId = service.startNewTrack();
|
||||
assertTrue(service.isRecording());
|
||||
|
||||
// when (crash and restart)
|
||||
service.onDestroy();
|
||||
service.onCreate();
|
||||
service.onStartCommand(null, 0, 1);
|
||||
|
||||
// then
|
||||
assertTrue(service.isRecording());
|
||||
assertEquals(trackId, service.getRecordingStatusObservable().getValue().trackId());
|
||||
|
||||
service.endCurrentTrack();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@Test
|
||||
public void recording_startStop() {
|
||||
|
||||
+43
@@ -52,6 +52,7 @@ public class VoiceAnnouncementUtilsTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
PreferencesUtils.setVoiceAnnounceUnit(true);
|
||||
PreferencesUtils.setVoiceAnnounceHeartRateCurrent(false);
|
||||
PreferencesUtils.setVoiceAnnounceLapHeartRate(false);
|
||||
PreferencesUtils.setVoiceAnnounceAverageHeartRate(false);
|
||||
@@ -221,6 +222,48 @@ public class VoiceAnnouncementUtilsTest {
|
||||
assertEquals("12:00 AM. Total distance 19.9 kilometers. 1 hour. Average moving speed 19.9 kilometers per hour.", announcement);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAnnouncement_metric_distance_without_unit() {
|
||||
PreferencesUtils.setVoiceAnnounceUnit(false);
|
||||
|
||||
Track track = new Track(
|
||||
null,
|
||||
null,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
ActivityType.AIRPLANE,
|
||||
ZoneOffset.UTC,
|
||||
new Statistics(
|
||||
Instant.EPOCH,
|
||||
Instant.EPOCH,
|
||||
Duration.ofHours(2).plusMinutes(5).plusSeconds(10),
|
||||
Duration.ofHours(1),
|
||||
Distance.of(19900),
|
||||
Speed.of(100),
|
||||
null,
|
||||
new AltitudeGainLoss(6000, 6000),
|
||||
null,
|
||||
null
|
||||
));
|
||||
|
||||
SensorDataSet dataSet = new SensorDataSet(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new SensorData<>(HeartRate.of(60), "unused"),
|
||||
null, null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
// when
|
||||
String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.METRIC, true, null, null).toString();
|
||||
|
||||
// then
|
||||
assertEquals("12:00 AM. Total distance 19.9. 1 hour. Average moving speed 19.9.", announcement);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAnnouncement_withInterval_metric_speed() {
|
||||
// given
|
||||
|
||||
@@ -69,6 +69,9 @@ limitations under the License.
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"
|
||||
android:minSdkVersion="33" />
|
||||
|
||||
<uses-permission android:name="android.permission.health.WRITE_EXERCISE" />
|
||||
<uses-permission android:name="android.permission.health.WRITE_EXERCISE_ROUTE" />
|
||||
|
||||
<application
|
||||
android:name=".Startup"
|
||||
android:allowBackup="true"
|
||||
@@ -126,9 +129,32 @@ limitations under the License.
|
||||
|
||||
<activity android:name=".AboutActivity" />
|
||||
|
||||
<!-- Permissions -->
|
||||
<!-- until Android 13 -->
|
||||
<activity
|
||||
android:name=".HelpActivity"
|
||||
android:label="@string/menu_help" />
|
||||
android:name=".HealthConnectPermissionsRationaleActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- for Android 14 -->
|
||||
<activity-alias
|
||||
android:name="ViewPermissionUsageActivity"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.START_VIEW_PERMISSION_USAGE"
|
||||
android:targetActivity=".HealthConnectPermissionsRationaleActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
|
||||
<category android:name="android.intent.category.HEALTH_PERMISSIONS" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<activity android:name=".settings.HealthConnect$Settings" />
|
||||
<activity android:name=".settings.HealthConnect$ConfigurePermissions" />
|
||||
<activity android:name=".settings.HealthConnect$ExportAll" />
|
||||
|
||||
<activity android:name=".HelpActivity" />
|
||||
|
||||
<activity android:name=".io.file.importer.DirectoryChooserActivity$ImportDirectoryChooserActivity" />
|
||||
|
||||
@@ -410,5 +436,6 @@ limitations under the License.
|
||||
<intent>
|
||||
<action android:name="android.intent.action.TTS_SERVICE" />
|
||||
</intent>
|
||||
<package android:name="com.google.android.apps.healthdata" />
|
||||
</queries>
|
||||
</manifest>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package de.dennisguse.opentracks;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import de.dennisguse.opentracks.databinding.ActivityHealthConnectPermissionsRationaleBinding;
|
||||
|
||||
public class HealthConnectPermissionsRationaleActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityHealthConnectPermissionsRationaleBinding viewBinding = ActivityHealthConnectPermissionsRationaleBinding.inflate(getLayoutInflater());
|
||||
setSupportActionBar(viewBinding.healthConnectActivityToolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
setContentView(viewBinding.getRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSupportNavigateUp() {
|
||||
getOnBackPressedDispatcher().onBackPressed();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.StrictMode;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -27,6 +28,11 @@ public class Startup extends Application {
|
||||
|
||||
// Include version information into stack traces.
|
||||
Log.i(TAG, BuildConfig.APPLICATION_ID + "; BuildType: " + BuildConfig.BUILD_TYPE + "; VersionName: " + BuildConfig.VERSION_NAME + "/" + BuildConfig.VERSION_NAME_FULL + " VersionCode: " + BuildConfig.VERSION_CODE);
|
||||
// In debug builds: show thread and VM warnings.
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(TAG, "Enabling strict mode");
|
||||
StrictMode.enableDefaults();
|
||||
}
|
||||
|
||||
PreferencesUtils.initPreferences(this);
|
||||
// Set default values of preferences on first start.
|
||||
|
||||
@@ -367,7 +367,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
|
||||
}
|
||||
|
||||
if (itemId == R.id.list_context_menu_show_on_map) {
|
||||
DataProvider.showTrackOnMap(this, false, trackIds);
|
||||
DataProvider.showTrackOnMap(this, recordingStatus.isRecording(), trackIds);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import de.dennisguse.opentracks.data.models.TrackBuilder;
|
||||
import de.dennisguse.opentracks.databinding.TrackStoppedBinding;
|
||||
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
||||
import de.dennisguse.opentracks.io.file.exporter.ExportUtils;
|
||||
import de.dennisguse.opentracks.io.healthconnect.exporter.HealthConnectUtils;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.ui.aggregatedStatistics.ConfirmDeleteDialogFragment;
|
||||
@@ -93,6 +94,7 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements
|
||||
viewBinding.finishButton.setOnClickListener(v -> {
|
||||
storeTrackMetaData(contentProviderUtils, track);
|
||||
ExportUtils.postWorkoutExport(this, trackId);
|
||||
HealthConnectUtils.postExportTrack(this, trackId);
|
||||
finish();
|
||||
});
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ public enum ActivityType {
|
||||
FERRY("ferry", R.string.activity_type_ferry, R.drawable.ic_activity_boat_24dp, true),
|
||||
FRISBEE("frisbee", R.string.activity_type_frisbee, ActivityIcon.ICON_UNKNOWN, true),
|
||||
GLIDING("gliding", R.string.activity_type_gliding, ActivityIcon.ICON_UNKNOWN, true),
|
||||
GRAVEL_BIKING("gravel biking", R.string.activity_type_biking, R.drawable.ic_activity_bike_24dp, true),
|
||||
HANG_GLIDING("hang gliding", R.string.activity_type_hang_gliding, ActivityIcon.ICON_UNKNOWN, true),
|
||||
HELICOPTER("helicopter", R.string.activity_type_helicopter, ActivityIcon.ICON_UNKNOWN, true),
|
||||
HIKING("hiking", R.string.activity_type_hiking, R.drawable.ic_activity_walk_24dp, false),
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ExportUtils {
|
||||
private static final String TAG = ExportUtils.class.getSimpleName();
|
||||
|
||||
public static void postWorkoutExport(AppCompatActivity context, Track.Id trackId) {
|
||||
if (PreferencesUtils.shouldInstantExportAfterWorkout()) {
|
||||
if (PreferencesUtils.shouldInstantExportToFile()) {
|
||||
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat();
|
||||
DocumentFile directory = IntentUtils.toDocumentFile(context, PreferencesUtils.getDefaultExportDirectoryUri());
|
||||
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package de.dennisguse.opentracks.io.healthconnect.exporter;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.health.connect.client.HealthConnectClient;
|
||||
import androidx.health.connect.client.PermissionController;
|
||||
import androidx.health.connect.client.permission.HealthPermission;
|
||||
import androidx.health.connect.client.records.ExerciseSessionRecord;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.ExistingWorkPolicy;
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
import androidx.work.WorkRequest;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlin.jvm.JvmClassMappingKt;
|
||||
import kotlin.jvm.functions.Function2;
|
||||
import kotlinx.coroutines.BuildersKt;
|
||||
|
||||
/**
|
||||
* Exports a single track as an ExerciseSession to Health Connect.
|
||||
* Uses the Track.uuid as clientRecordId to prevent duplicates on re-export.
|
||||
*/
|
||||
public class HealthConnectUtils {
|
||||
|
||||
private static final String TAG = HealthConnectUtils.class.getSimpleName();
|
||||
|
||||
static final String WRITE_EXERCISE_PERMISSION = HealthPermission.getWritePermission(JvmClassMappingKt.getKotlinClass(ExerciseSessionRecord.class));
|
||||
static final String WRITE_EXERCISE_ROUTE_PERMISSION = HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE;
|
||||
|
||||
//TODO Should be package private
|
||||
public static final Set<String> PERMISSIONS = Set.of(WRITE_EXERCISE_PERMISSION, WRITE_EXERCISE_ROUTE_PERMISSION);
|
||||
|
||||
private HealthConnectUtils() {
|
||||
}
|
||||
|
||||
public static boolean isAvailable(Context context) {
|
||||
return HealthConnectClient.getSdkStatus(context) == HealthConnectClient.SDK_AVAILABLE;
|
||||
}
|
||||
|
||||
public static Set<String> getGrantedPermissions(Context context) {
|
||||
try {
|
||||
HealthConnectClient client = HealthConnectClient.getOrCreate(context);
|
||||
PermissionController controller = client.getPermissionController();
|
||||
|
||||
return (Set<String>) BuildersKt.runBlocking(
|
||||
kotlin.coroutines.EmptyCoroutineContext.INSTANCE,
|
||||
(Function2) (scope, cont) -> controller.getGrantedPermissions((Continuation) cont));
|
||||
} catch (InterruptedException e) {
|
||||
return Set.of();
|
||||
}
|
||||
}
|
||||
|
||||
static boolean hasRequiredPermissions(Context context) {
|
||||
return getGrantedPermissions(context)
|
||||
.containsAll(PERMISSIONS);
|
||||
}
|
||||
|
||||
public static void postExportTrack(Context context, Track.Id trackId) {
|
||||
if (!PreferencesUtils.shouldInstantExportToHealthConnect()) {
|
||||
return;
|
||||
}
|
||||
|
||||
WorkRequest request = new OneTimeWorkRequest.Builder(HealthConnectWorker.class)
|
||||
.addTag(HealthConnectWorker.WORK_TAG)
|
||||
.setInputData(new Data.Builder()
|
||||
.putLong(HealthConnectWorker.TRACK_ID_KEY, trackId.id())
|
||||
.build())
|
||||
.build();
|
||||
WorkManager.getInstance(context).enqueue(request);
|
||||
}
|
||||
|
||||
public static void postExportAll(Context context) {
|
||||
OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(HealthConnectWorker.class)
|
||||
.addTag(HealthConnectWorker.WORK_TAG)
|
||||
.build();
|
||||
|
||||
WorkManager.getInstance(context).enqueueUniqueWork(
|
||||
HealthConnectWorker.WORK_TAG,
|
||||
ExistingWorkPolicy.REPLACE,
|
||||
request
|
||||
);
|
||||
}
|
||||
|
||||
public static void cancelHealthConnectExport(Context context) {
|
||||
WorkManager workManager = WorkManager.getInstance(context);
|
||||
workManager.cancelAllWorkByTag(HealthConnectWorker.WORK_TAG);
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
package de.dennisguse.opentracks.io.healthconnect.exporter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.health.connect.client.HealthConnectClient;
|
||||
import androidx.health.connect.client.records.ExerciseRoute;
|
||||
import androidx.health.connect.client.records.ExerciseSessionRecord;
|
||||
import androidx.health.connect.client.records.metadata.Device;
|
||||
import androidx.health.connect.client.records.metadata.Metadata;
|
||||
import androidx.health.connect.client.units.Length;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlin.jvm.functions.Function2;
|
||||
import kotlinx.coroutines.BuildersKt;
|
||||
|
||||
/**
|
||||
* Exports a single track as an ExerciseSession to Health Connect.
|
||||
* Uses the Track.uuid as clientRecordId to prevent duplicates on re-export.
|
||||
*/
|
||||
//TODO add reasons for failures (if shown in the UI: must be localized)
|
||||
//TODO Export sensor data (permissions needed)
|
||||
//TODO Show progress: like ExportActivity? Or use a notification (aka handle it as a background process)
|
||||
public class HealthConnectWorker extends Worker {
|
||||
|
||||
private static final String TAG = HealthConnectWorker.class.getSimpleName();
|
||||
static final String WORK_TAG = "HealthConnectSync";
|
||||
|
||||
static final String TRACK_ID_KEY = "trackId";
|
||||
|
||||
public HealthConnectWorker(Context context, WorkerParameters params) {
|
||||
super(context, params);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Result doWork() {
|
||||
if (!HealthConnectUtils.isAvailable(getApplicationContext())) {
|
||||
Log.w(TAG, "Health Connect SDK not available");
|
||||
return Result.failure();
|
||||
}
|
||||
|
||||
//TODO If not all permissions are granted, export the data that was granted.
|
||||
if (!HealthConnectUtils.hasRequiredPermissions(getApplicationContext())) {
|
||||
Log.w(TAG, "Health Connect required permissions not granted");
|
||||
return Result.failure();
|
||||
}
|
||||
|
||||
Track.Id trackId = new Track.Id(getInputData().getLong(TRACK_ID_KEY, -1L));
|
||||
if (trackId.id() != -1L) {
|
||||
return exportTrack(trackId);
|
||||
}
|
||||
return exportAll();
|
||||
}
|
||||
|
||||
private Result exportTrack(Track.Id trackId) {
|
||||
try {
|
||||
export(getApplicationContext(), trackId);
|
||||
return Result.success();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return Result.retry();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Health Connect export failed for track " + trackId, e);
|
||||
return Result.failure();
|
||||
}
|
||||
}
|
||||
|
||||
private Result exportAll() {
|
||||
List<Track> allTracks = new ContentProviderUtils(getApplicationContext())
|
||||
.getTracks();
|
||||
|
||||
for (Track track : allTracks) {
|
||||
if (isStopped()) {
|
||||
Log.i(TAG, "Initial Health Connect sync stopped by WorkManager");
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
try {
|
||||
export(getApplicationContext(), track.id());
|
||||
} catch (InterruptedException e) {
|
||||
return Result.retry();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Initial Health Connect sync failed for track " + track.id().id(), e);
|
||||
return Result.failure();
|
||||
}
|
||||
}
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
private static ExportResult export(Context context, Track.Id trackId) throws InterruptedException {
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
if (track == null) {
|
||||
throw new RuntimeException("Track not found: " + trackId);
|
||||
}
|
||||
|
||||
ExerciseRoute exerciseRoute = createExerciseRoute(contentProviderUtils, trackId);
|
||||
|
||||
HealthConnectClient client = HealthConnectClient.getOrCreate(context);
|
||||
|
||||
ExerciseSessionRecord record = new ExerciseSessionRecord(
|
||||
track.startTime().toInstant(),
|
||||
track.startTime().getOffset(),
|
||||
track.stopTime().toInstant(),
|
||||
track.stopTime().getOffset(),
|
||||
Metadata.activelyRecorded(
|
||||
new Device(Device.TYPE_PHONE, Build.MANUFACTURER, Build.MODEL),
|
||||
track.uuid().toString()
|
||||
),
|
||||
toExerciseType(track.activityType()),
|
||||
track.name(),
|
||||
track.description(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
exerciseRoute);
|
||||
|
||||
List<ExerciseSessionRecord> records = Collections.singletonList(record);
|
||||
Object ignored = BuildersKt.runBlocking(
|
||||
kotlin.coroutines.EmptyCoroutineContext.INSTANCE,
|
||||
(Function2) (scope, cont) -> client.insertRecords(records, (Continuation) cont));
|
||||
|
||||
Log.i(TAG, "Exported track to Health Connect: " + track.name());
|
||||
return new ExportResult(track.name());
|
||||
}
|
||||
|
||||
private static ExerciseRoute createExerciseRoute(ContentProviderUtils contentProviderUtils, Track.Id trackId) {
|
||||
List<ExerciseRoute.Location> route = new ArrayList<>();
|
||||
|
||||
try (TrackPointIterator iterator = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
while (iterator.hasNext()) {
|
||||
TrackPoint trackPoint = iterator.next();
|
||||
if (trackPoint.type() != TrackPoint.Type.TRACKPOINT) continue;
|
||||
|
||||
Position position = trackPoint.position();
|
||||
|
||||
route.add(new ExerciseRoute.Location(
|
||||
trackPoint.getTime(),
|
||||
position.latitude(),
|
||||
position.longitude(),
|
||||
position.horizontalAccuracy() != null ? Length.meters(position.horizontalAccuracy().toM()) : null,
|
||||
position.verticalAccuracy() != null ? Length.meters(position.verticalAccuracy().toM()) : null,
|
||||
position.altitude() != null ? Length.meters(position.altitude().toM()) : null)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return new ExerciseRoute(route);
|
||||
}
|
||||
|
||||
private static int toExerciseType(ActivityType activityType) {
|
||||
return switch (activityType) {
|
||||
case RUNNING, STREET_RUNNING, TRAIL_RUNNING, TRACK_RUNNING -> ExerciseSessionRecord.EXERCISE_TYPE_RUNNING;
|
||||
case BIKING, CYCLING, ROAD_BIKING, MOUNTAIN_BIKING, TRACK_CYCLING -> ExerciseSessionRecord.EXERCISE_TYPE_BIKING;
|
||||
case WALKING, SPEED_WALKING -> ExerciseSessionRecord.EXERCISE_TYPE_WALKING;
|
||||
case HIKING, OFF_TRAIL_HIKING, TRAIL_HIKING -> ExerciseSessionRecord.EXERCISE_TYPE_HIKING;
|
||||
case CROSS_COUNTRY_SKIING, SKIING -> ExerciseSessionRecord.EXERCISE_TYPE_SKIING;
|
||||
case SNOW_BOARDING -> ExerciseSessionRecord.EXERCISE_TYPE_SNOWBOARDING;
|
||||
case KAYAKING -> ExerciseSessionRecord.EXERCISE_TYPE_PADDLING;
|
||||
case ROWING -> ExerciseSessionRecord.EXERCISE_TYPE_ROWING_MACHINE;
|
||||
case SWIMMING -> ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_POOL;
|
||||
case SWIMMING_OPEN -> ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER;
|
||||
default -> ExerciseSessionRecord.EXERCISE_TYPE_OTHER_WORKOUT;
|
||||
};
|
||||
}
|
||||
|
||||
public record ExportResult(String trackName) {
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import de.dennisguse.opentracks.sensors.driver.CyclingCadenceBluetooth;
|
||||
import de.dennisguse.opentracks.sensors.driver.Driver;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingCadence;
|
||||
|
||||
public class CyclingCadenceHandler extends SensorHandler<CyclingCadenceBluetooth.CrankData, Cadence> {
|
||||
public class CyclingCadenceHandler extends SensorHandler<CyclingCadenceBluetooth.CyclingCadenceMeasurement, Cadence> {
|
||||
|
||||
protected CyclingCadenceHandler(SensorManager sensorManager) {
|
||||
super(sensorManager);
|
||||
|
||||
@@ -6,23 +6,25 @@ import android.util.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Cadence;
|
||||
import de.dennisguse.opentracks.sensors.ServiceMeasurementUUID;
|
||||
|
||||
public class CyclingCadenceBluetooth implements BluetoothDriver.BluetoothParser<CyclingCadenceBluetooth.CrankData> {
|
||||
public class CyclingCadenceBluetooth implements BluetoothDriver.BluetoothParser<CyclingCadenceBluetooth.CyclingCadenceMeasurement> {
|
||||
private static final String TAG = CyclingCadenceBluetooth.class.getSimpleName();
|
||||
|
||||
public static final List<ServiceMeasurementUUID> CYCLING_CADENCE = List.of(
|
||||
public static final List<ServiceMeasurementUUID> SUPPORTED_SERVICES = List.of(
|
||||
CyclingPowerBluetooth.CYCLING_POWER,
|
||||
CyclingDistanceSpeedBluetooth.CYCLING_SPEED_CADENCE
|
||||
CyclingDistanceSpeedBluetooth.CYCLING_SPEED_CADENCE,
|
||||
BoschEbikeParser.BOSCH_EBIKE
|
||||
);
|
||||
|
||||
@Override
|
||||
public List<ServiceMeasurementUUID> getServices() {
|
||||
return CYCLING_CADENCE;
|
||||
return SUPPORTED_SERVICES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrankData parsePayload(ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, BluetoothGattCharacteristic characteristic) {
|
||||
public CyclingCadenceMeasurement parsePayload(ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, BluetoothGattCharacteristic characteristic) {
|
||||
if (serviceMeasurementUUID.equals(CyclingPowerBluetooth.CYCLING_POWER)) {
|
||||
CyclingPowerBluetooth.Data data = CyclingPowerBluetooth.parseCyclingPower(characteristic);
|
||||
if (data != null && data.crank() != null) {
|
||||
@@ -38,12 +40,28 @@ public class CyclingCadenceBluetooth implements BluetoothDriver.BluetoothParser<
|
||||
}
|
||||
}
|
||||
|
||||
if (serviceMeasurementUUID.equals(BoschEbikeParser.BOSCH_EBIKE)) {
|
||||
BoschEbikeParser.Data boschData = BoschEbikeParser.parse(characteristic.getValue());
|
||||
if (boschData != null && boschData.cadence() != null) {
|
||||
return new DirectCadenceData(boschData.cadence());
|
||||
}
|
||||
}
|
||||
|
||||
Log.e(TAG, "Don't know how to decode this payload.");
|
||||
return null;
|
||||
}
|
||||
|
||||
public sealed interface CyclingCadenceMeasurement permits CrankData, DirectCadenceData {
|
||||
}
|
||||
|
||||
public record CrankData(
|
||||
long crankRevolutionsCount, // UINT32
|
||||
int crankRevolutionsTime // UINT16; 1/1024s
|
||||
) {}
|
||||
) implements CyclingCadenceMeasurement {
|
||||
}
|
||||
|
||||
public record DirectCadenceData(
|
||||
Cadence cadence
|
||||
) implements CyclingCadenceMeasurement {
|
||||
}
|
||||
}
|
||||
|
||||
+22
-6
@@ -10,7 +10,7 @@ import de.dennisguse.opentracks.data.models.Cadence;
|
||||
import de.dennisguse.opentracks.sensors.UintUtils;
|
||||
import de.dennisguse.opentracks.sensors.driver.CyclingCadenceBluetooth;
|
||||
|
||||
public class AggregatorCyclingCadence extends Aggregator<CyclingCadenceBluetooth.CrankData, Cadence> {
|
||||
public class AggregatorCyclingCadence extends Aggregator<CyclingCadenceBluetooth.CyclingCadenceMeasurement, Cadence> {
|
||||
|
||||
private final String TAG = AggregatorCyclingCadence.class.getSimpleName();
|
||||
|
||||
@@ -19,12 +19,20 @@ public class AggregatorCyclingCadence extends Aggregator<CyclingCadenceBluetooth
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void computeValue(@NonNull Raw<CyclingCadenceBluetooth.CrankData> current) {
|
||||
if (previous == null) {
|
||||
protected void computeValue(@NonNull Raw<CyclingCadenceBluetooth.CyclingCadenceMeasurement> current) {
|
||||
if (current.value() instanceof CyclingCadenceBluetooth.DirectCadenceData directCadenceData) {
|
||||
output = directCadenceData.cadence();
|
||||
return;
|
||||
}
|
||||
|
||||
float timeDiff_ms = UintUtils.diff(current.value().crankRevolutionsTime(), previous.value().crankRevolutionsTime(), UintUtils.UINT16_MAX) / 1024f * 1000;
|
||||
computeRawCadence((CyclingCadenceBluetooth.CrankData) current.value());
|
||||
}
|
||||
|
||||
private void computeRawCadence(@NonNull CyclingCadenceBluetooth.CrankData currentRaw) {
|
||||
CyclingCadenceBluetooth.CrankData previousRaw = getPreviousRaw();
|
||||
if (previousRaw == null) return;
|
||||
|
||||
float timeDiff_ms = UintUtils.diff(currentRaw.crankRevolutionsTime(), previousRaw.crankRevolutionsTime(), UintUtils.UINT16_MAX) / 1024f * 1000;
|
||||
Duration timeDiff = Duration.ofMillis((long) timeDiff_ms);
|
||||
|
||||
if (timeDiff.isZero()) {
|
||||
@@ -37,13 +45,21 @@ public class AggregatorCyclingCadence extends Aggregator<CyclingCadenceBluetooth
|
||||
}
|
||||
|
||||
// TODO We have to treat with overflow according to the documentation: read https://codeberg.org/OpenTracksApp/OpenTracks/pulls/953#issuecomment-6466930
|
||||
if (current.value().crankRevolutionsCount() < previous.value().crankRevolutionsCount()) {
|
||||
if (currentRaw.crankRevolutionsCount() < previousRaw.crankRevolutionsCount()) {
|
||||
Log.e(TAG, "Crank revolutions count difference is invalid: cannot compute cadence.");
|
||||
output = null;
|
||||
return;
|
||||
}
|
||||
|
||||
long crankDiff = UintUtils.diff(current.value().crankRevolutionsCount(), previous.value().crankRevolutionsCount(), UintUtils.UINT32_MAX);
|
||||
long crankDiff = UintUtils.diff(currentRaw.crankRevolutionsCount(), previousRaw.crankRevolutionsCount(), UintUtils.UINT32_MAX);
|
||||
output = Cadence.of(crankDiff, timeDiff);
|
||||
}
|
||||
|
||||
private CyclingCadenceBluetooth.CrankData getPreviousRaw() {
|
||||
if (previous == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return previous.value() instanceof CyclingCadenceBluetooth.CrankData raw ? raw : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package de.dennisguse.opentracks.services;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
|
||||
/**
|
||||
* For handling restarts of TrackRecordingService: while recording, stores the {@link de.dennisguse.opentracks.data.models.Track.Id}.
|
||||
*/
|
||||
class TrackIdStorage {
|
||||
|
||||
private final static String SHARED_PREFERENCE_NAME = "TrackRecordingService_pref";
|
||||
|
||||
private final static String KEY = "trackId_key";
|
||||
|
||||
private static SharedPreferences sharedPreferences;
|
||||
|
||||
private static void init(Context context) {
|
||||
if (sharedPreferences == null) {
|
||||
sharedPreferences = context.getSharedPreferences(SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Track.Id get(Context context) {
|
||||
TrackIdStorage.init(context);
|
||||
|
||||
long value = sharedPreferences.getLong(KEY, -1);
|
||||
if (value < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Track.Id(value);
|
||||
}
|
||||
|
||||
public static void set(Context context, @NonNull Track.Id trackId) {
|
||||
TrackIdStorage.init(context);
|
||||
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putLong(KEY, trackId.id());
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static void unset(Context context) {
|
||||
TrackIdStorage.init(context);
|
||||
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.remove(KEY);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen
|
||||
contentProviderUtils = new ContentProviderUtils(context);
|
||||
}
|
||||
|
||||
Track.Id startNewTrack() {
|
||||
synchronized Track.Id startNewTrack() {
|
||||
TrackPoint segmentStartTrackPoint = trackPointCreator.createSegmentStartManual();
|
||||
|
||||
ZoneOffset zoneOffset = ZoneOffset.systemDefault().getRules().getOffset(segmentStartTrackPoint.getTime());
|
||||
@@ -103,7 +103,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen
|
||||
/**
|
||||
* @return if the recording could be started.
|
||||
*/
|
||||
boolean resumeExistingTrack(@NonNull Track.Id resumeTrackId) {
|
||||
synchronized boolean resumeExistingTrack(@NonNull Track.Id resumeTrackId) {
|
||||
trackId = resumeTrackId;
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
if (track == null) {
|
||||
@@ -119,7 +119,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen
|
||||
return true;
|
||||
}
|
||||
|
||||
void endCurrentTrack() {
|
||||
synchronized void endCurrentTrack() {
|
||||
TrackPoint segmentEnd = trackPointCreator.createSegmentEnd();
|
||||
insertTrackPoint(segmentEnd, true);
|
||||
|
||||
@@ -149,7 +149,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
||||
public void onIdle() {
|
||||
public synchronized void onIdle() {
|
||||
Log.d(TAG, "Becoming idle");
|
||||
onNewTrackPoint(trackPointCreator.createIdle());
|
||||
|
||||
|
||||
@@ -86,7 +86,6 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
|
||||
private MutableLiveData<GpsStatusValue> gpsStatusObservable;
|
||||
private MutableLiveData<RecordingData> recordingDataObservable;
|
||||
|
||||
// The following variables are set when recording:
|
||||
private Handler handler;
|
||||
|
||||
private TrackPointCreator trackPointCreator;
|
||||
@@ -119,9 +118,6 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.d(TAG, "Destroying");
|
||||
if (isRecording()) {
|
||||
endCurrentTrack();
|
||||
}
|
||||
if (trackPointCreator != null && trackPointCreator.isStarted()) {
|
||||
stopSensors();
|
||||
}
|
||||
@@ -150,6 +146,16 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (intent == null) {
|
||||
Log.i(TAG, "Service got killed and is restarting");
|
||||
|
||||
//Best guess: do we need to resume a recording?
|
||||
Track.Id trackId = TrackIdStorage.get(this);
|
||||
if (trackId != null) {
|
||||
Log.i(TAG, "After restart: resuming recording for " + trackId);
|
||||
resumeTrack(trackId);
|
||||
}
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@@ -167,9 +173,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
|
||||
|
||||
// Set recording status
|
||||
Track.Id trackId = trackRecordingManager.startNewTrack();
|
||||
updateRecordingStatus(RecordingStatus.record(trackId));
|
||||
|
||||
startRecording();
|
||||
startRecording(trackId);
|
||||
return trackId;
|
||||
}
|
||||
|
||||
@@ -180,12 +184,13 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
|
||||
}
|
||||
Log.i(TAG, "resumeTrack");
|
||||
|
||||
updateRecordingStatus(RecordingStatus.record(trackId));
|
||||
|
||||
startRecording();
|
||||
startRecording(trackId);
|
||||
}
|
||||
|
||||
private void startRecording() {
|
||||
private void startRecording(Track.Id trackId) {
|
||||
updateRecordingStatus(RecordingStatus.record(trackId));
|
||||
TrackIdStorage.set(this, trackId);
|
||||
|
||||
startSensors();
|
||||
|
||||
voiceAnnouncementManager.start(trackRecordingManager.getTrackStatistics());
|
||||
@@ -226,6 +231,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
|
||||
updateRecordingStatus(STATUS_DEFAULT);
|
||||
|
||||
trackRecordingManager.endCurrentTrack();
|
||||
TrackIdStorage.unset(this);
|
||||
|
||||
stopUpdateRecordingData();
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package de.dennisguse.opentracks.settings;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.health.connect.client.HealthConnectClient;
|
||||
import androidx.health.connect.client.PermissionController;
|
||||
|
||||
import de.dennisguse.opentracks.io.healthconnect.exporter.HealthConnectUtils;
|
||||
|
||||
public class HealthConnect {
|
||||
|
||||
public static class Settings extends AppCompatActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
startActivity(new Intent(HealthConnectClient.getHealthConnectSettingsAction()));
|
||||
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConfigurePermissions extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (!HealthConnectUtils.isAvailable(this)) {
|
||||
finish();
|
||||
}
|
||||
|
||||
registerForActivityResult(
|
||||
PermissionController.createRequestPermissionResultContract(),
|
||||
grantedPermissions -> {
|
||||
// TODO User feedback via Toast.makeText()?
|
||||
finish();
|
||||
}
|
||||
).launch(HealthConnectUtils.PERMISSIONS);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExportAll extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
HealthConnectUtils.postExportAll(this);
|
||||
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,11 @@ import java.util.Map;
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.io.file.TrackFilenameGenerator;
|
||||
import de.dennisguse.opentracks.io.healthconnect.exporter.HealthConnectUtils;
|
||||
import de.dennisguse.opentracks.util.IntentUtils;
|
||||
|
||||
public class ImportExportSettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
private static final String TAG = ImportExportSettingsFragment.class.getSimpleName();
|
||||
public class ImportExportSettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
@@ -27,6 +27,11 @@ public class ImportExportSettingsFragment extends PreferenceFragmentCompat {
|
||||
setExportTrackFileFormatOptions();
|
||||
setExportDirectorySummary();
|
||||
setFilenameTemplate();
|
||||
|
||||
findPreference("healthConnectPermissions").setSummaryProvider(preference -> {
|
||||
//TODO This should be localized and prefixes trimmed.
|
||||
return String.join(",", HealthConnectUtils.getGrantedPermissions(getActivity()));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,9 +45,21 @@ public class ImportExportSettingsFragment extends PreferenceFragmentCompat {
|
||||
super.onResume();
|
||||
|
||||
setExportDirectorySummary();
|
||||
findPreference(getString(R.string.post_workout_export_enabled_key)).setEnabled(PreferencesUtils.isDefaultExportDirectoryUri());
|
||||
|
||||
Preference instantExportEnabledPreference = findPreference(getString(R.string.post_workout_export_enabled_key));
|
||||
instantExportEnabledPreference.setEnabled(PreferencesUtils.isDefaultExportDirectoryUri());
|
||||
setHealthConnectPreference();
|
||||
}
|
||||
|
||||
private void setHealthConnectPreference() {
|
||||
boolean healthConnectAvailable = HealthConnectUtils.isAvailable(requireContext());
|
||||
findPreference("healthConnectCategory")
|
||||
.setEnabled(healthConnectAvailable);
|
||||
|
||||
if (!healthConnectAvailable) {
|
||||
findPreference(getString(R.string.post_workout_export_health_connect_enabled_key))
|
||||
.setSummary(R.string.health_connect_not_available);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void setExportTrackFileFormatOptions() {
|
||||
|
||||
@@ -71,6 +71,7 @@ public class PreferencesUtils {
|
||||
private static SharedPreferences sharedPreferences;
|
||||
|
||||
private static Resources resources;
|
||||
private static final long LONG_UNSET = Long.MIN_VALUE;
|
||||
|
||||
/**
|
||||
* Must be called during application startup.
|
||||
@@ -168,24 +169,36 @@ public class PreferencesUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static long getLong(int keyId, long defaultValue) {
|
||||
try {
|
||||
return sharedPreferences.getLong(getKey(keyId), defaultValue);
|
||||
} catch (ClassCastException e) {
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
try {
|
||||
String stringValue = sharedPreferences.getString(getKey(keyId), null);
|
||||
return Long.parseLong(stringValue);
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getString(int keyId, String defaultValue) {
|
||||
return sharedPreferences.getString(getKey(keyId), defaultValue);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static void setString(int keyId, String value) {
|
||||
static void setString(int keyId, String value) {
|
||||
Editor editor = sharedPreferences.edit();
|
||||
editor.putString(getKey(keyId), value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static void setString(int keyId, int valueId) {
|
||||
static void setString(int keyId, int valueId) {
|
||||
setString(keyId, resources.getString(valueId));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static void setBoolean(int keyId, Boolean value) {
|
||||
static void setBoolean(int keyId, Boolean value) {
|
||||
Editor editor = sharedPreferences.edit();
|
||||
editor.putBoolean(getKey(keyId), value);
|
||||
editor.apply();
|
||||
@@ -197,6 +210,12 @@ public class PreferencesUtils {
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private static void setLong(int keyId, long value) {
|
||||
Editor editor = sharedPreferences.edit();
|
||||
editor.putLong(getKey(keyId), value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public static boolean isPublicAPIenabled() {
|
||||
return getBoolean(R.string.publicapi_enabled_key, resources.getBoolean(R.bool.publicapi_enabled_default));
|
||||
}
|
||||
@@ -328,6 +347,11 @@ public class PreferencesUtils {
|
||||
return getBoolean(R.string.voice_announce_unit_key, true);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static void setVoiceAnnounceUnit(boolean value) {
|
||||
setBoolean(R.string.voice_announce_unit_key, value);
|
||||
}
|
||||
|
||||
public static Duration getVoiceAnnouncementFrequency() {
|
||||
final int DEFAULT = Integer.parseInt(resources.getString(R.string.voice_announcement_frequency_default));
|
||||
int value = getInt(R.string.voice_announcement_frequency_key, DEFAULT);
|
||||
@@ -422,7 +446,7 @@ public class PreferencesUtils {
|
||||
}
|
||||
|
||||
public static boolean shouldVoiceAnnounceLapPower() {
|
||||
return getBoolean(R.string.voice_announce_lap_power_key, false);
|
||||
return getBoolean(R.string.voice_announce_lap_power_key, getBoolean(R.bool.voice_announce_lap_power_default, false));
|
||||
}
|
||||
|
||||
public static boolean shouldVoiceAnnounceHeartRateCurrent() {
|
||||
@@ -655,12 +679,16 @@ public class PreferencesUtils {
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
public static boolean shouldInstantExportAfterWorkout() {
|
||||
public static boolean shouldInstantExportToFile() {
|
||||
final boolean INSTANT_POST_WORKOUT_EXPORT_DEFAULT = resources.getBoolean(R.bool.post_workout_export_enabled_default);
|
||||
return getBoolean(R.string.post_workout_export_enabled_key, INSTANT_POST_WORKOUT_EXPORT_DEFAULT) && isDefaultExportDirectoryUri();
|
||||
}
|
||||
|
||||
public static boolean shouldInstantExportToHealthConnect() {
|
||||
final boolean DEFAULT = resources.getBoolean(R.bool.post_workout_export_health_connect_enabled_default);
|
||||
return getBoolean(R.string.post_workout_export_health_connect_enabled_key, DEFAULT);
|
||||
}
|
||||
|
||||
public static TrackFilenameGenerator getTrackFileformatGenerator() {
|
||||
String DEFAULT = resources.getString(R.string.export_filename_format_default);
|
||||
TrackFilenameGenerator generator = new TrackFilenameGenerator(getString(R.string.export_filename_format_key, DEFAULT));
|
||||
@@ -748,11 +776,13 @@ public class PreferencesUtils {
|
||||
sharedPreferences.edit().clear().commit();
|
||||
}
|
||||
|
||||
// Each setting file must be mentioned here.
|
||||
// Each setting file must be mentioned here: see xml/settings.xml
|
||||
PreferenceManager.setDefaultValues(context, R.xml.settings, readAgain);
|
||||
PreferenceManager.setDefaultValues(context, R.xml.settings_defaults, readAgain);
|
||||
PreferenceManager.setDefaultValues(context, R.xml.settings_user_interface, readAgain);
|
||||
PreferenceManager.setDefaultValues(context, R.xml.settings_recording, readAgain);
|
||||
PreferenceManager.setDefaultValues(context, R.xml.settings_sensors, readAgain);
|
||||
PreferenceManager.setDefaultValues(context, R.xml.settings_announcements, readAgain);
|
||||
PreferenceManager.setDefaultValues(context, R.xml.settings_import_export, readAgain);
|
||||
PreferenceManager.setDefaultValues(context, R.xml.settings_public_api, readAgain);
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,6 +27,6 @@ public class BluetoothLeCyclingCadencePreference extends BluetoothLeSensorPrefer
|
||||
|
||||
@Override
|
||||
public PreferenceDialogFragmentCompat createInstance() {
|
||||
return BluetoothLeSensorPreferenceDialog.newInstance(getKey(), CyclingCadenceBluetooth.CYCLING_CADENCE);
|
||||
return BluetoothLeSensorPreferenceDialog.newInstance(getKey(), CyclingCadenceBluetooth.SUPPORTED_SERVICES);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,13 +7,51 @@ import android.widget.ArrayAdapter;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* <a href="Data source for UTC Offsets">https://en.wikipedia.org/wiki/List_of_UTC_offsets</a>
|
||||
*/
|
||||
public class ZoneOffsetAdapter extends ArrayAdapter<ZoneOffset> {
|
||||
public ZoneOffsetAdapter(@NonNull Context context, int resource) {
|
||||
super(context, resource, IntStream.range(-12, +12)
|
||||
.boxed()
|
||||
.map(ZoneOffset::ofHours)
|
||||
.toList());
|
||||
super(context, resource);
|
||||
|
||||
addAll(
|
||||
ZoneOffset.ofHoursMinutes(-12, 00),
|
||||
ZoneOffset.ofHoursMinutes(-11, 00),
|
||||
ZoneOffset.ofHoursMinutes(-10, 00),
|
||||
ZoneOffset.ofHoursMinutes(-9, -30),
|
||||
ZoneOffset.ofHoursMinutes(-8, 00),
|
||||
ZoneOffset.ofHoursMinutes(-7, 00),
|
||||
ZoneOffset.ofHoursMinutes(-6, 00),
|
||||
ZoneOffset.ofHoursMinutes(-5, 00),
|
||||
ZoneOffset.ofHoursMinutes(-4, 00),
|
||||
ZoneOffset.ofHoursMinutes(-3, -30),
|
||||
ZoneOffset.ofHoursMinutes(-3, 00),
|
||||
ZoneOffset.ofHoursMinutes(-2, 00),
|
||||
ZoneOffset.ofHoursMinutes(-1, 00),
|
||||
ZoneOffset.ofHoursMinutes(0, 00),
|
||||
ZoneOffset.ofHoursMinutes(1, 00),
|
||||
ZoneOffset.ofHoursMinutes(2, 00),
|
||||
ZoneOffset.ofHoursMinutes(3, 00),
|
||||
ZoneOffset.ofHoursMinutes(3, 30),
|
||||
ZoneOffset.ofHoursMinutes(4, 00),
|
||||
ZoneOffset.ofHoursMinutes(4, 30),
|
||||
ZoneOffset.ofHoursMinutes(5, 30),
|
||||
ZoneOffset.ofHoursMinutes(5, 45),
|
||||
ZoneOffset.ofHoursMinutes(6, 00),
|
||||
ZoneOffset.ofHoursMinutes(6, 30),
|
||||
ZoneOffset.ofHoursMinutes(7, 00),
|
||||
ZoneOffset.ofHoursMinutes(8, 00),
|
||||
ZoneOffset.ofHoursMinutes(8, 45),
|
||||
ZoneOffset.ofHoursMinutes(9, 00),
|
||||
ZoneOffset.ofHoursMinutes(9, 30),
|
||||
ZoneOffset.ofHoursMinutes(10, 00),
|
||||
ZoneOffset.ofHoursMinutes(10, 30),
|
||||
ZoneOffset.ofHoursMinutes(11, 00),
|
||||
ZoneOffset.ofHoursMinutes(12, 00),
|
||||
ZoneOffset.ofHoursMinutes(12, 45),
|
||||
ZoneOffset.ofHoursMinutes(13, 00),
|
||||
ZoneOffset.ofHoursMinutes(14, 00)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package de.dennisguse.opentracks.ui.customRecordingLayout;
|
||||
|
||||
public enum CustomLayoutFieldType {
|
||||
GENERIC(1),
|
||||
CLOCK(2);
|
||||
|
||||
private final int value;
|
||||
|
||||
CustomLayoutFieldType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/health_connect_activity_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:title="@string/app_name" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="20dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="?attr/textAppearanceHeadline6"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/health_connect_permissions_rationale_heading" />
|
||||
|
||||
<TextView
|
||||
style="?attr/textAppearanceBody1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/health_connect_permissions_rationale_summary" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -386,7 +386,6 @@ limitations under the License.
|
||||
<item quantity="many">اكتمل مع %1$d خطأ</item>
|
||||
<item quantity="other">اكتمل مع %1$d خطأ</item>
|
||||
</plurals>
|
||||
<string name="voice_announce_lap_power_key">الإعلان الصوتي عن قوة اللفة voiceAnnounceLapPower</string>
|
||||
<string name="settings_defaults_title">الوحدات الافتراضية والنشاط</string>
|
||||
<string name="settings_defaults_summary">الوحدات المفضلة، النشاط الافتراضي، اسم المسار الافتراضي</string>
|
||||
<string name="settings_announcements_summary">الوقت، المسافة، سرعة الصوت</string>
|
||||
@@ -457,7 +456,7 @@ limitations under the License.
|
||||
<string name="settings_recording_title">التسجيل</string>
|
||||
<string name="settings_public_api_enabled_title">واجهة برمجة التطبيقات العامة</string>
|
||||
<string name="settings_public_api_disabled_toast">واجهة برمجة التطبيقات العامة لـ المسارات المفتوحة معطلة: يمكن تفعيلها في الإعدادات.</string>
|
||||
<string name="settings_export_section">التصدير</string>
|
||||
<string name="settings_export_as_file_section">التصدير</string>
|
||||
<string name="instant_export_enabled_summary">تصدير المسار إلى التخزين بعد انتهاء التسجيل</string>
|
||||
<string name="create_marker_error">غير قادر على إنشاء علامة. حاول مرة أخرى.</string>
|
||||
<string name="sensor_state_heart_rate_avg">متوسط معدل ضربات القلب</string>
|
||||
|
||||
@@ -430,7 +430,7 @@
|
||||
<string name="settings_gps_summary">Intervalo de tiempo, Intervalo de distancia, Distancia máxima, Precisión</string>
|
||||
<string name="settings_sensors_title">Sensores</string>
|
||||
<string name="settings_sensors_summary">Sensores de ciclismo, Circunferencia de la rueda, Sensores de carrera</string>
|
||||
<string name="settings_export_section">Exportar</string>
|
||||
<string name="settings_export_as_file_section">Exportar</string>
|
||||
<string name="activity_type_swimming">Natación</string>
|
||||
<string name="activity_type_swimming_open">Natación en aguas abiertas</string>
|
||||
<string name="activity_type_workout">Entrenamiento</string>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<string name="settings_stats_units_imperial_meter">Imperiale (mi, m)</string>
|
||||
<string name="settings_stats_units_metric">Metrica (km, m)</string>
|
||||
<string name="settings_import_section">Impurtà</string>
|
||||
<string name="settings_export_section">Espurtà</string>
|
||||
<string name="settings_export_as_file_section">Espurtà</string>
|
||||
<string name="settings_public_api_package_title">Nome di u pacchettu per l’API publica</string>
|
||||
<string name="settings_public_api_enabled_summary_off">Solu OpenTracks pò lancià è piantà l’arregistramenti.</string>
|
||||
<string name="settings_public_api_enabled_summary_on">D’altre appiecazioni installate ponu lancià o piantà l’arregistramenti.</string>
|
||||
@@ -534,7 +534,6 @@
|
||||
<string name="settings_locale_title">Lingua</string>
|
||||
<string name="settings_locale_system_default">Predefinizione di u sistema</string>
|
||||
<string name="stats_gain_loss">Guadagnu è perdita</string>
|
||||
<string name="voice_announce_lap_power_key">AnnunziamentuVucalePutenzaÀUGiru</string>
|
||||
<string name="lap_heart_rate">Frequenza cardiaca à u giru</string>
|
||||
<string name="settings_charts_title">Grafici</string>
|
||||
<string name="settings_chart_display_elevation_title">Affissà l’altitudine</string>
|
||||
|
||||
@@ -444,7 +444,7 @@ limitations under the License.
|
||||
<string name="settings_cycling_sensor">Cyklistika</string>
|
||||
<string name="settings_running_sensor">Běh</string>
|
||||
<string name="settings_import_section">Importovat</string>
|
||||
<string name="settings_export_section">Exportovat</string>
|
||||
<string name="settings_export_as_file_section">Exportovat</string>
|
||||
<string name="stats_sensors_power">Napájení</string>
|
||||
<string name="permission_bluetooth_failed_rejected">V nastavení systému je třeba ručně povolit aplikaci OpenTracks přístup k blízkým zařízením.</string>
|
||||
<string name="value_float_mile_hour">%1$.1f mi/h</string>
|
||||
@@ -580,7 +580,6 @@ limitations under the License.
|
||||
<string name="settings_announcements_unit">Jednotka vzdálenosti/rychlosti</string>
|
||||
<string name="voiceSpeed">{n, plural, =1 {1} few {{n,number}} other {{n,number,#.0}} }</string>
|
||||
<string name="voiceDistance">{n, plural, =1 {1 } few {{n,number}} other {{n,number,#.0}} }</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="power">Výkon</string>
|
||||
<string name="settings_announcements_lap_power">Výkon kola</string>
|
||||
<string name="power_x_watt">Výkon {x, plural, =1 {1 watt} few {# watty} other {# wattů} }</string>
|
||||
|
||||
@@ -471,7 +471,7 @@ limitations under the License.
|
||||
<string name="custom_layout_select_layout">Vælg layout</string>
|
||||
<string name="settings_running_sensor">Kører</string>
|
||||
<string name="settings_import_section">Importere</string>
|
||||
<string name="settings_export_section">Eksport</string>
|
||||
<string name="settings_export_as_file_section">Eksport</string>
|
||||
<string name="stats_clock">Ur</string>
|
||||
<string name="value_float_mile_hour_recommended">%1$.1f mi/h (anbefalet)</string>
|
||||
<string name="value_float_mile_hour">%1$.1f mi/h</string>
|
||||
|
||||
@@ -511,7 +511,7 @@ Meldet das GPS-Gerät ungenaue Daten (z.B. Standort, Geschwindigkeit, Höhe), ka
|
||||
<string name="settings_sensor_bluetooth_service_filter_on">Zeige nur Bluetooth-Geräte, die benötigte Dienste bekanntmachen</string>
|
||||
<string name="settings_public_api_enabled_summary_on">Andere installierte Anwendungen können Aufzeichnungen starten oder stoppen.</string>
|
||||
<string name="settings_public_api_disabled_toast">OpenTracks öffentliche API ist deaktiviert: es kann in den Einstellungen aktiviert werden.</string>
|
||||
<string name="settings_export_section">Export</string>
|
||||
<string name="settings_export_as_file_section">Export</string>
|
||||
<string name="settings_public_api_enabled_summary_off">Nur OpenTracks kann Aufzeichnungen starten und stoppen.</string>
|
||||
<string name="settings_import_section">Import</string>
|
||||
<string name="settings_api_title">Öffentliche API</string>
|
||||
@@ -635,7 +635,6 @@ Meldet das GPS-Gerät ungenaue Daten (z.B. Standort, Geschwindigkeit, Höhe), ka
|
||||
<string name="voiceDistance">{n, plural, =1 {1 } other {{n,number,#.0}} }</string>
|
||||
<string name="settings_recording_min_sampling_interval_title">Abtastzeitintervall</string>
|
||||
<string name="voiceIdle">Untätig werden.</string>
|
||||
<string name="voice_announce_lap_power_key">StimmeAnkündigungLapPower</string>
|
||||
<string name="settings_announcements_lap_power">Rundenleistung</string>
|
||||
<string name="create_marker_error">Die Markierung konnte nicht erstellt werden. Versuchen Sie es erneut.</string>
|
||||
<string name="settings_locale_title">Sprache</string>
|
||||
|
||||
@@ -94,7 +94,7 @@ limitations under the License.
|
||||
<string name="description_max_altitude">Μέγιστη ανύψωση: %1$d μέτρα (%2$d πόδια)</string>
|
||||
<string name="description_max_speed">Μέγιστη ταχύτητα: %1$.2f χλμ/ώρα (%2$.1f μίλια/ώρα)</string>
|
||||
<string name="description_min_altitude">Ελάχιστη ανύψωση: %1$d μέτρα (%2$d πόδια)</string>
|
||||
<string name="description_moving_time">Χρόνος μεταφοράς: %1$s</string>
|
||||
<string name="description_moving_time">Χρόνος κίνησης: %1$s</string>
|
||||
<string name="description_pace_imperial">Ρυθμός (λεπτά/μίλι)</string>
|
||||
<string name="description_pace_metric">Ρυθμός (λεπτά/χλμ)</string>
|
||||
<string name="description_recorded_time">Εγγραφή: %1$s</string>
|
||||
@@ -195,7 +195,7 @@ limitations under the License.
|
||||
<string name="settings_stats_units_metric">Μετρικό (χλμ, μέτρα)</string>
|
||||
<string name="settings_stats_units_title">Προτιμώμενες μονάδες</string>
|
||||
<!-- Share Track -->
|
||||
<string name="share_track_share_file_body">Νομίζω ότι μπορεί να σε ενδιαφέρει αυτό το ίχνος.\n\nΓια να δεις αυτό το ίχνος, χρησιμοποίησε το Google Earth ή άλλο λογισμικό χαρτογράφησης.\n\n%1$s</string>
|
||||
<string name="share_track_share_file_body">Νομίζω ότι μπορεί να σε ενδιαφέρει αυτό το ίχνος.\n\n%1$s</string>
|
||||
<string name="share_track_subject">Θα ήθελα να μοιραστώ μία διαδρομή μαζί σου</string>
|
||||
<!-- Stats -->
|
||||
<string name="stats_average_moving_pace">Μέσος ρυθμός κίνησης</string>
|
||||
@@ -230,22 +230,22 @@ limitations under the License.
|
||||
<!-- Tracks -->
|
||||
<!-- Unit -->
|
||||
<string name="unit_feet">πόδια</string>
|
||||
<string name="unit_kilometer">χλμ.</string>
|
||||
<string name="unit_kilometer">χλμ</string>
|
||||
<string name="unit_kilometer_per_hour">χλμ/ώρα</string>
|
||||
<string name="unit_meter">μέτρα</string>
|
||||
<string name="unit_mile">μίλι</string>
|
||||
<string name="unit_mile_per_hour">μίλια/ώρα</string>
|
||||
<string name="unit_minute_per_kilometer">λεπτά / χιλ.</string>
|
||||
<string name="unit_minute_per_kilometer">λεπτά/χλμ</string>
|
||||
<string name="unit_minute_per_mile">λεπτά/μίλι</string>
|
||||
<!-- Value -->
|
||||
<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_feet_recommended">%1$d πόδια (συνιστάται)</string>
|
||||
<string name="value_integer_kilometer_hour">%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>
|
||||
<string name="value_integer_meter_recommended">%1$d m (συνιστάται)</string>
|
||||
<string name="value_integer_mile_hour">%1$d μίλια/ώρα</string>
|
||||
<string name="value_integer_minute">%1$d λεπ.</string>
|
||||
<string name="value_integer_minute">%1$d λεπ</string>
|
||||
<string name="value_integer_second">%1$d δευτ</string>
|
||||
<string name="value_none">Καμία</string>
|
||||
<string name="value_off">Απενεργοποιημένο</string>
|
||||
@@ -325,4 +325,119 @@ limitations under the License.
|
||||
<string name="settings_recording_min_sampling_interval_title">Χρονικό μεσοδιάστημα δειγματοληψίας</string>
|
||||
<string name="settings_recording_location_distance_summary">%1$s μεταξύ καταγεγραμμένων τοποθεσιών</string>
|
||||
<string name="field_remove_from_layout">Αφαίρεση</string>
|
||||
<string name="value_float_kilometer_hour">%1$.1f χλμ/ώρα</string>
|
||||
<string name="value_float_kilometer_hour_recommended">%1$.1f χλμ/ώρα (συνιστάται)</string>
|
||||
<string name="value_integer_knots">%1$d κόμβοι</string>
|
||||
<string name="value_float_mile_hour">%1$.1f μίλια/ώρα</string>
|
||||
<string name="value_float_knots">%1$.1f κόμβοι</string>
|
||||
<string name="value_float_mile_hour_recommended">%1$.1f μίλια/ώρα (συνιστάται)</string>
|
||||
<string name="value_float_knots_recommended">%1$.1f κόμβοι (συνιστάται)</string>
|
||||
<string name="value_internal_sensor">Εσωτερικός αισθητήρας</string>
|
||||
<string name="value_int_seconds">%1$d δευτ (συνιστάται)</string>
|
||||
<string name="voice_per_kilometer">ανά χιλιόμετρο</string>
|
||||
<string name="voice_per_mile">ανά μίλι</string>
|
||||
<string name="voice_per_nautical_mile">ανά ναυτικό μίλι</string>
|
||||
<string name="lap_time">Χρόνος γύρου</string>
|
||||
<string name="pace">Ρυθμός</string>
|
||||
<string name="lap_speed">Ταχύτητα γύρου</string>
|
||||
<string name="speed">Μέση ταχύτητα κίνησης</string>
|
||||
<string name="total_distance">Συνολική απόσταση</string>
|
||||
<string name="voiceDistanceKilometersPlural">{n, plural, =1 {1 χιλιόμετρο} other {{n,number,#.0} χιλιόμετρα} }</string>
|
||||
<string name="voiceDistanceMilesPlural">{n, plural, =1 {1 μίλι} other {{n,number,#.0} μίλια} }</string>
|
||||
<string name="voiceDistanceNauticalMilesPlural">{n, plural, =1 {1 ναυτικό μίλι} other {{n,number,#.0} ναυτικά μίλια} }</string>
|
||||
<string name="voiceDistance">{n, plural, =1 {1 } other {{n,number,#.0}} }</string>
|
||||
<string name="voiceHoursPlural">{n, plural, =1 {1 ώρα} other {{n,number} ώρες} }</string>
|
||||
<string name="settings_import_section">Εισαγωγή</string>
|
||||
<string name="settings_api_title">Δημόσιο API</string>
|
||||
<string name="settings_public_api_enabled_title">Δημόσιο API</string>
|
||||
<string name="settings_public_api_package_title">Όνομα πακέτου για Δημόσιο API</string>
|
||||
<string name="settings_api_summary">API απομακρυσμένου ελέγχου και στατιστικών για άλλες εφαρμογές</string>
|
||||
<string name="voiceMinutesPlural">{n, plural, =1 {1 λεπτό} other {{n,number} λεπτά} }</string>
|
||||
<string name="voiceSecondsPlural">{n, plural, =1 {1 δευτερόλεπτο} other {{n,number} δευτερόλεπτα} }</string>
|
||||
<string name="voiceSpeedKilometersPerHourPlural">{n, plural, =1 {1 χιλιόμετρο ανά ώρα} other {{n,number,#.0} χιλιόμετρα ανά ώρα} }</string>
|
||||
<string name="voiceSpeedMilesPerHourPlural">{n, plural, =1 {1 μίλι ανά ώρα} other {{n,number,#.0} μίλια ανά ώρα} }</string>
|
||||
<string name="voiceSpeedMKnotsPlural">{n, plural, =1 {1 κόμβος} other {{n,number,#.0} κόμβοι} }</string>
|
||||
<string name="voiceSpeed">{n, plural, =1 {1} other {{n,number,#.0}} }</string>
|
||||
<string name="description_speed_nautical">Ταχύτητα (κόμβοι)</string>
|
||||
<string name="description_sensor_temperature">Θερμοκρασία (Κελσίου)</string>
|
||||
<string name="export_with_photos">με φωτογραφίες</string>
|
||||
<string name="export_without_photos">χωρίς φωτογραφίες</string>
|
||||
<string name="export_progress_summary_errors_msg">Σφάλματα</string>
|
||||
<string name="import_progress_summary_errors_msg">Σφάλματα</string>
|
||||
<string name="import_progress_summary_exists_msg">Υπάρχει ήδη</string>
|
||||
<string name="import_error_info">%1$s: %2$s</string>
|
||||
<string name="gps_recording_status">%1$s: %2$s</string>
|
||||
<string name="generic_undo">Αναίρεση</string>
|
||||
<string name="generic_filter">Φίλτρο</string>
|
||||
<string name="menu_filter">Φίλτρο</string>
|
||||
<string name="menu_voice_rate">Ταχύτητα φωνής</string>
|
||||
<string name="sensor_state_cadence_avg">Μέσο πεταλάρισμα</string>
|
||||
<string name="sensor_state_cadence_max">Μέγιστο πεταλάρισμα</string>
|
||||
<string name="sensor_state_temperature">Θερμόμετρο</string>
|
||||
<string name="sensor_state_pressure">Βαρόμετρο</string>
|
||||
<string name="bluetooth_sensor_summary">%1$s (%2$s)</string>
|
||||
<string name="bluetooth_disabled">Παρακαλούμε ενεργοποιήστε το Bluetooth.</string>
|
||||
<string name="settings_ui_title">Διεπαφή Χρήστη</string>
|
||||
<string name="settings_ui_summary">Εμφάνιση, Διάταξη Εγγραφής, Θέμα</string>
|
||||
<string name="settings_gps_sensor">GPS</string>
|
||||
<string name="description_speed_source_gps">GPS</string>
|
||||
<string name="settings_sensors_title">Αισθητήρες</string>
|
||||
<string name="settings_sensors_summary">Αισθητήρες Ποδηλασίας, Περιφέρεια Ρόδας, Αισθητήρες Τρεξίματος</string>
|
||||
<string name="settings_defaults_title">Προεπιλεγμένες Μονάδες και Δραστηριότητα</string>
|
||||
<string name="settings_announcements_summary">Χρόνος, Απόσταση, Ταχύτητα Φωνής</string>
|
||||
<string name="settings_import_export_title">Εισαγωγή και Εξαγωγή</string>
|
||||
<string name="settings_import_export_summary">Εισαγωγή, Εξαγωγή, Αυτόματη Εξαγωγή</string>
|
||||
<string name="settings_units_category">Μονάδες</string>
|
||||
<string name="settings_activity_defaults_category">Προεπιλογές Δραστηριότητας</string>
|
||||
<string name="settings_reset_summary">Επαναφορά Ρυθμίσεων στις Προεπιλεγμένες Τιμές</string>
|
||||
<string name="generic_from">Από</string>
|
||||
<string name="generic_to">Μέχρι</string>
|
||||
<string name="generic_today">Σήμερα</string>
|
||||
<string name="generic_yesterday">Χθες</string>
|
||||
<string name="generic_dismiss">Παράβλεψη</string>
|
||||
<string name="generic_completed">Ολοκληρώθηκε</string>
|
||||
<string name="generic_click_twice_cancel">Πατήστε ξανά πίσω για ακύρωση</string>
|
||||
<string name="generic_choose_an_option">Επιλέξτε μια επιλογή</string>
|
||||
<string name="generic_skip">Παράλειψη</string>
|
||||
<string name="generic_separator_done_total">/</string>
|
||||
<string name="generic_show_errors">Εμφάνιση σφαλμάτων</string>
|
||||
<plurals name="generic_completed_with_errors">
|
||||
<item quantity="one">Ολοκληρώθηκε με ένα σφάλμα</item>
|
||||
<item quantity="other">Ολοκληρώθηκε με %1$d σφάλματα</item>
|
||||
</plurals>
|
||||
<string name="generic_overwrite">Αντικατάσταση</string>
|
||||
<string name="gps_disabled_msg">GPS απενεργοποιημένο</string>
|
||||
<string name="gps_fixed_and_ready">GPS σταθερό και έτοιμο</string>
|
||||
<string name="image_discard">Απόρριψη</string>
|
||||
<string name="menu_select_layout">Επιλογή διάταξης</string>
|
||||
<string name="custom_layout_select_layout">Επιλογή διάταξης</string>
|
||||
<string name="settings_announcements_distance_frequency">Μήκος γύρου</string>
|
||||
<string name="settings_locale_title">Γλώσσα</string>
|
||||
<string name="settings_locale_system_default">Προεπιλογή συστήματος</string>
|
||||
<string name="settings_night_mode_option_system">Σύστημα</string>
|
||||
<string name="settings_night_mode_option_day">Μέρα</string>
|
||||
<string name="settings_night_mode_option_night">Νύχτα</string>
|
||||
<string name="custom_layout_list_title">Διατάξεις</string>
|
||||
<string name="stats_custom_layout_default_layout">Προεπιλεγμένη διάταξη</string>
|
||||
<string name="settings_all_reset">Επαναφορά</string>
|
||||
<string name="settings_recording_fullscreen_on_while_recording_title">Πλήρης οθόνη</string>
|
||||
<string name="settings_recording_show_gps_disabled_warning_title">Προειδοποίηση απενεργοποιημένου GPS</string>
|
||||
<string name="settings_recording_keep_screen_on_while_recording_title">Διατήρηση της οθόνης ενεργοποιημένης</string>
|
||||
<string name="settings_recording_show_on_lockscreen_while_recording_title">Εμφάνιση στατιστικών στο κλείδωμα οθόνης</string>
|
||||
<string name="settings_ui_dynamic_colors_title">Δυναμικά Χρώματα</string>
|
||||
<string name="settings_recording_customize_layout_title">Προσαρμόστε τη διάταξη εγγραφής</string>
|
||||
<string name="settings_sensor_cycling_cadence">Πεταλάρισμα</string>
|
||||
<string name="stats_sensors_cadence">Πεταλάρισμα</string>
|
||||
<string name="stats_sensors_temperature">Θερμοκρασία</string>
|
||||
<string name="stats_clock">Ρολόι</string>
|
||||
<string name="track_recording_notification_accuracy">Ακρίβεια τοποθεσίας: %1$s</string>
|
||||
<string name="track_distance_notification">Απόσταση: %1$s</string>
|
||||
<string name="track_speed_notification">Ταχύτητα: %1$s</string>
|
||||
<string name="track_pace_notification">Ρυθμός: %1$s</string>
|
||||
<string name="stats_coordinates">Γεωγραφικό πλάτος/Γεωγραφικό μήκος</string>
|
||||
<string name="settings_sensor_running_speed_and_cadence">Απόσταση, Ταχύτητα και Πεταλάρισμα</string>
|
||||
<string name="settings_sensor_cycling_distance_speed">Απόσταση και Ταχύτητα</string>
|
||||
<string name="settings_sensor_bluetooth_service_filter_title">Φιλτράτισμα Συσκευών Bluetooth</string>
|
||||
<string name="settings_sensor_wheel_circumference">Περιφέρεια Ρόδας (mm)</string>
|
||||
<string name="settings_public_api_dashboard_enabled_title">Αυτόματη μεταφορά δεδομένων</string>
|
||||
</resources>
|
||||
|
||||
@@ -503,7 +503,7 @@ limitations under the License.
|
||||
<string name="permission_bluetooth_failed_rejected">Es necesario conceder manualmente a OpenTracks el acceso a los Dispositivos Cercanos en la configuración del sistema.</string>
|
||||
<string name="settings_running_sensor">Correr</string>
|
||||
<string name="settings_import_section">Importar</string>
|
||||
<string name="settings_export_section">Exportar</string>
|
||||
<string name="settings_export_as_file_section">Exportar</string>
|
||||
<string name="generic_today">Hoy</string>
|
||||
<string name="generic_yesterday">Ayer</string>
|
||||
<string name="menu_add_custom_layout">Nuevo diseño</string>
|
||||
@@ -654,7 +654,6 @@ limitations under the License.
|
||||
<string name="settings_announcements_lap_power">Potencia por vuelta</string>
|
||||
<string name="power_x_watt">Potencia {x, plural, =1 {1 vatio} otros {# vatios} }</string>
|
||||
<string name="create_marker_error">No se ha podido crear un marcador. Inténtelo de nuevo.</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="power">Potencia</string>
|
||||
<string name="settings_locale_title">Idioma</string>
|
||||
<string name="settings_locale_system_default">Predeterminado del sistema</string>
|
||||
|
||||
@@ -442,7 +442,7 @@ limitations under the License.
|
||||
<string name="settings_reset_summary">Lähtesta seadistused vaikeväärtusteks</string>
|
||||
<string name="settings_recording_customize_layout_title">Kohanda oma salvestuse paigutust</string>
|
||||
<string name="settings_recording_customize_layout_select_columns">Andmeväljad rea kohta</string>
|
||||
<string name="settings_export_section">Eksport</string>
|
||||
<string name="settings_export_as_file_section">Eksport</string>
|
||||
<string name="settings_announcements_totaltime_frequency">Ajavahemik</string>
|
||||
<string name="settings_layout_reset">Lähtesta kohandatud paigutus</string>
|
||||
<string name="settings_layout_reset_confirm_title">Kas lähtestad oma paigutused?</string>
|
||||
@@ -595,8 +595,8 @@ limitations under the License.
|
||||
<string name="show_on_dashboard_not_installed">Pole paigaldatud ühtegi rakendust, mis toetaks OpenTracksi juhtpaneeli API-t.</string>
|
||||
<string name="introduction_osm_dashboard">Kaardi kuvamine pole OpenTracks-i automaatselt lisatud. Oma salvestiste kaardil vaatamiseks palun paigalda OSMDashboard.</string>
|
||||
<string name="settings_recording_min_sampling_interval_title">Proovivõtu ajavahemik</string>
|
||||
<string name="voice_announce_lap_power_key">RingiVõimsuseHäälteade</string>
|
||||
<string name="description_sensor_temperature">Temperatuur (Celsius)</string>
|
||||
<string name="sensor_state_temperature">Termomeeter</string>
|
||||
<string name="stats_sensors_temperature">Temperatuur</string>
|
||||
<string name="activity_type_gravel_biking">rattasõit kruusateedel</string>
|
||||
</resources>
|
||||
|
||||
@@ -458,7 +458,7 @@ GPS gailuak datu okerrak salatzen baditu (adibidez, kokapena, abiadura, kota), O
|
||||
<string name="settings_layout_reset_done">Diseinuaren ezarpen guztiak balio lehenetsietara itzuli dira</string>
|
||||
<string name="settings_all_reset">Berrezarri</string>
|
||||
<string name="settings_import_section">Inportatu</string>
|
||||
<string name="settings_export_section">Esportatu</string>
|
||||
<string name="settings_export_as_file_section">Esportatu</string>
|
||||
<string name="stats_coordinates">Latitudea /Longitudea</string>
|
||||
<string name="stats_clock">Erlojua</string>
|
||||
<string name="value_float_mile_hour">%1$.1f mi/h</string>
|
||||
|
||||
@@ -490,7 +490,7 @@ limitations under the License.
|
||||
<string name="stats_sensors_power">Teho</string>
|
||||
<string name="no_compatible_file_manager_installed">Yhteensopiva tiedostojen hallinta puuttuu</string>
|
||||
<string name="settings_export_filename_title">Tiedostonimen muoto</string>
|
||||
<string name="settings_export_section">Vienti</string>
|
||||
<string name="settings_export_as_file_section">Vienti</string>
|
||||
<string name="settings_recording_customize_layout_title">Muokkaa tallennuksen asettelua</string>
|
||||
<string name="settings_sensor_bluetooth_service_filter_on">Näytä vain Bluetooth-laitteet, jotka ilmoittavat tarvittavat palvelut</string>
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">Tallennettuja tietoja ei jaeta automaattisesti muiden sovellusten kanssa.</string>
|
||||
|
||||
@@ -505,7 +505,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="settings_cycling_sensor">Cyclisme</string>
|
||||
<string name="settings_running_sensor">Course à pied</string>
|
||||
<string name="settings_import_section">Importer</string>
|
||||
<string name="settings_export_section">Exporter</string>
|
||||
<string name="settings_export_as_file_section">Exporter</string>
|
||||
<string name="settings_reset_summary">Réinitialiser les paramètres aux valeurs par défaut</string>
|
||||
<string name="settings_activity_defaults_category">Valeurs par défaut de l\'activité</string>
|
||||
<string name="settings_sensors_summary">Capteurs de cyclisme, Circonférence de roue, Capteurs de course à pied</string>
|
||||
@@ -660,7 +660,6 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="settings_locale_system_default">Paramètres par défaut du système</string>
|
||||
<string name="settings_locale_title">Langue</string>
|
||||
<string name="stats_gain_loss">Gain et perte</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="settings_chart_display_pace_or_speed_title">Afficher le pas ou la vitesse</string>
|
||||
<string name="settings_chart_display_elevation_title">Afficher l\'altitude</string>
|
||||
<string name="settings_chart_display_heart_rate_title">Afficher la fréquence cardiaque</string>
|
||||
|
||||
@@ -257,7 +257,7 @@
|
||||
<string name="settings_public_api_enabled_summary_off">Ní féidir ach le OpenTracks taifeadtaí a thosú agus a stopadh.</string>
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">Ní dhéanfar sonraí taifeadta a roinnt go huathoibríoch le feidhmchláir eile.</string>
|
||||
<string name="settings_import_section">Iompórtáil</string>
|
||||
<string name="settings_export_section">Easpórtáil</string>
|
||||
<string name="settings_export_as_file_section">Easpórtáil</string>
|
||||
<string name="share_track_share_file_body">Sílim go mb\'fhéidir go mbeadh suim agat sa rian seo.
|
||||
\n
|
||||
\n%1$s</string>
|
||||
@@ -510,7 +510,6 @@
|
||||
<string name="sensor_state_cadence_unit">rpm</string>
|
||||
<string name="sensor_state_heart_rate_unit">bpm</string>
|
||||
<string name="settings_night_mode_option_night_oled">OLED-chairdiúil</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="power">Cumhacht</string>
|
||||
<string name="value_int_seconds">%1$d s (molta)</string>
|
||||
<string name="menu_export_all_one_file">Easpórtáil gach ceann (comhad amháin do gach traic)</string>
|
||||
|
||||
@@ -443,7 +443,7 @@ limitations under the License.
|
||||
<string name="settings_cycling_sensor">Ciclismo</string>
|
||||
<string name="settings_running_sensor">Correr</string>
|
||||
<string name="settings_import_section">Importar</string>
|
||||
<string name="settings_export_section">Exportar</string>
|
||||
<string name="settings_export_as_file_section">Exportar</string>
|
||||
<string name="settings_announcements_distance_frequency">Lonxitude da volta</string>
|
||||
<string name="permission_bluetooth_failed">OpenTracks require permiso para usar o Bluetooth.</string>
|
||||
<string name="permission_bluetooth_failed_rejected">Tes que permitirlle a OpenTracks nos axustes do sistema que acceda a Dispositivos Próximos.</string>
|
||||
@@ -600,11 +600,11 @@ limitations under the License.
|
||||
<string name="settings_night_mode_option_day_dynamic">Día (Cores Dinámicas)</string>
|
||||
<string name="settings_night_mode_option_night_dynamic">Noite (Cores Dinámicas)</string>
|
||||
<string name="settings_night_mode_option_night_oled_dynamic">para OLED (Cores Dinámicas)</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="settings_announcements_segment_average_speed_pace">Velocidade/Ritmo medios (Tramo)</string>
|
||||
<string name="stats_average_segment_pace">Ritmo medio no Tramo</string>
|
||||
<string name="stats_elapsed_segment_time">Tempo transcurrido no tramo</string>
|
||||
<string name="stats_sensors_temperature">Temperatura</string>
|
||||
<string name="description_sensor_temperature">Temperatura (Celsius)</string>
|
||||
<string name="sensor_state_temperature">Termómetro</string>
|
||||
<string name="activity_type_gravel_biking">ciclismo por grava</string>
|
||||
</resources>
|
||||
|
||||
@@ -305,7 +305,7 @@ limitations under the License.
|
||||
<string name="waypoint_type_water_fountain">fontana</string>
|
||||
<string name="waypoint_type_waypoint">točka na ruti</string>
|
||||
<string name="settings_import_section">Uvoz</string>
|
||||
<string name="settings_export_section">Izvoz</string>
|
||||
<string name="settings_export_as_file_section">Izvoz</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">Spriječi ponovni uvoz ruta</string>
|
||||
<string name="menu_export_all_one_file">Izvezi sve (jedna datoteka za sve rute)</string>
|
||||
<string name="menu_select_layout">Odaberi raspored</string>
|
||||
@@ -594,7 +594,6 @@ limitations under the License.
|
||||
<string name="create_marker_error">Nije moguće stvoriti oznaku. Pokušaj ponovo.</string>
|
||||
<string name="settings_night_mode_option_night_oled">Noć (pogodno za OLED)</string>
|
||||
<string name="power_x_watt">Snaga {x, plural, =1 {1 watt} few {# watta} other {# watta} }</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="settings_announcements_lap_power">Snaga runde</string>
|
||||
<string name="power">Snaga</string>
|
||||
</resources>
|
||||
|
||||
@@ -467,7 +467,7 @@ limitations under the License.
|
||||
<string name="average_heart_rate">Átlagos pulzusszám</string>
|
||||
<string name="settings_sensor_bluetooth_service_filter_on">Csak azokat a Bluetooth-eszközöket jelenítse meg, amelyek szükséges szolgáltatásokat kérnek</string>
|
||||
<string name="settings_import_section">Importálás</string>
|
||||
<string name="settings_export_section">Exportálás</string>
|
||||
<string name="settings_export_as_file_section">Exportálás</string>
|
||||
<string name="settings_layout_reset_confirm_title">Az elrendezések visszaállítása?</string>
|
||||
<string name="settings_layout_reset_done">Az összes elrendezési beállítás visszaállt az alapértelmezett értékekre</string>
|
||||
<string name="custom_layout_list_layout_removed">Az elrendezést eltávolították</string>
|
||||
@@ -578,7 +578,6 @@ limitations under the License.
|
||||
<string name="settings_announcements_lap_power">Kör teljesítmény</string>
|
||||
<string name="create_marker_error">Nem sikerült jelölőt létrehozni. Próbálja újra.</string>
|
||||
<string name="voiceDistance">{n, plural, =1 {1 } other {{n,number,#.0}} }</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="power_x_watt">Teljesítmény {x, plural, =1 {1 watt} other {# watts} }</string>
|
||||
<string name="settings_locale_title">Nyelv</string>
|
||||
<string name="settings_locale_system_default">Rendszer alapértelmezett</string>
|
||||
|
||||
@@ -448,7 +448,7 @@ Infatti, un\'applicazione deve supportare <i>ACTION_VIEW</i> con MIME <i>applica
|
||||
<string name="settings_cycling_sensor">Ciclismo</string>
|
||||
<string name="settings_running_sensor">Corsa</string>
|
||||
<string name="settings_import_section">Importa</string>
|
||||
<string name="settings_export_section">Esporta</string>
|
||||
<string name="settings_export_as_file_section">Esporta</string>
|
||||
<string name="stats_coordinates">Latitudine/Longitudine</string>
|
||||
<string name="field_remove_from_layout">Rimuovi</string>
|
||||
<string name="field_set_primary">Primario</string>
|
||||
@@ -549,7 +549,6 @@ Infatti, un\'applicazione deve supportare <i>ACTION_VIEW</i> con MIME <i>applica
|
||||
<string name="voiceDistanceMilesPlural">{n, plural, =1 {un miglio} other {{n,number,#.0} miglia} }</string>
|
||||
<string name="no_compatible_gallery_installed">Nessuna delle applicazioni galleria (foto) installate è compatibile</string>
|
||||
<string name="no_compatible_camera_installed">Nessuna delle applicazioni telecamera installate è compatibile</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="settings_announcements_idle_category_title">Annunci di inattività</string>
|
||||
<string name="settings_announcements_idle_title">Inattività</string>
|
||||
<string name="settings_recording_title">Registrazione</string>
|
||||
|
||||
@@ -150,7 +150,7 @@ limitations under the License.
|
||||
<string name="menu_aggregated_statistics">集計統計</string>
|
||||
<string name="menu_delete">削除</string>
|
||||
<string name="menu_edit">編集</string>
|
||||
<string name="menu_export_all">すべてエクスポート</string>
|
||||
<string name="menu_export_all">すべてエクスポート(トラックごとに別ファイル)</string>
|
||||
<string name="menu_help">ヘルプ</string>
|
||||
<string name="menu_import_all">すべてインポート</string>
|
||||
<string name="menu_insert_marker">マーカーを追加</string>
|
||||
@@ -313,4 +313,24 @@ limitations under the License.
|
||||
<string name="import_progress_summary_ok_msg">インポート完了</string>
|
||||
<string name="import_progress_summary_exists_msg">既に存在しています</string>
|
||||
<string name="help_track_map_content">小さな地図のアイコンを使います.\n a) (live updates) <a href="https://codeberg.org/OpenTracksApp/OSMDashboard">OSMDashboard</a>をインストールして下さい。 <a href="https://www.openstreetmap.org">OpenStreetMap</a> を利用したオンラインまたはオフラインの地図を使用できるようになります。\n実際、OSMDashbordは (一時的に保存された) 表示するトラッキングデータにだけアクセスする独立したアプリケーションです。\n b) 一般的な地図アプリケーションを使用 (e.g., <a href="http://osmand.net/">OsmAnd</a> and <a href="https://maps.me/">MAPS.ME</a>) 。 KMZフォーマットをサポートしている必要があります (位置及びタイムスタンプのみを含む)。 加えて、 MIME <i>application/vnd.google-earth.kmz</i> の <i>ACTION_VIEW</i> をサポートしている必要もあります。</string>
|
||||
<string name="help_storage_pictures_title">マーカーとして撮影した写真の保存場所</string>
|
||||
<string name="help_storage_pictures_content">アプリケーションの内部ストレージ(つまり、OpenTracks内部からのみアクセス可能な場所)に保存されます。</string>
|
||||
<string name="help_track_export_title">記録したトラックのエクスポート/共有方法</string>
|
||||
<string name="stats_sensors_temperature">温度</string>
|
||||
<string name="settings_announcements_average_heart_rate">平均心拍数</string>
|
||||
<string name="description_speed_source_gps">GPS</string>
|
||||
<string name="export_dir_not_writable">" (書き込み失敗!)"</string>
|
||||
<string name="export_progress_summary_overwrite_msg">上書きされたファイル</string>
|
||||
<string name="export_progress_summary_skip_msg">スキップされたファイル</string>
|
||||
<string name="export_progress_summary_errors_msg">エラー</string>
|
||||
<string name="generic_separator_done_total">/</string>
|
||||
<string name="generic_today">今日</string>
|
||||
<string name="generic_yesterday">昨日</string>
|
||||
<string name="gps_disabled_msg">GPSが無効化されています</string>
|
||||
<string name="import_no_kml_file_found">KMZ中にkmlファイルが見つかりませんでした</string>
|
||||
<string name="import_error_info">%1$s: %2$s</string>
|
||||
<string name="create_marker_error">マーカーを作成することができませんでした。もう一度やり直して下さい。</string>
|
||||
<string name="menu_export_all_one_file">すべてエクスポート(全てのトラックを1つのファイルに)</string>
|
||||
<string name="menu_select_layout">レイアウトを選択</string>
|
||||
<string name="permission_gps_failed">OpenTracksはGPSにアクセスする権限が必要です。</string>
|
||||
</resources>
|
||||
|
||||
@@ -333,7 +333,7 @@
|
||||
<string name="settings_public_api_dashboard_enabled_summary_on">ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿದ ಅಪ್ಲಿಕೇಶನ್ ರೆಕಾರ್ಡ್ ಮಾಡಿದ ಡೇಟಾವನ್ನು ಸಹ ಪ್ರವೇಶಿಸಬಹುದು.</string>
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">ರೆಕಾರ್ಡ್ ಮಾಡಲಾದ ಡೇಟಾವನ್ನು ಇತರ ಅಪ್ಲಿಕೇಶನ್ಗಳೊಂದಿಗೆ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಹಂಚಿಕೊಳ್ಳಲಾಗುವುದಿಲ್ಲ.</string>
|
||||
<string name="settings_import_section">ಆಮದು</string>
|
||||
<string name="settings_export_section">ರಫ್ತು</string>
|
||||
<string name="settings_export_as_file_section">ರಫ್ತು</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">ಟ್ರ್ಯಾಕ್ಗಳ ಮರು-ಆಮದು ತಡೆಯಿರಿ</string>
|
||||
<string name="share_track_share_file_body">ನೀವು ಈ ಟ್ರ್ಯಾಕ್ನಲ್ಲಿ ಆಸಕ್ತಿ ಹೊಂದಿರಬಹುದು ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ.
|
||||
\n
|
||||
|
||||
@@ -437,7 +437,7 @@ limitations under the License.
|
||||
<string name="settings_cycling_sensor">Sykling</string>
|
||||
<string name="settings_running_sensor">Løping</string>
|
||||
<string name="settings_import_section">Import</string>
|
||||
<string name="settings_export_section">Eksport</string>
|
||||
<string name="settings_export_as_file_section">Eksport</string>
|
||||
<string name="value_float_kilometer_hour">%1$.1f km/t</string>
|
||||
<string name="value_float_kilometer_hour_recommended">%1$.1f km/t (anbefales)</string>
|
||||
<string name="value_float_mile_hour">%1$.1f mi/h</string>
|
||||
@@ -588,4 +588,8 @@ limitations under the License.
|
||||
<string name="stats_sensors_temperature">Temperatur</string>
|
||||
<string name="sensor_state_temperature">Termometer</string>
|
||||
<string name="description_sensor_temperature">Temperatur (Celsius)</string>
|
||||
<string name="activity_type_gravel_biking">gravelsykling</string>
|
||||
<string name="settings_night_mode_option_day_dynamic">Dag (DynamicColor)</string>
|
||||
<string name="settings_night_mode_option_night_dynamic">Natt (DynamicColor)</string>
|
||||
<string name="settings_night_mode_option_night_oled_dynamic">OLED-vennlig (DynamicColor)</string>
|
||||
</resources>
|
||||
|
||||
@@ -465,7 +465,7 @@ Als het GPS-apparaat onnauwkeurige gegevens rapporteert (bijv. locatie, snelheid
|
||||
<string name="settings_cycling_sensor">Fietsen</string>
|
||||
<string name="settings_running_sensor">Hardlopen</string>
|
||||
<string name="settings_import_section">Invoer</string>
|
||||
<string name="settings_export_section">Uitvoer</string>
|
||||
<string name="settings_export_as_file_section">Uitvoer</string>
|
||||
<string name="settings_generic_sensor">Generiek</string>
|
||||
<string name="export_dir_not_writable">" (geen schrijfrecht!)"</string>
|
||||
<string name="value_float_kilometer_hour_recommended">%1$.1f km/u (aanbevolen)</string>
|
||||
@@ -581,7 +581,6 @@ Als het GPS-apparaat onnauwkeurige gegevens rapporteert (bijv. locatie, snelheid
|
||||
<string name="settings_announcements_unit">Afstand-/snelheidseenheid</string>
|
||||
<string name="voiceSpeed">{n, plural, =1 {1} other {{n,number,#.0}} }</string>
|
||||
<string name="voiceDistance">{n, plural, =1 {1 } other {{n,number,#.0}} }</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="power">Power</string>
|
||||
<string name="settings_announcements_lap_power">Lap power</string>
|
||||
<string name="power_x_watt">Power {x, plural, =1 {1 watt} other {# watt} }</string>
|
||||
|
||||
@@ -450,7 +450,7 @@ limitations under the License.
|
||||
<string name="settings_cycling_sensor">Kolarstwo</string>
|
||||
<string name="settings_running_sensor">Bieganie</string>
|
||||
<string name="settings_import_section">Import</string>
|
||||
<string name="settings_export_section">Eksport</string>
|
||||
<string name="settings_export_as_file_section">Eksport</string>
|
||||
<string name="settings_generic_sensor">Domyślny</string>
|
||||
<string name="description_speed_source_gps">GPS</string>
|
||||
<string name="permission_bluetooth_failed">OpenTracks wymaga uprawnień do urzycia Bluetooth.</string>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
<string name="activity_type_train">treino</string>
|
||||
<string name="activity_type_ultimate_frisbee">frisbee definitivo</string>
|
||||
<string name="activity_type_unknown">desconhecida</string>
|
||||
<string name="activity_type_wakeboarding">esqui aquático</string>
|
||||
<string name="activity_type_wakeboarding">wakeboarding</string>
|
||||
<string name="activity_type_walking">caminhada</string>
|
||||
<string name="activity_type_water_skiing">esqui aquático</string>
|
||||
<string name="activity_type_wind_surfing">windsurfe</string>
|
||||
@@ -136,7 +136,7 @@
|
||||
<string name="recording_service">Serviço de gravação</string>
|
||||
<string name="sensor_state_heart_rate">Frequência cardíaca</string>
|
||||
<string name="sensor_state_heart_rate_value">%1$d bom</string>
|
||||
<string name="sensor_state_power">Alimentação</string>
|
||||
<string name="sensor_state_power">Potência</string>
|
||||
<string name="settings_advanced">Avançado</string>
|
||||
<string name="settings_chart_by_distance">Por distância</string>
|
||||
<string name="settings_chart_by_time">Por tempo</string>
|
||||
@@ -280,7 +280,7 @@
|
||||
<string name="settings_default_export_uri_title">Diretório de exportação de trilhas</string>
|
||||
<string name="stats_split_interval">Intervalo de divisão</string>
|
||||
<string name="track_recording_notification_accuracy">Precisão da localização: %1$s</string>
|
||||
<string name="about_preference_title">Sobre OpenTracks</string>
|
||||
<string name="about_preference_title">Sobre</string>
|
||||
<string name="about_description"><i>OpenTracks</i> é um aplicativo de rastreamento de esportes que respeita totalmente a sua privacidade.</string>
|
||||
<string name="help_feature_content">* criar trilhas de GPS
|
||||
\n* use um sensor de frequência cardíaca (apenas Bluetooth LE)
|
||||
@@ -288,10 +288,7 @@
|
||||
\n* criar marcadores (incluindo imagens)
|
||||
\n* funciona completamente offline
|
||||
\n* mostrar trilhas em um mapa (veja abaixo)</string>
|
||||
<string name="help_track_map_content"> Use o pequeno ícone do mapa.
|
||||
\n a) (atualizações ao vivo) Instale <a href="https://codeberg.org/OpenTracksApp/OSMDashboard">OSMDashboard</a>. Ele fornece mapas online ou offline via <a href="https://www.openstreetmap.org">OpenStreetMap</a>.
|
||||
\n Na verdade, OSMDashboard é um aplicativo separado que só pode acessar (temporariamente) os dados da(s) trilha(s) que serão mostradas.
|
||||
\n b) Por meio de um aplicativo de mapa normal (por exemplo, <a href="http://osmand.net/">OsmAn </a> e <a href="https://maps.me/">MAPS.ME</a>). Esses aplicativos precisam ser compatíveis com o formato de arquivo KMZ (apenas locais e marcações de data/hora). Na verdade, um aplicativo precisa ser compatível com<i>ACTION_VIEW</i> com MIME<i> application/vnd.google-earth.kmz</i>. </string>
|
||||
<string name="help_track_map_content">Use o pequeno ícone no mapa.\n a) (atualizações ao vivo) Instale <a href="https://codeberg.org/OpenTracksApp/OSMDashboard">OSMDashboard</a>. Ele fornece mapas online ou offline via <a href="https://www.openstreetmap.org">OpenStreetMap</a>.\n Na verdade, OSMDashboard é um aplicativo separado que só pode acessar (temporariamente) os dados da(s) trilha(s) que serão mostradas. \n b) Por meio de um aplicativo de mapa normal (por exemplo:, <a href="http://osmand.net/">OsmAnd</a> e <a href="https://maps.me/">MAPS.ME</a>). Esses aplicativos precisam ser compatíveis com o formato de arquivo KMZ (apenas locais e marcações de data/hora). Na verdade, um aplicativo precisa ser compatível com <i>ACTION_VIEW</i> com MIME <i>application/vnd.google-earth.kmz</i>.</string>
|
||||
<string name="help_data_storage_content"> Os dados do sensor são armazenados por local registrado. Em termos de sensor de frequência cardíaca, isso significa que apenas <i>uma</i> medição de frequência cardíaca é armazenada por local. Se você estiver parado ou dentro de casa, nenhum dado do sensor será registrado (mas será mostrado). </string>
|
||||
<string name="help_support_content"> Você pode:
|
||||
\n a) espalhe a palavra sobre OpenTracks,
|
||||
@@ -304,6 +301,7 @@
|
||||
<string name="activity_type_escooter">escolta</string>
|
||||
<plurals name="generic_completed_with_errors">
|
||||
<item quantity="one">Concluído com %1$d erro</item>
|
||||
<item quantity="many">Concluído com %1$d erros</item>
|
||||
<item quantity="other">Concluído com %1$d erros</item>
|
||||
</plurals>
|
||||
<string name="import_unsupported_format">Formato de arquivo não suportado</string>
|
||||
@@ -372,7 +370,7 @@
|
||||
<string name="import_progress_summary_exists_msg">Já existe</string>
|
||||
<string name="import_progress_summary_errors_msg">Erros</string>
|
||||
<string name="sensor_state_heart_rate_max">Freqüência cardíaca máxima</string>
|
||||
<string name="sensor_state_power_avg">Energia Avg</string>
|
||||
<string name="sensor_state_power_avg">Potência Média</string>
|
||||
<string name="sensor_state_heart_rate_avg">Ritmo cardíaco Avg</string>
|
||||
<string name="sensor_state_cadence_max">Ritmo cardíaco médio</string>
|
||||
<string name="sensor_state_cadence_avg">Avg Cadência</string>
|
||||
@@ -396,7 +394,7 @@
|
||||
<string name="settings_layout_reset_done">Todas as configurações de layout foram revertidas para os valores padrão</string>
|
||||
<string name="settings_all_reset">Redefinir</string>
|
||||
<string name="stats_coordinates">Latitude/Longitude</string>
|
||||
<string name="stats_sensors_power">Poder</string>
|
||||
<string name="stats_sensors_power">Potência</string>
|
||||
<string name="field_set_primary">Primário</string>
|
||||
<string name="field_set_secondary">Secundário</string>
|
||||
<string name="field_remove_from_layout">Remover</string>
|
||||
@@ -412,7 +410,7 @@
|
||||
<string name="settings_cycling_sensor">Ciclismo</string>
|
||||
<string name="settings_running_sensor">Correndo</string>
|
||||
<string name="settings_import_section">Importar</string>
|
||||
<string name="settings_export_section">Exportar</string>
|
||||
<string name="settings_export_as_file_section">Exportar</string>
|
||||
<string name="value_float_kilometer_hour">%1$.1f km/h</string>
|
||||
<string name="value_float_kilometer_hour_recommended">%1$.1f km/h (Recomendado)</string>
|
||||
<string name="stats_clock">Relógio</string>
|
||||
@@ -500,4 +498,75 @@
|
||||
<string name="show_on_dashboard">Painel API do OpenTracks</string>
|
||||
<string name="always">Sempre</string>
|
||||
<string name="description_speed_nautical">Velocidade (nós)</string>
|
||||
</resources>
|
||||
<string name="help_data_google_play_services_content">Não</string>
|
||||
<string name="activity_type_gravel_biking">ciclismo de gravel</string>
|
||||
<string name="activity_type_kickscooter">patinete</string>
|
||||
<string name="description_sensor_temperature">Temperatura (Celsius)</string>
|
||||
<string name="create_marker_error">Incapaz de criar um marcador. Tente outra vez.</string>
|
||||
<string name="marker_detail_title">%1$d de %2$d: %3$s</string>
|
||||
<string name="menu_export_all_one_file">Exportar tudo (Um arquivo para todas as trilhas)</string>
|
||||
<string name="permission_recording_failed">OpenTracks precisa de permissão para acessar a sua localização e dispositivos próximos.</string>
|
||||
<string name="sensor_state_cadence_unit">rpm</string>
|
||||
<string name="sensor_state_heart_rate_unit">bpm</string>
|
||||
<string name="sensor_state_temperature">Termômetro</string>
|
||||
<string name="sensor_state_pressure">Barômetro</string>
|
||||
<string name="sensor_state_power_max">Potência Máxima</string>
|
||||
<string name="sensor_state_power_unit">W</string>
|
||||
<string name="bluetooth_sensor_summary">%1$s (%2$s)</string>
|
||||
<string name="settings_announcements_idle_category_title">Anúncios de Inatividade</string>
|
||||
<string name="settings_announcements_idle_title">Inativo</string>
|
||||
<string name="settings_charts_title">Gráficos</string>
|
||||
<string name="settings_chart_display_elevation_title">Mostrar elevação</string>
|
||||
<string name="settings_chart_display_pace_or_speed_title">Mostrar ritmo ou velocidade</string>
|
||||
<string name="settings_chart_display_heart_rate_title">Mostrar frequência cardíaca</string>
|
||||
<string name="settings_recording_title">Gravação</string>
|
||||
<string name="settings_theme_switch_restart">Mudanças de tema podem exigir uma reinicialização manual.</string>
|
||||
<string name="settings_ui_dynamic_colors_title">Cores Dinâmicas</string>
|
||||
<string name="settings_ui_dynamic_colors_summary">Utilizar Cores Dinâmicas definidas pelo usuário (Android 12+ apenas; necessita de reinicialização manual.)</string>
|
||||
<string name="settings_recording_show_gps_disabled_warning_title">Aviso de GPS desabilitado</string>
|
||||
<string name="settings_recording_show_gps_disabled_warning_summary">Ao gravar, exibir um aviso se o GPS estiver desabilitado.</string>
|
||||
<string name="settings_recording_min_required_accuracy_summary">Localização é ignorada se sua precisão for maior que %1$s</string>
|
||||
<string name="settings_recording_idle_timeout_title">Limiar inativo</string>
|
||||
<string name="settings_locale_title">Língua</string>
|
||||
<string name="settings_locale_system_default">Padrão do sistema</string>
|
||||
<string name="settings_night_mode_option_system_dynamic">Sistema (Cores Dinâmicas)</string>
|
||||
<string name="settings_night_mode_option_day_dynamic">Dia (Cores Dinâmicas)</string>
|
||||
<string name="settings_night_mode_option_night_dynamic">Noite (Cores Dinâmicas)</string>
|
||||
<string name="settings_night_mode_option_night_oled">OLED compatível</string>
|
||||
<string name="settings_night_mode_option_night_oled_dynamic">Compatível OLED (Cores Dinâmicas)</string>
|
||||
<string name="settings_announcements_segment_average_speed_pace">Velocidade/ritmo médio (Segmento)</string>
|
||||
<string name="settings_announcements_unit">Unidade de distância/velocidade</string>
|
||||
<string name="settings_sensor_bluetooth_service_filter_title">Filtrar Dispositivos Bluetooth</string>
|
||||
<string name="settings_sensor_bluetooth_service_filter_off">Mostrar todos os dispositivos Bluetooth detectáveis</string>
|
||||
<string name="settings_sensor_heart_rate_max">Zonas: Frequência cardíaca máxima (bpm)</string>
|
||||
<string name="settings_stats_units_imperial_meter">Imperial (mi, m)</string>
|
||||
<string name="settings_api_summary">API de controle remoto e estatísticas para outros apps</string>
|
||||
<string name="stats_average_segment_pace">Ritmo médio no segmento</string>
|
||||
<string name="stats_elapsed_segment_time">Tempo decorrido no segmento</string>
|
||||
<string name="stats_gain_loss">Ganhos e Perdas</string>
|
||||
<string name="stats_sensors_temperature">Temperatura</string>
|
||||
<string name="track_edit_time_offset">Deslocamento de fuso horário</string>
|
||||
<string name="value_internal_sensor">Sensor interno</string>
|
||||
<string name="value_int_seconds">%1$d s (recomendado)</string>
|
||||
<string name="voiceIdle">Ficando inativo.</string>
|
||||
<string name="voiceHoursPlural">{n, plural, =1 {1 hora} other {{n,number} horas} }</string>
|
||||
<string name="voiceMinutesPlural">{n, plural, =1 {1 minuto} other {{n,number} minutos} }</string>
|
||||
<string name="voiceSecondsPlural">{n, plural, =1 {1 segundo} other {{n,number} segundos} }</string>
|
||||
<string name="voiceSpeedKilometersPerHourPlural">{n, plural, =1 {1 quilômetro por hora} other {{n,number,#.0} quilômetros por hora} }</string>
|
||||
<string name="voiceSpeedMilesPerHourPlural">{n, plural, =1 {1 milha por hora} other {{n,number,#.0} milhas por hora} }</string>
|
||||
<string name="voiceSpeedMKnotsPlural">{n, plural, =1 {1 nó} other {{n,number,#.0} nós} }</string>
|
||||
<string name="voiceSpeed">{n, plural, =1 {1} other {{n,number,#.0}} }</string>
|
||||
<string name="voice_on_device_speaker_title">Use o alto-falante do dispositivo</string>
|
||||
<string name="voiceDistanceKilometersPlural">{n, plural, =1 {1 quilômetro} other {{n,number,#.0} quilômetros} }</string>
|
||||
<string name="voiceDistanceMilesPlural">{n, plural, =1 {1 milha} other {{n,number,#.0} milhas} }</string>
|
||||
<string name="voiceDistanceNauticalMilesPlural">{n, plural, =1 {1 milha náutica} other {{n,number,#.0} milhas náuticas} }</string>
|
||||
<string name="voiceDistance">{n, plural, =1 {1 } other {{n,number,#.0}} }</string>
|
||||
<string name="lap_heart_rate">Frequência cardíaca na volta</string>
|
||||
<string name="no_compatible_camera_installed">Nenhum aplicativo compatível de camera instalado</string>
|
||||
<string name="no_compatible_gallery_installed">Nenhum aplicativo compatível de galeria de imagens instalado</string>
|
||||
<string name="settings_recording_min_sampling_interval_title">Intervalo de tempo de amostragem</string>
|
||||
<string name="settings_recording_location_distance_summary">%1$s entre localizações gravadas</string>
|
||||
<string name="settings_announcements_lap_power">Potência por volta</string>
|
||||
<string name="power_x_watt">Potência {x, plural, =1 {1 watt} other {# watts} }</string>
|
||||
<string name="power">Potência</string>
|
||||
</resources>
|
||||
|
||||
@@ -451,7 +451,7 @@
|
||||
<string name="settings_public_api_dashboard_enabled_summary_on">Uma aplicação que iniciou uma gravação também pode acessar os dados gravados.</string>
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">Os dados gravados não serão compartilhados automaticamente com outras aplicações.</string>
|
||||
<string name="settings_import_section">Importar</string>
|
||||
<string name="settings_export_section">Exportar</string>
|
||||
<string name="settings_export_as_file_section">Exportar</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">Impedir a reimportação de trilhas</string>
|
||||
<string name="stats_loss">Perda</string>
|
||||
<string name="stats_coordinates">Latitude/Longitude</string>
|
||||
|
||||
@@ -466,7 +466,7 @@ limitations under the License.
|
||||
<string name="settings_public_api_enabled_summary_off">Apenas o OpenTracks pode iniciar e parar gravações.</string>
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">Os dados gravados não serão compartilhados automaticamente com outras aplicações.</string>
|
||||
<string name="settings_import_section">Importar</string>
|
||||
<string name="settings_export_section">Exportar</string>
|
||||
<string name="settings_export_as_file_section">Exportar</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">Impedir a reimportação de trilhas</string>
|
||||
<string name="stats_loss">Perda</string>
|
||||
<string name="stats_coordinates">Latitude/Longitude</string>
|
||||
|
||||
@@ -498,7 +498,7 @@ limitations under the License.
|
||||
<string name="current_heart_rate">Текущий пульс</string>
|
||||
<string name="generic_filter">Фильтр</string>
|
||||
<string name="generic_from">с</string>
|
||||
<string name="settings_export_section">Экспорт</string>
|
||||
<string name="settings_export_as_file_section">Экспорт</string>
|
||||
<string name="settings_import_section">Импорт</string>
|
||||
<string name="settings_api_title">Публичный API</string>
|
||||
<string name="settings_public_api_disabled_toast">Публичный API OpenTracks отключен: он может быть включен в настройках.</string>
|
||||
@@ -600,7 +600,6 @@ limitations under the License.
|
||||
<string name="settings_locale_system_default">Как в системе</string>
|
||||
<string name="settings_night_mode_option_night_oled">Полностью чёрный</string>
|
||||
<string name="settings_announcements_unit">Единицы расстояния/скорости</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="power_x_watt">Мощность {x, plural, =1 {1 Ватт} few {# Ватта} other {# Ваттов} }</string>
|
||||
<string name="settings_recording_min_sampling_interval_title">Интервал выборки</string>
|
||||
<string name="settings_announcements_lap_power">Мощность на круге</string>
|
||||
|
||||
@@ -381,7 +381,7 @@ limitations under the License.
|
||||
<string name="settings_running_sensor">Spúšťanie</string>
|
||||
<string name="settings_cycling_sensor">Cyklistika</string>
|
||||
<string name="custom_layout_list_layout_removed">Rozloženie bolo odstránené</string>
|
||||
<string name="settings_export_section">Exportujte</string>
|
||||
<string name="settings_export_as_file_section">Exportujte</string>
|
||||
<string name="settings_import_section">Importovať</string>
|
||||
<string name="track_recording_notification_accuracy">Presnosť polohy: %1$s</string>
|
||||
<string name="stats_clock">Hodiny</string>
|
||||
|
||||
@@ -352,7 +352,7 @@ limitations under the License.
|
||||
<string name="import_parser_error">Napaka analizatorja: %1$s</string>
|
||||
<string name="settings_sensor_cycling_cadence">Kadenca</string>
|
||||
<string name="menu_select_layout">Izberite postavitev</string>
|
||||
<string name="settings_export_section">Izvoz</string>
|
||||
<string name="settings_export_as_file_section">Izvoz</string>
|
||||
<string name="stats_sensors_cadence">Kadenca</string>
|
||||
<string name="stats_sensors_heart_rate">Srčni utrip</string>
|
||||
<string name="settings_ui_title">Uporabniški vmesnik</string>
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
<string name="introduction_osm_dashboard">ஓபன்ட்ராக்ச் ஒரு வரைபடத்தை வழங்காது. உங்கள் பதிவுகளை வரைபடத்தில் காண OSMDashboard ஐ நிறுவவும்.</string>
|
||||
<string name="settings_recording_min_sampling_interval_title">மாதிரி நேர இடைவெளி</string>
|
||||
<string name="settings_recording_location_distance_summary">பதிவுசெய்யப்பட்ட இடங்களுக்கு இடையில் %1$s</string>
|
||||
<string name="voice_announce_lap_power_key">VoiceAnnouncelappower</string>
|
||||
<string name="settings_announcements_lap_power">மடியில் ஆற்றல்</string>
|
||||
<string name="power_x_watt">ஆற்றல் {x, plural, = 1 {1 watt} other {# வாட்ச்}}</string>
|
||||
<string name="power">விசை</string>
|
||||
@@ -339,7 +338,7 @@
|
||||
<string name="settings_public_api_dashboard_enabled_summary_on">பதிவைத் தொடங்கிய பயன்பாடு பதிவு செய்யப்பட்ட தரவையும் அணுகலாம்.</string>
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">பதிவுசெய்யப்பட்ட தரவு மற்ற பயன்பாடுகளுடன் தானாக பகிரப்படாது.</string>
|
||||
<string name="settings_import_section">இறக்குமதி</string>
|
||||
<string name="settings_export_section">ஏற்றுமதி</string>
|
||||
<string name="settings_export_as_file_section">ஏற்றுமதி</string>
|
||||
<string name="share_track_share_file_body">இந்த பாதையில் நீங்கள் ஆர்வமாக இருக்கலாம் என்று நினைக்கிறேன்.\n\n %1$s</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">தடங்களை மீண்டும் இறக்குமதி செய்வதைத் தடுக்கவும்</string>
|
||||
<string name="share_track_subject">நான் உங்களுடன் ஒரு பாதையைப் பகிர்ந்து கொள்ள விரும்புகிறேன்</string>
|
||||
|
||||
@@ -438,7 +438,7 @@ limitations under the License.
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">Kaydedilen veriler diğer uygulamalarla otomatik olarak paylaşılmayacaktır.</string>
|
||||
<!-- Settings import/export -->
|
||||
<string name="settings_import_section">İçe Aktar</string>
|
||||
<string name="settings_export_section">Dışa Aktar</string>
|
||||
<string name="settings_export_as_file_section">Dışa Aktar</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">Parkurların yeniden içe aktarılmasını engelle</string>
|
||||
<!-- Share Track -->
|
||||
<string name="share_track_share_file_body">Bu parkurun ilginizi çekebileceğini düşündüm.\n\n%1$s</string>
|
||||
@@ -683,7 +683,6 @@ limitations under the License.
|
||||
<string name="introduction_osm_dashboard">OpenTracks kendi başına bir harita sunmaz. Kayıtlarınızı bir harita üzerinde görüntülemek için lütfen OSMDashboard\'u yükleyin.</string>
|
||||
<string name="settings_recording_min_sampling_interval_title">Örnekleme zaman aralığı</string>
|
||||
<string name="settings_recording_location_distance_summary">Kaydedilen konumlar arasında %1$s</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="settings_announcements_lap_power">Tur gücü</string>
|
||||
<string name="power_x_watt">Güç {x, plural, =1 {1 watt} other {# watt} }</string>
|
||||
<string name="power">Güç</string>
|
||||
|
||||
@@ -425,7 +425,7 @@ limitations under the License.
|
||||
<string name="field_remove_from_layout">Видалити</string>
|
||||
<string name="stats_clock">Годинник</string>
|
||||
<string name="settings_recording_customize_layout_select_columns">Поля даних у рядку</string>
|
||||
<string name="settings_export_section">Експорт</string>
|
||||
<string name="settings_export_as_file_section">Експорт</string>
|
||||
<string name="field_set_secondary">Вторинний</string>
|
||||
<string name="settings_all_reset">Скидання</string>
|
||||
<string name="generic_filter">Фільтр</string>
|
||||
@@ -598,9 +598,9 @@ limitations under the License.
|
||||
<string name="voiceIdle">Перехід у режим без руху.</string>
|
||||
<string name="settings_recording_idle_timeout_title">Поріг режиму «Без руху»</string>
|
||||
<string name="stats_gain_loss">Підйом і спуск</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="stats_elapsed_segment_time">Час на відрізок</string>
|
||||
<string name="description_sensor_temperature">Температура (Цельсій)</string>
|
||||
<string name="sensor_state_temperature">Термометр</string>
|
||||
<string name="stats_sensors_temperature">Температура</string>
|
||||
<string name="activity_type_gravel_biking">гравійний велосипед</string>
|
||||
</resources>
|
||||
|
||||
@@ -455,7 +455,7 @@ limitations under the License.
|
||||
<string name="settings_cycling_sensor">Đạp xe</string>
|
||||
<string name="settings_running_sensor">Chạy</string>
|
||||
<string name="settings_import_section">Nhập</string>
|
||||
<string name="settings_export_section">Xuất</string>
|
||||
<string name="settings_export_as_file_section">Xuất</string>
|
||||
<string name="settings_generic_sensor">Chung chung</string>
|
||||
<string name="value_float_mile_hour">%1$.1f mi/h</string>
|
||||
<string name="value_float_mile_hour_recommended">%1$.1f mi/h (khuyến khích)</string>
|
||||
|
||||
@@ -393,7 +393,7 @@ limitations under the License.
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">記錄的資料將不會自動與其他應用程式共用。</string>
|
||||
<!-- Settings import/export -->
|
||||
<string name="settings_import_section">匯入</string>
|
||||
<string name="settings_export_section">匯出</string>
|
||||
<string name="settings_export_as_file_section">匯出</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">防止重新匯入蹤跡</string>
|
||||
<!-- Share Track -->
|
||||
<string name="share_track_share_file_body">我想您應該會對這個路線感興趣。
|
||||
@@ -613,7 +613,6 @@ limitations under the License.
|
||||
<string name="settings_theme_switch_restart">主題變更也許需要手動重新啟動。</string>
|
||||
<string name="settings_night_mode_option_night_oled">夜(OLED 友善的)</string>
|
||||
<string name="power_x_watt">功率 {x, plural, =1 {1 瓦特} other {# 瓦特} }</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="settings_charts_title">圖表</string>
|
||||
<string name="stats_gain_loss">收益&損失</string>
|
||||
<string name="settings_recording_show_gps_disabled_warning_title">GPS 禁用警告</string>
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
<!-- Activity Type -->
|
||||
<string name="activity_type_airplane">坐飞机</string>
|
||||
<string name="activity_type_atv">全地形越野</string>
|
||||
<string name="activity_type_biking">自行车</string>
|
||||
<string name="activity_type_biking">骑行</string>
|
||||
<string name="activity_type_blimp">小型飞艇游览</string>
|
||||
<string name="activity_type_boat">船</string>
|
||||
<string name="activity_type_climbing">攀岩</string>
|
||||
@@ -539,7 +539,7 @@ limitations under the License.
|
||||
<string name="settings_public_api_disabled_toast">OpenTracks 公共 API 已禁用:可以在设置中启用。</string>
|
||||
<string name="settings_public_api_dashboard_enabled_title">自动数据传输</string>
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">记录的数据不会自动与其他应用程序共享。</string>
|
||||
<string name="settings_export_section">导出</string>
|
||||
<string name="settings_export_as_file_section">导出</string>
|
||||
<string name="stats_loss">下降</string>
|
||||
<string name="stats_coordinates">纬度/经度</string>
|
||||
<string name="track_pace_notification">配速:%1$s</string>
|
||||
@@ -633,4 +633,5 @@ limitations under the License.
|
||||
<string name="description_sensor_temperature">温度(摄氏度)</string>
|
||||
<string name="sensor_state_temperature">温度计</string>
|
||||
<string name="stats_sensors_temperature">温度</string>
|
||||
<string name="activity_type_gravel_biking">砾石骑行</string>
|
||||
</resources>
|
||||
|
||||
@@ -58,6 +58,9 @@
|
||||
<string name="export_filename_format_key" translatable="false">instantExportFilename</string>
|
||||
<string name="export_filename_format_default" translatable="false">{date}_{time}_{name}</string>
|
||||
|
||||
<string name="post_workout_export_health_connect_enabled_key" translatable="false">instantExportHealthConnectEnabled</string>
|
||||
<bool name="post_workout_export_health_connect_enabled_default" translatable="false">false</bool>
|
||||
|
||||
<!-- Stats layout customization default layout -->
|
||||
<string name="settings_layout_reset_key" translatable="false">settingsLayoutReset</string>
|
||||
|
||||
@@ -261,6 +264,9 @@
|
||||
<string name="voice_announce_lap_heart_rate_key" translatable="false">voiceAnnounceLapHeartRate</string>
|
||||
<bool name="voice_announce_lap_heart_rate_default" translatable="false">false</bool>
|
||||
|
||||
<string name="voice_announce_lap_power_key" translateable="false">voiceAnnounceLapPower</string>
|
||||
<bool name="voice_announce_lap_power_default" translateable="false">false</bool>
|
||||
|
||||
<string name="export_trackfileformat_key" translatable="false">exportTrackFileFormat</string>
|
||||
<!-- See TrackFileFormat -->
|
||||
<string name="export_trackfileformat_default" translatable="false">KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES</string>
|
||||
|
||||
@@ -83,6 +83,7 @@ limitations under the License.
|
||||
<string name="activity_type_airplane">airplane</string>
|
||||
<string name="activity_type_atv">ATV</string>
|
||||
<string name="activity_type_biking">biking</string>
|
||||
<string name="activity_type_gravel_biking">gravel biking</string>
|
||||
<string name="activity_type_blimp">blimp</string>
|
||||
<string name="activity_type_boat">boat</string>
|
||||
<string name="activity_type_climbing">climbing</string>
|
||||
@@ -279,6 +280,7 @@ limitations under the License.
|
||||
<string name="menu_edit">Edit</string>
|
||||
<string name="menu_export_all">Export all (one file per track)</string>
|
||||
<string name="menu_export_all_one_file">Export all (one file for all tracks)</string>
|
||||
<string name="menu_export_all_to_health_connect">Export all</string>
|
||||
<string name="menu_help">Help</string>
|
||||
<string name="menu_import_all">Import all</string>
|
||||
<string name="menu_insert_marker">Insert marker</string>
|
||||
@@ -447,7 +449,8 @@ limitations under the License.
|
||||
<string name="settings_public_api_dashboard_enabled_summary_off">Recorded data will not be shared automatically with other applications.</string>
|
||||
<!-- Settings import/export -->
|
||||
<string name="settings_import_section">Import</string>
|
||||
<string name="settings_export_section">Export</string>
|
||||
<string name="settings_export_as_file_section">Export as file</string>
|
||||
<string name="settings_export_to_health_connect">Export to Health Connect</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">Prevent re-import of tracks</string>
|
||||
<!-- Share Track -->
|
||||
<string name="share_track_share_file_body">I think you might be interested in this track.\n\n%1$s</string>
|
||||
@@ -678,6 +681,13 @@ limitations under the License.
|
||||
<string name="hold_to_stop">Hold to stop</string>
|
||||
<string name="instant_export_enabled_summary">Export track to storage after recording is finished</string>
|
||||
<string name="instant_export_enabled_title">Instant post-workout export</string>
|
||||
<string name="health_connect_export_enabled_summary">Export activity to Health Connect after recording is finished</string>
|
||||
<string name="health_connect_not_available">Health Connect is not available on this device</string>
|
||||
<string name="health_connect_open_settings_title">Health Connect settings</string>
|
||||
<string name="health_connect_open_settings_summary">Open the Health Connect settings</string>
|
||||
<string name="health_connect_permissions_rationale_title">Health Connect permissions</string>
|
||||
<string name="health_connect_permissions_rationale_heading">How OpenTracks uses Health Connect</string>
|
||||
<string name="health_connect_permissions_rationale_summary">If enabled in the settings, OpenTracks writes exercise to Health Connect. OpenTracks does not read data from Health Connect.</string>
|
||||
<string name="settings_default_export_uri_title">Track export directory</string>
|
||||
<!-- Fields -->
|
||||
<string name="field_set_primary">Primary</string>
|
||||
@@ -695,7 +705,6 @@ limitations under the License.
|
||||
<string name="introduction_osm_dashboard">OpenTracks itself does not provide a map. Please install OSMDashboard to view your recordings on a map.</string>
|
||||
<string name="settings_recording_min_sampling_interval_title">Sampling time interval</string>
|
||||
<string name="settings_recording_location_distance_summary">%1$s between recorded locations</string>
|
||||
<string name="voice_announce_lap_power_key">voiceAnnounceLapPower</string>
|
||||
<string name="settings_announcements_lap_power">Lap power</string>
|
||||
<string name="power_x_watt">Power {x, plural, =1 {1 watt} other {# watts} }</string>
|
||||
<string name="power">Power</string>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
android:title="@string/settings_prevent_reimport_tracks_title" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/settings_export_section">
|
||||
<PreferenceCategory android:title="@string/settings_export_as_file_section">
|
||||
<Preference
|
||||
android:title="@string/menu_export_all">
|
||||
<intent
|
||||
@@ -52,4 +52,37 @@
|
||||
android:title="@string/settings_export_filename_title"
|
||||
android:defaultValue="@string/export_filename_format_default" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/settings_export_to_health_connect"
|
||||
android:key="healthConnectCategory">
|
||||
<Preference
|
||||
android:persistent="false"
|
||||
android:summary="@string/health_connect_open_settings_summary"
|
||||
android:title="@string/health_connect_open_settings_title">
|
||||
<intent
|
||||
android:targetClass="de.dennisguse.opentracks.settings.HealthConnect$Settings"
|
||||
android:targetPackage="@string/applicationId" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
android:title="@string/health_connect_permissions_rationale_title"
|
||||
android:key="healthConnectPermissions">
|
||||
<intent
|
||||
android:targetClass="de.dennisguse.opentracks.settings.HealthConnect$ConfigurePermissions"
|
||||
android:targetPackage="@string/applicationId" />
|
||||
</Preference>
|
||||
|
||||
<Preference android:title="@string/menu_export_all_to_health_connect">
|
||||
<intent
|
||||
android:targetClass="de.dennisguse.opentracks.settings.HealthConnect$ExportAll"
|
||||
android:targetPackage="@string/applicationId" />
|
||||
</Preference>
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="@bool/post_workout_export_health_connect_enabled_default"
|
||||
android:key="@string/post_workout_export_health_connect_enabled_key"
|
||||
android:summary="@string/health_connect_export_enabled_summary"
|
||||
android:title="@string/instant_export_enabled_title" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
||||
Reference in New Issue
Block a user