From 28a5c5b343a8ffc206f70809d8a3e104fe8e12d0 Mon Sep 17 00:00:00 2001 From: Rodrigo Damazio Date: Tue, 12 Apr 2011 01:42:27 -0300 Subject: [PATCH] Merging to head. --- MyTracks/res/values-ca/arrays.xml | 12 +- MyTracks/res/values-de/arrays.xml | 9 +- MyTracks/res/values-es/arrays.xml | 22 +- MyTracks/res/values-es/strings.xml | 20 +- MyTracks/res/values-fr/arrays.xml | 25 +- MyTracks/res/values-it/arrays.xml | 22 +- MyTracks/res/values-ja/arrays.xml | 29 +- MyTracks/res/values-pl/arrays.xml | 24 +- MyTracks/res/values-pt-rBR/arrays.xml | 55 +- MyTracks/res/values-ru/arrays.xml | 282 ++++++++++ MyTracks/res/values-ru/strings.xml | 501 ++++++++++++++++++ MyTracks/res/values-sv/arrays.xml | 23 +- MyTracks/res/values-zh-rCN/arrays.xml | 23 +- MyTracks/res/values/arrays.xml | 143 +---- .../res/values/arrays_do_not_translate.xml | 122 +++++ MyTracks/res/xml/preferences.xml | 4 +- .../android/apps/mytracks/ChartActivity.java | 2 +- .../android/apps/mytracks/MapActivity.java | 2 +- .../android/apps/mytracks/MyTracks.java | 2 +- .../apps/mytracks/SettingsActivity.java | 20 +- .../android/apps/mytracks/StatsActivity.java | 2 +- .../android/apps/mytracks/TrackDataHub.java | 2 +- .../apps/mytracks/io/file/TrackWriter.java | 318 +---------- .../mytracks/io/file/TrackWriterFactory.java | 2 +- .../mytracks/io/file/TrackWriterImpl.java | 336 ++++++++++++ .../mytracks/services/PreferenceManager.java | 4 +- .../apps/mytracks/services/SplitManager.java | 160 ------ .../services/TaskExecuterManager.java | 87 --- .../services/TrackRecordingService.java | 118 ++--- .../{ => tasks}/FroyoStatusAnnouncerTask.java | 3 +- .../services/{ => tasks}/PeriodicTask.java | 4 +- .../services/tasks/PeriodicTaskExecutor.java | 189 +++++++ .../services/tasks/PeriodicTaskFactory.java | 33 ++ .../SplitTask.java} | 23 +- .../{ => tasks}/StatusAnnouncerFactory.java | 10 +- .../{ => tasks}/StatusAnnouncerTask.java | 6 +- .../TimerTaskExecutor.java} | 20 +- .../mytracks/io/file/TrackWriterTest.java | 26 +- .../StatusAnnouncerFactoryTest.java | 9 +- .../{ => tasks}/StatusAnnouncerTaskTest.java | 3 +- 40 files changed, 1701 insertions(+), 996 deletions(-) create mode 100755 MyTracks/res/values-ru/arrays.xml create mode 100644 MyTracks/res/values-ru/strings.xml create mode 100644 MyTracks/res/values/arrays_do_not_translate.xml create mode 100644 MyTracks/src/com/google/android/apps/mytracks/io/file/TrackWriterImpl.java delete mode 100644 MyTracks/src/com/google/android/apps/mytracks/services/SplitManager.java delete mode 100644 MyTracks/src/com/google/android/apps/mytracks/services/TaskExecuterManager.java rename MyTracks/src/com/google/android/apps/mytracks/services/{ => tasks}/FroyoStatusAnnouncerTask.java (97%) rename MyTracks/src/com/google/android/apps/mytracks/services/{ => tasks}/PeriodicTask.java (88%) create mode 100644 MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskExecutor.java create mode 100644 MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskFactory.java rename MyTracks/src/com/google/android/apps/mytracks/services/{TimeSplitTask.java => tasks/SplitTask.java} (64%) rename MyTracks/src/com/google/android/apps/mytracks/services/{ => tasks}/StatusAnnouncerFactory.java (87%) rename MyTracks/src/com/google/android/apps/mytracks/services/{ => tasks}/StatusAnnouncerTask.java (96%) rename MyTracks/src/com/google/android/apps/mytracks/services/{PeriodicTaskExecuter.java => tasks/TimerTaskExecutor.java} (81%) rename MyTracksTest/src/com/google/android/apps/mytracks/services/{ => tasks}/StatusAnnouncerFactoryTest.java (87%) rename MyTracksTest/src/com/google/android/apps/mytracks/services/{ => tasks}/StatusAnnouncerTaskTest.java (99%) diff --git a/MyTracks/res/values-ca/arrays.xml b/MyTracks/res/values-ca/arrays.xml index 2eddecf5b..2bba332fa 100644 --- a/MyTracks/res/values-ca/arrays.xml +++ b/MyTracks/res/values-ca/arrays.xml @@ -112,9 +112,9 @@ limitations under the License. 3.1 miles (senyal GPS pobre) - - - Sense divisió + + + Inactiu 100 km 50 km 25 km @@ -130,8 +130,8 @@ limitations under the License. 1 min - - No splitting + + Inactiu 100 mi 50 mi 25 mi @@ -286,6 +286,8 @@ limitations under the License. Cap + ANT+ Sensors + SRM ANT+ Bridge Zephyr Bluetooth diff --git a/MyTracks/res/values-de/arrays.xml b/MyTracks/res/values-de/arrays.xml index ed7915fc8..f33ae9fe1 100644 --- a/MyTracks/res/values-de/arrays.xml +++ b/MyTracks/res/values-de/arrays.xml @@ -48,7 +48,6 @@ limitations under the License. 328 Fuß - 50 m @@ -113,9 +112,9 @@ limitations under the License. 3,1 Meilen (sehr schlechtes GPS-Signal) - - - Nicht zerteilen + + + Aus 100 km 50 km 25 km @@ -132,7 +131,7 @@ limitations under the License. - Nicht zerteilen + Aus 100 Meilen 50 Meilen 25 Meilen diff --git a/MyTracks/res/values-es/arrays.xml b/MyTracks/res/values-es/arrays.xml index 25bd36439..2c9ac030a 100644 --- a/MyTracks/res/values-es/arrays.xml +++ b/MyTracks/res/values-es/arrays.xml @@ -15,18 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - Apagado - 1 min - 2 min - 5 min - 10 min - 15 min - 30 min - 60 min - - 1 m @@ -112,9 +100,9 @@ limitations under the License. 3.1 miles (señal GPS débil) - - - No dividir + + + Apagado 100 km 50 km 25 km @@ -130,8 +118,8 @@ limitations under the License. 1 min - - No dividir + + Apagado 100 mi 50 mi 25 mi diff --git a/MyTracks/res/values-es/strings.xml b/MyTracks/res/values-es/strings.xml index 7996ad1d8..fdb13e168 100644 --- a/MyTracks/res/values-es/strings.xml +++ b/MyTracks/res/values-es/strings.xml @@ -25,7 +25,7 @@ limitations under the License. Borrar todos los recorridos Configuraciones Elevación - Por favor seleccione el recorrido que desea ver + Por favor, seleccione el recorrido que desea ver Recorrido actual Último segmento @@ -41,21 +41,21 @@ limitations under the License. A ocurrido un error. Por favor, inténtelo de nuevo. El recorrido no existe. El archivo es demasiado grande (tiene que ser menor a 500 KB). Abortando. - No se puede insertar el marcador. La ubicación no esta disponible. + No se puede insertar el marcador. La ubicación no está disponible. Esperando una ubicación mas exacta del GPS. Asegúrese que el cielo sea visible. Grabando un nuevo recorrido. - Grabacíon interrumpida. - Un mapa Google Fusion Tables nuevo has sido creado en google.com/fusiontables. + Grabación interrumpida. + Una nueva tabla de Google Fusion ha sido creada en google.com/fusiontables. Su recorrido ha sido enviado a maps.google.com. - Su recorrido ha sido enviado a una nueva hoja de cálculo en docs.google.com. + Su recorrido ha sido enviado a una nueva hoja de cálculo de docs.google.com. Su recorrido ha sido enviado a docs.google.com. - Por favor presione aquí para ir al menú de Seguridad y Ubicación y asegúrese que el GPS esté habilitado. Presione el botón de regreso para regresar. - Nota: Una ubicación aproximada es mostrada, basada en informacion de torres de telefonía celular y red WIFI. - La ubicación actual no puede ser determinada. Habilite más fuentes de datos (vea configuraciones de Seguridad y Ubicación) y asegúrese que el cielo sea visible. Inténtelo mas tarde. - Una señal de recorrido fue insertada. - Una señal con estadísticas fue insertada. + Por favor, presione aquí para ir al menú de Seguridad y Ubicación, y asegúrese que el GPS esté habilitado. Presione el botón "atrás" para regresar. + Nota: Una ubicación aproximada es determinada a partir de torres de telefonía celular y redes WIFI. + No puede ser determinada la ubicación actual. Habilite más fuentes de datos (vea las configuraciones de Seguridad y Ubicación) y asegúrese que el cielo sea visible. Inténtelo mas tarde. + Un marcador de recorrido fue insertado. + Un marcador de estadísticas fue insertado. Por favor espere... diff --git a/MyTracks/res/values-fr/arrays.xml b/MyTracks/res/values-fr/arrays.xml index 0c9eedf72..18740a364 100644 --- a/MyTracks/res/values-fr/arrays.xml +++ b/MyTracks/res/values-fr/arrays.xml @@ -15,18 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - Absent - 1 min - 2 min - 5 min - 10 min - 15 min - 30 min - 60 min - - 1 m @@ -112,10 +100,9 @@ limitations under the License. 3.1 miles (mauvais signal GPS) - - - - Pas de séparation + + + Absent 100 km 50 km 25 km @@ -131,8 +118,8 @@ limitations under the License. 1 min - - Pas de séparation + + Absent 100 mi 50 mi 25 mi @@ -310,5 +297,5 @@ limitations under the License. Pont SRM ANT+ Bluetooth Zephyr - + diff --git a/MyTracks/res/values-it/arrays.xml b/MyTracks/res/values-it/arrays.xml index 4b8e02cb5..9974d2fc2 100644 --- a/MyTracks/res/values-it/arrays.xml +++ b/MyTracks/res/values-it/arrays.xml @@ -15,18 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - Disattivato - 1 min - 2 min - 5 min - 10 min - 15 min - 30 min - 60 min - - 1 m @@ -112,9 +100,9 @@ limitations under the License. 3.1 mi (segnale GPS debole) - - - Non dividere + + + Disattivato 100 km 50 km 25 km @@ -130,8 +118,8 @@ limitations under the License. 1 min - - Non dividere + + Disattivato 100 mi 50 mi 25 mi diff --git a/MyTracks/res/values-ja/arrays.xml b/MyTracks/res/values-ja/arrays.xml index 582056996..31e45abee 100644 --- a/MyTracks/res/values-ja/arrays.xml +++ b/MyTracks/res/values-ja/arrays.xml @@ -15,19 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - 不使用 - 1 分 - 2 分 - 5 分 - 10 分 - 15 分 - 30 分 - 60 分 - - - + 1 m 2 m @@ -48,7 +36,6 @@ limitations under the License. 328 ft - 50 m @@ -68,7 +55,6 @@ limitations under the License. 3.1 mi - 電源節約 (動的制御) @@ -89,7 +75,6 @@ limitations under the License. 30 分 - 10 m (GPS信号強度良好) @@ -115,10 +100,9 @@ limitations under the License. 3.1 mi (GPS信号強度不良) - - - - 分割なし + + + 不使用 100 km 50 km 25 km @@ -134,8 +118,8 @@ limitations under the License. 1 分 - - 分割なし + + 不使用 100 mi 50 mi 25 mi @@ -294,4 +278,5 @@ limitations under the License. SRM ANT+ ブリッジ Zephyr Bluetooth + diff --git a/MyTracks/res/values-pl/arrays.xml b/MyTracks/res/values-pl/arrays.xml index 80c7d0dbd..bf55da1a4 100644 --- a/MyTracks/res/values-pl/arrays.xml +++ b/MyTracks/res/values-pl/arrays.xml @@ -15,18 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - Brak - 1 min - 2 min - 5 min - 10 min - 15 min - 30 min - 60 min - - 1 m @@ -112,9 +100,9 @@ limitations under the License. 3.1 mili (słaby sygnał GPS) - - - Brak dzielenia + + + Brak 100 km 50 km 25 km @@ -130,8 +118,8 @@ limitations under the License. 1 min - - Brak dzielenia + + Brak 100 mi 50 mi 25 mi @@ -146,7 +134,7 @@ limitations under the License. 2 min 1 min - + Nigdy diff --git a/MyTracks/res/values-pt-rBR/arrays.xml b/MyTracks/res/values-pt-rBR/arrays.xml index 8f442d0fd..60090ae40 100644 --- a/MyTracks/res/values-pt-rBR/arrays.xml +++ b/MyTracks/res/values-pt-rBR/arrays.xml @@ -15,21 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - Desligado - 1 min - 2 min - 5 min - 10 min - 15 min - 30 min - 60 min - - - - + 1 m 2 m 3 m @@ -37,9 +24,9 @@ limitations under the License. 5 m (recomendada) 10 m 100 m - + - + 3 pés 6 pés 10 pés @@ -47,31 +34,29 @@ limitations under the License. 16 pés (recomendado) 33 pés 328 pés - - + - + 50 m 100 m 200 m (recomendado) 500 m 1000 m 5000 m - + - + 164 pés 328 pés 656 pés (recomendado) 1640 pés 0.6 milhas 3.1 milhas - - + - + economia de bateria (adaptativo) alta precisão (adaptativo) máxima (recomendada) @@ -88,11 +73,10 @@ limitations under the License. 10 min 15 min 30 min - - + - + 10 m (sinal de GPS excelente) 20 m 50 m @@ -102,9 +86,9 @@ limitations under the License. 1000 m 2000 m 5000 m (sinal de GPS ruim) - + - + 33 pés (sinal de GPS excelente) 66 pés 165 pés @@ -114,12 +98,11 @@ limitations under the License. 0.6 milhas 1.2 milhas 3.1 milhas (sinal de GPS ruim) - + - - - - Sem divisões + + + Desligado 100 km 50 km 25 km @@ -135,8 +118,8 @@ limitations under the License. 1 min - - Sem divisões + + Desligado 100 mi 50 mi 25 mi diff --git a/MyTracks/res/values-ru/arrays.xml b/MyTracks/res/values-ru/arrays.xml new file mode 100755 index 000000000..feb32549f --- /dev/null +++ b/MyTracks/res/values-ru/arrays.xml @@ -0,0 +1,282 @@ + + + + + + 1 м + 2 м + 3 м + 4 м + 5 м (рекомендуется) + 10 м + 100 м + + + + 3 фута + 6 футов + 10 футов + 13 футов + 16 футов (рекомендуется) + 33 фута + 328 футов + + + + + 50 м + 100 м + 200 м (рекомендуется) + 500 м + 1000 м + 5000 м + + + + 164 фута + 328 футов + 656 фута (рекомендуется) + 1640 футов + 0,6 мили + 3,1 мили + + + + + экономия батареи (адаптивная) + высокая точность (адаптивная) + высочайшая точность (рекомендуется) + 2 с + 3 с + 4 с + 5 с + 10 с + 20 с + 30 с + 1 мин + 2 мин + 5 мин + 10 мин + 15 мин + 30 мин + + + + + 10 м (отличный сигнал GPS) + 20 м + 50 м + 100 м + 200 м (рекомендуется) + 500 м + 1000 м + 2000 м + 5000 м (плохой сигнал GPS) + + + + 33 фута (отличный сигнал GPS) + 66 футов + 165 футов + 328 футов + 656 футов (рекомендуется) + 1640 футов + 0,6 мили + 1,2 мили + 3,1 мили (плохой сигнал GPS) + + + + + Выкл. + 100 км + 50 км + 25 км + 10 км + 5 км + 1 км + 60 мин + 30 мин + 15 мин + 10 мин + 5 мин + 2 мин + 1 мин + + + + Выкл. + 100 миль + 50 миль + 25 миль + 10 миль + 5 миль + 1 миля + 60 мин + 30 мин + 15 мин + 10 мин + 5 мин + 2 мин + 1 мин + + + + + Никогда + 5 мин + 10 мин + 15 мин + Всегда + + + + + не определен + смешанного типа + другое + + бег + бег по улице + бег по треку + бег по тропе + ходьба + быстрая ходьба + пешая прогулка + прогулка по туристической тропе + прогулка по бездорожью + восхождение + + велосипедная прогулка + шоссейный велосипед + горный велосипед + велотрек + + катание на коньках + катания на роликовых коньках + катания на роликовых коньках + + прогулка на снегоступах + лыжи + сноубординг + сани + ледяной парусный спорт + + парусный спорт + гребля + каякинг + академическая гребля + моторная лодка + паром + RC лодка + серфинг + виндсерфинг + кайтсерфинг + водные лыжи + вейкбординг + + самолет + гидроплан + коммерческий самолет + вертолет + воздушный шар + дирижабль + RC самолет + RC вертолет + прыжки + планеризм + дельтаплан + парный планеризм + + верховая езда + катание на лошадях + прогулка на осле + + вождение автомобиля + вождение автобуса + поезд + мотоцикл + Байк + ATV + + парусный спорт на земле + фрисби + алтимат фризби + + + + банкомат + банк + бар + барбекю + здание + автобусная остановка + кафе + костер + лагерь + церковь + кофейня + удобный магазин + питьевая вода + оползень + паром + камин + пожарная станция + рыболовство + автозаправочная станция + поле для гольфа + продуктовый магазин + парикмахерская + гавань + тропа + отель + дом + информация + пересечение + почтовый ящик + рынок + место встречи + опера + парковка + почтовое отделение + выбоина + полицейский участок + железнодорожный переезд + ресторан + покупки + вид + магазин + бассейн + телефон + театр + туалет + туристическая информация + туннель + дерево + водопад + фонтан + путевая точка + + + + Нет + ANT+ Sensors + SRM ANT+ Bridge + Zephyr Bluetooth + + + diff --git a/MyTracks/res/values-ru/strings.xml b/MyTracks/res/values-ru/strings.xml new file mode 100644 index 000000000..062383b40 --- /dev/null +++ b/MyTracks/res/values-ru/strings.xml @@ -0,0 +1,501 @@ + + + + + Запись трека + Остановить запись + Режим спутника + Режим карты + Мое местоположение + Треки + Маркеры + Удалить все треки + Настройки + Высота + Пожалуйста, выберите трек для просмотра + Текущий трек + Последний сегмент + Состояние датчика + Совокупная статистика + + + На этом устройстве не был обнаружен диспетчер местоположения! + На этом устройстве не был обнаружен поставщик GPS местоположения. + Ошибка при отправке вашего трека в Google \"Мои карты\". + Ошибка при отправке вашего трека в Google Fusion Tables. + Ошибка при отправке вашего трека в Google Документы. + Пожалуйста, повторите попытку позже. + Не удалось начать запись. Попробуйте еще раз. + Не удалось остановить запись. Попробуйте еще раз. + Не удалось прочитать из файла. + Неверный формат GPX файла. + Произошла ошибка. Пожалуйста, попробуйте еще раз. + Трек не существует. + Этот файл слишком большой (должен быть меньше, чем 500 КБ). Прервано. + Невозможно вставить маркер. Местоположение неизвестно. + + + Ожидание сигнала GPS. Убедитесь в том, что вы находитесь под открытым небом. + Записывается новый трек. + Запись вашего трека остановлена. + Новая Google \"Мои карты\" была создана на maps.google.com. + Новая таблица Google Fusion была создана на google.com/fusiontables. + Твой трек был отправлен на maps.google.com. + Ваш трек был отправлен в новую электронную таблицу на docs.google.com. + Ваш трек был отправлен в docs.google.com. + Это может занять несколько минут, прежде чем появятся новые треки. + Пожалуйста, нажмите здесь для перехода к разделу настроек Координаты и отметьте пункт \"Спутники GPS\". Для возвращения нажмите кнопку Назад. + Примечание: приблизительное местоположение определено относительно вышек сотовой связи и беспроводных сетей. + В настоящее время местоположение не может быть определено. Включите больше источников местоположение (см. раздел настроек Координаты) и убедитесь в том, что находитесь под открытым небом. Повторите попытку позднее. + Маркер путевой точки был вставлен. + Маркер статистики был вставлен. + Статус загрузки: + + + Пожалуйста, подождите... + Отправка вашего трека в Google. + Чтение трека... + Подготовка трека... + Аутентификация на Google Fusion Tables... + Аутентификация на Google Карты... + Аутентификация в Google Документы... + Отправка трека в Google Документы... + Отправка трека в Google Карты... + Создание новой \"Моей карты\" ... + Отправка трека в Fusion Tables... + Создание новой Fusion table... + Импорт GPS трека. Это может занять некоторое время. + Запись файла на SD карту. Это может занять некоторое время. + Обновление статистики трека... + + + Вы уверены? + Все треки и маркеры будут удалены с этого телефона. + Трек и его маркеры будут удалены из этого телефона. + Маркер будет удален с этого телефона. + + + Создано My Tracks на Android. + Создано <a href=\'http://mytracks.appspot.com\'>My Tracks</a> на Android. + + + Создано <a href=\'http://mytracks.appspot.com\'>My Tracks</a> на Android. + Новая карта + + + Точки + Записан + Тип деятельности + Тип маркера + (Часть %d) + + + Запись трека... + Трек %d + + + Нет + Да + ОК + Ошибка + Готово + Путевая точка + Лицензия + Отмена + Закрыть + Правка + Сохранить + + + (Старт) + (Конец) + + + Показать + Отправить в Google \"Мои карты\" + Отправить в новый Google \"Мои карты\" + Отправить в Google Fusion Tables + Отправить в новую Google Fusion Table + Отправить в Google Документы + Отправить в Google ... + Удалить из телефона... + Править детали + Записать на SD карту... + Сохранить файл GPX + Сохранить файл KML + Сохранить файл CSV + Сохранить файл TCX + Отправить в Google Fusion Tables + Отправить в Google \"Мои карты\" + Удалить все + + Экспорт всех + Экспорт закончен + Выберите трек. Нажмите и удерживайте для получения дополнительных возможностей. + Все треки: + Этот трек + Поделиться с друзьями... + Ссылка на карту + Файл GPX + Файл KML + Файла CSV + Файл TCX + Очистить карту + + Импорт всех + Импорт закончен + + Импортировано %1$d из %2$d GPX файлов с %3$s + GPX файлы не найденны в %s. Возможно не читается SD-карта или каталог не содержит GPX файлы. + Ошибка импорта файла %s + + + Удалить все маркеры + Этот маркер + Удалить + Править детали + Показать на карте + Вставить путевую точку + Вставить статистику + Выберите маркер. Нажмите и удерживайте для получения дополнительных возможностей. + + + Трек детали + Название трека + Описание трека + Тип деятельности (например: пешая прогулка, велосипедная прогулка, бег, восхождение...) + + + Маркер детали + Имя маркера + Описание маркера + Тип маркера (например: здание, выбоина, достопримечательность...) + + + Настройки My Tracks + Отображение + Запись + Обмен + + Не доступен в вашем версии Android + Не доступно во время записи трека + + Частота объявлений + Минимальное время между двумя голосовыми объявлениями + + Минимальное расстояние между точками + Наименьшее расстояние между двумя записями вашей позиции + + Максимальное расстояние между точками + Если два пункта находятся дальше, чем указано, то трек будет разделен + + Минимальное время между точками + Наименьший интервал времени между двумя записями вашей позиции + + Минимальная точность + Запись будет приостановлена, если ваша позиция не является достаточно точной + + Использовать метрические единицы + Все расстояния будут отображаться в метрических единицах + Все расстояния будут отображаться в имперских единицах + + Обнародовать карты + Загруженные карты будут общедоступны на maps.google.com + Загруженные карты не будут перечислены публично на maps.google.com + + Отображать скорость + Скорость будет отображаться + Темп будет отображаться + + Поделиться только URL + При обмене будет отправлен только URL-адрес + Содержимое трека будет также включено при обмене + + Частота деления + Максимальное время или расстояние, после которого будет вставлен новый маркер деления + + Автоматическое возобновление трек тайм-аут + Максимальное время в минутах, после которого предыдущая запись трека не будет возобновлена на перезагруженном телефоне + + Штамп времени как название дорожки + По умолчанию имя трека будет складываться из даты и времени старта трека + Названия треков будут иметь прирост чисел для каждого нового трека. + + Восстановить значения по умолчанию + Восстановить значения по умолчанию во всех настройках + Все ваши настройки будут стерты и восстановлены значения по умолчанию. Записанные треки будут сохранены. Вы уверены? + Все настройки были возвращены к значениям по умолчанию. + + Темп + + Поддерживается только в Android 2.0 или выше + Тип датчика + Тип подключенного датчика + Очистить ANT подсоединенного датчика пульса + Очистить ANT подсоединенного датчика мощности + Очистить ANT подсоединенного датчика SRM + ANT датчик не подсоединен + ANT датчик подсоединен с: %d + Bluetooth датчик + Подключенный bluetooth датчик + Отображение модульной статистики + + + Резервное копирование (BETA) + Резервное копирование SD карты + Резервировать + Создать полную копию всех ваших треков и настроек на SD карту + Восстановить + Восстановить все треки и параметры с SD карты + + Восстановление резервной копии с SD карты ПЕРЕЗАПИШЕТ все текущие треки и настройки. Вы уверены? + Выберите резервную копию для восстановления + Резервные копии не найдены. + Запись на SD-карту всех треков и настроек. Это может занять некоторое время... + Чтение всех треков и настроек с SD-карты. Это может занять некоторое время... + + + Спутники GPS + + + Выберите карту из вашей учетной записи: + Создать новую карту... + Отправить в Google \"Мои карты\" + Загрузка карты ... + Ваши карты не могут быть загружены в данный момент! + Выберите эту карту + Править детали карты + Поделиться треком + Удалить Карту из вашей учетной записи + Название карты: + Описание карты: + Сделать чтобы карта и ее содержимое отображались в результатах поиска + Не позволить этой карте или ее содержимому отображаться в результатах поиска, хотя они все еще могут просматриваться другими через прямой URL-адрес + Эта карта и ее содержимое будут отображаться в результатах поиска + Ни эта карта, ни ее содержимое не будут отображаться в результатах поиска, но их могут по-прежнему просматривать другие через прямую ссылку + + + Поделиться картой с друзьями + Я хотел бы поделиться с вами треком + Я думаю, вы можете быть заинтересованы в этом треке: + +%s + Я хотел бы поделиться с вами треком + Я думаю, вы можете быть заинтересованы в этом треке. + +Просмотреть трек можно с помощью Google Планета Земля или другого программного обоспечения для карт. + + + Общественные + Частные + У вас пока еще нет карт. + + + + Средняя скорость движения + Средний темп движения + + + Средняя скорость + Средний темп + + Диаграмма высоты + Набор высоты + Высота + Широта + Долгота + + + Минимальная высота + Минимальный уклон + Минимальный темп + + + Максимальная высота + Максимальный уклон + Максимальная скорость + + Загрузка трека... + + + Настройки диаграммы + + Ось X + По расстоянию + По времени + + + Ось Y + + + + час + часов + ч + мин + минута + минут + секунда + секунд + мс + + + м + км + километров + футов + миль + мили + + + км/ч + километров в час + мин/км + за километр + миль/ч + миль в час + мин/миля + за милю + + + Вт + + об/мин + bpm + + + Время движения + Общее время + Время + SD карта недоступна + Скорость + Вы должны начать путешествие. + Статистика + Общее расстояние + Расстояние + Мощность + Каденс + Пульс + Максимальный пульс + - + Ожидание... + + + Лицензионное соглашение + Принять + Отклонить + + + О программе + Справка + Команда: + Версия: + Поддержка: + Приватность: + + + Отправить... + Google Fusion Tables + Google \"Мои карты\" + Google Документы + Отправить + Создать новую карту + Выбрать существующую карту + Отправить статистику трека + Отправить статистику и точки + + + Учетная запись не найдена + Не найдена учетная запись для загрузки треков. + Выбор учетной записи + + + Не обнаружено внешнее устройство хранения данных. Убедитесь, что SD карта вставлена, и что ваш телефон не подключен к компьютеру. + Невозможно записать файл. + Невозможно прочитать из файла. + Невозможно создать папку на SD карте. + Запись на SD карту закончена. + Чтение с SD карты закончено. + + + Проверить обновления + Обновить сейчас + Продолжить без обновления + Ваша версия %1$S больше не может работать должным образом, и больше не поддерживается. Обновите %1$s для продолжения использования. + Ваша версия %1$S больше не может работать должным образом. Вы можете обновить ее сейчас, либо продолжать использовать ее на свой страх и риск. Некоторые функции, такие как синхронизация с сервером может не функционировать до обновления. + Доступна новая версия %1$s. Вы можете продолжать использовать текущую версию без проблем, но вы не получите новейшие функции, до тех пор, пока не обновитесь. + + + Добро пожаловать + Ок + О My Tracks + + + My Tracks нет расстояния + + Мои треки %1$s %2$.2f %3$s в %4$s на %5$s %6$s + + + Единицы измерения обратите внимание + По умолчанию используются метрические единицы. Вы хотели бы изменить этот параметр? + + + Bluetooth + Параметры Bluetooth + Подключение устройства + Открыть настройки Android по bluetooth для подключения устройства + bluetoothSensorsEnabled + Параметры ANT + Параметры датчика + + + Подключен к %s + Подключение Bluetooth датчика... + Bluetooth датчик не подключен + + + Датчик времени + Измеритель мощности включен + Монитор пульса включен + Нет диспетчера датчиков + Включено + Подключение + Подключено + Отключено + Нет службы датчиков + Поиск + Отправка + + + получать уведомления о записи трека + чтение записанных данных трека + запись данных трека, старт/стоп записи треков + Получать уведомления, при старте или останове записи трека. + Иметь возможность читать данные трека, такие как точки и путевые точки. + Иметь возможность записать данные трека, такие как начало записи или добавление путевых точек. + diff --git a/MyTracks/res/values-sv/arrays.xml b/MyTracks/res/values-sv/arrays.xml index eb24d0ef3..fef8a4ec9 100644 --- a/MyTracks/res/values-sv/arrays.xml +++ b/MyTracks/res/values-sv/arrays.xml @@ -15,18 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - Av - 1 min - 2 min - 5 min - 10 min - 15 min - 30 min - 60 min - - 1 m @@ -67,7 +55,6 @@ limitations under the License. 3.1 miles - batterioptimerad (anpassningsbar) @@ -113,9 +100,9 @@ limitations under the License. 3.1 miles (dålig GPS-signal) - - - Ingen delning + + + Av 100 km 50 km 25 km @@ -131,8 +118,8 @@ limitations under the License. 1 min - - Ingen delning + + Av 100 mi 50 mi 25 mi diff --git a/MyTracks/res/values-zh-rCN/arrays.xml b/MyTracks/res/values-zh-rCN/arrays.xml index 48f15e956..e3108f9e2 100644 --- a/MyTracks/res/values-zh-rCN/arrays.xml +++ b/MyTracks/res/values-zh-rCN/arrays.xml @@ -15,18 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - 关闭 - 1 分钟 - 2 分钟 - 5 分钟 - 10 分钟 - 15 分钟 - 30 分钟 - 60 分钟 - - 1 米 @@ -112,9 +100,9 @@ limitations under the License. 3.1 英里 (糟糕的 GPS 信号) - - - 不分割 + + + 关闭 100 千米 50 千米 25 千米 @@ -130,8 +118,8 @@ limitations under the License. 1 分钟 - - 不分割 + + 关闭 100 英里 50 英里 25 英里 @@ -155,6 +143,7 @@ limitations under the License. 15 分钟 总是 + 未知 diff --git a/MyTracks/res/values/arrays.xml b/MyTracks/res/values/arrays.xml index d50dfd701..783668362 100644 --- a/MyTracks/res/values/arrays.xml +++ b/MyTracks/res/values/arrays.xml @@ -15,31 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - Off - 1 min - 2 min - 5 min - 10 min - 15 min - 30 min - 60 min - - - - - -1 - 1 - 2 - 5 - 10 - 15 - 30 - 60 - - - 1 m @@ -61,18 +36,6 @@ limitations under the License. 328 ft - - - 1 - 2 - 3 - 4 - 5 - 10 - 100 - - - 50 m @@ -92,17 +55,6 @@ limitations under the License. 3.1 miles - - - 50 - 100 - 200 - 500 - 1000 - 5000 - - - battery miser (adaptive) @@ -123,27 +75,6 @@ limitations under the License. 30 min - - - -2 - -1 - 0 - 2 - 3 - 4 - 5 - 10 - 20 - 30 - 60 - 120 - 300 - 480 - 900 - 1800 - - - 10 m (excellent GPS signal) @@ -169,23 +100,9 @@ limitations under the License. 3.1 miles (poor GPS signal) - - - 10 - 20 - 50 - 100 - 200 - 500 - 1000 - 2000 - 5000 - - - - - - No splitting + + + Off 100 km 50 km 25 km @@ -201,8 +118,8 @@ limitations under the License. 1 min - - No splitting + + Off 100 mi 50 mi 25 mi @@ -218,24 +135,6 @@ limitations under the License. 1 min - - - 0 - -100 - -50 - -25 - -10 - -5 - -1 - 60 - 30 - 15 - 10 - 5 - 2 - 1 - - Never @@ -245,16 +144,6 @@ limitations under the License. Always - - - 0 - 5 - 10 - 15 - -1 - - - unknown @@ -383,14 +272,6 @@ limitations under the License. way point - - - GPX - KML - CSV - TCX - - None ANT+ Sensors @@ -398,18 +279,4 @@ limitations under the License. Zephyr Bluetooth - - - @string/none - @string/ant_sensor_type - @string/srm_ant_bridge_sensor_type - @string/zephyr_sensor_type - - - - - @string/ant_sensor_type - @string/srm_ant_bridge_sensor_type - - diff --git a/MyTracks/res/values/arrays_do_not_translate.xml b/MyTracks/res/values/arrays_do_not_translate.xml new file mode 100644 index 000000000..219049f4f --- /dev/null +++ b/MyTracks/res/values/arrays_do_not_translate.xml @@ -0,0 +1,122 @@ + + + + + + 10 + 20 + 50 + 100 + 200 + 500 + 1000 + 2000 + 5000 + + + + 1 + 2 + 3 + 4 + 5 + 10 + 100 + + + + 1 + 2 + 3 + 4 + 5 + 10 + 100 + + + + 50 + 100 + 200 + 500 + 1000 + 5000 + + + + -2 + -1 + 0 + 2 + 3 + 4 + 5 + 10 + 20 + 30 + 60 + 120 + 300 + 480 + 900 + 1800 + + + + 0 + -100 + -50 + -25 + -10 + -5 + -1 + 60 + 30 + 15 + 10 + 5 + 2 + 1 + + + + 0 + 5 + 10 + 15 + -1 + + + + GPX + KML + CSV + TCX + + + + @string/none + @string/ant_sensor_type + @string/srm_ant_bridge_sensor_type + @string/zephyr_sensor_type + + + + @string/ant_sensor_type + @string/srm_ant_bridge_sensor_type + + diff --git a/MyTracks/res/xml/preferences.xml b/MyTracks/res/xml/preferences.xml index e4d0b093f..d964f124b 100644 --- a/MyTracks/res/xml/preferences.xml +++ b/MyTracks/res/xml/preferences.xml @@ -48,8 +48,8 @@ limitations under the License. android:key="@string/split_frequency_key" android:title="@string/settings_split_frequency" android:summary="@string/settings_split_frequency_summary" - android:entries="@array/split_frequency_options" - android:entryValues="@array/split_frequency_values" + android:entries="@array/task_frequency_options" + android:entryValues="@array/task_frequency_values" android:defaultValue="0" /> 0) && (splitExecuter != null)) { - splitExecuter.scheduleTask(splitFrequency * 60000); - } - calculateNextSplit(); - } - - /** - * Shuts down the manager. - */ - public void shutdown() { - if (splitExecuter != null) { - splitExecuter.shutdown(); - } - } - - /** - * Calculates the next distance that a split should be inserted at. - */ - public void calculateNextSplit() { - // TODO: Decouple service from this class once and forever. - if (!service.isRecording()) { - return; - } - - if (splitFrequency >= 0) { - nextSplitDistance = Double.MAX_VALUE; - Log.d(Constants.TAG, - "SplitManager: Distance splits disabled."); - return; - } - - double dist = service.getTripStatistics().getTotalDistance() / 1000; - if (!metricUnits) { - dist *= UnitConversions.KM_TO_MI; - } - // The index will be negative since the frequency is negative. - int index = (int) (dist / splitFrequency); - index -= 1; - nextSplitDistance = splitFrequency * index; - Log.d(Constants.TAG, - "SplitManager: Next split distance: " + nextSplitDistance); - } - - /** - * Updates split manager with new trip statistics. - */ - public void updateSplits() { - if (this.splitFrequency >= 0) { - return; - } - // Convert the distance in meters to km or mi. - double distance = service.getTripStatistics().getTotalDistance() / 1000.0; - if (!metricUnits) { - distance *= UnitConversions.KM_TO_MI; - } - - if (distance > this.nextSplitDistance) { - service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS); - calculateNextSplit(); - } - } - - /** - * Sets the split frequency. - * < 0 Use the absolute value as a distance in the current measurement km - * or mi - * 0 Turn off splits - * > 0 Use the value as a time in minutes - * @param splitFrequency The frequency in time or distance - */ - public void setSplitFrequency(int splitFrequency) { - Log.d(Constants.TAG, - "setSplitFrequency: splitFrequency = " + splitFrequency); - this.splitFrequency = splitFrequency; - - // TODO: Decouple service from this class once and forever. - if (!service.isRecording()) { - return; - } - - if (splitFrequency < 1) { - if (splitExecuter != null) { - splitExecuter.shutdown(); - splitExecuter = null; - } - } - if (splitFrequency > 0) { - if (splitExecuter == null) { - TimeSplitTask splitter = new TimeSplitTask(); - splitExecuter = new PeriodicTaskExecuter(splitter, service); - } - splitExecuter.scheduleTask(splitFrequency * 60000); - } else { - // For distance based splits. - calculateNextSplit(); - } - } - - public void setMetricUnits(boolean metricUnits) { - this.metricUnits = metricUnits; - calculateNextSplit(); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TaskExecuterManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/TaskExecuterManager.java deleted file mode 100644 index ec3b47d82..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TaskExecuterManager.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services; - -import com.google.android.apps.mytracks.Constants; - -import android.util.Log; - -/** - * This class manages a period task executer. - * - * @author Sandor Dornbush - */ -public class TaskExecuterManager { - - private int frequency; - private final PeriodicTask task; - private PeriodicTaskExecuter executer; - - public TaskExecuterManager(int frequency, PeriodicTask task, - TrackRecordingService service) { - this.task = task; - setFrequency(frequency, service); - } - - public int getFrequency() { - return frequency; - } - - /** - * Sets the frequency that the task should be run at. - * If needed the task will be scheduled. - * - * @param frequency The frequency in minutes for the task to run - * @param service The service to run the task on - */ - public void setFrequency(int frequency, TrackRecordingService service) { - this.frequency = frequency; - Log.i(Constants.TAG, "Frequency set to " + frequency - + " for task " + task.getClass().getSimpleName()); - - if (frequency == -1) { - if (executer != null) { - executer.shutdown(); - executer = null; - Log.i(Constants.TAG, - "Shut down service: " + task.getClass().getSimpleName()); - } - } else { - if (executer == null) { - executer = new PeriodicTaskExecuter(task, service); - } - executer.scheduleTask(frequency * 60000); - } - } - - /** - * Restores the task at the current frequency. - */ - public void restore() { - if (frequency > 0) { - executer.scheduleTask(frequency * 60000); - } - } - - /** - * Shuts down this executer. - */ - public void shutdown() { - if (executer != null) { - executer.shutdown(); - } - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java index fa15577d4..2934dbf69 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -31,6 +31,9 @@ import com.google.android.apps.mytracks.content.WaypointsColumns; import com.google.android.apps.mytracks.content.Sensor.SensorDataSet; import com.google.android.apps.mytracks.services.sensors.SensorManager; import com.google.android.apps.mytracks.services.sensors.SensorManagerFactory; +import com.google.android.apps.mytracks.services.tasks.PeriodicTaskExecutor; +import com.google.android.apps.mytracks.services.tasks.SplitTask; +import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory; import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatisticsBuilder; import com.google.android.apps.mytracks.util.ApiFeatures; @@ -111,10 +114,10 @@ public class TrackRecordingService extends Service implements LocationListener { private double length; /** - * Status announcer executer. + * Status announcer executor. */ - private PeriodicTaskExecuter announcementExecuter; - private SplitManager splitManager; + private PeriodicTaskExecutor announcementExecutor; + private PeriodicTaskExecutor splitExecutor; private SensorManager sensorManager; @@ -185,11 +188,9 @@ public class TrackRecordingService extends Service implements LocationListener { private Location lastValidLocation; /** - * The frequency of status announcements. + * A service to run tasks outside of the main thread. */ - private int announcementFrequency = -1; - - private ExecutorService executerServce; + private ExecutorService executorService; /* * Utility functions @@ -273,7 +274,8 @@ public class TrackRecordingService extends Service implements LocationListener { "Caught SQLiteException: " + e.getMessage(), e); return false; } - splitManager.updateSplits(); + announcementExecutor.update(); + splitExecutor.update(); return true; } @@ -425,9 +427,7 @@ public class TrackRecordingService extends Service implements LocationListener { TripStatistics stats = track.getStatistics(); statsBuilder = new TripStatisticsBuilder(stats.getStartTime()); statsBuilder.setMinRecordingDistance(minRecordingDistance); - setUpAnnouncer(); - splitManager.restore(); length = 0; lastValidLocation = null; @@ -475,7 +475,8 @@ public class TrackRecordingService extends Service implements LocationListener { } } - splitManager.calculateNextSplit(); + announcementExecutor.restore(); + splitExecutor.restore(); } /* @@ -483,7 +484,7 @@ public class TrackRecordingService extends Service implements LocationListener { */ @Override public void onLocationChanged(final Location location) { - this.executerServce.submit( + executorService.submit( new Runnable() { @Override public void run() { @@ -662,8 +663,8 @@ public class TrackRecordingService extends Service implements LocationListener { notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); - splitManager = new SplitManager(this); + setUpTaskExecutors(); prefManager = new PreferenceManager(this); registerLocationListener(); @@ -688,49 +689,29 @@ public class TrackRecordingService extends Service implements LocationListener { prefManager.setRecordingTrack(recordingTrackId = -1); } showNotification(); - executerServce = Executors.newSingleThreadExecutor(); + executorService = Executors.newSingleThreadExecutor(); } /** - * Creates an {@link Executer} and schedules {@class SafeStatusAnnouncerTask}. - * The announcer requires a TTS service and user should have enabled - * the announcements, otherwise this method is no-op. + * Creates the periodic task executors. */ - private void setUpAnnouncer() { - Log.d(TAG, "TrackRecordingService.setUpAnnouncer: " - + announcementExecuter); - if (announcementFrequency != -1 && recordingTrackId != -1) { - handler.post(new Runnable() { - @Override - public void run() { - if (announcementExecuter == null) { - StatusAnnouncerFactory statusAnnouncerFactory = - new StatusAnnouncerFactory(ApiFeatures.getInstance()); - PeriodicTask announcer = statusAnnouncerFactory.create( - TrackRecordingService.this); - if (announcer == null) { - return; - } - - // TODO: Either use TaskExecuterManager everywhere, or get rid of it - announcementExecuter = new PeriodicTaskExecuter(announcer, - TrackRecordingService.this); - } - announcementExecuter.scheduleTask(announcementFrequency * 60000); - } - }); - } + private void setUpTaskExecutors() { + announcementExecutor = new PeriodicTaskExecutor( + this, new StatusAnnouncerFactory(ApiFeatures.getInstance())); + splitExecutor = new PeriodicTaskExecutor(this, new SplitTask.Factory()); } - private void shutdownAnnouncer() { - Log.d(TAG, "TrackRecordingService.shutdownAnnouncer: " - + announcementExecuter); - if (announcementExecuter != null) { - try { - announcementExecuter.shutdown(); - } finally { - announcementExecuter = null; - } + private void shutdownTaskExecutors() { + Log.d(TAG, "TrackRecordingService.shutdownExecuters"); + try { + announcementExecutor.shutdown(); + } finally { + announcementExecutor = null; + } + try { + splitExecutor.shutdown(); + } finally { + splitExecutor = null; } } @@ -747,9 +728,7 @@ public class TrackRecordingService extends Service implements LocationListener { timer.cancel(); timer.purge(); unregisterLocationListener(); - shutdownAnnouncer(); - splitManager.shutdown(); - splitManager = null; + shutdownTaskExecutors(); if (sensorManager != null) { sensorManager.shutdown(); sensorManager = null; @@ -1104,11 +1083,9 @@ public class TrackRecordingService extends Service implements LocationListener { waypointStatsBuilder = new TripStatisticsBuilder(startTime); waypointStatsBuilder.setMinRecordingDistance(minRecordingDistance); currentWaypointId = insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS); - setUpAnnouncer(); length = 0; showNotification(); registerLocationListener(); - splitManager.restore(); sensorManager = SensorManagerFactory.getSensorManager(this); if (sensorManager != null) { sensorManager.onStartTrack(); @@ -1123,6 +1100,8 @@ public class TrackRecordingService extends Service implements LocationListener { // Notify the world that we're now recording. sendTrackBroadcast( R.string.track_started_broadcast_action, recordingTrackId); + announcementExecutor.restore(); + splitExecutor.restore(); return recordingTrackId; } @@ -1133,7 +1112,8 @@ public class TrackRecordingService extends Service implements LocationListener { throw new IllegalStateException("No recording track in progress!"); } - shutdownAnnouncer(); + announcementExecutor.shutdown(); + splitExecutor.shutdown(); isRecording = false; Track recordingTrack = providerUtils.getTrack(recordingTrackId); if (recordingTrack != null) { @@ -1193,19 +1173,6 @@ public class TrackRecordingService extends Service implements LocationListener { this.recordingTrackId = recordingTrackId; } - public int getAnnouncementFrequency() { - return announcementFrequency; - } - - public void setAnnouncementFrequency(int announcementFrequency) { - this.announcementFrequency = announcementFrequency; - if (announcementFrequency == -1) { - shutdownAnnouncer(); - } else { - setUpAnnouncer(); - } - } - public int getMaxRecordingDistance() { return maxRecordingDistance; } @@ -1251,7 +1218,16 @@ public class TrackRecordingService extends Service implements LocationListener { this.autoResumeTrackTimeout = autoResumeTrackTimeout; } - public SplitManager getSplitManager() { - return splitManager; + public void setAnnouncementFrequency(int announcementFrequency) { + announcementExecutor.setTaskFrequency(announcementFrequency); + } + + public void setSplitFrequency(int frequency) { + splitExecutor.setTaskFrequency(frequency); + } + + public void setMetricUnits(boolean metric) { + announcementExecutor.setMetricUnits(metric); + splitExecutor.setMetricUnits(metric); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/FroyoStatusAnnouncerTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/FroyoStatusAnnouncerTask.java similarity index 97% rename from MyTracks/src/com/google/android/apps/mytracks/services/FroyoStatusAnnouncerTask.java rename to MyTracks/src/com/google/android/apps/mytracks/services/tasks/FroyoStatusAnnouncerTask.java index 06050a2c6..5bdec230a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/FroyoStatusAnnouncerTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/FroyoStatusAnnouncerTask.java @@ -14,7 +14,7 @@ * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.services.tasks; import static com.google.android.apps.mytracks.Constants.TAG; @@ -26,6 +26,7 @@ import android.util.Log; import java.util.HashMap; + /** * This class will periodically announce the user's trip statistics for Froyo and future handsets. * This class will request and release audio focus. diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/PeriodicTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTask.java similarity index 88% rename from MyTracks/src/com/google/android/apps/mytracks/services/PeriodicTask.java rename to MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTask.java index 354b4bccd..1d351bec4 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/PeriodicTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTask.java @@ -14,7 +14,9 @@ * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.services.tasks; + +import com.google.android.apps.mytracks.services.TrackRecordingService; /** * This is interface for a task that will be executed on some schedule. diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskExecutor.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskExecutor.java new file mode 100644 index 000000000..f307e4741 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskExecutor.java @@ -0,0 +1,189 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.android.apps.mytracks.services.tasks; + +import static com.google.android.apps.mytracks.Constants.TAG; + +import com.google.android.apps.mytracks.services.TrackRecordingService; +import com.google.android.apps.mytracks.util.UnitConversions; + +import android.util.Log; + +/** + * Execute a task on a time or distance schedule. + * + * @author Sandor Dornbush + */ +public class PeriodicTaskExecutor { + + /** + * The frequency of the task. + * A value greater than zero is a frequency in time. + * A value less than zero is considered a frequency in distance. + */ + private int taskFrequency = 0; + + /** + * The next distance when the task should execute. + */ + private double nextTaskDistance = 0; + + /** + * Time based executor. + */ + private TimerTaskExecutor timerExecutor = null; + + private boolean metricUnits; + + private final TrackRecordingService service; + + private final PeriodicTaskFactory factory; + + private PeriodicTask task; + + public PeriodicTaskExecutor(TrackRecordingService service, PeriodicTaskFactory factory) { + this.service = service; + this.factory = factory; + } + + /** + * Restores the manager. + */ + public void restore() { + // TODO: Decouple service from this class once and forever. + if (!service.isRecording()) { + return; + } + + if (!isTimeFrequency()) { + if (timerExecutor != null) { + timerExecutor.shutdown(); + timerExecutor = null; + } + } + if (taskFrequency == 0) { + return; + } + + // Try to make the task. + task = factory.create(service); + // Returning null is ok. + if (task == null) { + return; + } + task.start(); + + if (isTimeFrequency()) { + if (timerExecutor == null) { + timerExecutor = new TimerTaskExecutor(task, service); + } + timerExecutor.scheduleTask(taskFrequency * 60000); + } else { + // For distance based splits. + calculateNextTaskDistance(); + } + } + + /** + * Shuts down the manager. + */ + public void shutdown() { + if (task != null) { + task.shutdown(); + task = null; + } + if (timerExecutor != null) { + timerExecutor.shutdown(); + timerExecutor = null; + } + } + + /** + * Calculates the next distance when the task should execute. + */ + void calculateNextTaskDistance() { + // TODO: Decouple service from this class once and forever. + if (!service.isRecording() || task == null) { + return; + } + + if (!isDistanceFrequency()) { + nextTaskDistance = Double.MAX_VALUE; + Log.d(TAG, "SplitManager: Distance splits disabled."); + return; + } + + double distance = service.getTripStatistics().getTotalDistance() / 1000; + if (!metricUnits) { + distance *= UnitConversions.KM_TO_MI; + } + // The index will be negative since the frequency is negative. + int index = (int) (distance / taskFrequency); + index -= 1; + nextTaskDistance = taskFrequency * index; + Log.d(TAG, "SplitManager: Next split distance: " + nextTaskDistance); + } + + /** + * Updates executer with new trip statistics. + */ + public void update() { + if (!isDistanceFrequency() || task == null) { + return; + } + // Convert the distance in meters to km or mi. + double distance = service.getTripStatistics().getTotalDistance() / 1000.0; + if (!metricUnits) { + distance *= UnitConversions.KM_TO_MI; + } + + if (distance > nextTaskDistance) { + task.run(service); + calculateNextTaskDistance(); + } + } + + private boolean isTimeFrequency() { + return taskFrequency > 0; + } + + private boolean isDistanceFrequency() { + return taskFrequency < 0; + } + + /** + * Sets the task frequency. + * < 0 Use the absolute value as a distance in the current measurement km + * or mi + * 0 Turn off the task + * > 0 Use the value as a time in minutes + * @param taskFrequency The frequency in time or distance + */ + public void setTaskFrequency(int taskFrequency) { + Log.d(TAG, "setTaskFrequency: taskFrequency = " + taskFrequency); + this.taskFrequency = taskFrequency; + restore(); + } + + public void setMetricUnits(boolean metricUnits) { + this.metricUnits = metricUnits; + calculateNextTaskDistance(); + } + + double getNextTaskDistance() { + return nextTaskDistance; + } +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskFactory.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskFactory.java new file mode 100644 index 000000000..f3f8be445 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskFactory.java @@ -0,0 +1,33 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.android.apps.mytracks.services.tasks; + +import android.content.Context; + +/** + * An interface for classes that can create periodic tasks. + * + * @author Sandor Dornbush + */ +public interface PeriodicTaskFactory { + + /** + * Creates a periodic task which does voice announcements. + * + * @return the task, or null if task is not supported + */ + PeriodicTask create(Context context); +} \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TimeSplitTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/SplitTask.java similarity index 64% rename from MyTracks/src/com/google/android/apps/mytracks/services/TimeSplitTask.java rename to MyTracks/src/com/google/android/apps/mytracks/services/tasks/SplitTask.java index 333ce6ae4..763a922be 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TimeSplitTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/SplitTask.java @@ -14,16 +14,22 @@ * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.services.tasks; import com.google.android.apps.mytracks.content.WaypointCreationRequest; +import com.google.android.apps.mytracks.services.TrackRecordingService; + +import android.content.Context; /** - * A simple task to insert statistics markers every n minutes. + * A simple task to insert statistics markers periodically. * @author Sandor Dornbush */ -public class TimeSplitTask implements PeriodicTask { +public class SplitTask implements PeriodicTask { + + private SplitTask() { + } @Override public void run(TrackRecordingService service) { @@ -37,4 +43,15 @@ public class TimeSplitTask implements PeriodicTask { @Override public void start() { } + + /** + * Create new SplitTasks. + */ + public static class Factory implements PeriodicTaskFactory { + + @Override + public PeriodicTask create(Context context) { + return new SplitTask(); + } + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactory.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactory.java similarity index 87% rename from MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactory.java rename to MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactory.java index 01216a164..30c87d781 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactory.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactory.java @@ -13,7 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.services.tasks; import com.google.android.apps.mytracks.util.ApiFeatures; @@ -26,7 +26,7 @@ import android.media.AudioManager; * * @author Rodrigo Damazio */ -public class StatusAnnouncerFactory { +public class StatusAnnouncerFactory implements PeriodicTaskFactory { private final boolean hasTts; @@ -34,11 +34,7 @@ public class StatusAnnouncerFactory { this.hasTts = apiFeatures.hasTextToSpeech(); } - /** - * Creates a periodic task which does voice announcements. - * - * @return the task, or null if announcements are not supported - */ + @Override public PeriodicTask create(Context context) { if (hasTts) { if (ApiFeatures.getInstance().isAudioFocusSupported()) { diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java similarity index 96% rename from MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java rename to MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java index 4f27556d1..bf0645b3e 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java @@ -14,11 +14,12 @@ * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.services.tasks; import static com.google.android.apps.mytracks.Constants.TAG; import com.google.android.apps.mytracks.Constants; +import com.google.android.apps.mytracks.services.TrackRecordingService; import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.UnitConversions; @@ -101,7 +102,8 @@ public class StatusAnnouncerTask implements PeriodicTask { */ protected void onTtsInit(int status) { Log.i(TAG, "TrackRecordingService.TTS init: " + status); - this.ready = status == TextToSpeech.SUCCESS; + // TTS should be valid here but NPE exceptions were reported to the market. + this.ready = status == TextToSpeech.SUCCESS && tts != null; if (ready) { // Force the language to be the same as the string we will be speaking, diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/PeriodicTaskExecuter.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/TimerTaskExecutor.java similarity index 81% rename from MyTracks/src/com/google/android/apps/mytracks/services/PeriodicTaskExecuter.java rename to MyTracks/src/com/google/android/apps/mytracks/services/tasks/TimerTaskExecutor.java index 955db49e1..ec7d66c05 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/PeriodicTaskExecuter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/TimerTaskExecutor.java @@ -14,9 +14,9 @@ * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.services.tasks; -import com.google.android.apps.mytracks.Constants; +import static com.google.android.apps.mytracks.Constants.TAG; import android.util.Log; @@ -24,12 +24,14 @@ import java.util.Date; import java.util.Timer; import java.util.TimerTask; +import com.google.android.apps.mytracks.services.TrackRecordingService; + /** - * This class will periodically announce the user's trip statistics. + * This class will periodically perform a task. * * @author Sandor Dornbush */ -public class PeriodicTaskExecuter { +public class TimerTaskExecutor { private final PeriodicTask task; private final TrackRecordingService service; @@ -40,8 +42,8 @@ public class PeriodicTaskExecuter { */ private Timer timer; - public PeriodicTaskExecuter(PeriodicTask task, - TrackRecordingService service) { + public TimerTaskExecutor(PeriodicTask task, + TrackRecordingService service) { this.task = task; this.service = service; } @@ -77,8 +79,7 @@ public class PeriodicTaskExecuter { } Date start = new Date(next); - Log.i(Constants.TAG, - task.getClass().getSimpleName() + " scheduled to start at " + start + Log.i(TAG, task.getClass().getSimpleName() + " scheduled to start at " + start + " every " + interval + " milliseconds."); timer.scheduleAtFixedRate(new PeriodicTimerTask(), start, interval); } @@ -87,8 +88,7 @@ public class PeriodicTaskExecuter { * Cleans up this object. */ public void shutdown() { - Log.i(Constants.TAG, - task.getClass().getSimpleName() + " shutting down."); + Log.i(TAG, task.getClass().getSimpleName() + " shutting down."); if (timer != null) { timer.cancel(); timer.purge(); diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/TrackWriterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/TrackWriterTest.java index c623d9a78..d066ce06b 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/TrackWriterTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/TrackWriterTest.java @@ -10,7 +10,7 @@ import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory; import com.google.android.apps.mytracks.io.file.TrackFormatWriter; -import com.google.android.apps.mytracks.io.file.TrackWriter; +import com.google.android.apps.mytracks.io.file.TrackWriterImpl; import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext; import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory; @@ -35,10 +35,10 @@ import org.easymock.IMocksControl; */ public class TrackWriterTest extends AndroidTestCase { /** - * {@link TrackWriter} subclass which mocks out methods called from - * {@link TrackWriter#openFile}. + * {@link TrackWriterImpl} subclass which mocks out methods called from + * {@link TrackWriterImpl#openFile}. */ - private static final class OpenFileTrackWriter extends TrackWriter { + private static final class OpenFileTrackWriter extends TrackWriterImpl { private final ByteArrayOutputStream stream; private final boolean canWrite; @@ -46,9 +46,9 @@ public class TrackWriterTest extends AndroidTestCase { * Constructor. * * @param stream the stream to return from - * {@link TrackWriter#newOutputStream}, or null to throw a + * {@link TrackWriterImpl#newOutputStream}, or null to throw a * {@link FileNotFoundException} - * @param canWrite the value that {@link TrackWriter#canWriteFile} will + * @param canWrite the value that {@link TrackWriterImpl#canWriteFile} will * return */ private OpenFileTrackWriter(Context context, @@ -80,16 +80,16 @@ public class TrackWriterTest extends AndroidTestCase { } /** - * {@link TrackWriter} subclass which mocks out methods called from - * {@link TrackWriter#writeTrack}. + * {@link TrackWriterImpl} subclass which mocks out methods called from + * {@link TrackWriterImpl#writeTrack}. */ - private final class WriteTracksTrackWriter extends TrackWriter { + private final class WriteTracksTrackWriter extends TrackWriterImpl { private final boolean openResult; /** * Constructor. * - * @param openResult the return value for {@link TrackWriter#openFile} + * @param openResult the return value for {@link TrackWriterImpl#openFile} */ private WriteTracksTrackWriter(Context context, MyTracksProviderUtils providerUtils, Track track, @@ -123,7 +123,7 @@ public class TrackWriterTest extends AndroidTestCase { private Track track; private TrackFormatWriter formatWriter; - private TrackWriter writer; + private TrackWriterImpl writer; private IMocksControl mocksControl; private MyTracksProviderUtils providerUtils; private Factory oldProviderUtilsFactory; @@ -228,7 +228,7 @@ public class TrackWriterTest extends AndroidTestCase { } public void testWriteDocument_emptyTrack() { - writer = new TrackWriter(getContext(), providerUtils, track, formatWriter); + writer = new TrackWriterImpl(getContext(), providerUtils, track, formatWriter); // Set expected mock behavior formatWriter.writeHeader(); @@ -243,7 +243,7 @@ public class TrackWriterTest extends AndroidTestCase { } public void testWriteDocument() { - writer = new TrackWriter(getContext(), providerUtils, track, formatWriter); + writer = new TrackWriterImpl(getContext(), providerUtils, track, formatWriter); final Location[] locs = { new Location("fake0"), diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactoryTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactoryTest.java similarity index 87% rename from MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactoryTest.java rename to MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactoryTest.java index 304002a8d..ea9a8d441 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactoryTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactoryTest.java @@ -13,8 +13,11 @@ * License for the specific language governing permissions and limitations under * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.services.tasks; +import com.google.android.apps.mytracks.services.tasks.PeriodicTask; +import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory; +import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerTask; import com.google.android.apps.mytracks.util.ApiFeatures; import android.media.AudioManager; @@ -55,7 +58,7 @@ public class StatusAnnouncerFactoryTest extends AndroidTestCase { public void testCreate() { apiFeatures.setHasTextToSpeech(true); - StatusAnnouncerFactory factory = + PeriodicTaskFactory factory = new StatusAnnouncerFactory(apiFeatures); PeriodicTask task = factory.create(getContext()); assertTrue(task instanceof StatusAnnouncerTask); @@ -63,7 +66,7 @@ public class StatusAnnouncerFactoryTest extends AndroidTestCase { public void testCreate_notAvailable() { apiFeatures.setHasTextToSpeech(false); - StatusAnnouncerFactory factory = + PeriodicTaskFactory factory = new StatusAnnouncerFactory(apiFeatures); PeriodicTask task = factory.create(getContext()); assertNull(task); diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerTaskTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java similarity index 99% rename from MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerTaskTest.java rename to MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java index 4bc7a3664..5d0bc0c87 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerTaskTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java @@ -13,13 +13,14 @@ * License for the specific language governing permissions and limitations under * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.services.tasks; import static com.google.android.testing.mocking.AndroidMock.capture; import static com.google.android.testing.mocking.AndroidMock.eq; import static com.google.android.testing.mocking.AndroidMock.expect; import static com.google.android.testing.mocking.AndroidMock.same; +import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerTask; import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.testing.mocking.AndroidMock;