Compare commits

..

25 Commits

Author SHA1 Message Date
Dennis Guse 823dc1c12b Release: v3.18.5 2021-06-24 18:44:36 +02:00
Dennis Guse 26490f5a66 Launcher icon (API <26): does not have a background circle.
Rendering a multilayer image is not consistent (size).

Fixes #814.
2021-06-24 18:29:50 +02:00
Dennis Guse d299dbdf06 Also send speed to UI. 2021-06-24 12:02:22 +02:00
Dennis Guse b5555e302f Bugfix: TrackRecordingService now computes EGM2008 for UI (i.e., StatisticsRecordingFragment).
Fixes #828.
2021-06-24 12:02:22 +02:00
Dennis Guse 3030b4dfd9 Bugfix: TrackRecordingService needs to send data from lastTrackPoint in it's 1s updates.
This also removes UI updates if a GPS measurement is received as 1s update should be sufficient.

Fixes #828.
2021-06-24 12:02:22 +02:00
dependabot[bot] a5431b1cf5 Bump reactivecircus/android-emulator-runner from 2.17.0 to 2.18.0
Bumps [reactivecircus/android-emulator-runner](https://github.com/reactivecircus/android-emulator-runner) from 2.17.0 to 2.18.0.
- [Release notes](https://github.com/reactivecircus/android-emulator-runner/releases)
- [Changelog](https://github.com/ReactiveCircus/android-emulator-runner/blob/main/CHANGELOG.md)
- [Commits](https://github.com/reactivecircus/android-emulator-runner/compare/v2.17.0...v2.18.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-23 07:35:59 +02:00
serpico 9314221647 Translated using Weblate (Indonesian)
Currently translated at 79.3% (415 of 523 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/id/
2021-06-22 17:19:35 +02:00
Dennis Guse 9bb9d5c283 Voice announcement: make rate configurable.
Fixes #777.
2021-06-22 17:19:31 +02:00
Patrick Georgi 1095a1442f Fix typo in German translation
It's Geschwindigkeit, not Geshwindigkeit.
2021-06-22 17:00:22 +02:00
Dennis Guse d373fdaaeb Downgrade espresso-coret to 3.3.0; no need to use an alpha. 2021-06-20 17:43:05 +02:00
serpico 5278ba4d35 Translated using Weblate (French)
Currently translated at 98.5% (67 of 68 strings)

Translation: OpenTracks/App store metadata files
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/app-store-metadata-files/fr/
2021-06-17 23:36:18 +02:00
FTno 9b71b7f88c Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (523 of 523 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/nb_NO/
2021-06-17 23:36:18 +02:00
serpico bc96c2c05b Translated using Weblate (French)
Currently translated at 99.8% (522 of 523 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fr/
2021-06-17 23:36:18 +02:00
Dennis Guse e655762c72 EspressoCategoryUnitTest needs to set metricUnits. 2021-06-17 23:26:05 +02:00
Dennis Guse 71c385a1a9 Android12: add new Bluetooth connect permission.
Fixes #821.
2021-06-17 23:18:04 +02:00
Dennis Guse b947a727e7 Bugfix: while recording UI values were doubled.
Issue: copy constructor of  TrackStatisticsUpdater was not copying completely and the same reference used.
2021-06-17 23:08:06 +02:00
Román Martínez 470f23afa8 Bugfix: pace or speed header text is not showing in intervals.
Bugfix: viewModel checking onPause.
2021-06-17 14:36:30 +02:00
Dennis Guse 0a1f9dfe41 Cleanup. 2021-06-15 22:55:42 +02:00
Weblate 6fcd19bf2e Merge branch 'origin/main' into Weblate. 2021-06-15 22:43:54 +02:00
serpico 32d9705a4c Translated using Weblate (French)
Currently translated at 99.6% (521 of 523 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fr/
2021-06-15 18:08:46 +02:00
Xosé M 2ac66c08f2 Translated using Weblate (Galician)
Currently translated at 100.0% (523 of 523 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/gl/
2021-06-15 18:08:46 +02:00
serpico 3b776407fa Translated using Weblate (French)
Currently translated at 99.6% (521 of 523 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/fr/
2021-06-15 17:08:24 +02:00
Xosé M 399f90a8f0 Translated using Weblate (Galician)
Currently translated at 100.0% (523 of 523 strings)

Translation: OpenTracks/opentracks.src-main-res-values-strings-xml--main
Translate-URL: https://weblate.bubu1.eu/projects/OpenTracks/opentracks/gl/
2021-06-15 17:08:24 +02:00
Román Martínez b2c2047ca2 Dennis Review. 2021-06-15 17:08:16 +02:00
Román Martínez 838671e2ce IntervalsFragment doesn't use TrackDataHub anymore. This improve intervals performance. Fixes #808. 2021-06-15 17:08:16 +02:00
33 changed files with 289 additions and 96 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
uses: actions/checkout@v2.3.4
- name: run tests
uses: reactivecircus/android-emulator-runner@v2.17.0
uses: reactivecircus/android-emulator-runner@v2.18.0
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
+3 -3
View File
@@ -55,8 +55,8 @@ android {
defaultConfig {
applicationId "de.dennisguse.opentracks"
versionCode 4151
versionName "v3.18.4"
versionCode 4176
versionName "v3.18.5"
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
@@ -90,7 +90,6 @@ android {
}
dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0-alpha06'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation 'androidx.appcompat:appcompat:1.3.0'
@@ -103,5 +102,6 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test:rules:1.3.0'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'org.mockito:mockito-android:3.10.0'
}
@@ -0,0 +1,12 @@
v3.18.5: OpenTracks
Changes:
- Voice announcement speed configurable
- API <26: Launcher icon omits background
Bugfixes:
- Recording UI: show correct values
- Recording UI: show (again) altitude in EGM2008
Developer:
- Android12 permissions (BLUETOOTH_CONNECT)
@@ -4,6 +4,8 @@ Fonctionnalités :
* Suivi d'activité : enregistre vos activités sportives et de plein air
* Photos et repères : ajout de photos et de repères pendant l'enregistrement de l'activité
* Rythme cardiaque : support des capteurs Bluetooth LE
* Export : export des traces au format KML ou GPX
* Dénivelé positif et négatif: via capteur de pression barométrique
* Synthèse vocale
* Prise en charge des capteurs Bluetooth LE : rythme cardiaque, vitesse et distance (vélo), cadence de pédalage (vélo), et capteur de puissance (vélo)
* Export : export des traces au format KMZ (photos incluses), KML ou GPX
* Pas d'accès internet requis : Internet n'est pas nécessaire pour le fonctionnement de l'application
@@ -1 +1 @@
OpenTracks - Suivi d'activités sportives respectueux de votre vie privée.
OpenTracks - Suivi d'activités sportives respectueux de votre vie privée.
@@ -1,6 +1,7 @@
package de.dennisguse.opentracks;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -9,16 +10,18 @@ import androidx.test.espresso.DataInteraction;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.ViewInteraction;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.GrantPermissionRule;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import static androidx.test.espresso.Espresso.onData;
@@ -44,12 +47,15 @@ import static org.hamcrest.Matchers.is;
public class EspressoCategoryUnitTest {
@Rule
public ActivityTestRule<TrackListActivity> mActivityTestRule = new ActivityTestRule<>(TrackListActivity.class);
public ActivityScenarioRule<TrackListActivity> mActivityTestRule = new ActivityScenarioRule<>(TrackListActivity.class);
@Rule
public GrantPermissionRule mGrantPermissionRule =
GrantPermissionRule.grant(
"android.permission.ACCESS_FINE_LOCATION");
public TestRule mRuntimePermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
private final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
@Rule
public TestRule mLocaleRule = new PreferenceMetricUnitRule(context, true);
@Test
public void changeBetweenCategoryUpdateProperlyUnitTest() {
@@ -18,10 +18,10 @@ import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.action.MotionEvents;
import androidx.test.espresso.assertion.ViewAssertions;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
@@ -55,7 +55,7 @@ public class EspressoDeleteTrackTest {
public ActivityScenarioRule<TrackListActivity> mActivityTestRule = new ActivityScenarioRule<>(TrackListActivity.class);
@Rule
public GrantPermissionRule mGrantPermissionRule = GrantPermissionRule.grant("android.permission.ACCESS_FINE_LOCATION");
public GrantPermissionRule mGrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
private MyIdlingResource idlingResource;
@@ -241,7 +241,7 @@ public class EspressoDeleteTrackTest {
private class MyIdlingResource implements IdlingResource {
private Context context;
private final Context context;
private ResourceCallback resourceCallback;
public MyIdlingResource(Context context) {
@@ -35,7 +35,7 @@ public class EspressoUITest {
public ActivityScenarioRule<TrackListActivity> mActivityTestRule = new ActivityScenarioRule<>(TrackListActivity.class);
@Rule
public GrantPermissionRule mGrantPermissionRule = GrantPermissionRule.grant("android.permission.ACCESS_FINE_LOCATION");
public GrantPermissionRule mGrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
@LargeTest
@Test
@@ -0,0 +1,40 @@
package de.dennisguse.opentracks;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import de.dennisguse.opentracks.util.PreferencesUtils;
public class PreferenceMetricUnitRule implements TestRule {
private final Context context;
private final boolean metricUnits;
public PreferenceMetricUnitRule(@NonNull Context context, boolean metricUnits) {
this.context = context;
this.metricUnits = metricUnits;
}
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
SharedPreferences sharedPreferences = PreferencesUtils.getSharedPreferences(context);
final boolean previousMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context);
try {
PreferencesUtils.setMetricUnits(sharedPreferences, context, metricUnits);
base.evaluate();
} finally {
PreferencesUtils.setMetricUnits(sharedPreferences, context, previousMetricUnits);
}
}
};
}
}
@@ -193,4 +193,31 @@ public class TrackStatisticsUpdaterTest {
@Test
public void addTrackPoint_speed_from_GPS_moving_and_sensor_speed() {
}
@Test
public void copy_constructor() {
// given
TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
TrackPoint tp4 = new TrackPoint(0.0005, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(4000));
TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
subject.addTrackPoint(tp1, GPS_DISTANCE);
subject.addTrackPoint(tp2, GPS_DISTANCE);
subject.addTrackPoint(tp3, GPS_DISTANCE);
subject.addTrackPoint(tp4, GPS_DISTANCE);
// when
TrackStatisticsUpdater copy = new TrackStatisticsUpdater(subject);
subject.addTrackPoint(tp5, GPS_DISTANCE);
copy.addTrackPoint(tp5, GPS_DISTANCE);
// then
assertEquals(55.287, subject.getTrackStatistics().getTotalDistance().toM(), 0.01);
assertEquals(55.287, copy.getTrackStatistics().getTotalDistance().toM(), 0.01);
}
}
+1
View File
@@ -46,6 +46,7 @@ limitations under the License.
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<application
android:name=".Startup"
@@ -30,8 +30,7 @@ public class Startup extends Application {
// Set default values of preferences on first start.
SharedPreferences sharedPreferences = PreferencesUtils.resetPreferences(this, false);
if (PreferencesUtils.getString(sharedPreferences, this, R.string.stats_units_key, "").equals("")) {
String statsUnits = getString(Locale.US.equals(Locale.getDefault()) ? R.string.stats_units_imperial : R.string.stats_units_metric);
PreferencesUtils.setString(sharedPreferences, this, R.string.stats_units_key, statsUnits);
PreferencesUtils.setMetricUnits(sharedPreferences, this, !Locale.US.equals(Locale.getDefault()));
}
ActivityUtils.applyNightMode(sharedPreferences, this);
@@ -1,5 +1,7 @@
package de.dennisguse.opentracks.content.data;
import de.dennisguse.opentracks.R;
public abstract class Altitude {
private final double altitude_m;
@@ -12,12 +14,18 @@ public abstract class Altitude {
return altitude_m;
}
public abstract int getLabelId();
public static class WGS84 extends Altitude {
private WGS84(double altitude_m) {
super(altitude_m);
}
@Override
public int getLabelId() {
return R.string.wgs84;
}
public static Altitude of(double altitude_m) {
return new WGS84(altitude_m);
@@ -30,6 +38,10 @@ public abstract class Altitude {
super(altitude_m);
}
@Override
public int getLabelId() {
return R.string.egm2008;
}
public static Altitude of(double altitude_m) {
return new EGM2008(altitude_m);
@@ -154,7 +154,9 @@ public class IntervalsFragment extends Fragment {
public void onPause() {
super.onPause();
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
viewModel.onPause();
if (viewModel != null) {
viewModel.onPause();
}
}
@Override
@@ -180,6 +182,7 @@ public class IntervalsFragment extends Fragment {
if (viewModel == null) {
return;
}
viewBinding.intervalRate.setText(isReportSpeed ? getString(R.string.stats_speed) : getString(R.string.stats_pace));
LiveData<List<IntervalStatistics.Interval>> liveData = viewModel.getIntervalStats(trackId, metricUnits, selectedInterval);
liveData.observe(getActivity(), intervalList -> adapter.swapData(intervalList, metricUnits, isReportSpeed));
}
@@ -276,10 +276,18 @@ public class StatisticsRecordingFragment extends Fragment {
if (preferenceShowAltitude) {
// Current altitude
Float altitude = latestTrackPoint != null && latestTrackPoint.hasAltitude() ? (float) latestTrackPoint.getAltitude().toM() : null;
Float altitude = null;
int labelId = R.string.value_unknown;
if (latestTrackPoint != null && latestTrackPoint.hasAltitude()) {
altitude = (float) latestTrackPoint.getAltitude().toM();
labelId = latestTrackPoint.getAltitude().getLabelId();
}
Pair<String, String> parts = StringUtils.formatAltitude(getContext(), altitude, preferenceMetricUnits);
viewBinding.statsAltitudeCurrentValue.setText(parts.first);
viewBinding.statsAltitudeCurrentUnit.setText(parts.second);
viewBinding.statsAltitudeCurrentLabelEgm.setText(labelId);
}
// Set coordinate
@@ -313,7 +321,7 @@ public class StatisticsRecordingFragment extends Fragment {
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, getString(R.string.stats_rate_key));
}
this.latestTrackPoint = recordingData.getLatestTrackPoint();
latestTrackPoint = recordingData.getLatestTrackPoint();
if (latestTrackPoint != null && latestTrackPoint.hasLocation() && !latestTrackPoint.isRecent()) {
latestTrackPoint = null;
}
@@ -36,12 +36,14 @@ import androidx.core.app.TaskStackBuilder;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.TrackListActivity;
import de.dennisguse.opentracks.TrackRecordingActivity;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Track;
@@ -59,6 +61,7 @@ import de.dennisguse.opentracks.services.tasks.PeriodicTaskExecutor;
import de.dennisguse.opentracks.settings.SettingsActivity;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
import de.dennisguse.opentracks.util.EGM2008Utils;
import de.dennisguse.opentracks.util.ExportUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.util.PreferencesUtils;
@@ -128,6 +131,8 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
private BluetoothRemoteSensorManager remoteSensorManager;
private AltitudeSumManager altitudeSumManager;
private EGM2008Utils.EGM2008Correction egm2008Correction;
private TrackStatisticsUpdater trackStatisticsUpdater;
private TrackPoint lastTrackPoint;
private boolean isIdle;
@@ -539,6 +544,8 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
fillWithSensorDataSet(trackPoint);
correctAltitude(trackPoint);
notificationManager.updateTrackPoint(this, track.getTrackStatistics(), trackPoint, recordingGpsAccuracy);
//TODO Figure out how to avoid loading the lastValidTrackPoint from the database
@@ -602,6 +609,25 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
lastTrackPoint = trackPoint;
}
//TODO Identical to TrackDataHub
private void correctAltitude(TrackPoint trackPoint) {
if (!trackPoint.hasLocation() || !trackPoint.hasAltitude()) {
Log.d(TAG, "No altitude correction necessary.");
return;
}
if (egm2008Correction == null || !egm2008Correction.canCorrect(trackPoint.getLocation())) {
try {
egm2008Correction = EGM2008Utils.createCorrection(this, trackPoint.getLocation());
} catch (IOException e) {
Log.e(TAG, "Could not load altitude correction for " + trackPoint, e);
return;
}
}
trackPoint.setAltitude(Altitude.EGM2008.of(egm2008Correction.correctAltitude(trackPoint.getLocation())));
}
@Override
public void newGpsStatus(GpsStatusValue gpsStatusValue) {
notificationManager.updateContent(getString(gpsStatusValue.message));
@@ -652,8 +678,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
recordingDataObservable.postValue(new RecordingData(track, trackPoint, sensorDataSet));
contentProviderUtils.updateTrack(track);
} catch (SQLiteException e) {
/*
@@ -761,12 +785,20 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
//TODO This somehow should happen in the HandlerServer as we create a new TrackPoint.
TrackStatisticsUpdater tmpTrackStatisticsUpdater = new TrackStatisticsUpdater(trackStatisticsUpdater);
TrackPoint tmpLastTrackPoint = new TrackPoint(TrackPoint.Type.TRACKPOINT);
if (lastTrackPoint != null && lastTrackPoint.hasLocation()) {
//TODO Should happen in TrackPoint? via constructor
tmpLastTrackPoint.setSpeed(lastTrackPoint.getSpeed());
tmpLastTrackPoint.setAltitude(lastTrackPoint.getAltitude());
tmpLastTrackPoint.setLongitude(lastTrackPoint.getLongitude());
tmpLastTrackPoint.setLatitude(lastTrackPoint.getLatitude());
}
SensorDataSet sensorDataSet = fillWithSensorDataSet(tmpLastTrackPoint);
tmpTrackStatisticsUpdater.addTrackPoint(tmpLastTrackPoint, recordingDistanceInterval);
track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics());
recordingDataObservable.postValue(new RecordingData(track, tmpLastTrackPoint, sensorDataSet));
}
@@ -25,13 +25,11 @@ import android.util.Log;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.provider.TrackPointIterator;
import de.dennisguse.opentracks.services.TrackRecordingService;
@@ -47,11 +45,6 @@ import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
*/
public class AnnouncementPeriodicTask implements PeriodicTask {
/**
* The rate at which announcements are spoken.
*/
private static final float TTS_SPEECH_RATE = 0.9f;
private static final String TAG = AnnouncementPeriodicTask.class.getSimpleName();
private final Context context;
@@ -213,10 +206,7 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
*/
}
tts.setLanguage(locale);
// Slow down the speed just a bit as it is hard to hear when exercising.
tts.setSpeechRate(TTS_SPEECH_RATE);
tts.setSpeechRate(PreferencesUtils.getVoiceSpeedRate(PreferencesUtils.getSharedPreferences(context), context));
tts.setOnUtteranceProgressListener(utteranceListener);
}
@@ -130,7 +130,8 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
// Used to forward update from ChooseActivityTypeDialogFragment; TODO Could be replaced with LiveData.
private ActivityTypePreference.ActivityPreferenceDialog activityPreferenceDialog;
private Preference voiceAnnouncements;
private Preference announcementsFrequency;
private Preference announcementsSpeed;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -140,7 +141,7 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
ttsInitStatus = status;
Log.i(TAG, "TextToSpeech initialized with status " + status);
if (voiceAnnouncements != null) {
if (announcementsFrequency != null && announcementsSpeed != null) {
updateVoiceAnnouncements();
}
});
@@ -172,7 +173,8 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
return directory != null ? directory.getName() : getString(R.string.not_set);
});
voiceAnnouncements = findPreference(getString(R.string.voice_frequency_key));
announcementsFrequency = findPreference(getString(R.string.voice_frequency_key));
announcementsSpeed = findPreference(getString(R.string.voice_speed_rate_key));
updateVoiceAnnouncements();
}
@@ -232,7 +234,8 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
super.onDestroy();
trackRecordingServiceConnection.unbind(getContext());
sharedPreferences = null;
voiceAnnouncements = null;
announcementsFrequency = null;
announcementsSpeed = null;
tts = null;
}
@@ -323,7 +326,9 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
}
private void updateVoiceAnnouncements() {
voiceAnnouncements.setEnabled(ttsInitStatus == TextToSpeech.SUCCESS);
boolean enabled = ttsInitStatus == TextToSpeech.SUCCESS;
announcementsFrequency.setEnabled(enabled);
announcementsSpeed.setEnabled(enabled);
}
private void onRecordingStatusChanged(TrackRecordingService.RecordingStatus status) {
@@ -68,7 +68,7 @@ public class TrackStatisticsUpdater {
private final DoubleRingBuffer speedBuffer_mps;
// The current segment's statistics
private final TrackStatistics currentSegment = new TrackStatistics();
private final TrackStatistics currentSegment;
// Current segment's last trackPoint
private TrackPoint lastTrackPoint;
// Current segment's last moving trackPoint
@@ -85,6 +85,8 @@ public class TrackStatisticsUpdater {
*/
public TrackStatisticsUpdater(TrackStatistics trackStatistics) {
this.trackStatistics = trackStatistics;
this.currentSegment = new TrackStatistics();
trackInitialized = true;
altitudeBuffer_m = new DoubleRingBuffer(ALTITUDE_SMOOTHING_FACTOR);
@@ -92,6 +94,9 @@ public class TrackStatisticsUpdater {
}
public TrackStatisticsUpdater(TrackStatisticsUpdater toCopy) {
this.currentSegment = new TrackStatistics(toCopy.currentSegment);
this.trackStatistics = new TrackStatistics(toCopy.trackStatistics);
this.trackInitialized = toCopy.trackInitialized;
this.segmentInitialized = toCopy.segmentInitialized;
this.altitudeBuffer_m = new DoubleRingBuffer(toCopy.altitudeBuffer_m);
@@ -99,9 +104,6 @@ public class TrackStatisticsUpdater {
this.lastTrackPoint = toCopy.lastTrackPoint;
this.lastMovingTrackPoint = toCopy.lastMovingTrackPoint;
this.trackStatistics = toCopy.getTrackStatistics();
this.currentSegment.merge(toCopy.currentSegment);
}
public TrackStatistics getTrackStatistics() {
@@ -96,6 +96,22 @@ public class PreferencesUtils {
}
}
private static float getFloat(SharedPreferences sharedPreferences, Context context, int keyId, float defaultValue) {
try {
return sharedPreferences.getFloat(getKey(context, keyId), defaultValue);
} catch (ClassCastException e) {
//Ignore
}
//NOTE: We assume that the data was stored as String due to use of ListPreference.
try {
String stringValue = sharedPreferences.getString(getKey(context, keyId), null);
return Float.parseFloat(stringValue);
} catch (NumberFormatException e) {
return defaultValue;
}
}
public static String getString(SharedPreferences sharedPreferences, Context context, int keyId, String defaultValue) {
return sharedPreferences.getString(getKey(context, keyId), defaultValue);
}
@@ -112,6 +128,16 @@ public class PreferencesUtils {
return STATS_UNIT.equals(getString(sharedPreferences, context, R.string.stats_units_key, STATS_UNIT));
}
public static void setMetricUnits(SharedPreferences sharedPreferences, Context context, boolean metricUnits) {
String unit;
if (metricUnits) {
unit = context.getString(R.string.stats_units_metric);
} else {
unit = context.getString(R.string.stats_units_imperial);
}
setString(sharedPreferences, context, R.string.stats_units_key, unit);
}
public static boolean isReportSpeed(SharedPreferences sharedPreferences, Context context, String category) {
final String STATS_RATE_DEFAULT = context.getString(R.string.stats_rate_default);
String currentStatsRate = getString(sharedPreferences, context, R.string.stats_rate_key, STATS_RATE_DEFAULT);
@@ -181,6 +207,11 @@ public class PreferencesUtils {
return getInt(sharedPreferences, context, R.string.voice_frequency_key, VOICE_FREQUENCY_DEFAULT);
}
public static float getVoiceSpeedRate(SharedPreferences sharedPreferences, Context context) {
final float DEFAULT = Float.parseFloat(context.getResources().getString(R.string.voice_frequency_default));
return getFloat(sharedPreferences, context, R.string.voice_speed_rate_key, DEFAULT);
}
public static Distance getRecordingDistanceInterval(SharedPreferences sharedPreferences, Context context) {
return Distance.of(getInt(sharedPreferences, context, R.string.recording_distance_interval_key, getRecordingDistanceIntervalDefaultInternal(context)));
}
+2 -13
View File
@@ -1,14 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/ic_launcher_background" />
</shape>
</item>
<item>
<inset
android:drawable="@drawable/ic_logo_color_24dp"
android:inset="8dp" />
</item>
</layer-list>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_logo_color_24dp" />
+2 -2
View File
@@ -269,7 +269,7 @@
android:id="@+id/stats_altitude_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="stats_altitude_horizontal_line,stats_altitude_current_label,stats_altitude_current_value,stats_altitude_current_unit,stats_altitude_gain_label,stats_altitude_gain_value,stats_altitude_gain_unit,stats_altitude_loss_label,stats_altitude_loss_value,stats_altitude_loss_unit,stats_elevation_current_label_egm" />
app:constraint_referenced_ids="stats_altitude_horizontal_line,stats_altitude_current_label,stats_altitude_current_value,stats_altitude_current_unit,stats_altitude_gain_label,stats_altitude_gain_value,stats_altitude_gain_unit,stats_altitude_loss_label,stats_altitude_loss_value,stats_altitude_loss_unit,@+id/stats_altitude_current_label_egm" />
<!-- altitude -->
<TextView
@@ -282,7 +282,7 @@
app:layout_constraintTop_toBottomOf="@id/stats_altitude_horizontal_line" />
<TextView
android:id="@+id/stats_elevation_current_label_egm"
android:id="@+id/stats_altitude_current_label_egm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
+2 -2
View File
@@ -360,7 +360,7 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
<string name="share_track_subject">Ich möchte einen Track mit dir teilen</string>
<!-- Stats -->
<string name="stats_average_moving_pace">Durchschnitt\n(Bewegung)</string>
<string name="stats_average_moving_speed">Durchschnittsgeshwindigkeit
<string name="stats_average_moving_speed">Durchschnittsgeschwindigkeit
\n(Bewegung)</string>
<string name="stats_average_pace">Durchschnitt</string>
<string name="stats_average_speed">Durchschnitt</string>
@@ -596,4 +596,4 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
<string name="track_distance_notification">Strecke: %1$s</string>
<string name="track_speed_notification">Geschwindigkeit: %1$s</string>
<string name="track_pace_notification">Tempo: %1$s</string>
</resources>
</resources>
+21 -21
View File
@@ -32,11 +32,11 @@ limitations under the License.
<string name="help_track_map_title">Comment faire apparaître une trace sur une carte ?</string>
<string name="help_track_map_content"> Utilisez la petite icône de carte.
\n a) (mises à jour en direct) Installez <a href="https://github.com/OpenTracksApp/OSMDashboard">OSMDashboard</a>. Il fournit des cartes en ligne ou hors ligne via <a href="https://www.openstreetmap.org ">OpenStreetMap</a>.
\n En fait, OSMDashboard est une application séparée qui ne peut accéder (temporairement) qu aux données des piste(s) qui vont être affichées.
\n En fait, OSMDashboard est une application séparée qui ne peut accéder (temporairement) qu aux données des trace(s) qui vont être affichées.
\n b) Via une application cartographique normale (par exemple) , <a href="http://osmand.net/">OsmAnd</a> et <a href="https://maps.me/">MAPS.ME</a> Ces applications doivent prendre en charge le format de fichier KMZ (uniquement les lieux et les horodatages). En fait, une application doit prendre en charge <i>ACTION_VIEW</i> avec MIME <i>application/vnd.google-earth.kmz</i>. </string>
<string name="help_storage_pictures_title">Comment OpenTracks stocke-t-il les photos qui ont été prises comme marqueurs ?</string>
<string name="help_storage_pictures_content">Elles sont stockées dans le stockage interne de lapplication (c est-à-dire uniquement accessible dans OpenTracks).</string>
<string name="help_track_export_title">Comment puis-je exporter/partager des pistes enregistrées ?</string>
<string name="help_track_export_title">Comment puis-je exporter/partager des traces enregistrées \?</string>
<string name="help_track_export_content"> Les traces peuvent être exportées à partir des paramètres en tant que KMZ, KML ou GPX. KMZ/KML toutes les données ; GPX seulement les emplacements. Les traces partagées via l\'icône <i>partager</i> sont partagées au format KMZ. </string>
<string name="help_data_google_play_services_title">OpenTracks nécessite-t-il/utilise-t-il le service Google Play ?</string>
<string name="help_recording_title">Comment OpenTracks enregistre-t-il les données ?</string>
@@ -136,7 +136,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="description_average_moving_speed">Vitesse moyenne de déplacement : %1$.2f km/h (%2$.1f mi/h)</string>
<string name="description_average_pace_in_minute">Vitesse moyenne : %1$s min/km (%2$s min/mi)</string>
<string name="description_average_speed">Vitesse moyenne : %1$.2f km/h (%2$.1f mi/h)</string>
<string name="description_altitude_gain">Dénivelé : %1$d m (%2$d pi)</string>
<string name="description_altitude_gain">Dénivelé positif : %1$d m (%2$d pi)</string>
<string name="description_altitude_imperial">Altitude (pi)</string>
<string name="description_altitude_metric">Altitude (m)</string>
<string name="description_fastest_pace_in_minute">Vitesse maximale : %1$s min/km (%2$s min/mi)</string>
@@ -276,7 +276,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="menu_stop_gps">Arrêter le GPS</string>
<string name="menu_view_photo">Afficher la photo</string>
<string name="menu_voice_frequency">Fréquence vocale</string>
<string name="menu_resume_track">Reprendre la piste</string>
<string name="menu_resume_track">Reprendre la trace</string>
<!-- OpenTracks -->
<string name="recording_service">Service enregistrement</string>
<!-- Permission -->
@@ -284,7 +284,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<!-- Search -->
<string name="search_global_description">Parcours et repères</string>
<string name="search_list_empty_message">Aucun parcours ni repère ne correspond à votre recherche</string>
<string name="search_list_marker_track_location">Dans la piste « %1$s ».</string>
<string name="search_list_marker_track_location">Dans la trace « %1$s ».</string>
<!-- Sensor State -->
<string name="sensor_state_battery">Niveau de la batterie</string>
<string name="sensor_state_cadence">Cadences</string>
@@ -358,7 +358,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="stats_average_speed">Vitesse moyenne</string>
<string name="stats_altitude">Altitude</string>
<string name="stats_fastest_pace">Allure la plus rapide</string>
<string name="stats_gain">Gagner</string>
<string name="stats_gain">Dénivelé positif</string>
<string name="stats_grade">Inclinaison</string>
<string name="stats_latitude">Latitude</string>
<string name="stats_longitude">Longitude</string>
@@ -384,7 +384,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="track_detail_chart_tab">Graphique</string>
<string name="track_detail_stats_tab">Statistiques</string>
<string name="track_detail_record_success">Enregistrement d\'un nouveau parcours en cours</string>
<string name="track_detail_resume_success">Reprenons maintenant la piste</string>
<string name="track_detail_resume_success">Reprenons maintenant la trace</string>
<!-- Track Edit -->
<string name="track_edit_activity_type">Type d\'activité (exemple : randonnée)</string>
<string name="track_edit_activity_type_hint">Type d\'activité</string>
@@ -536,23 +536,23 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="track_speed_notification">Vitesse : %1$s</string>
<string name="track_detail_intervals_tab">Intervalles</string>
<string name="interval_list_empty_message">Il n\'y a pas encore d\'intervalle</string>
<string name="aggregated_stats_empty_message">Enregistrez votre première piste pour voir les statistiques agrégées</string>
<string name="aggregated_stats_empty_message">Enregistrez votre première trace pour voir les statistiques agrégées</string>
<string name="voice_pace_lap">Temps au tour de %1$s</string>
<string name="voice_speed_lap">Vitesse du tour de %1$s</string>
<string name="toast_message_instant_track_was_exported">Dernière piste exportée</string>
<string name="settings_default_export_uri_title">Répertoire d\'exportation des pistes</string>
<string name="toast_message_instant_track_was_exported">Dernière trace exportée</string>
<string name="settings_default_export_uri_title">Répertoire d\'exportation des traces</string>
<string name="instant_export_enabled_title">Exportation instantanée après l\'entraînement</string>
<string name="stats_intervals">Intervalles</string>
<string name="stats_loss">Perte</string>
<string name="settings_prevent_reimport_tracks_title">Empêcher la réimportation de pistes</string>
<string name="stats_loss">Dénivelé négatif</string>
<string name="settings_prevent_reimport_tracks_title">Empêcher la réimportation de traces</string>
<string name="settings_night_mode_option_night">Nuit</string>
<string name="settings_night_mode_option_day">Jour</string>
<string name="settings_night_mode_option_system">Système</string>
<string name="stats_split_interval">Intervalle partagé</string>
<string name="instant_export_enabled_summary">Exportation de la piste vers le stockage après la fin de l\'enregistrement</string>
<string name="instant_export_enabled_summary">Exportation de la trace vers le stockage après la fin de l\'enregistrement</string>
<string name="hold_to_pause">Tenir pour faire une pause</string>
<string name="hold_to_stop">Maintenir pour arrêter</string>
<string name="track_distance_notification">Distanciation : %1$s</string>
<string name="track_distance_notification">Distance : %1$s</string>
<string name="open_track_as_KMZ">Ouvert comme KMZ</string>
<string name="open_track_as_GPX">Ouvert en tant que GPX</string>
<string name="open_track_as_trackfileformat">Ouvrir comme %1$s</string>
@@ -561,7 +561,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="settings_sensor_wheel_circumference">Circonférence de roue (millimètre)</string>
<string name="export_error_post_workout">L\'exportation du post-travail a échoué, veuillez vérifier le répertoire d\'exportation.</string>
<string name="export_all_do_it_for_all">le faire pour tous les conflits</string>
<string name="export_track_errors">Pistes non exportées</string>
<string name="export_track_errors">Traces non exportées</string>
<string name="import_unable_to_import_file">Impossible d\'importer le fichier : %1$s</string>
<string name="import_no_kml_file_found">Pas de doc.fichier kml trouvé dans KMZ</string>
<string name="import_error_info">%1$s : %2$s</string>
@@ -576,8 +576,8 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="sensor_state_heart_rate_avg">Rythme cardiaque moyen</string>
<string name="sensor_state_cadence_avg">Cadence moyenne</string>
<string name="generic_click_twice_cancel">Cliquez sur retour pour annuler</string>
<string name="export_progress_summary_new_msg">Nouvelles pistes exportées</string>
<string name="export_progress_summary_skip_msg">Pistes sautées</string>
<string name="export_progress_summary_new_msg">Nouvelles traces exportées</string>
<string name="export_progress_summary_skip_msg">Traces ignorées</string>
<string name="export_progress_summary_errors_msg">Erreurs</string>
<string name="generic_overwrite">Écraser</string>
<string name="generic_show_errors">Afficher les erreurs</string>
@@ -590,7 +590,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="import_unsupported_format">Format de fichier non pris en charge</string>
<string name="import_parser_error">Erreur de l\'analyseur : %1$s</string>
<string name="import_file_imported">Fichier %1$s importé</string>
<string name="import_prevent_reimport">Vous avez défini empêcher la réimportation de la piste</string>
<string name="import_prevent_reimport">Vous avez défini empêcher la réimportation de la trace</string>
<string name="import_progress_summary_ok_msg">Les fichiers importés</string>
<string name="import_progress_summary_exists_msg">Il existe déjà</string>
<string name="import_progress_summary_errors_msg">Erreur</string>
@@ -599,9 +599,9 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<item quantity="other">Terminé avec des erreurs %1$d</item>
</plurals>
<string name="settings_default_trackfileformat">Format de fichier d\'exportation / partage</string>
<string name="description_altitude_loss">Perte d\'altitude : %1$d m (%2$d ft)</string>
<string name="export_track_already_exists_msg">La piste %1$s existe déjà dans le répertoire de destination.</string>
<string name="export_progress_summary_overwrite_msg">Pistes écrasées</string>
<string name="description_altitude_loss">Dénivelé négatif : %1$d m (%2$d ft)</string>
<string name="export_track_already_exists_msg">La trace %1$s existe déjà dans le répertoire de destination.</string>
<string name="export_progress_summary_overwrite_msg">Traces écrasées</string>
<string name="about_third_party_data">Données de tiers</string>
<string name="track_delete_progress">%1$d/%2$d</string>
<string name="delete_service">Service de suppression</string>
+3 -3
View File
@@ -34,7 +34,7 @@ limitations under the License.
<string name="help_track_map_title">¿Como mostrar a ruta nun mapa?</string>
<string name="help_track_map_content"> Usa a icona do mapa pequeno.
\n a) (actualizacións en directo) Instala <a href="https://github.com/OpenTracksApp/OSMDashboard"> OSMDashboard </a>. Ofrece mapas en liña ou fóra de liña a través de <a href="https://www.openstreetmap.org"> OpenStreetMap </a>.
\n \u0020En realidade, OSMDashboard é unha aplicación independente que só pode acceder (temporalmente) aos datos das pistas que se amosarán.
\n En realidade, OSMDashboard é unha aplicación independente que só pode acceder (temporalmente) aos datos das pistas que se amosarán.
\n b) A través dunha aplicación de mapa normal (por exemplo, <a href="http://osmand.net/">OsmAnd</a> e <a href="https://maps.me/">MAPS.ME</a>). Estas aplicacións precisan admitir o formato de ficheiro KMZ (só localizacións e marcas de tempo). De feito, unha aplicación ten que admitir <i> ACTION_VIEW </i> con MIME <i>application/vnd.google-earth.kmz</i>. </string>
<string name="help_storage_pictures_title">¿De que xeito garda OpenTracks as fotos tomadas como marcadores?</string>
<string name="help_storage_pictures_content">Gárdanse no almacenaxe interno da app (só accesible desde OpenTracks).</string>
@@ -236,7 +236,7 @@ Se te detés ou estás en interiores, non se gardarán datos do sensor (mais ser
<string name="image_stop">Deter</string>
<string name="image_track">Traxecto</string>
<!-- Import -->
<string name="import_error">Importados: %1$d de %2$s de %3$s</string>
<string name="import_error">Importados: %1$d de %2$s desde %3$s</string>
<string name="import_no_directory">%1$s non existe</string>
<string name="import_no_file">Non hai ficheiros para importar. Conecta o teu dispositivo ao ordenador e coloca os ficheiros para importar en %1$s.</string>
<string name="import_no_file_title">Importar ficheiros</string>
@@ -422,7 +422,7 @@ Se te detés ou estás en interiores, non se gardarán datos do sensor (mais ser
<string name="unit_kilometer_per_hour">km/h</string>
<string name="unit_meter">m</string>
<string name="unit_mile">km</string>
<string name="unit_mile_per_hour">km/h</string>
<string name="unit_mile_per_hour">mph</string>
<string name="unit_minute_per_kilometer">min/km</string>
<string name="unit_minute_per_mile">min/km</string>
<!-- Value -->
+21 -7
View File
@@ -151,8 +151,8 @@
<string name="image_track">Lacak</string>
<string name="import_error">Mengimpor %1$d dari %2$s dari %3$s</string>
<string name="import_no_directory">%1$s tidak ada.</string>
<string name="import_no_file">Tidak ada file untuk diimpor. Hubungkan perangkat ke komputer Anda dan tempatkan file yang akan diimpor di %1$s.</string>
<string name="import_no_file_title">Impor file</string>
<string name="import_no_file">Tidak ada berkas untuk diimpor. Hubungkan perangkat ke komputer Anda dan tempatkan file yang akan diimpor di %1$s.</string>
<string name="import_no_file_title">Impor berkas</string>
<string name="import_progress_message">Mengimpor dari %1$s…</string>
<string name="import_selection_option">Semua %1$s</string>
<string name="import_selection_title">Impor dari penyimpanan external</string>
@@ -160,10 +160,10 @@
<string name="marker_add_error">Tidak dapat memasukkan penanda. Tidak ada sinyal GPS. Coba lagi.</string>
<string name="marker_add_success">Penanda disisipkan.</string>
<string name="marker_add_canceled">Batal, penanda tidak ditambahkan</string>
<string name="marker_delete_all_confirm_message">Semua penanda untuk lintasan ini akan dihapus permanen dari perangkat</string>
<string name="marker_delete_one_confirm_message">Penanda akan dihapus permanen dari perangkat</string>
<string name="marker_delete_all_confirm_message">Semua penanda untuk lintasan ini akan dihapus secara permanen dari perangkat</string>
<string name="marker_delete_one_confirm_message">Penanda akan dihapus secara permanen dari perangkat</string>
<string name="marker_delete_one_confirm_title">Hapus penanda?</string>
<string name="marker_delete_multiple_confirm_message">Penanda yang dipilih akan dihapus permanen dari perangkat</string>
<string name="marker_delete_multiple_confirm_message">Penanda yang dipilih akan dihapus secara permanen dari perangkat</string>
<string name="marker_label_end">%1$s (Akhir)</string>
<string name="marker_label_start">%1$s (Awal)</string>
<string name="marker_name_format">Penanda %1$d</string>
@@ -229,7 +229,7 @@
<string name="settings_recording_track_name_number_option">Angka</string>
<string name="settings_recording_track_name_title">Nama trek default</string>
<string name="settings_reset">Setel ulang</string>
<string name="settings_reset_confirm_message">Semua setelan akan diubah ke nilai default.</string>
<string name="settings_reset_confirm_message">Semua setelan akan diubah ke nilai default. Tiada lintasan yang akan dihapus dari perangkat.</string>
<string name="settings_reset_confirm_title">Setel ulang sekarang?</string>
<string name="settings_reset_done">Semua setelan telah dikembalikan ke nilai default</string>
<string name="settings_sensor">Sensor</string>
@@ -406,4 +406,18 @@
<string name="waypoint_type_waterfall">air terjun</string>
<string name="waypoint_type_water_fountain">air mancur</string>
<string name="waypoint_type_waypoint">titik jalan</string>
</resources>
<string name="settings_night_mode_option_night">Malam</string>
<string name="open_track_as_KMZ">Buka sebagai KMZ</string>
<string name="import_error_list_dialog_title">Berkas tidak diimpor</string>
<string name="import_file_imported">Berkas %1$s telah diimpor</string>
<string name="settings_night_mode_option_day">Siang</string>
<string name="help_support_title">Bagaimana mendukung OpenTracks\?</string>
<string name="import_progress_summary_errors_msg">Kesalahan</string>
<string name="open_track_as_GPX">Buka sebagai GPX</string>
<string name="settings_error_initial_values_restored">Maaf, kesalahan terjadi. Semua setelan telah dikembalikan ke nilai default</string>
<string name="track_speed_notification">Kecepatan: %1$s</string>
<string name="import_unable_to_import_file">Tidak bisa mengimpor berkas: %1$s</string>
<string name="open_track_as_trackfileformat">Buka sebagai %1$s</string>
<string name="track_distance_notification">Jarak: %1$s</string>
<string name="settings_recording_show_on_lockscreen_while_recording_summary">Selama perekaman,</string>
</resources>
+2 -2
View File
@@ -335,7 +335,7 @@ limitations under the License.
<string name="unit_kilometer_per_hour">km/t</string>
<string name="unit_meter">m</string>
<string name="unit_mile">mi</string>
<string name="unit_mile_per_hour">mi/h</string>
<string name="unit_mile_per_hour">mph</string>
<string name="unit_minute_per_kilometer">min/km</string>
<string name="unit_minute_per_mile">min/mi</string>
<!-- Value -->
@@ -393,7 +393,7 @@ limitations under the License.
<string name="voice_speed_miles_per_hour_other">%1$.1f engelske mil i timen</string>
<string name="voice_speed_miles_per_hour_two">2 engelske mil i timen</string>
<string name="voice_speed_miles_per_hour_zero">0 engelske mil i timen</string>
<string name="voice_template">Spor %1$s om %2$s ved %3$s</string>
<string name="voice_template">OpenTracks %1$s på %2$s med %3$s</string>
<string name="voice_total_distance_kilometers_few">total distanse %1$.2f kilometer</string>
<string name="voice_total_distance_kilometers_many">total distanse %1$.2f kilometer</string>
<string name="voice_total_distance_kilometers_one">total distanse 1 kilometer</string>
+1
View File
@@ -18,6 +18,7 @@ limitations under the License.
<string name="app_name" translatable="false">OpenTracks</string>
<string name="egm2008" translatable="false">EGM2008</string>
<string name="wgs84" translatable="false">WGS84</string>
<string name="third_party_data" translatable="false">
<a href="https://earth-info.nga.mil/">National Geospatial-Intelligence Agency (NGA)\'s EGM2008 model</a> 5\' minute resolution.
+11
View File
@@ -238,6 +238,17 @@
<item>-50</item>
<item>-100</item>
</string-array>
<string name="voice_speed_rate_key" translatable="false">voiceSpeedRate</string>
<string name="voice_speed_rate_default" translatable="false">0.9</string>
<string-array name="voice_speed_rate_values">
<item>0.7</item>
<item>0.8</item>
<item>@string/voice_speed_rate_default</item>
<item>1.0</item>
<item>1.1</item>
<item>1.2</item>
<item>1.3</item>
</string-array>
<string name="export_trackfileformat_key" translatable="false">exportTrackFileFormat</string>
<!-- See TrackFileFormat -->
+1
View File
@@ -349,6 +349,7 @@ limitations under the License.
<string name="menu_stop_gps">Stop GPS</string>
<string name="menu_view_photo">View photo</string>
<string name="menu_voice_frequency">Voice frequency</string>
<string name="menu_voice_rate">Voice speed</string>
<string name="menu_resume_track">Resume track</string>
<!-- OpenTracks -->
<string name="recording_service">Recording service</string>
+7
View File
@@ -85,6 +85,13 @@ limitations under the License.
android:key="@string/voice_frequency_key"
android:title="@string/menu_voice_frequency"
app:useSimpleSummaryProvider="true" />
<ListPreference
android:defaultValue="@string/voice_speed_rate_default"
android:entryValues="@array/voice_speed_rate_values"
android:entries="@array/voice_speed_rate_values"
android:key="@string/voice_speed_rate_key"
android:title="@string/menu_voice_rate"
app:useSimpleSummaryProvider="true" />
<de.dennisguse.opentracks.settings.ActivityTypePreference
android:defaultValue="@string/default_activity_default"
android:key="@string/default_activity_key"