Compare commits

..

19 Commits

Author SHA1 Message Date
Dennis Guse c0b84c3d72 Release: v4.3.0 2023-03-09 05:20:22 +01:00
Miguel Almeida e275d3e5c0 Enable backups if client side encryption is enabled 2023-03-08 23:12:26 +01:00
Dennis Guse b4ebad2c3c Merge remote-tracking branch 'weblate/main' 2023-03-07 21:25:56 +01:00
dependabot[bot] 1ab76e1317 Bump com.android.tools.build:gradle from 7.4.1 to 7.4.2
Bumps com.android.tools.build:gradle from 7.4.1 to 7.4.2.

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 06:04:48 -05:00
nobkd 3d1104dd0b remove typo 2023-02-17 10:44:41 -05:00
dependabot[bot] 2df45d31de Bump androidx.appcompat:appcompat from 1.6.0 to 1.6.1
Bumps androidx.appcompat:appcompat from 1.6.0 to 1.6.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-12 14:06:47 +01:00
Allan Nordhøy 5436981e0d Translated using Weblate (Norwegian Bokmål)
Currently translated at 97.4% (492 of 505 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/nb_NO/
2023-02-10 07:38:30 +01:00
dependabot[bot] fd2b1bec7d Bump com.android.tools:desugar_jdk_libs from 2.0.1 to 2.0.2
Bumps [com.android.tools:desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 2.0.1 to 2.0.2.
- [Release notes](https://github.com/google/desugar_jdk_libs/releases)
- [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/desugar_jdk_libs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-06 12:18:53 +01:00
elastic rock bb1eaa5b56 Android system per-app language preferences 2023-02-05 00:58:21 +01:00
Peter Storch dae8eaa97a Release: v4.2.2 2023-02-04 21:53:35 +01:00
Peter Storch 565b1ce94d Correct link to F-Droid build monitor 2023-02-04 21:53:24 +01:00
dependabot[bot] 543d5e18bf Bump com.android.tools:desugar_jdk_libs from 2.0.0 to 2.0.1
Bumps [com.android.tools:desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/google/desugar_jdk_libs/releases)
- [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/desugar_jdk_libs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-03 05:05:29 +01:00
dependabot[bot] 01368df6b1 Bump com.android.tools.build:gradle from 7.4.0 to 7.4.1
Bumps com.android.tools.build:gradle from 7.4.0 to 7.4.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-02 07:03:02 +01:00
Dennis Guse c666d55211 Bug: crash due to color not found.
Introduced in 674d231b7a
2023-01-30 23:11:21 +01:00
Dennis Guse 8cc4fd1d4f Bugfix: not all activityTypes were shown in dropdownlist. 2023-01-29 16:50:04 +01:00
Dennis Guse c241a35861 Refactor: introduced ActivityType. 2023-01-29 16:50:04 +01:00
Dennis Guse 674d231b7a Bug: textcolor for heartrate zone 1 was ignoring theme.
Fixes #1455.
2023-01-27 02:00:38 +01:00
Dennis Guse bebee59eb2 Bug: Track icon wrongly shown in dialog.
Fixes #1453.
2023-01-25 16:37:35 +01:00
dependabot[bot] 24f843b0db Bump material from 1.7.0 to 1.8.0
Bumps [material](https://github.com/material-components/material-components-android) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/material-components/material-components-android/releases)
- [Commits](https://github.com/material-components/material-components-android/compare/1.7.0...1.8.0)

---
updated-dependencies:
- dependency-name: com.google.android.material:material
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-25 07:04:21 +01:00
19 changed files with 244 additions and 290 deletions
+1 -1
View File
@@ -150,7 +150,7 @@ The developer documentation is in [README_API.md](README_API.md).
## Project history
_OpenTracks_ is based upon Google _My Tracks app_ ([code](https://code.google.com/archive/p/mytracks/)).
Initially, _My Tracks_ was initially released by Google in 2010 as [open-source software](http://google-latlong.blogspot.fr/2010/05/code-for-my-tracks-is-now-yours.html).
_My Tracks_ was initially released by Google in 2010 as [open-source software](http://google-latlong.blogspot.fr/2010/05/code-for-my-tracks-is-now-yours.html).
In 2016, [Google decided to discontinue](https://support.google.com/maps/answer/6333516) _My Tracks_ and stopped distributing it via the Google Play store in April 2016.
Then [Plonk42](https://github.com/plonk42) conducted some maintenance work until 2016, so _My Tracks_ could still be used (based upon version _Google's MyTracks_ version 2.0.6).
Plonk42's version is available [here](https://github.com/Plonk42/mytracks).
+1 -1
View File
@@ -17,7 +17,7 @@ Application id: de.dennisguse.opentracks
It if it properly tagged F-Droid takes care of building the app and publishing.
Usually, it takes two days before the update is published (build, signed, and published).
The recent build activity can be found [here](https://f-droid.org/wiki/index.php?title=Special:RecentChanges&days=7&from=&hidebots=0&hideanons=1&hideliu=1&limit=500)
The recent build activity can be found [here](https://monitor.f-droid.org/builds/build)
## Google Play Store
Application id: `de.dennisguse.opentracks.playstore`
+8 -6
View File
@@ -6,7 +6,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.0'
classpath 'com.android.tools.build:gradle:7.4.2'
}
}
@@ -59,8 +59,8 @@ android {
defaultConfig {
applicationId "de.dennisguse.opentracks"
versionCode 5132
versionName "v4.2.1"
versionCode 5151
versionName "v4.3.0"
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
@@ -69,6 +69,8 @@ android {
testInstrumentationRunner "de.dennisguse.opentracks.TestRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
resConfigs "ar", "bg", "ca", "cs", "da", "de", "el", "en", "es", "et", "eu", "fa", "fi", "fr", "ga", "gl", "hi", "hr", "hu", "in", "it", "iw", "ja", "ko", "lt", "lv", "mo", "ms", "nb", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tl", "tr", "uk", "vi", "zh"
}
signingConfigs {
nightly {
@@ -120,13 +122,13 @@ android {
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.preference:preference:1.2.0'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.core:core-splashscreen:1.0.0'
@@ -0,0 +1,9 @@
v4.2.2: OpenTracks
Bugfix:
- Track icon wrongly shown in dialog
- Textcolor for heartrate zone 1 was ignoring theme
- Not all activityTypes were shown in dropdownlist
- Crash due to color not found
@@ -0,0 +1,5 @@
v4.3.0: OpenTracks
Changes:
- Allow backups (incl. encrypted to the Google)
- Android 13: allow app-specific language settings
+5 -2
View File
@@ -62,13 +62,16 @@ limitations under the License.
<application
android:name=".Startup"
android:allowBackup="false"
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules_30_lower"
android:dataExtractionRules="@xml/backup_rules_31_higher"
android:hardwareAccelerated="true"
android:hasFragileUserData="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/ThemeCustom">
android:theme="@style/ThemeCustom"
android:localeConfig="@xml/locales_config">
<activity
android:name=".publicapi.StartRecording"
@@ -24,6 +24,7 @@ import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.databinding.TrackEditBinding;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
@@ -75,7 +76,7 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
viewBinding.fields.trackEditActivityType.setText(track.getCategory());
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, ActivityType.getLocalizedStrings(this));
viewBinding.fields.trackEditActivityType.setAdapter(adapter);
viewBinding.fields.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> setActivityTypeIcon(TrackIconUtils.getIconValue(this, (String) viewBinding.fields.trackEditActivityType.getAdapter().getItem(position))));
viewBinding.fields.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> {
@@ -8,6 +8,7 @@ import android.view.View;
import android.widget.ArrayAdapter;
import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.DistanceFormatter;
import de.dennisguse.opentracks.data.models.SpeedFormatter;
import de.dennisguse.opentracks.data.models.Track;
@@ -51,7 +52,7 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements
viewBinding.trackEditActivityType.setText(track.getCategory());
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, ActivityType.getLocalizedStrings(this));
viewBinding.trackEditActivityType.setAdapter(adapter);
viewBinding.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> setActivityTypeIcon(TrackIconUtils.getIconValue(this, (String) viewBinding.trackEditActivityType.getAdapter().getItem(position))));
viewBinding.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> {
@@ -0,0 +1,79 @@
package de.dennisguse.opentracks.data.models;
import android.content.Context;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import de.dennisguse.opentracks.R;
public enum ActivityType {
AIRPLANE("AIRPLANE", R.drawable.ic_activity_flight_24dp, true, R.string.activity_type_airplane, R.string.activity_type_commercial_airplane, R.string.activity_type_rc_airplane),
BIKE("BIKE", R.drawable.ic_activity_bike_24dp, true, R.string.activity_type_biking, R.string.activity_type_cycling, R.string.activity_type_dirt_bike, R.string.activity_type_road_biking, R.string.activity_type_track_cycling),
MOUNTAIN_BIKE("MOUNTAIN_BIKE", R.drawable.ic_activity_mtb_24dp, true, R.string.activity_type_mountain_biking),
MOTOR_BIKE("MOTOR_BIKE", R.drawable.ic_activity_motorbike_24dp, true, R.string.activity_type_motor_bike),
KAYAK("KAYAK", R.drawable.ic_activity_kayaking_24dp, true, R.string.activity_type_kayaking),
BOAT("BOAT", R.drawable.ic_activity_boat_24dp, true, R.string.activity_type_boat, R.string.activity_type_ferry, R.string.activity_type_motor_boating, R.string.activity_type_rc_boat),
SAILING("SAILING", R.drawable.ic_activity_sailing_24dp, true, R.string.activity_type_sailing),
DRIVE("DRIVE", R.drawable.ic_activity_drive_24dp, true, R.string.activity_type_atv, R.string.activity_type_driving, R.string.activity_type_driving_bus, R.string.activity_type_driving_car),
RUN("RUN", R.drawable.ic_activity_run_24dp, false, R.string.activity_type_running, R.string.activity_type_street_running, R.string.activity_type_track_running, R.string.activity_type_trail_running),
SKI("SKI", R.drawable.ic_activity_skiing_24dp, true, R.string.activity_type_cross_country_skiing, R.string.activity_type_skiing),
SNOW_BOARDING("SNOW_BOARDING", R.drawable.ic_activity_snowboarding_24dp, true, R.string.activity_type_snow_boarding),
UNKNOWN("UNKNOWN", R.drawable.ic_logo_24dp, true, R.string.activity_type_unknown),
WALK("WALK", R.drawable.ic_activity_walk_24dp, false, R.string.activity_type_hiking, R.string.activity_type_off_trail_hiking, R.string.activity_type_speed_walking, R.string.activity_type_trail_hiking, R.string.activity_type_walking),
ESCOOTER("ESCOOTER", R.drawable.ic_activity_escooter_24dp, true, R.string.activity_type_escooter),
INLINE_SKATING("INLINES_SKATING", R.drawable.ic_activity_inline_skating_24dp, true, R.string.activity_type_inline_skating),
SKATE_BOARDING("SKATE_BOARDING", R.drawable.ic_activity_skateboarding_24dp, true, R.string.activity_type_skate_boarding),
CLIMBING("CLIMBING", R.drawable.ic_activity_climbing_24dp, false, R.string.activity_type_climbing),
SWIMMING("SWIMMING", R.drawable.ic_activity_swimming_24dp, false, R.string.activity_type_swimming),
SWIMMING_OPEN("SWIMMING_OPEN", R.drawable.ic_activity_swimming_open_24dp, false, R.string.activity_type_swimming_open),
WORKOUT("WORKOUT", R.drawable.ic_activity_workout_24dp, false, R.string.activity_type_workout);
final String id;
final int iconId;
final boolean showSpeedPreferred;
final int[] localizedStringIds;
//isSpeed?
ActivityType(String id, int iconId, boolean showSpeedPreferred, int... localizedStringIds) {
this.id = id;
this.iconId = iconId;
this.showSpeedPreferred = showSpeedPreferred;
this.localizedStringIds = localizedStringIds;
}
public String getId() {
return id;
}
public int getIconId() {
return iconId;
}
public boolean isShowSpeedPreferred() {
return showSpeedPreferred;
}
public int[] getLocalizedStringIds() {
return localizedStringIds;
}
public int getFirstLocalizedStringId() {
return localizedStringIds[0];
}
public static List<String> getLocalizedStrings(Context context) {
List<String> result = new ArrayList<>();
for (ActivityType activityType : values()) {
List<String> strings = Arrays.stream(activityType.localizedStringIds)
.mapToObj(context::getString)
.collect(Collectors.toList());
result.addAll(strings);
}
return result;
}
}
@@ -1,8 +1,12 @@
package de.dennisguse.opentracks.data.models;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.ui.util.ThemeUtils;
public class HeartRateZones {
@@ -12,22 +16,23 @@ public class HeartRateZones {
this.max = max;
}
public int getColorForZone(HeartRate current) {
public int getTextColorForZone(Context context, HeartRate current) {
if (current != null) {
if (current.getBPM() >= max.getBPM() * 0.9) {
return R.color.heart_rate_zone_textcolor_5;
return ContextCompat.getColor(context, R.color.heart_rate_zone_textcolor_5);
}
if (current.getBPM() >= max.getBPM() * 0.8) {
return R.color.heart_rate_zone_textcolor_4;
return ContextCompat.getColor(context, R.color.heart_rate_zone_textcolor_4);
}
if (current.getBPM() >= max.getBPM() * 0.7) {
return R.color.heart_rate_zone_textcolor_3;
return ContextCompat.getColor(context, R.color.heart_rate_zone_textcolor_3);
}
if (current.getBPM() >= max.getBPM() * 0.6) {
return R.color.heart_rate_zone_textcolor_2;
return ContextCompat.getColor(context, R.color.heart_rate_zone_textcolor_2);
}
}
return R.color.heart_rate_zone_textcolor_1;
// Zone 1
return ThemeUtils.getTextColorPrimary(context);
}
}
@@ -28,6 +28,7 @@ import androidx.preference.DialogPreference;
import androidx.preference.PreferenceDialogFragmentCompat;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
import de.dennisguse.opentracks.util.TrackIconUtils;
@@ -79,7 +80,7 @@ public class ActivityTypePreference extends DialogPreference {
textView = view.findViewById(R.id.activity_type_preference_text_view);
String category = PreferencesUtils.getDefaultActivity();
textView.setText(category);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
ArrayAdapter<String> adapter = new ArrayAdapter<>(context, android.R.layout.simple_dropdown_item_1line, ActivityType.getLocalizedStrings(context));
textView.setAdapter(adapter);
textView.setOnItemClickListener((parent, v, position, id) -> {
String iconValue = TrackIconUtils.getIconValue(context, (String) textView.getAdapter().getItem(position));
@@ -18,15 +18,15 @@ package de.dennisguse.opentracks.util;
import android.content.Context;
import android.content.res.Resources;
import android.util.Pair;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.models.ActivityType;
/**
* Utilities for track icon.
@@ -35,219 +35,71 @@ import de.dennisguse.opentracks.R;
*/
public class TrackIconUtils {
private static final String AIRPLANE = "AIRPLANE";
private static final String BIKE = "BIKE";
private static final String MOUNTAIN_BIKE = "MOUNTAIN_BIKE";
private static final String MOTOR_BIKE = "MOTOR_BIKE";
private static final String KAYAK = "KAYAK";
private static final String BOAT = "BOAT";
private static final String SAILING = "SAILING";
private static final String DRIVE = "DRIVE";
private static final String RUN = "RUN";
private static final String SKI = "SKI";
private static final String SNOW_BOARDING = "SNOW_BOARDING";
private static final String UNKNOWN = "UNKNOWN";
private static final String WALK = "WALK";
private static final String ESCOOTER = "ESCOOTER";
private static final String INLINE_SKATING = "INLINES_SKATING";
private static final String SKATE_BOARDING = "SKATE_BOARDING";
private static final String CLIMBING = "CLIMBING";
private static final String SWIMMING = "SWIMMING";
private static final String SWIMMING_OPEN = "SWIMMING_OPEN";
private static final String WORKOUT = "WORKOUT";
public static int getIconDrawable(String activityTypeId) {
Optional<ActivityType> found = Arrays.stream(ActivityType.values()).filter(
it -> it.getId().equals(activityTypeId)
).findFirst();
private static final int ACTIVITY_UNKNOWN_LOGO = R.drawable.ic_logo_24dp;
private static final int[] AIRPLANE_LIST = new int[]{R.string.activity_type_airplane, R.string.activity_type_commercial_airplane, R.string.activity_type_rc_airplane};
private static final int[] BIKE_LIST = new int[]{R.string.activity_type_biking, R.string.activity_type_cycling, R.string.activity_type_dirt_bike, R.string.activity_type_road_biking, R.string.activity_type_track_cycling};
private static final int[] BOAT_LIST = new int[]{R.string.activity_type_boat, R.string.activity_type_ferry, R.string.activity_type_motor_boating, R.string.activity_type_rc_boat};
private static final int[] CLIMBING_LIST = new int[]{R.string.activity_type_climbing};
private static final int[] DRIVE_LIST = new int[]{R.string.activity_type_atv, R.string.activity_type_driving, R.string.activity_type_driving_bus, R.string.activity_type_driving_car};
private static final int[] MOTOR_BIKE_LIST = new int[]{R.string.activity_type_motor_bike};
private static final int[] MOUNTAIN_BIKE_LIST = new int[]{R.string.activity_type_mountain_biking};
private static final int[] ESCOOTER_LIST = new int[]{R.string.activity_type_escooter};
private static final int[] INLINE_SKATING_LIST = new int[]{R.string.activity_type_inline_skating};
private static final int[] RUN_LIST = new int[]{R.string.activity_type_running, R.string.activity_type_street_running, R.string.activity_type_track_running, R.string.activity_type_trail_running};
private static final int[] SAILING_LIST = new int[]{R.string.activity_type_sailing};
private static final int[] SKI_LIST = new int[]{R.string.activity_type_cross_country_skiing, R.string.activity_type_skiing};
private static final int[] SNOW_BOARDING_LIST = new int[]{R.string.activity_type_snow_boarding};
private static final int[] SKATE_BOARDING_LIST = new int[]{R.string.activity_type_skate_boarding};
private static final int[] KAYAKING_LIST = new int[]{R.string.activity_type_kayaking};
private static final int[] WALK_LIST = new int[]{R.string.activity_type_hiking, R.string.activity_type_off_trail_hiking, R.string.activity_type_speed_walking, R.string.activity_type_trail_hiking, R.string.activity_type_walking};
private static final int[] SWIM_LIST = new int[]{R.string.activity_type_swimming, R.string.activity_type_swimming_open};
private static final int[] WORKOUT_LIST = new int[]{R.string.activity_type_workout};
// List of icons whose sports associated use speed (in km/h or mi/h).
private static final int[] SPEED_ICON = {
// Unknown.
R.string.activity_type_unknown,
// All airplane categories.
R.string.activity_type_airplane, R.string.activity_type_commercial_airplane, R.string.activity_type_rc_airplane,
// All bike categories.
R.string.activity_type_biking, R.string.activity_type_cycling, R.string.activity_type_dirt_bike, R.string.activity_type_motor_bike, R.string.activity_type_mountain_biking, R.string.activity_type_road_biking, R.string.activity_type_track_cycling, R.string.activity_type_inline_skating,
// All boat categories.
R.string.activity_type_boat, R.string.activity_type_ferry, R.string.activity_type_motor_boating, R.string.activity_type_rc_boat, R.string.activity_type_sailing, R.string.activity_type_kayaking,
// All drive categories.
R.string.activity_type_atv, R.string.activity_type_driving, R.string.activity_type_driving_bus, R.string.activity_type_driving_car, R.string.activity_type_escooter, R.string.activity_type_skate_boarding,
// All wintersport categories
R.string.activity_type_skiing, R.string.activity_type_snow_boarding
};
//TODO Use Map.of()
private static final LinkedHashMap<String, Pair<Integer, Integer>> MAP = new LinkedHashMap<>();
static {
//Reflects order in ChooseActivityTypeDialogFragmentActivity
MAP.put(UNKNOWN, new Pair<>(R.string.activity_type_unknown, ACTIVITY_UNKNOWN_LOGO));
MAP.put(RUN, new Pair<>(R.string.activity_type_running, R.drawable.ic_activity_run_24dp));
MAP.put(WALK, new Pair<>(R.string.activity_type_walking, R.drawable.ic_activity_walk_24dp));
MAP.put(CLIMBING, new Pair<>(R.string.activity_type_climbing, R.drawable.ic_activity_climbing_24dp));
MAP.put(SKATE_BOARDING, new Pair<>(R.string.activity_type_skate_boarding, R.drawable.ic_activity_skateboarding_24dp));
MAP.put(INLINE_SKATING, new Pair<>(R.string.activity_type_inline_skating, R.drawable.ic_activity_inline_skating_24dp));
MAP.put(SNOW_BOARDING, new Pair<>(R.string.activity_type_snow_boarding, R.drawable.ic_activity_snowboarding_24dp));
MAP.put(SKI, new Pair<>(R.string.activity_type_skiing, R.drawable.ic_activity_skiing_24dp));
MAP.put(ESCOOTER, new Pair<>(R.string.activity_type_escooter, R.drawable.ic_activity_escooter_24dp));
MAP.put(BIKE, new Pair<>(R.string.activity_type_biking, R.drawable.ic_activity_bike_24dp));
MAP.put(MOUNTAIN_BIKE, new Pair<>(R.string.activity_type_mountain_biking, R.drawable.ic_activity_mtb_24dp));
MAP.put(MOTOR_BIKE, new Pair<>(R.string.activity_type_motor_bike, R.drawable.ic_activity_motorbike_24dp));
MAP.put(DRIVE, new Pair<>(R.string.activity_type_driving, R.drawable.ic_activity_drive_24dp));
MAP.put(AIRPLANE, new Pair<>(R.string.activity_type_airplane, R.drawable.ic_activity_flight_24dp));
MAP.put(KAYAK, new Pair<>(R.string.activity_type_kayaking, R.drawable.ic_activity_kayaking_24dp));
MAP.put(BOAT, new Pair<>(R.string.activity_type_boat, R.drawable.ic_activity_boat_24dp));
MAP.put(SAILING, new Pair<>(R.string.activity_type_sailing, R.drawable.ic_activity_sailing_24dp));
MAP.put(SWIMMING, new Pair<>(R.string.activity_type_swimming, R.drawable.ic_activity_swimming_24dp));
MAP.put(SWIMMING_OPEN, new Pair<>(R.string.activity_type_swimming_open, R.drawable.ic_activity_swimming_open_24dp));
MAP.put(WORKOUT, new Pair<>(R.string.activity_type_workout, R.drawable.ic_activity_workout_24dp));
}
private TrackIconUtils() {
}
/**
* Gets the icon drawable.
*
* @param iconValue the icon value
*/
public static int getIconDrawable(String iconValue) {
if (iconValue == null || iconValue.equals("")) {
return ACTIVITY_UNKNOWN_LOGO;
if (found.isEmpty()) {
return ActivityType.UNKNOWN.getIconId();
}
Pair<Integer, Integer> pair = MAP.get(iconValue);
return pair == null ? ACTIVITY_UNKNOWN_LOGO : pair.second;
return found.get().getIconId();
}
/**
* Gets the icon activity type.
*
* @param iconValue the icon value
*/
public static int getIconActivityType(String iconValue) {
if (iconValue == null || iconValue.equals("")) {
return R.string.activity_type_unknown;
public static int getIconActivityType(String activityTypeId) {
Optional<ActivityType> found = Arrays.stream(ActivityType.values()).filter(
it -> it.getId().equals(activityTypeId)
).findFirst();
if (found.isEmpty()) {
return ActivityType.UNKNOWN.getFirstLocalizedStringId();
}
Pair<Integer, Integer> pair = MAP.get(iconValue);
return pair == null ? R.string.activity_type_unknown : pair.first;
return found.get().getFirstLocalizedStringId();
}
/**
* Gets all icon values.
*/
public static List<String> getAllIconValues() {
return new ArrayList<>(MAP.keySet());
return Arrays.stream(ActivityType.values())
.map(ActivityType::getId)
.collect(Collectors.toList());
}
/**
* Gets the icon value.
*
* @param context the context
* @param activityType the activity type
* @param context the context
* @param activityTypeId the activity type
*/
@NonNull
public static String getIconValue(Context context, String activityType) {
Resources resources = context.getResources();
if (activityType == null || activityType.equals("")) {
return UNKNOWN;
public static String getIconValue(Context context, String activityTypeId) {
Optional<ActivityType> selected = Arrays.stream(ActivityType.values())
.filter(
it -> Arrays.stream(it.getLocalizedStringIds())
.anyMatch(id -> context.getString(id).equals(activityTypeId))
)
.findFirst();
if (selected.isEmpty()) {
return ActivityType.UNKNOWN.getId();
}
if (inList(resources, activityType, AIRPLANE_LIST)) {
return AIRPLANE;
}
if (inList(resources, activityType, BIKE_LIST)) {
return BIKE;
}
if (inList(resources, activityType, MOUNTAIN_BIKE_LIST)) {
return MOUNTAIN_BIKE;
}
if (inList(resources, activityType, CLIMBING_LIST)) {
return CLIMBING;
}
if (inList(resources, activityType, MOTOR_BIKE_LIST)) {
return MOTOR_BIKE;
}
if (inList(resources, activityType, KAYAKING_LIST)) {
return KAYAK;
}
if (inList(resources, activityType, BOAT_LIST)) {
return BOAT;
}
if (inList(resources, activityType, SAILING_LIST)) {
return SAILING;
}
if (inList(resources, activityType, DRIVE_LIST)) {
return DRIVE;
}
if (inList(resources, activityType, INLINE_SKATING_LIST)) {
return INLINE_SKATING;
}
if (inList(resources, activityType, ESCOOTER_LIST)) {
return ESCOOTER;
}
if (inList(resources, activityType, RUN_LIST)) {
return RUN;
}
if (inList(resources, activityType, SKI_LIST)) {
return SKI;
}
if (inList(resources, activityType, SNOW_BOARDING_LIST)) {
return SNOW_BOARDING;
}
if (inList(resources, activityType, SKATE_BOARDING_LIST)) {
return SKATE_BOARDING;
}
if (inList(resources, activityType, WALK_LIST)) {
return WALK;
}
if (inList(resources, activityType, SWIM_LIST)) {
return SWIMMING;
}
if (inList(resources, activityType, WORKOUT_LIST)) {
return WORKOUT;
}
return UNKNOWN;
return selected.get().getId();
}
/**
* Returns true if the activity type is in the list.
*
* @param context the context
* @param activityType the activity type
* @param list the list
*/
private static boolean inList(Resources context, String activityType, int[] list) {
for (int i : list) {
if (context.getString(i).equals(activityType)) {
return true;
}
}
return false;
}
public static boolean isSpeedIcon(Resources resources, String activityTypeId) {
Optional<ActivityType> selected = Arrays.stream(ActivityType.values())
.filter(
it -> Arrays.stream(it.getLocalizedStringIds())
.anyMatch(id -> resources.getString(id).equals(activityTypeId))
)
.findFirst();
/**
* Returns true if category is in the SPEED_ICON array. Otherwise returns false.
*
* @param category the name of the category, activity type.
*/
public static boolean isSpeedIcon(Resources resources, String category) {
return inList(resources, category, SPEED_ICON);
if (selected.isEmpty()) {
return false;
}
return selected.get().isShowSpeedPreferred();
}
}
@@ -4,8 +4,6 @@ import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import androidx.core.content.ContextCompat;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.models.DistanceFormatter;
import de.dennisguse.opentracks.data.models.HeartRateZones;
@@ -274,10 +272,10 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder<St
if (sensorDataSet != null && sensorDataSet.getHeartRate() != null) {
valueAndUnit = StringUtils.getHeartRateParts(getContext(), sensorDataSet.getHeartRate().first);
sensorName = sensorDataSet.getHeartRate().second;
textColor = zones.getColorForZone(sensorDataSet.getHeartRate().first);
textColor = zones.getTextColorForZone(getContext(), sensorDataSet.getHeartRate().first);
} else {
valueAndUnit = StringUtils.getHeartRateParts(getContext(), null);
textColor = zones.getColorForZone(null);
textColor = zones.getTextColorForZone(getContext(), null);
}
getBinding().statsValue.setText(valueAndUnit.first);
@@ -287,7 +285,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder<St
getBinding().statsDescriptionSecondary.setVisibility(View.VISIBLE);
getBinding().statsDescriptionSecondary.setText(sensorName);
getBinding().statsValue.setTextColor(ContextCompat.getColor(getContext(), textColor));
getBinding().statsValue.setTextColor(textColor);
}
}
+2
View File
@@ -603,4 +603,6 @@ limitations under the License.
<string name="settings_public_api_package_title">Pakkenavn for offentlig API</string>
<string name="introduction_osm_dashboard">OpenTracks sørger ikke selv for kart. Installer OSMDashboard for å vise opptakene dine på et kart.</string>
<string name="help_data_google_play_services_content">Nei</string>
<string name="settings_sensor_heart_rate_max">Soner: Makspuls (bpm)</string>
<string name="settings_api_summary">Fjernkontroll- og statistikk-API for andre programmer</string>
</resources>
-1
View File
@@ -61,5 +61,4 @@ limitations under the License.
<color name="heart_rate_zone_textcolor_4">#FFBD04</color>
<color name="heart_rate_zone_textcolor_3">#6ACC2B</color>
<color name="heart_rate_zone_textcolor_2">#64D1FD</color>
<color name="heart_rate_zone_textcolor_1">@color/opentracks_on_primary_color</color>
</resources>
-69
View File
@@ -64,75 +64,6 @@
<!-- Stats layout customization default layout -->
<string name="default_activity_key" translatable="false">defaultActivity</string>
<string name="default_activity_default" translatable="false">@string/activity_type_unknown</string>
<string-array name="activity_types">
<item>@string/default_activity_default</item>
<item>@string/activity_type_airplane</item>
<item>@string/activity_type_atv</item>
<item>@string/activity_type_biking</item>
<item>@string/activity_type_blimp</item>
<item>@string/activity_type_boat</item>
<item>@string/activity_type_climbing</item>
<item>@string/activity_type_commercial_airplane</item>
<item>@string/activity_type_cross_country_skiing</item>
<item>@string/activity_type_cycling</item>
<item>@string/activity_type_dirt_bike</item>
<item>@string/activity_type_donkey_back_riding</item>
<item>@string/activity_type_driving</item>
<item>@string/activity_type_driving_bus</item>
<item>@string/activity_type_driving_car</item>
<item>@string/activity_type_ferry</item>
<item>@string/activity_type_frisbee</item>
<item>@string/activity_type_gliding</item>
<item>@string/activity_type_hang_gliding</item>
<item>@string/activity_type_helicopter</item>
<item>@string/activity_type_hiking</item>
<item>@string/activity_type_horse_back_riding</item>
<item>@string/activity_type_hot_air_balloon</item>
<item>@string/activity_type_ice_sailing</item>
<item>@string/activity_type_inline_skating</item>
<item>@string/activity_type_kayaking</item>
<item>@string/activity_type_kite_surfing</item>
<item>@string/activity_type_land_sailing</item>
<item>@string/activity_type_mixed_type</item>
<item>@string/activity_type_motor_bike</item>
<item>@string/activity_type_motor_boating</item>
<item>@string/activity_type_mountain_biking</item>
<item>@string/activity_type_off_trail_hiking</item>
<item>@string/activity_type_other</item>
<item>@string/activity_type_paddling</item>
<item>@string/activity_type_para_gliding</item>
<item>@string/activity_type_rc_airplane</item>
<item>@string/activity_type_rc_boat</item>
<item>@string/activity_type_rc_helicopter</item>
<item>@string/activity_type_riding</item>
<item>@string/activity_type_road_biking</item>
<item>@string/activity_type_roller_skiing</item>
<item>@string/activity_type_rowing</item>
<item>@string/activity_type_running</item>
<item>@string/activity_type_sailing</item>
<item>@string/activity_type_seaplane</item>
<item>@string/activity_type_skate_boarding</item>
<item>@string/activity_type_skating</item>
<item>@string/activity_type_skiing</item>
<item>@string/activity_type_sky_jumping</item>
<item>@string/activity_type_sled</item>
<item>@string/activity_type_snow_boarding</item>
<item>@string/activity_type_snow_shoeing</item>
<item>@string/activity_type_speed_walking</item>
<item>@string/activity_type_street_running</item>
<item>@string/activity_type_surfing</item>
<item>@string/activity_type_track_cycling</item>
<item>@string/activity_type_track_running</item>
<item>@string/activity_type_trail_hiking</item>
<item>@string/activity_type_trail_running</item>
<item>@string/activity_type_train</item>
<item>@string/activity_type_ultimate_frisbee</item>
<item>@string/activity_type_wakeboarding</item>
<item>@string/activity_type_walking</item>
<item>@string/activity_type_water_skiing</item>
<item>@string/activity_type_wind_surfing</item>
</string-array>
<string name="recording_distance_interval_key" translatable="false">recordingDistanceInterval</string>
<string name="recording_distance_interval_default" translatable="false">10</string>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<include domain="sharedpref" path="." requireFlags="clientSideEncryption"/>
<include domain="database" path="." requireFlags="clientSideEncryption"/>
<include domain="external" path="." requireFlags="clientSideEncryption"/>
</full-backup-content>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup disableIfNoEncryptionCapabilities="true">
<include domain="sharedpref" path="."/>
<include domain="database" path="."/>
<include domain="external" path="."/>
</cloud-backup>
<device-transfer>
<include domain="sharedpref" path="."/>
<include domain="database" path="."/>
<include domain="external" path="."/>
</device-transfer>
</data-extraction-rules>
+47
View File
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="ar"/>
<locale android:name="bg"/>
<locale android:name="ca"/>
<locale android:name="cs"/>
<locale android:name="da"/>
<locale android:name="de"/>
<locale android:name="el"/>
<locale android:name="en"/>
<locale android:name="es"/>
<locale android:name="et"/>
<locale android:name="eu"/>
<locale android:name="fa"/>
<locale android:name="fi"/>
<locale android:name="fr"/>
<locale android:name="ga"/>
<locale android:name="gl"/>
<locale android:name="hi"/>
<locale android:name="hr"/>
<locale android:name="hu"/>
<locale android:name="in"/>
<locale android:name="it"/>
<locale android:name="iw"/>
<locale android:name="ja"/>
<locale android:name="ko"/>
<locale android:name="lt"/>
<locale android:name="lv"/>
<locale android:name="mo"/>
<locale android:name="ms"/>
<locale android:name="nb"/>
<locale android:name="nl"/>
<locale android:name="pl"/>
<locale android:name="pt"/>
<locale android:name="ro"/>
<locale android:name="ru"/>
<locale android:name="sk"/>
<locale android:name="sl"/>
<locale android:name="sr"/>
<locale android:name="sv"/>
<locale android:name="th"/>
<locale android:name="tl"/>
<locale android:name="tr"/>
<locale android:name="uk"/>
<locale android:name="vi"/>
<locale android:name="zh"/>
</locale-config>