Compare commits

...

20 Commits

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Fixes #2108.
2025-06-29 08:30:59 +02:00
30 changed files with 698 additions and 550 deletions
+1
View File
@@ -13,6 +13,7 @@
* Amazfit Neo. But first you have to enable "Discoverable" and "Activity heart rate sharing" in the official Zepp app. (after pairing with OpenTracks you can disable them again)
* Garmin HRM-Dual (Reference: 010-12883-00)
* CYCPLUS H1
* Mojawa Haptifit Terra - all you have to do is connect the app to device called "HT"
## 0x1816: Cycling Cadence and Speed Service
+4 -4
View File
@@ -6,7 +6,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.11.0'
classpath 'com.android.tools.build:gradle:8.11.1'
}
}
@@ -46,8 +46,8 @@ android {
defaultConfig {
applicationId 'de.dennisguse.opentracks'
versionCode 6217
versionName "v4.20.0"
versionCode 6237
versionName "v4.21.1"
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
@@ -150,7 +150,7 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'androidx.core:core:1.16.0'
implementation 'androidx.core:core-splashscreen:1.0.1'
implementation 'androidx.mediarouter:mediarouter:1.8.0'
implementation 'androidx.mediarouter:mediarouter:1.8.1'
implementation 'androidx.core:core-location-altitude:1.0.0-alpha03'
androidTestImplementation 'androidx.test:core:1.6.1'
@@ -0,0 +1,8 @@
v4.20.0: OpenTracks
Změny:
- Umožnění změny časového pásma stop
- Zjednodušené rozhraní značek
Oprava chyby:
- Edge-2-edge: reakce na virtuální klávesnici
@@ -0,0 +1,5 @@
v4.21.0: OpenTracks
Changes:
- Track list supports swipe-to-delete
- Re-implemented themes (for DynamicColor and OLED)
@@ -0,0 +1,4 @@
v4.21.1: OpenTracks
Bugfix:
- Fixed crash on export/import UI (introduced in v4.21.0)
+1 -1
View File
@@ -80,7 +80,7 @@ limitations under the License.
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/OpenTracksTheme">
android:theme="@style/DayNightDynamicTheme"> <!-- Default for AppCompatActivities -->
<activity
android:name=".publicapi.StartRecording"
@@ -37,9 +37,7 @@ public abstract class AbstractActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
if (PreferencesUtils.shouldApplyOledTheme()) {
setTheme(R.style.OpenTracksThemeOled);
}
PreferencesUtils.applyTheme(this);
EdgeToEdge.enable(this);
@@ -43,6 +43,7 @@ public abstract class AbstractTrackDeleteActivity extends AbstractActivity imple
ConfirmDeleteDialogFragment.showDialog(getSupportFragmentManager(), trackIds);
}
//TODO A callback is better.
@Override
public void onConfirmDeleteDone(Track.Id... trackIds) {
ArrayList<Track.Id> trackIdList = Arrays.stream(trackIds)
@@ -6,8 +6,6 @@ import android.content.Context;
import android.os.Build;
import android.util.Log;
import com.google.android.material.color.DynamicColors;
import java.lang.reflect.Method;
import de.dennisguse.opentracks.settings.PreferencesUtils;
@@ -34,11 +32,7 @@ public class Startup extends Application {
// Set default values of preferences on first start.
PreferencesUtils.resetPreferences(this, false);
PreferencesUtils.applyDefaultUnit();
PreferencesUtils.applyNightMode();
if (PreferencesUtils.shouldUseDynamicColors()) {
DynamicColors.applyToActivitiesIfAvailable(this);
}
PreferencesUtils.applyNightModeAndDynamicColors(this);
}
@Override
@@ -34,7 +34,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.button.MaterialButton;
@@ -60,6 +62,7 @@ import de.dennisguse.opentracks.ui.aggregatedStatistics.AggregatedStatisticsActi
import de.dennisguse.opentracks.ui.aggregatedStatistics.ConfirmDeleteDialogFragment;
import de.dennisguse.opentracks.ui.markers.MarkerListActivity;
import de.dennisguse.opentracks.ui.util.ActivityUtils;
import de.dennisguse.opentracks.ui.util.RecyclerViewSwipeDeleteCallback;
import de.dennisguse.opentracks.util.IntentDashboardUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.util.PermissionRequester;
@@ -168,6 +171,13 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
viewBinding.trackList.setLayoutManager(layoutManager);
viewBinding.trackList.setAdapter(adapter);
ItemTouchHelper itemTouchhelper = new ItemTouchHelper(new RecyclerViewSwipeDeleteCallback(this) {
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
TrackListActivity.this.deleteTracks(new Track.Id(viewHolder.getItemId()));
}
});
itemTouchhelper.attachToRecyclerView(viewBinding.trackList);
viewBinding.trackListFabAction.setOnClickListener((view) -> {
if (recordingStatus.isRecording()) {
Toast.makeText(TrackListActivity.this, getString(R.string.hold_to_stop), Toast.LENGTH_LONG).show();
@@ -306,6 +316,12 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
adapter.swapData(tracks);
}
@Override
public void onConfirmDeleteAbort(Track.Id... trackIds) {
// This is not nice, but it will happen rarely (as deletion is not a standard case).
adapter.notifyItemRangeChanged(0, adapter.getItemCount());
}
@Override
protected void onDeleteConfirmed() {
// Do nothing
@@ -17,6 +17,7 @@
package de.dennisguse.opentracks.settings;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
@@ -30,6 +31,8 @@ import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;
import com.google.android.material.color.DynamicColors;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -338,11 +341,6 @@ public class PreferencesUtils {
return getBoolean(R.string.chart_display_heart_rate_key, DEFAULT);
}
public static boolean shouldUseDynamicColors() {
final boolean DEFAULT = resources.getBoolean(R.bool.settings_ui_dynamic_colors_default);
return getBoolean(R.string.settings_ui_dynamic_colors_key, DEFAULT);
}
public static boolean shouldVoiceAnnouncementOnDeviceSpeaker() {
final boolean DEFAULT = resources.getBoolean(R.bool.voice_on_device_speaker_default);
return getBoolean(R.string.voice_on_device_speaker_key, DEFAULT);
@@ -705,7 +703,7 @@ public class PreferencesUtils {
public static TrackFileFormat getExportTrackFileFormat() {
final String TRACKFILEFORMAT_NAME_DEFAULT = getString(R.string.export_trackfileformat_default, null);
String trackFileFormatName = getString(R.string.export_trackfileformat_key, TRACKFILEFORMAT_NAME_DEFAULT);
return Arrays.stream(TrackFileFormat.values())
return Arrays.stream(TrackFileFormat.values())
.filter(format -> format.getPreferenceId().equals(trackFileFormatName))
.findFirst().orElse(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES);
}
@@ -715,30 +713,62 @@ public class PreferencesUtils {
return getBoolean(R.string.import_prevent_reimport_key, defaultValue);
}
/**
* @return * {@link androidx.appcompat.app.AppCompatDelegate}.MODE_*
* * 3: Night OLED friendly
*/
private static String getUiMode() {
final String defaultValue = getKey(R.string.night_mode_default);
final String value = getString(R.string.night_mode_key, defaultValue);
return value;
record ThemeConfig(int themeResourceId, int dayNight, boolean dynamicColor) {
}
public static boolean shouldApplyOledTheme() {
return resources.getString(R.string.night_mode_night_oled_value)
.equals(getUiMode());
private static ThemeConfig getThemeMode() {
final String defaultValue = getKey(R.string.theme_default);
final String value = getString(R.string.theme_key, defaultValue);
switch (value) {
case "0" -> {
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, false);
}
case "1" -> {
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, true);
}
case "2" -> {
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_NO, false);
}
case "3" -> {
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_NO, true);
}
case "4" -> {
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_YES, false);
}
case "5" -> {
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_YES, true);
}
case "6" -> {
return new ThemeConfig(R.style.NightOledColorTheme, AppCompatDelegate.MODE_NIGHT_YES, false);
}
case "7" -> {
return new ThemeConfig(R.style.NightOledDynamicTheme, AppCompatDelegate.MODE_NIGHT_YES, true);
}
default -> {
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, false);
}
}
}
public static void applyTheme(Context context) {
context.setTheme(getThemeMode().themeResourceId());
}
public static void applyNightMode() {
String uiMode = getUiMode();
if (resources.getString(R.string.night_mode_night_oled_value)
.equals(uiMode)) {
return;
}
ThemeConfig themeConfig = getThemeMode();
AppCompatDelegate.setDefaultNightMode(Integer.parseInt(uiMode));
AppCompatDelegate.setDefaultNightMode(themeConfig.dayNight);
}
public static void applyNightModeAndDynamicColors(Application application) {
ThemeConfig themeConfig = getThemeMode();
applyNightMode();
if (application != null && themeConfig.dynamicColor)
DynamicColors.applyToActivitiesIfAvailable(application);
}
public static void resetPreferences(Context context, boolean readAgain) {
@@ -2,7 +2,6 @@ package de.dennisguse.opentracks.settings;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
@@ -15,7 +14,7 @@ import de.dennisguse.opentracks.R;
public class UserInterfaceSettingsFragment extends PreferenceFragmentCompat {
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> {
if (PreferencesUtils.isKey(R.string.night_mode_key, key)) {
if (PreferencesUtils.isKey(R.string.theme_key, key)) {
getActivity().runOnUiThread(() -> {
PreferencesUtils.applyNightMode();
Toast.makeText(getContext(), R.string.settings_theme_switch_restart, Toast.LENGTH_LONG).show();
@@ -33,9 +32,6 @@ public class UserInterfaceSettingsFragment extends PreferenceFragmentCompat {
startActivity(intent);
return true;
});
Preference dynamicColors = findPreference(getString(R.string.settings_ui_dynamic_colors_key));
dynamicColors.setEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU);
}
@Override
@@ -55,6 +55,7 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
this.recyclerView = recyclerView;
this.recordingStatus = recordingStatus;
this.unitSystem = unitSystem;
setHasStableIds(true);
}
public void setActionModeCallback(ActivityUtils.ContextualActionModeCallback actionModeCallback) {
@@ -76,6 +77,12 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
viewHolder.bind(cursor);
}
@Override
public long getItemId(int position) {
cursor.moveToPosition(position);
return cursor.getLong(cursor.getColumnIndexOrThrow(TracksColumns._ID));
}
@Override
public int getItemCount() {
if (cursor == null) {
@@ -234,6 +241,7 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
viewBinding.getRoot().setActivated(isSelected);
}
//TODO Check if this still required.
public long getId() {
return trackId.id();
}
@@ -75,7 +75,8 @@ public class ConfirmDeleteDialogFragment extends DialogFragment {
getActivity(),
titleId,
getString(messageId),
(dialog, which) -> caller.onConfirmDeleteDone(trackIds)
(dialog, which) -> caller.onConfirmDeleteDone(trackIds),
(dialog, which) -> caller.onConfirmDeleteAbort(trackIds)
);
}
@@ -86,6 +87,9 @@ public class ConfirmDeleteDialogFragment extends DialogFragment {
*/
public interface ConfirmDeleteCaller {
default void onConfirmDeleteAbort(Track.Id... trackIds) {
}
void onConfirmDeleteDone(Track.Id... trackIds);
}
}
@@ -71,13 +71,18 @@ public class DeleteMarkerDialogFragment extends DialogFragment {
int titleId = markerIds.length > 1 ? R.string.generic_delete_selected_confirm_title : R.string.marker_delete_one_confirm_title;
int messageId = markerIds.length > 1 ? R.string.marker_delete_multiple_confirm_message : R.string.marker_delete_one_confirm_message;
return DialogUtils.createConfirmationDialog(
fragmentActivity, titleId, getString(messageId), (dialog, which) -> new Thread(() -> {
fragmentActivity, titleId, getString(messageId),
(dialog, which) -> new Thread(() -> {
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(fragmentActivity);
for (Marker.Id markerId : markerIds) {
contentProviderUtils.deleteMarker(context, markerId);
}
caller.onMarkerDeleted();
}).start());
}
).start(),
(dialog, which) -> {
// None
});
}
/**
@@ -42,12 +42,12 @@ public class DialogUtils {
* @param message the message
* @param okListener the listener when OK is clicked
*/
public static Dialog createConfirmationDialog(final Context context, int titleId, String message, DialogInterface.OnClickListener okListener) {
public static Dialog createConfirmationDialog(final Context context, int titleId, String message, DialogInterface.OnClickListener okListener, DialogInterface.OnClickListener cancelListener) {
return new AlertDialog.Builder(context)
.setCancelable(true)
.setIcon(R.drawable.ic_delete_forever_24dp)
.setMessage(message)
.setNegativeButton(android.R.string.cancel, null)
.setNegativeButton(android.R.string.cancel, cancelListener)
.setPositiveButton(android.R.string.ok, okListener)
.setTitle(titleId).create();
}
@@ -7,6 +7,8 @@ import android.util.TypedValue;
import androidx.core.content.ContextCompat;
import com.google.android.material.R;
public class ThemeUtils {
private ThemeUtils() {
@@ -18,7 +20,7 @@ public class ThemeUtils {
public static int getBackgroundColor(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(android.R.attr.colorBackground, typedValue, true);
theme.resolveAttribute(R.attr.colorSurface, typedValue, true);
return ContextCompat.getColor(context, typedValue.resourceId);
}
@@ -26,7 +28,7 @@ public class ThemeUtils {
public static int getTextColorPrimary(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
theme.resolveAttribute(R.attr.colorOnSurface, typedValue, true);
return ContextCompat.getColor(context, typedValue.resourceId);
}
@@ -34,20 +36,20 @@ public class ThemeUtils {
public static int getTextColorSecondary(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
theme.resolveAttribute(R.attr.colorSecondary, typedValue, true);
return ContextCompat.getColor(context, typedValue.resourceId);
}
public static int getFontSizeSmallInPx(Context context) {
TypedArray typedArray = context.obtainStyledAttributes(com.google.android.material.R.style.TextAppearance_MaterialComponents_Body2, new int[]{android.R.attr.textSize});
TypedArray typedArray = context.obtainStyledAttributes(R.style.TextAppearance_MaterialComponents_Body2, new int[]{android.R.attr.textSize});
int fontSize = typedArray.getDimensionPixelSize(0, 12);
typedArray.recycle();
return fontSize;
}
public static int getFontSizeMediumInPx(Context context) {
TypedArray typedArray = context.obtainStyledAttributes(com.google.android.material.R.style.TextAppearance_MaterialComponents_Body1, new int[]{android.R.attr.textSize});
TypedArray typedArray = context.obtainStyledAttributes(R.style.TextAppearance_MaterialComponents_Body1, new int[]{android.R.attr.textSize});
int fontSize = typedArray.getDimensionPixelSize(0, 15);
typedArray.recycle();
return fontSize;
+2 -3
View File
@@ -1,7 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="108"
android:viewportHeight="108">
<group
@@ -10,7 +9,7 @@
android:translateX="22"
android:translateY="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M82.489,12.834C83.196,10.418 82.043,9.556 79.926,10.917L10.087,55.828c-2.117,1.361 -1.795,2.628 0.714,2.815L39.806,60.807c2.51,0.188 5.291,2.267 6.18,4.621l10.282,27.208c0.89,2.354 2.195,2.304 2.902,-0.111z" />
android:pathData="M85.133,20.59C85.731,18.546 84.756,17.817 82.965,18.968L23.874,56.967c-1.791,1.152 -1.519,2.224 0.604,2.382L49.019,61.18c2.124,0.159 4.477,1.918 5.229,3.91l8.7,23.021c0.753,1.992 1.857,1.949 2.455,-0.094z"
android:fillColor="#FFFFFF"></path>
</group>
</vector>
+2
View File
@@ -546,4 +546,6 @@
<string name="settings_recording_show_gps_disabled_warning_summary">Durante l’arregistramentu, un avertimentu hè affissatu s’è u GPS hè disattivatu.</string>
<string name="empty">viotu</string>
<string name="track_edit_time_offset">Sfarenza di u fusu orariu</string>
<string name="marker_detail_title">%1$d nant’à %2$d : %3$s</string>
<string name="stats_coordinates">Latitudine/Lungitudine</string>
</resources>
+1
View File
@@ -599,4 +599,5 @@ limitations under the License.
<string name="settings_recording_show_gps_disabled_warning_title">Varování o vypnuté poloze</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Během nahrávání zobrazit varování, pokud je vypnutá poloha.</string>
<string name="track_edit_time_offset">Posunutí časového pásma</string>
<string name="marker_detail_title">%1$d z %2$d: %3$s</string>
</resources>
+2
View File
@@ -671,4 +671,6 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
<string name="settings_recording_show_gps_disabled_warning_title">Alerte GPS désactivée</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Pendant l\'enregistrement, afficher un avertissement si le GPS est désactivé.</string>
<string name="empty">vide</string>
<string name="marker_detail_title">%1$d de %2$d: %3$s</string>
<string name="track_edit_time_offset">Décalage de fuseau horaire</string>
</resources>
+3
View File
@@ -598,4 +598,7 @@ Se o GPS informa sobre datos pouco precisos (ex.: localización, velocidade, ele
<string name="settings_charts_title">Gráficos</string>
<string name="settings_recording_show_gps_disabled_warning_title">Aviso do GPS desactivado</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Ao gravar, mostrar aviso se o GPS está desactivado.</string>
<string name="empty">baleiro</string>
<string name="marker_detail_title">%1$d de %2$d: %3$s</string>
<string name="track_edit_time_offset">Diferenza de Zona horaria</string>
</resources>
+1
View File
@@ -594,4 +594,5 @@ limitations under the License.
<string name="settings_recording_show_gps_disabled_warning_title">GPS letiltott figyelmeztetés</string>
<string name="settings_recording_show_gps_disabled_warning_summary">Felvétel közben egy figyelmeztetés jelenik meg, ha a GPS ki van kapcsolva.</string>
<string name="track_edit_time_offset">Időzóna eltolódás</string>
<string name="marker_detail_title">%1$d %2$d-ból/ből %3$s</string>
</resources>
@@ -1,38 +0,0 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="OpenTracksTheme" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Material3 tech documentation; https://github.com/material-components/material-components-android/blob/master/docs/components/ -->
<item name="colorPrimary">@color/opentracks</item>
<item name="colorSecondary">@color/opentracks</item>
<!-- Material3 https://github.com/material-components/material-components-android/issues/2828#issuecomment-1187563903 -->
<item name="switchPreferenceCompatStyle">@style/MaterialSwitchPreferenceCompat</item>
<item name="android:statusBarColor">@color/oled_friendly</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:navigationBarColor">@color/oled_friendly</item>
<item name="bottomAppBarStyle">@style/Widget.OpenTracks.BottomAppBar</item>
<item name="floatingActionButtonStyle">@style/Widget.OpenTracks.FloatingActionButton</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="SplashTheme" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_logo_color_108dp</item>
<item name="postSplashScreenTheme">@style/OpenTracksTheme</item>
</style>
<style name="Widget.OpenTracks.BottomAppBar" parent="Widget.Material3.BottomAppBar">
<item name="materialThemeOverlay">@style/ThemeOverlay.OpenTracks.BottomAppBar</item>
</style>
<style name="ThemeOverlay.OpenTracks.BottomAppBar" parent="">
<item name="colorPrimary">@color/oled_friendly</item>
</style>
</resources>
File diff suppressed because it is too large Load Diff
+24 -12
View File
@@ -270,8 +270,7 @@
<!-- User Interface Settings -->
<string name="settings_ui_dynamic_colors_key" translatable="false">uiDynamicColors</string>
<bool name="settings_ui_dynamic_colors_default" translatable="false">false</bool>
<string name="deleted20250703" translatable="false">uiDynamicColors</string> <!-- DELETED -->
<!-- Recording Settings -->
<string name="stats_show_on_lockscreen_while_recording_key" translatable="false">trackdetail_show_on_lockscreen_while_recording</string>
@@ -301,23 +300,36 @@
<string name="locale_key" translatable="false">localeKey</string>
<!-- androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode() -->
<string name="night_mode_key" translatable="false">nightMode</string>
<string name="night_mode_default" translatable="false">@string/night_mode_system_value</string>
<string name="night_mode_no_value" translatable="false">1</string>
<string name="night_mode_yes_value" translatable="false">2</string>
<string name="night_mode_night_oled_value" translatable="false">3</string>
<string name="night_mode_system_value" translatable="false">-1</string>
<string name="theme_key" translatable="false">nightMode</string>
<string name="theme_default" translatable="false">@string/theme_daynight_value</string>
<string name="theme_daynight_value" translatable="false">0</string>
<string name="theme_daynight_dynamic_value" translatable="false">1</string>
<string name="theme_day_value" translatable="false">2</string>
<string name="theme_day_dynamic_value" translatable="false">3</string>
<string name="theme_night_value" translatable="false">4</string>
<string name="theme_night_dynamic_value" translatable="false">5</string>
<string name="theme_oled_value" translatable="false">6</string>
<string name="theme_oled_dynamic_value" translatable="false">7</string>
<string-array name="night_mode_values">
<item>@string/night_mode_system_value</item>
<item>@string/night_mode_no_value</item>
<item>@string/night_mode_yes_value</item>
<item>@string/night_mode_night_oled_value</item>
<item>@string/theme_daynight_value</item>
<item>@string/theme_daynight_dynamic_value</item>
<item>@string/theme_day_value</item>
<item>@string/theme_day_dynamic_value</item>
<item>@string/theme_night_value</item>
<item>@string/theme_night_dynamic_value</item>
<item>@string/theme_oled_value</item>
<item>@string/theme_oled_dynamic_value</item>
</string-array>
<string-array name="night_mode_options">
<!-- TODO: rename night_mode to theme and night_oled to oled -->
<item>@string/settings_night_mode_option_system</item>
<item>@string/settings_night_mode_option_system_dynamic</item>
<item>@string/settings_night_mode_option_day</item>
<item>@string/settings_night_mode_option_day_dynamic</item>
<item>@string/settings_night_mode_option_night</item>
<item>@string/settings_night_mode_option_night_dynamic</item>
<item>@string/settings_night_mode_option_night_oled</item>
<item>@string/settings_night_mode_option_night_oled_dynamic</item>
</string-array>
<!-- Stats layout customization -->
+5 -1
View File
@@ -380,9 +380,13 @@ limitations under the License.
<string name="settings_locale_system_default">System default</string>
<string name="settings_night_mode_title">UI Theme</string>
<string name="settings_night_mode_option_system">System</string>
<string name="settings_night_mode_option_system_dynamic">System (DynamicColor)</string>
<string name="settings_night_mode_option_day">Day</string>
<string name="settings_night_mode_option_day_dynamic">Day (DynamicColor)</string>
<string name="settings_night_mode_option_night">Night</string>
<string name="settings_night_mode_option_night_oled">Night (OLED friendly)</string>
<string name="settings_night_mode_option_night_dynamic">Night (DynamicColor)</string>
<string name="settings_night_mode_option_night_oled">OLED friendly</string>
<string name="settings_night_mode_option_night_oled_dynamic">OLED friendly (DynamicColor)</string>
<string name="settings_announcements_totaltime_frequency">Time interval</string>
<string name="settings_announcements_distance_frequency">Lap length</string>
<string name="settings_announcements_average_heart_rate">Average heart rate</string>
+26 -23
View File
@@ -1,10 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="OpenTracksTheme" parent="Theme.Material3.DayNight.NoActionBar">
<item name="colorPrimary">@color/opentracks</item>
<item name="colorSecondary">@color/opentracks</item>
<style name="DayNightDynamicTheme" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Material3 https://github.com/material-components/material-components-android/issues/2828#issuecomment-1187563903 -->
<item name="switchPreferenceCompatStyle">@style/MaterialSwitchPreferenceCompat</item>
@@ -17,28 +14,18 @@
<item name="windowActionModeOverlay">true</item>
<item name="bottomAppBarStyle">@style/Widget.OpenTracks.BottomAppBar</item>
<item name="android:statusBarColor">?attr/colorSurfaceBright</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:navigationBarColor">?attr/colorSurfaceContainer</item>
<!-- Material3-related: otherwise the actionbar does not overlay the SearchBar completely (with AppBarLayout) -->
<item name="actionBarSize">88dp</item>
</style>
<style name="SplashTheme" parent="Theme.SplashScreen">
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_logo_color_108dp</item>
<item name="postSplashScreenTheme">@style/OpenTracksTheme</item>
</style>
<style name="Widget.OpenTracks.BottomAppBar" parent="Widget.Material3.BottomAppBar">
<item name="backgroundTint">?attr/colorSurfaceContainer</item>
</style>
<style name="OpenTracksThemeOled" parent="Theme.Material3.Dark.NoActionBar">
<style name="DayNightColorTheme" parent="DayNightDynamicTheme">
<item name="colorPrimary">@color/opentracks</item>
<item name="colorSecondary">@color/opentracks</item>
</style>
<style name="NightOledDynamicTheme" parent="Theme.Material3.Dark.NoActionBar">
<!-- Material3 https://github.com/material-components/material-components-android/issues/2828#issuecomment-1187563903 -->
<item name="switchPreferenceCompatStyle">@style/MaterialSwitchPreferenceCompat</item>
@@ -54,16 +41,32 @@
<!-- Differences to OpenTracksTheme -->
<item name="bottomAppBarStyle">@style/Widget.OpenTracks.BottomAppBarOled</item>
<item name="android:statusBarColor">@android:color/black</item>
<item name="android:statusBarColor">@color/oled_friendly</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:navigationBarColor">@android:color/black</item>
<item name="android:navigationBarColor">@color/oled_friendly</item>
<item name="colorSurface">@android:color/black</item>
<item name="colorSurfaceContainer">@android:color/black</item>
<item name="android:windowBackground">@android:color/black</item>
<item name="colorSurface">@color/oled_friendly</item>
<item name="colorSurfaceContainer">@color/oled_friendly</item>
<item name="colorSurfaceDim">@color/oled_friendly</item>
<item name="backgroundColor">@color/oled_friendly</item>
<item name="android:windowBackground">@color/oled_friendly</item>
<!-- Material3-related: otherwise the actionbar does not overlay the SearchBar completely (with AppBarLayout) -->
<item name="actionBarSize">88dp</item>
</style>
<style name="NightOledColorTheme" parent="NightOledDynamicTheme">
<item name="colorPrimary">@color/opentracks</item>
<item name="colorSecondary">@color/opentracks</item>
</style>
<style name="Widget.OpenTracks.BottomAppBarOled" parent="Widget.Material3.BottomAppBar">
<item name="backgroundTint">@android:color/transparent</item>
<item name="elevation">0dp</item>
</style>
<style name="SplashTheme" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_logo_color_108dp</item>
<item name="postSplashScreenTheme">@style/DayNightColorTheme</item>
</style>
</resources>
+2 -8
View File
@@ -11,19 +11,13 @@
app:useSimpleSummaryProvider="true" />
<ListPreference
android:defaultValue="@string/night_mode_default"
android:defaultValue="@string/theme_default"
android:entries="@array/night_mode_options"
android:entryValues="@array/night_mode_values"
android:key="@string/night_mode_key"
android:key="@string/theme_key"
android:title="@string/settings_night_mode_title"
app:useSimpleSummaryProvider="true" />
<SwitchPreferenceCompat
android:defaultValue="@bool/settings_ui_dynamic_colors_default"
android:key="@string/settings_ui_dynamic_colors_key"
android:summary="@string/settings_ui_dynamic_colors_summary"
android:title="@string/settings_ui_dynamic_colors_title" />
<PreferenceCategory app:title="@string/settings_recording_title">
<Preference
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_logo_108dp" />
<monochrome android:drawable="@drawable/ic_logo_108dp" />
</adaptive-icon>