diff --git a/MyTracks/res/values/arrays_do_not_translate.xml b/MyTracks/res/values/arrays_do_not_translate.xml
index 6c2f997e5..9f4c74502 100644
--- a/MyTracks/res/values/arrays_do_not_translate.xml
+++ b/MyTracks/res/values/arrays_do_not_translate.xml
@@ -200,6 +200,18 @@ limitations under the License.
- @string/sensor_type_value_zephyr
+
+ - @string/settings_recording_track_name_date_local_option
+ - @string/settings_recording_track_name_date_iso_8601_option
+ - @string/settings_recording_track_name_number_option
+
+
+
+ - @string/settings_recording_track_name_date_local_value
+ - @string/settings_recording_track_name_date_iso_8601_value
+ - @string/settings_recording_track_name_number_value
+
+
- @string/waypoint_type_atm
- @string/waypoint_type_bank
diff --git a/MyTracks/res/values/do_not_translate.xml b/MyTracks/res/values/do_not_translate.xml
index b208219c1..bf6d60df8 100644
--- a/MyTracks/res/values/do_not_translate.xml
+++ b/MyTracks/res/values/do_not_translate.xml
@@ -49,6 +49,9 @@ limitations under the License.
POLAR
SRM_ANT_BRIDGE
ZEPHYR
+ DATE_ISO_8601
+ DATE_LOCAL
+ NUMBER
com.google.android.apps.mytracks.END_CURRENT_TRACK
android.intent.action.SAVE
com.google.android.apps.mytracks.START_NEW_TRACK
diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml
index 08f619ddf..ceb8e6be4 100644
--- a/MyTracks/res/values/keys.xml
+++ b/MyTracks/res/values/keys.xml
@@ -36,9 +36,9 @@ limitations under the License.
sendToFusionTables
sendToMaps
sensorType
+ settingsRecordingTrackName
shareUrlOnly
splitFrequency
- timestampTrackName
trackColorModeDynamicVariation
trackColorModeFixedMediumDisplay
diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml
index 012e85517..88ff0558e 100644
--- a/MyTracks/res/values/strings.xml
+++ b/MyTracks/res/values/strings.xml
@@ -1677,28 +1677,6 @@ limitations under the License.
Screenshot: settings_recording_top.png">
Time/distance after which a new marker will be inserted.
-
- Use timestamp
-
-
- Use a number as the default track name.
-
-
- Use the track\'s start time as the default track name.
-
+ Track name
+
+
+ Date (ISO 8601)
+
+
+ Date (local)
+
+
+ Number
+
+
+ Default track name
+
-
+
127 || character == '-') {
+ if (Character.isLetterOrDigit(character) || codePoint > 127 || isSpecialFat32(character)) {
buffer.appendCodePoint(codePoint);
} else {
buffer.append("_");
@@ -157,6 +157,42 @@ public class FileUtils {
String result = buffer.toString();
return result.replaceAll("_+", "_");
}
+
+ /**
+ * Returns true if it is a special FAT32 character.
+ *
+ * @param character the character
+ */
+ private boolean isSpecialFat32(char character) {
+ switch (character) {
+ case '$':
+ case '%':
+ case '\'':
+ case '-':
+ case '_':
+ case '@':
+ case '~':
+ case '`':
+ case '!':
+ case '(':
+ case ')':
+ case '{':
+ case '}':
+ case '^':
+ case '#':
+ case '&':
+ case '+':
+ case ',':
+ case ';':
+ case '=':
+ case '[':
+ case ']':
+ case ' ':
+ return true;
+ default:
+ return false;
+ }
+ }
/**
* Truncates the name if necessary so the filename path length (directory +
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/DefaultTrackNameFactoryTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/DefaultTrackNameFactoryTest.java
index 4789f81f0..7462b6426 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/services/DefaultTrackNameFactoryTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/DefaultTrackNameFactoryTest.java
@@ -16,49 +16,55 @@
package com.google.android.apps.mytracks.services;
import com.google.android.apps.mytracks.util.StringUtils;
+import com.google.android.maps.mytracks.R;
-import android.content.Context;
import android.test.AndroidTestCase;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
/**
* Tests {@link DefaultTrackNameFactory}
- *
+ *
* @author Matthew Simmons
*/
public class DefaultTrackNameFactoryTest extends AndroidTestCase {
- /**
- * A version of the factory which allows us to supply our own answer as to
- * whether a timestamp-based track name should be used.
- */
- private static class MockDefaultTrackNameFactory
- extends DefaultTrackNameFactory {
- private final boolean useTimestamp;
- MockDefaultTrackNameFactory(Context context, boolean useTimestamp) {
- super(context);
- this.useTimestamp = useTimestamp;
- }
-
- @Override
- protected boolean useTimestampTrackName() {
- return useTimestamp;
- }
+ private static final int TRACK_ID = 1;
+ private static final long START_TIME = 1288213406000L;
+
+ public void testDefaultTrackName_date_local() {
+ DefaultTrackNameFactory defaultTrackNameFactory = new DefaultTrackNameFactory(getContext()) {
+ @Override
+ String getTrackNameSetting() {
+ return getContext().getString(R.string.settings_recording_track_name_date_local_value);
+ }
+ };
+ assertEquals(StringUtils.formatDateTime(getContext(), START_TIME),
+ defaultTrackNameFactory.getDefaultTrackName(TRACK_ID, START_TIME));
}
-
- private static final long TIMESTAMP = 1288213406000L;
- public void testTimestampTrackName() {
- DefaultTrackNameFactory factory =
- new MockDefaultTrackNameFactory(getContext(), true);
+ public void testDefaultTrackName_date_iso_8601() {
+ DefaultTrackNameFactory defaultTrackNameFactory = new DefaultTrackNameFactory(getContext()) {
+ @Override
+ String getTrackNameSetting() {
+ return getContext().getString(R.string.settings_recording_track_name_date_iso_8601_value);
+ }
+ };
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
+ DefaultTrackNameFactory.ISO_8601_FORMAT);
+ assertEquals(simpleDateFormat.format(new Date(START_TIME)),
+ defaultTrackNameFactory.getDefaultTrackName(TRACK_ID, START_TIME));
+ }
+ public void testDefaultTrackName_number() {
+ DefaultTrackNameFactory defaultTrackNameFactory = new DefaultTrackNameFactory(getContext()) {
+ @Override
+ String getTrackNameSetting() {
+ return getContext().getString(R.string.settings_recording_track_name_number_value);
+ }
+ };
assertEquals(
- StringUtils.formatDateTime(getContext(), TIMESTAMP), factory.newTrackName(1, TIMESTAMP));
- }
-
- public void testIncrementingTrackName() {
- DefaultTrackNameFactory factory =
- new MockDefaultTrackNameFactory(getContext(), false);
-
- assertEquals("Track 1", factory.newTrackName(1, TIMESTAMP));
+ "Track " + TRACK_ID, defaultTrackNameFactory.getDefaultTrackName(TRACK_ID, START_TIME));
}
}
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/util/FileUtilsTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/util/FileUtilsTest.java
index aa1765f3d..8adda2946 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/util/FileUtilsTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/util/FileUtilsTest.java
@@ -62,13 +62,45 @@ public class FileUtilsTest extends TestCase {
assertEquals(expectedName, dirName);
}
+ /**
+ * Tests sanitize filename.
+ */
public void testSanitizeFileName() {
- String name = "Swim\10ming-^across: the/ pacific (ocean).您好-привет_";
- String expected = "Swim_ming-_across_the_pacific_ocean_您好-привет_";
+ String name = "Swim\10ming-^across:/the/ pacific (ocean).";
+ String expected = "Swim_ming-^across_the_ pacific (ocean)_";
+ assertEquals(expected, fileUtils.sanitizeFileName(name));
+ }
+
+ /**
+ * Tests characters in other languages, like Chinese and Russian, are allowed.
+ */
+ public void testSanitizeFileName_i18n() {
+ String name = "您好-привет";
+ String expected = "您好-привет";
+
+ assertEquals(expected, fileUtils.sanitizeFileName(name));
+ }
+
+ /**
+ * Tests special FAT32 characters are allowed.
+ */
+ public void testSanitizeFileName_special_characters() {
+ String name = "$%'-_@~`!(){}^#&+,;=[] ";
+ String expected = "$%'-_@~`!(){}^#&+,;=[] ";
assertEquals(expected, fileUtils.sanitizeFileName(name));
}
+ /**
+ * Testing collapsing multiple underscores characters.
+ */
+ public void testSanitizeFileName_collapse() {
+ String name = "hello//there";
+ String expected = "hello_there";
+
+ assertEquals(expected, fileUtils.sanitizeFileName(name));
+ }
+
public void testTruncateFileName() {
File directory = new File("/dir1/dir2/");
String suffix = ".gpx";