mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 17:43:06 +02:00
Merging to head.
This commit is contained in:
@@ -112,9 +112,9 @@ limitations under the License.
|
||||
<item>3.1 miles (senyal GPS pobre)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>Sense divisió</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Inactiu</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -130,8 +130,8 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>No splitting</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Inactiu</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
@@ -286,6 +286,8 @@ limitations under the License.
|
||||
|
||||
<array name="sensor_type_options">
|
||||
<item>Cap</item>
|
||||
<item>ANT+ Sensors</item>
|
||||
<item>SRM ANT+ Bridge</item>
|
||||
<item>Zephyr Bluetooth</item>
|
||||
</array>
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ limitations under the License.
|
||||
<item>328 Fuß</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Maximum recording distance -->
|
||||
<string-array name="max_recording_distance_options">
|
||||
<item>50 m</item>
|
||||
@@ -113,9 +112,9 @@ limitations under the License.
|
||||
<item>3,1 Meilen (sehr schlechtes GPS-Signal)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>Nicht zerteilen</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Aus</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -132,7 +131,7 @@ limitations under the License.
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>Nicht zerteilen</item>
|
||||
<item>Aus</item>
|
||||
<item>100 Meilen</item>
|
||||
<item>50 Meilen</item>
|
||||
<item>25 Meilen</item>
|
||||
|
||||
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Apagado</item>
|
||||
<item>1 min</item>
|
||||
<item>2 min</item>
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>30 min</item>
|
||||
<item>60 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 m</item>
|
||||
@@ -112,9 +100,9 @@ limitations under the License.
|
||||
<item>3.1 miles (señal GPS débil)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>No dividir</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Apagado</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -130,8 +118,8 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>No dividir</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Apagado</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
|
||||
@@ -25,7 +25,7 @@ limitations under the License.
|
||||
<string name="delete_all_tracks">Borrar todos los recorridos</string>
|
||||
<string name="settings">Configuraciones</string>
|
||||
<string name="elevation">Elevación</string>
|
||||
<string name="choose_track_message">Por favor seleccione el recorrido que desea ver</string>
|
||||
<string name="choose_track_message">Por favor, seleccione el recorrido que desea ver</string>
|
||||
<string name="current_track">Recorrido actual</string>
|
||||
<string name="current_segment">Último segmento</string>
|
||||
|
||||
@@ -41,21 +41,21 @@ limitations under the License.
|
||||
<string name="error_generic">A ocurrido un error. Por favor, inténtelo de nuevo.</string>
|
||||
<string name="error_track_does_not_exist">El recorrido no existe.</string>
|
||||
<string name="error_out_of_memory">El archivo es demasiado grande (tiene que ser menor a 500 KB). Abortando.</string>
|
||||
<string name="error_unable_to_insert_marker">No se puede insertar el marcador. La ubicación no esta disponible.</string>
|
||||
<string name="error_unable_to_insert_marker">No se puede insertar el marcador. La ubicación no está disponible.</string>
|
||||
|
||||
<!-- Status messages -->
|
||||
<string name="wait_for_fix">Esperando una ubicación mas exacta del GPS. Asegúrese que el cielo sea visible.</string>
|
||||
<string name="status_now_recording">Grabando un nuevo recorrido.</string>
|
||||
<string name="status_stopped_recording">Grabacíon interrumpida.</string>
|
||||
<string name="status_new_fusiontable_has_been_created">Un mapa Google Fusion Tables nuevo has sido creado en google.com/fusiontables.</string>
|
||||
<string name="status_stopped_recording">Grabación interrumpida.</string>
|
||||
<string name="status_new_fusiontable_has_been_created">Una nueva tabla de Google Fusion ha sido creada en google.com/fusiontables.</string>
|
||||
<string name="status_tracks_have_been_uploaded">Su recorrido ha sido enviado a maps.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_new_doc">Su recorrido ha sido enviado a una nueva hoja de cálculo en docs.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_new_doc">Su recorrido ha sido enviado a una nueva hoja de cálculo de docs.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_docs">Su recorrido ha sido enviado a docs.google.com.</string>
|
||||
<string name="status_enable_gps">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.</string>
|
||||
<string name="status_approximate_location">Nota: Una ubicación aproximada es mostrada, basada en informacion de torres de telefonía celular y red WIFI.</string>
|
||||
<string name="status_no_location">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.</string>
|
||||
<string name="status_waypoint_inserted">Una señal de recorrido fue insertada.</string>
|
||||
<string name="status_statistics_inserted">Una señal con estadísticas fue insertada.</string>
|
||||
<string name="status_enable_gps">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.</string>
|
||||
<string name="status_approximate_location">Nota: Una ubicación aproximada es determinada a partir de torres de telefonía celular y redes WIFI.</string>
|
||||
<string name="status_no_location">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.</string>
|
||||
<string name="status_waypoint_inserted">Un marcador de recorrido fue insertado.</string>
|
||||
<string name="status_statistics_inserted">Un marcador de estadísticas fue insertado.</string>
|
||||
|
||||
<!-- Progress dialog -->
|
||||
<string name="progress_title">Por favor espere...</string>
|
||||
|
||||
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Absent</item>
|
||||
<item>1 min</item>
|
||||
<item>2 min</item>
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>30 min</item>
|
||||
<item>60 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 m</item>
|
||||
@@ -112,10 +100,9 @@ limitations under the License.
|
||||
<item>3.1 miles (mauvais signal GPS)</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>Pas de séparation</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Absent</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -131,8 +118,8 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>Pas de séparation</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Absent</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
@@ -310,5 +297,5 @@ limitations under the License.
|
||||
<item>Pont SRM ANT+</item>
|
||||
<item>Bluetooth Zephyr</item>
|
||||
</array>
|
||||
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Disattivato</item>
|
||||
<item>1 min</item>
|
||||
<item>2 min</item>
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>30 min</item>
|
||||
<item>60 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 m</item>
|
||||
@@ -112,9 +100,9 @@ limitations under the License.
|
||||
<item>3.1 mi (segnale GPS debole)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>Non dividere</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Disattivato</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -130,8 +118,8 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>Non dividere</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Disattivato</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
|
||||
@@ -15,19 +15,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>不使用</item>
|
||||
<item>1 分</item>
|
||||
<item>2 分</item>
|
||||
<item>5 分</item>
|
||||
<item>10 分</item>
|
||||
<item>15 分</item>
|
||||
<item>30 分</item>
|
||||
<item>60 分</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 m</item>
|
||||
<item>2 m</item>
|
||||
@@ -48,7 +36,6 @@ limitations under the License.
|
||||
<item>328 ft</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Maximum recording distance -->
|
||||
<string-array name="max_recording_distance_options">
|
||||
<item>50 m</item>
|
||||
@@ -68,7 +55,6 @@ limitations under the License.
|
||||
<item>3.1 mi</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Minimum recording interval -->
|
||||
<string-array name="min_recording_interval_options">
|
||||
<item>電源節約 (動的制御)</item>
|
||||
@@ -89,7 +75,6 @@ limitations under the License.
|
||||
<item>30 分</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Minimum required accuracy -->
|
||||
<string-array name="min_required_accuracy_options">
|
||||
<item>10 m (GPS信号強度良好)</item>
|
||||
@@ -115,10 +100,9 @@ limitations under the License.
|
||||
<item>3.1 mi (GPS信号強度不良)</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>分割なし</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>不使用</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -134,8 +118,8 @@ limitations under the License.
|
||||
<item>1 分</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>分割なし</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>不使用</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
@@ -294,4 +278,5 @@ limitations under the License.
|
||||
<item>SRM ANT+ ブリッジ</item>
|
||||
<item>Zephyr Bluetooth</item>
|
||||
</array>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Brak</item>
|
||||
<item>1 min</item>
|
||||
<item>2 min</item>
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>30 min</item>
|
||||
<item>60 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 m</item>
|
||||
@@ -112,9 +100,9 @@ limitations under the License.
|
||||
<item>3.1 mili (słaby sygnał GPS)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>Brak dzielenia</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Brak</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -130,8 +118,8 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>Brak dzielenia</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Brak</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
@@ -146,7 +134,7 @@ limitations under the License.
|
||||
<item>2 min</item>
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Auto-resume track timeout -->
|
||||
<string-array name="auto_resume_track_timeout_options">
|
||||
<item>Nigdy</item>
|
||||
|
||||
@@ -15,21 +15,8 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<array name="task_frequency_options">
|
||||
<item>Desligado</item>
|
||||
<item>1 min</item>
|
||||
<item>2 min</item>
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>30 min</item>
|
||||
<item>60 min</item>
|
||||
</array>
|
||||
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<array name="min_recording_distance_options">
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 m</item>
|
||||
<item>2 m</item>
|
||||
<item>3 m</item>
|
||||
@@ -37,9 +24,9 @@ limitations under the License.
|
||||
<item>5 m (recomendada)</item>
|
||||
<item>10 m</item>
|
||||
<item>100 m</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="min_recording_distance_options_ft">
|
||||
<string-array name="min_recording_distance_options_ft">
|
||||
<item>3 pés</item>
|
||||
<item>6 pés</item>
|
||||
<item>10 pés</item>
|
||||
@@ -47,31 +34,29 @@ limitations under the License.
|
||||
<item>16 pés (recomendado)</item>
|
||||
<item>33 pés</item>
|
||||
<item>328 pés</item>
|
||||
</array>
|
||||
|
||||
</string-array>
|
||||
|
||||
<!-- Maximum recording distance -->
|
||||
<array name="max_recording_distance_options">
|
||||
<string-array name="max_recording_distance_options">
|
||||
<item>50 m</item>
|
||||
<item>100 m</item>
|
||||
<item>200 m (recomendado)</item>
|
||||
<item>500 m</item>
|
||||
<item>1000 m</item>
|
||||
<item>5000 m</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="max_recording_distance_options_ft">
|
||||
<string-array name="max_recording_distance_options_ft">
|
||||
<item>164 pés</item>
|
||||
<item>328 pés</item>
|
||||
<item>656 pés (recomendado)</item>
|
||||
<item>1640 pés</item>
|
||||
<item>0.6 milhas</item>
|
||||
<item>3.1 milhas</item>
|
||||
</array>
|
||||
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording interval -->
|
||||
<array name="min_recording_interval_options">
|
||||
<string-array name="min_recording_interval_options">
|
||||
<item>economia de bateria (adaptativo)</item>
|
||||
<item>alta precisão (adaptativo)</item>
|
||||
<item>máxima (recomendada)</item>
|
||||
@@ -88,11 +73,10 @@ limitations under the License.
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>30 min</item>
|
||||
</array>
|
||||
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum required accuracy -->
|
||||
<array name="min_required_accuracy_options">
|
||||
<string-array name="min_required_accuracy_options">
|
||||
<item>10 m (sinal de GPS excelente)</item>
|
||||
<item>20 m</item>
|
||||
<item>50 m</item>
|
||||
@@ -102,9 +86,9 @@ limitations under the License.
|
||||
<item>1000 m</item>
|
||||
<item>2000 m</item>
|
||||
<item>5000 m (sinal de GPS ruim)</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="min_required_accuracy_options_ft">
|
||||
<string-array name="min_required_accuracy_options_ft">
|
||||
<item>33 pés (sinal de GPS excelente)</item>
|
||||
<item>66 pés</item>
|
||||
<item>165 pés</item>
|
||||
@@ -114,12 +98,11 @@ limitations under the License.
|
||||
<item>0.6 milhas</item>
|
||||
<item>1.2 milhas</item>
|
||||
<item>3.1 milhas (sinal de GPS ruim)</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>Sem divisões</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Desligado</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -135,8 +118,8 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>Sem divisões</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Desligado</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
|
||||
Executable
+282
@@ -0,0 +1,282 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 м</item>
|
||||
<item>2 м</item>
|
||||
<item>3 м</item>
|
||||
<item>4 м</item>
|
||||
<item>5 м (рекомендуется)</item>
|
||||
<item>10 м</item>
|
||||
<item>100 м</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="min_recording_distance_options_ft">
|
||||
<item>3 фута</item>
|
||||
<item>6 футов</item>
|
||||
<item>10 футов</item>
|
||||
<item>13 футов</item>
|
||||
<item>16 футов (рекомендуется)</item>
|
||||
<item>33 фута</item>
|
||||
<item>328 футов</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Maximum recording distance -->
|
||||
<string-array name="max_recording_distance_options">
|
||||
<item>50 м</item>
|
||||
<item>100 м</item>
|
||||
<item>200 м (рекомендуется)</item>
|
||||
<item>500 м</item>
|
||||
<item>1000 м</item>
|
||||
<item>5000 м</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="max_recording_distance_options_ft">
|
||||
<item>164 фута</item>
|
||||
<item>328 футов</item>
|
||||
<item>656 фута (рекомендуется)</item>
|
||||
<item>1640 футов</item>
|
||||
<item>0,6 мили</item>
|
||||
<item>3,1 мили</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording interval -->
|
||||
<string-array name="min_recording_interval_options">
|
||||
<item>экономия батареи (адаптивная)</item>
|
||||
<item>высокая точность (адаптивная)</item>
|
||||
<item>высочайшая точность (рекомендуется)</item>
|
||||
<item>2 с</item>
|
||||
<item>3 с</item>
|
||||
<item>4 с</item>
|
||||
<item>5 с</item>
|
||||
<item>10 с</item>
|
||||
<item>20 с</item>
|
||||
<item>30 с</item>
|
||||
<item>1 мин</item>
|
||||
<item>2 мин</item>
|
||||
<item>5 мин</item>
|
||||
<item>10 мин</item>
|
||||
<item>15 мин</item>
|
||||
<item>30 мин</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum required accuracy -->
|
||||
<string-array name="min_required_accuracy_options">
|
||||
<item>10 м (отличный сигнал GPS)</item>
|
||||
<item>20 м</item>
|
||||
<item>50 м</item>
|
||||
<item>100 м</item>
|
||||
<item>200 м (рекомендуется)</item>
|
||||
<item>500 м</item>
|
||||
<item>1000 м</item>
|
||||
<item>2000 м</item>
|
||||
<item>5000 м (плохой сигнал GPS)</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="min_required_accuracy_options_ft">
|
||||
<item>33 фута (отличный сигнал GPS)</item>
|
||||
<item>66 футов</item>
|
||||
<item>165 футов</item>
|
||||
<item>328 футов</item>
|
||||
<item>656 футов (рекомендуется)</item>
|
||||
<item>1640 футов</item>
|
||||
<item>0,6 мили</item>
|
||||
<item>1,2 мили</item>
|
||||
<item>3,1 мили (плохой сигнал GPS)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Выкл.</item>
|
||||
<item>100 км</item>
|
||||
<item>50 км</item>
|
||||
<item>25 км</item>
|
||||
<item>10 км</item>
|
||||
<item>5 км</item>
|
||||
<item>1 км</item>
|
||||
<item>60 мин</item>
|
||||
<item>30 мин</item>
|
||||
<item>15 мин</item>
|
||||
<item>10 мин</item>
|
||||
<item>5 мин</item>
|
||||
<item>2 мин</item>
|
||||
<item>1 мин</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Выкл.</item>
|
||||
<item>100 миль</item>
|
||||
<item>50 миль</item>
|
||||
<item>25 миль</item>
|
||||
<item>10 миль</item>
|
||||
<item>5 миль</item>
|
||||
<item>1 миля</item>
|
||||
<item>60 мин</item>
|
||||
<item>30 мин</item>
|
||||
<item>15 мин</item>
|
||||
<item>10 мин</item>
|
||||
<item>5 мин</item>
|
||||
<item>2 мин</item>
|
||||
<item>1 мин</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Auto-resume track timeout -->
|
||||
<string-array name="auto_resume_track_timeout_options">
|
||||
<item>Никогда</item>
|
||||
<item>5 мин</item>
|
||||
<item>10 мин</item>
|
||||
<item>15 мин</item>
|
||||
<item>Всегда</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Other non-preference arrays -->
|
||||
<array name="activity_types">
|
||||
<item>не определен</item>
|
||||
<item>смешанного типа</item>
|
||||
<item>другое</item>
|
||||
|
||||
<item>бег</item>
|
||||
<item>бег по улице</item>
|
||||
<item>бег по треку</item>
|
||||
<item>бег по тропе</item>
|
||||
<item>ходьба</item>
|
||||
<item>быстрая ходьба</item>
|
||||
<item>пешая прогулка</item>
|
||||
<item>прогулка по туристической тропе</item>
|
||||
<item>прогулка по бездорожью</item>
|
||||
<item>восхождение</item>
|
||||
|
||||
<item>велосипедная прогулка</item>
|
||||
<item>шоссейный велосипед</item>
|
||||
<item>горный велосипед</item>
|
||||
<item>велотрек</item>
|
||||
|
||||
<item>катание на коньках</item>
|
||||
<item>катания на роликовых коньках</item>
|
||||
<item>катания на роликовых коньках</item>
|
||||
|
||||
<item>прогулка на снегоступах</item>
|
||||
<item>лыжи</item>
|
||||
<item>сноубординг</item>
|
||||
<item>сани</item>
|
||||
<item>ледяной парусный спорт</item>
|
||||
|
||||
<item>парусный спорт</item>
|
||||
<item>гребля</item>
|
||||
<item>каякинг</item>
|
||||
<item>академическая гребля</item>
|
||||
<item>моторная лодка</item>
|
||||
<item>паром</item>
|
||||
<item>RC лодка</item>
|
||||
<item>серфинг</item>
|
||||
<item>виндсерфинг</item>
|
||||
<item>кайтсерфинг</item>
|
||||
<item>водные лыжи</item>
|
||||
<item>вейкбординг</item>
|
||||
|
||||
<item>самолет</item>
|
||||
<item>гидроплан</item>
|
||||
<item>коммерческий самолет</item>
|
||||
<item>вертолет</item>
|
||||
<item>воздушный шар</item>
|
||||
<item>дирижабль</item>
|
||||
<item>RC самолет</item>
|
||||
<item>RC вертолет</item>
|
||||
<item>прыжки</item>
|
||||
<item>планеризм</item>
|
||||
<item>дельтаплан</item>
|
||||
<item>парный планеризм</item>
|
||||
|
||||
<item>верховая езда</item>
|
||||
<item>катание на лошадях</item>
|
||||
<item>прогулка на осле</item>
|
||||
|
||||
<item>вождение автомобиля</item>
|
||||
<item>вождение автобуса</item>
|
||||
<item>поезд</item>
|
||||
<item>мотоцикл</item>
|
||||
<item>Байк</item>
|
||||
<item>ATV</item>
|
||||
|
||||
<item>парусный спорт на земле</item>
|
||||
<item>фрисби</item>
|
||||
<item>алтимат фризби</item>
|
||||
</array>
|
||||
|
||||
<array name="waypoint_types">
|
||||
<item>банкомат</item>
|
||||
<item>банк</item>
|
||||
<item>бар</item>
|
||||
<item>барбекю</item>
|
||||
<item>здание</item>
|
||||
<item>автобусная остановка</item>
|
||||
<item>кафе</item>
|
||||
<item>костер</item>
|
||||
<item>лагерь</item>
|
||||
<item>церковь</item>
|
||||
<item>кофейня</item>
|
||||
<item>удобный магазин</item>
|
||||
<item>питьевая вода</item>
|
||||
<item>оползень</item>
|
||||
<item>паром</item>
|
||||
<item>камин</item>
|
||||
<item>пожарная станция</item>
|
||||
<item>рыболовство</item>
|
||||
<item>автозаправочная станция</item>
|
||||
<item>поле для гольфа</item>
|
||||
<item>продуктовый магазин</item>
|
||||
<item>парикмахерская</item>
|
||||
<item>гавань</item>
|
||||
<item>тропа</item>
|
||||
<item>отель</item>
|
||||
<item>дом</item>
|
||||
<item>информация</item>
|
||||
<item>пересечение</item>
|
||||
<item>почтовый ящик</item>
|
||||
<item>рынок</item>
|
||||
<item>место встречи</item>
|
||||
<item>опера</item>
|
||||
<item>парковка</item>
|
||||
<item>почтовое отделение</item>
|
||||
<item>выбоина</item>
|
||||
<item>полицейский участок</item>
|
||||
<item>железнодорожный переезд</item>
|
||||
<item>ресторан</item>
|
||||
<item>покупки</item>
|
||||
<item>вид</item>
|
||||
<item>магазин</item>
|
||||
<item>бассейн</item>
|
||||
<item>телефон</item>
|
||||
<item>театр</item>
|
||||
<item>туалет</item>
|
||||
<item>туристическая информация</item>
|
||||
<item>туннель</item>
|
||||
<item>дерево</item>
|
||||
<item>водопад</item>
|
||||
<item>фонтан</item>
|
||||
<item>путевая точка</item>
|
||||
</array>
|
||||
|
||||
<array name="sensor_type_options">
|
||||
<item>Нет</item>
|
||||
<item>ANT+ Sensors</item>
|
||||
<item>SRM ANT+ Bridge</item>
|
||||
<item>Zephyr Bluetooth</item>
|
||||
</array>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,501 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Used by the Menu -->
|
||||
<string name="start_recording">Запись трека</string>
|
||||
<string name="stop_recording">Остановить запись</string>
|
||||
<string name="switch_to_sat">Режим спутника</string>
|
||||
<string name="switch_to_map">Режим карты</string>
|
||||
<string name="mylocation">Мое местоположение</string>
|
||||
<string name="list_tracks">Треки</string>
|
||||
<string name="list_markers">Маркеры</string>
|
||||
<string name="delete_all_tracks">Удалить все треки</string>
|
||||
<string name="settings">Настройки</string>
|
||||
<string name="elevation">Высота</string>
|
||||
<string name="choose_track_message">Пожалуйста, выберите трек для просмотра</string>
|
||||
<string name="current_track">Текущий трек</string>
|
||||
<string name="current_segment">Последний сегмент</string>
|
||||
<string name="sensor_state">Состояние датчика</string>
|
||||
<string name="aggregated_stats">Совокупная статистика</string>
|
||||
|
||||
<!-- Error messages -->
|
||||
<string name="error_no_location_manager">На этом устройстве не был обнаружен диспетчер местоположения!</string>
|
||||
<string name="error_no_gps_location_provider">На этом устройстве не был обнаружен поставщик GPS местоположения.</string>
|
||||
<string name="error_sending_to_mymap">Ошибка при отправке вашего трека в Google \"Мои карты\".</string>
|
||||
<string name="error_sending_to_fusiontables">Ошибка при отправке вашего трека в Google Fusion Tables.</string>
|
||||
<string name="error_sending_to_docs">Ошибка при отправке вашего трека в Google Документы.</string>
|
||||
<string name="error_please_try_again_later">Пожалуйста, повторите попытку позже.</string>
|
||||
<string name="error_unable_to_start_recording">Не удалось начать запись. Попробуйте еще раз.</string>
|
||||
<string name="error_unable_to_stop_recording">Не удалось остановить запись. Попробуйте еще раз.</string>
|
||||
<string name="error_unable_to_read_file">Не удалось прочитать из файла.</string>
|
||||
<string name="error_invalid_gpx_format">Неверный формат GPX файла.</string>
|
||||
<string name="error_generic">Произошла ошибка. Пожалуйста, попробуйте еще раз.</string>
|
||||
<string name="error_track_does_not_exist">Трек не существует.</string>
|
||||
<string name="error_out_of_memory">Этот файл слишком большой (должен быть меньше, чем 500 КБ). Прервано.</string>
|
||||
<string name="error_unable_to_insert_marker">Невозможно вставить маркер. Местоположение неизвестно.</string>
|
||||
|
||||
<!-- Status messages -->
|
||||
<string name="wait_for_fix">Ожидание сигнала GPS. Убедитесь в том, что вы находитесь под открытым небом.</string>
|
||||
<string name="status_now_recording">Записывается новый трек.</string>
|
||||
<string name="status_stopped_recording">Запись вашего трека остановлена.</string>
|
||||
<string name="status_new_mymap_has_been_created">Новая Google \"Мои карты\" была создана на maps.google.com.</string>
|
||||
<string name="status_new_fusiontable_has_been_created">Новая таблица Google Fusion была создана на google.com/fusiontables.</string>
|
||||
<string name="status_tracks_have_been_uploaded">Твой трек был отправлен на maps.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_new_doc">Ваш трек был отправлен в новую электронную таблицу на docs.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_docs">Ваш трек был отправлен в docs.google.com.</string>
|
||||
<string name="status_mymap_info">Это может занять несколько минут, прежде чем появятся новые треки.</string>
|
||||
<string name="status_enable_gps">Пожалуйста, нажмите здесь для перехода к разделу настроек Координаты и отметьте пункт \"Спутники GPS\". Для возвращения нажмите кнопку Назад.</string>
|
||||
<string name="status_approximate_location">Примечание: приблизительное местоположение определено относительно вышек сотовой связи и беспроводных сетей.</string>
|
||||
<string name="status_no_location">В настоящее время местоположение не может быть определено. Включите больше источников местоположение (см. раздел настроек Координаты) и убедитесь в том, что находитесь под открытым небом. Повторите попытку позднее.</string>
|
||||
<string name="status_waypoint_inserted">Маркер путевой точки был вставлен.</string>
|
||||
<string name="status_statistics_inserted">Маркер статистики был вставлен.</string>
|
||||
<string name="status_track_upload_status">Статус загрузки:</string>
|
||||
|
||||
<!-- Progress dialog -->
|
||||
<string name="progress_title">Пожалуйста, подождите...</string>
|
||||
<string name="progress_message">Отправка вашего трека в Google.</string>
|
||||
<string name="progress_message_reading_track">Чтение трека...</string>
|
||||
<string name="progress_message_preparing_track">Подготовка трека...</string>
|
||||
<string name="progress_message_authenticating_fusiontables">Аутентификация на Google Fusion Tables...</string>
|
||||
<string name="progress_message_authenticating_mymaps">Аутентификация на Google Карты...</string>
|
||||
<string name="progress_message_authenticating_docs">Аутентификация в Google Документы...</string>
|
||||
<string name="progress_message_sending_docs">Отправка трека в Google Документы...</string>
|
||||
<string name="progress_message_sending_mymaps">Отправка трека в Google Карты...</string>
|
||||
<string name="progress_message_creating_map">Создание новой \"Моей карты\" ...</string>
|
||||
<string name="progress_message_sending_fusiontables">Отправка трека в Fusion Tables...</string>
|
||||
<string name="progress_message_creating_fusiontable">Создание новой Fusion table...</string>
|
||||
<string name="import_progress_message">Импорт GPS трека. Это может занять некоторое время.</string>
|
||||
<string name="write_progress_message">Запись файла на SD карту. Это может занять некоторое время.</string>
|
||||
<string name="progress_message_updating_track">Обновление статистики трека...</string>
|
||||
|
||||
<!-- Used by DeleteAllDataHandler -->
|
||||
<string name="are_you_sure_question">Вы уверены?</string>
|
||||
<string name="all_data_will_be_permanently_deleted">Все треки и маркеры будут удалены с этого телефона.</string>
|
||||
<string name="track_will_be_permanently_deleted">Трек и его маркеры будут удалены из этого телефона.</string>
|
||||
<string name="marker_will_be_permanently_deleted">Маркер будет удален с этого телефона.</string>
|
||||
|
||||
<!-- Text and links when uploading to Google Fusion Tables -->
|
||||
<string name="new_map_description">Создано My Tracks на Android.</string>
|
||||
<string name="fusiontable_link">Создано <a href=\'http://mytracks.appspot.com\'>My Tracks</a> на Android.</string>
|
||||
|
||||
<!-- Text and links when uploading to Google My Maps -->
|
||||
<string name="my_map_link">Создано <a href=\'http://mytracks.appspot.com\'>My Tracks</a> на Android.</string>
|
||||
<string name="new_map_title">Новая карта</string>
|
||||
|
||||
<!-- Formatting of track and marker descriptions -->
|
||||
<string name="points">Точки</string>
|
||||
<string name="recorded_date">Записан</string>
|
||||
<string name="category">Тип деятельности</string>
|
||||
<string name="waypoint_category">Тип маркера</string>
|
||||
<string name="part">(Часть %d)</string>
|
||||
|
||||
<!-- Used by the track recording service -->
|
||||
<string name="recording_your_track">Запись трека...</string>
|
||||
<string name="new_track">Трек %d</string>
|
||||
|
||||
<!-- Common -->
|
||||
<string name="no">Нет</string>
|
||||
<string name="yes">Да</string>
|
||||
<string name="ok">ОК</string>
|
||||
<string name="error">Ошибка</string>
|
||||
<string name="success">Готово</string>
|
||||
<string name="waypoint">Путевая точка</string>
|
||||
<string name="license">Лицензия</string>
|
||||
<string name="cancel">Отмена</string>
|
||||
<string name="close">Закрыть</string>
|
||||
<string name="edit">Правка</string>
|
||||
<string name="save">Сохранить</string>
|
||||
|
||||
<!-- Placemark labels for start and end of track -->
|
||||
<string name="start">(Старт)</string>
|
||||
<string name="end">(Конец)</string>
|
||||
|
||||
<!-- TrackList -->
|
||||
<string name="tracklist_show_track">Показать</string>
|
||||
<string name="tracklist_send_to_mymaps">Отправить в Google \"Мои карты\"</string>
|
||||
<string name="tracklist_send_to_new_mymap">Отправить в новый Google \"Мои карты\"</string>
|
||||
<string name="tracklist_send_to_fusiontables">Отправить в Google Fusion Tables</string>
|
||||
<string name="tracklist_send_to_new_fusiontable">Отправить в новую Google Fusion Table</string>
|
||||
<string name="tracklist_send_to_docs">Отправить в Google Документы</string>
|
||||
<string name="tracklist_send_to_google">Отправить в Google ...</string>
|
||||
<string name="tracklist_delete_track">Удалить из телефона...</string>
|
||||
<string name="tracklist_edit_track">Править детали</string>
|
||||
<string name="tracklist_write_to_sd">Записать на SD карту...</string>
|
||||
<string name="tracklist_save_as_gpx">Сохранить файл GPX</string>
|
||||
<string name="tracklist_save_as_kml">Сохранить файл KML</string>
|
||||
<string name="tracklist_save_as_csv">Сохранить файл CSV</string>
|
||||
<string name="tracklist_save_as_tcx">Сохранить файл TCX</string>
|
||||
<string name="tracklist_btn_send_all_to_fusiontables">Отправить в Google Fusion Tables</string>
|
||||
<string name="tracklist_btn_send_all_to_mymaps">Отправить в Google \"Мои карты\"</string>
|
||||
<string name="tracklist_btn_delete_all">Удалить все</string>
|
||||
<!-- Export All -->
|
||||
<string name="tracklist_btn_export_all">Экспорт всех</string>
|
||||
<string name="export_done">Экспорт закончен</string>
|
||||
<string name="tracklist_pick_one">Выберите трек. Нажмите и удерживайте для получения дополнительных возможностей.</string>
|
||||
<string name="tracklist_all_tracks">Все треки:</string>
|
||||
<string name="tracklist_this_track">Этот трек</string>
|
||||
<string name="tracklist_share_track">Поделиться с друзьями...</string>
|
||||
<string name="tracklist_share_link">Ссылка на карту</string>
|
||||
<string name="tracklist_share_gpx_file">Файл GPX</string>
|
||||
<string name="tracklist_share_kml_file">Файл KML</string>
|
||||
<string name="tracklist_share_csv_file">Файла CSV</string>
|
||||
<string name="tracklist_share_tcx_file">Файл TCX</string>
|
||||
<string name="tracklist_clear_map">Очистить карту</string>
|
||||
<!-- Import All -->
|
||||
<string name="tracklist_btn_import_all">Импорт всех</string>
|
||||
<string name="import_done">Импорт закончен</string>
|
||||
<!-- Format:
|
||||
$1 : Successful imports
|
||||
$2 : Attempted imports
|
||||
$3 : MyTracks gpx path
|
||||
-->
|
||||
<string name="import_done">Импортировано %1$d из %2$d GPX файлов с %3$s</string>
|
||||
<string name="import_empty">GPX файлы не найденны в %s. Возможно не читается SD-карта или каталог не содержит GPX файлы.</string>
|
||||
<string name="import_error">Ошибка импорта файла %s</string>
|
||||
|
||||
<!-- Waypoints list -->
|
||||
<string name="waypointslist_btn_delete_all">Удалить все маркеры</string>
|
||||
<string name="waypointslist_this_waypoint">Этот маркер</string>
|
||||
<string name="waypointslist_delete_waypoint">Удалить</string>
|
||||
<string name="waypointslist_edit_waypoint">Править детали</string>
|
||||
<string name="waypointslist_show_waypoint">Показать на карте</string>
|
||||
<string name="waypointslist_btn_insert_waypoint">Вставить путевую точку</string>
|
||||
<string name="waypointslist_btn_insert_statistics">Вставить статистику</string>
|
||||
<string name="waypointslist_pick_one">Выберите маркер. Нажмите и удерживайте для получения дополнительных возможностей.</string>
|
||||
|
||||
<!-- MyTracks Details -->
|
||||
<string name="trackdetails_title">Трек детали</string>
|
||||
<string name="trackdetails_name">Название трека</string>
|
||||
<string name="trackdetails_description">Описание трека</string>
|
||||
<string name="trackdetails_category">Тип деятельности (например: пешая прогулка, велосипедная прогулка, бег, восхождение...)</string>
|
||||
|
||||
<!-- MyTracks Waypoint Details -->
|
||||
<string name="waypointdetails_title">Маркер детали</string>
|
||||
<string name="waypointdetails_name">Имя маркера</string>
|
||||
<string name="waypointdetails_description">Описание маркера</string>
|
||||
<string name="waypointdetails_category">Тип маркера (например: здание, выбоина, достопримечательность...)</string>
|
||||
|
||||
<!-- MyTracks Settings -->
|
||||
<string name="mytracks_settings">Настройки My Tracks</string>
|
||||
<string name="settings_display">Отображение</string>
|
||||
<string name="settings_recording">Запись</string>
|
||||
<string name="settings_sharing">Обмен</string>
|
||||
|
||||
<string name="settings_not_available_summary">Не доступен в вашем версии Android</string>
|
||||
<string name="settings_not_while_recording">Не доступно во время записи трека</string>
|
||||
|
||||
<string name="settings_announcement_frequency">Частота объявлений</string>
|
||||
<string name="settings_announcement_frequency_summary">Минимальное время между двумя голосовыми объявлениями</string>
|
||||
|
||||
<string name="settings_min_recording_distance">Минимальное расстояние между точками</string>
|
||||
<string name="settings_min_recording_distance_summary">Наименьшее расстояние между двумя записями вашей позиции</string>
|
||||
|
||||
<string name="settings_max_recording_distance">Максимальное расстояние между точками</string>
|
||||
<string name="settings_max_recording_distance_summary">Если два пункта находятся дальше, чем указано, то трек будет разделен</string>
|
||||
|
||||
<string name="settings_min_recording_interval">Минимальное время между точками</string>
|
||||
<string name="settings_min_recording_interval_summary">Наименьший интервал времени между двумя записями вашей позиции</string>
|
||||
|
||||
<string name="settings_min_required_accuracy">Минимальная точность</string>
|
||||
<string name="settings_min_required_accuracy_summary">Запись будет приостановлена, если ваша позиция не является достаточно точной</string>
|
||||
|
||||
<string name="settings_metric_units">Использовать метрические единицы</string>
|
||||
<string name="settings_metric_units_summary_on">Все расстояния будут отображаться в метрических единицах</string>
|
||||
<string name="settings_metric_units_summary_off">Все расстояния будут отображаться в имперских единицах</string>
|
||||
|
||||
<string name="settings_map_public">Обнародовать карты</string>
|
||||
<string name="settings_map_public_summary_on">Загруженные карты будут общедоступны на maps.google.com</string>
|
||||
<string name="settings_map_public_summary_off">Загруженные карты не будут перечислены публично на maps.google.com</string>
|
||||
|
||||
<string name="settings_report_speed_or_pace">Отображать скорость</string>
|
||||
<string name="settings_report_speed_or_pace_summary_on">Скорость будет отображаться</string>
|
||||
<string name="settings_report_speed_or_pace_summary_off">Темп будет отображаться</string>
|
||||
|
||||
<string name="settings_share_url_only">Поделиться только URL</string>
|
||||
<string name="settings_share_url_only_summary_on">При обмене будет отправлен только URL-адрес</string>
|
||||
<string name="settings_share_url_only_summary_off">Содержимое трека будет также включено при обмене</string>
|
||||
|
||||
<string name="settings_split_frequency">Частота деления</string>
|
||||
<string name="settings_split_frequency_summary">Максимальное время или расстояние, после которого будет вставлен новый маркер деления</string>
|
||||
|
||||
<string name="settings_auto_resume_track_timeout">Автоматическое возобновление трек тайм-аут</string>
|
||||
<string name="settings_auto_resume_track_timeout_summary">Максимальное время в минутах, после которого предыдущая запись трека не будет возобновлена на перезагруженном телефоне</string>
|
||||
|
||||
<string name="settings_timestamp_track_name">Штамп времени как название дорожки</string>
|
||||
<string name="settings_timestamp_track_name_summary_on">По умолчанию имя трека будет складываться из даты и времени старта трека</string>
|
||||
<string name="settings_timestamp_track_name_summary_off">Названия треков будут иметь прирост чисел для каждого нового трека.</string>
|
||||
|
||||
<string name="settings_reset">Восстановить значения по умолчанию</string>
|
||||
<string name="settings_reset_summary">Восстановить значения по умолчанию во всех настройках</string>
|
||||
<string name="settings_reset_dialog_message">Все ваши настройки будут стерты и восстановлены значения по умолчанию. Записанные треки будут сохранены. Вы уверены?</string>
|
||||
<string name="settings_reset_done">Все настройки были возвращены к значениям по умолчанию.</string>
|
||||
|
||||
<string name="pace_label">Темп</string>
|
||||
|
||||
<string name="eclair_required">Поддерживается только в Android 2.0 или выше</string>
|
||||
<string name="settings_sensor_type">Тип датчика</string>
|
||||
<string name="settings_sensor_type_summary">Тип подключенного датчика</string>
|
||||
<string name="settings_heart_rate_ant_sensor_id">Очистить ANT подсоединенного датчика пульса</string>
|
||||
<string name="settings_power_ant_sensor_id">Очистить ANT подсоединенного датчика мощности</string>
|
||||
<string name="settings_srm_bridge_ant_sensor_id">Очистить ANT подсоединенного датчика SRM</string>
|
||||
<string name="settings_ant_not_paired">ANT датчик не подсоединен</string>
|
||||
<string name="settings_ant_paired">ANT датчик подсоединен с: %d</string>
|
||||
<string name="bluetooth_sensor_title">Bluetooth датчик</string>
|
||||
<string name="bluetooth_sensor_summary">Подключенный bluetooth датчик</string>
|
||||
<string name="settings_modular_stats_display_title">Отображение модульной статистики</string>
|
||||
|
||||
<!-- Backups -->
|
||||
<string name="settings_backup">Резервное копирование (BETA)</string>
|
||||
<string name="settings_sd_backup">Резервное копирование SD карты</string>
|
||||
<string name="settings_backup_to_sd">Резервировать</string>
|
||||
<string name="settings_backup_to_sd_summary">Создать полную копию всех ваших треков и настроек на SD карту</string>
|
||||
<string name="settings_restore_from_sd">Восстановить</string>
|
||||
<string name="settings_restore_from_sd_summary">Восстановить все треки и параметры с SD карты</string>
|
||||
|
||||
<string name="restore_overwrites_warning">Восстановление резервной копии с SD карты ПЕРЕЗАПИШЕТ все текущие треки и настройки. Вы уверены?</string>
|
||||
<string name="select_backup_to_restore">Выберите резервную копию для восстановления</string>
|
||||
<string name="no_backups">Резервные копии не найдены.</string>
|
||||
<string name="backup_write_progress_message">Запись на SD-карту всех треков и настроек. Это может занять некоторое время...</string>
|
||||
<string name="backup_import_progress_message">Чтение всех треков и настроек с SD-карты. Это может занять некоторое время...</string>
|
||||
|
||||
<!-- MyTracksSky -->
|
||||
<string name="mytracks_sky">Спутники GPS</string>
|
||||
|
||||
<!-- My Maps -->
|
||||
<string name="select_map_message">Выберите карту из вашей учетной записи:</string>
|
||||
<string name="create_new_map">Создать новую карту...</string>
|
||||
<string name="map_list_title">Отправить в Google \"Мои карты\"</string>
|
||||
<string name="maps_list_loading">Загрузка карты ...</string>
|
||||
<string name="maps_list_failed">Ваши карты не могут быть загружены в данный момент!</string>
|
||||
<string name="open_map">Выберите эту карту</string>
|
||||
<string name="edit_map_details">Править детали карты</string>
|
||||
<string name="share_track">Поделиться треком</string>
|
||||
<string name="delete_map">Удалить Карту из вашей учетной записи</string>
|
||||
<string name="map_title">Название карты:</string>
|
||||
<string name="map_description">Описание карты:</string>
|
||||
<string name="map_searchable_edit">Сделать чтобы карта и ее содержимое отображались в результатах поиска</string>
|
||||
<string name="map_not_searchable_edit">Не позволить этой карте или ее содержимому отображаться в результатах поиска, хотя они все еще могут просматриваться другими через прямой URL-адрес</string>
|
||||
<string name="map_searchable">Эта карта и ее содержимое будут отображаться в результатах поиска</string>
|
||||
<string name="map_not_searchable">Ни эта карта, ни ее содержимое не будут отображаться в результатах поиска, но их могут по-прежнему просматривать другие через прямую ссылку</string>
|
||||
|
||||
<!-- Sharing -->
|
||||
<string name="share_map">Поделиться картой с друзьями</string>
|
||||
<string name="share_map_subject">Я хотел бы поделиться с вами треком</string>
|
||||
<string name="share_map_body_format">Я думаю, вы можете быть заинтересованы в этом треке:
|
||||
|
||||
%s</string>
|
||||
<string name="send_track_subject">Я хотел бы поделиться с вами треком</string>
|
||||
<string name="send_track_body_format">Я думаю, вы можете быть заинтересованы в этом треке.
|
||||
|
||||
Просмотреть трек можно с помощью Google Планета Земля или другого программного обоспечения для карт.</string>
|
||||
|
||||
<!-- Visibility -->
|
||||
<string name="public_map">Общественные</string>
|
||||
<string name="unlisted_map">Частные</string>
|
||||
<string name="mapslist_no_maps_available">У вас пока еще нет карт.</string>
|
||||
|
||||
<!-- Statistics View -->
|
||||
<!-- Average Moving -->
|
||||
<string name="average_moving_speed_label">Средняя скорость движения</string>
|
||||
<string name="average_moving_pace_label">Средний темп движения</string>
|
||||
|
||||
<!-- Average -->
|
||||
<string name="average_speed_label">Средняя скорость</string>
|
||||
<string name="average_pace_label">Средний темп</string>
|
||||
|
||||
<string name="elevation_chart_name">Диаграмма высоты</string>
|
||||
<string name="elevation_gain_label">Набор высоты</string>
|
||||
<string name="elevation_label">Высота</string>
|
||||
<string name="latitude_label">Широта</string>
|
||||
<string name="longitude_label">Долгота</string>
|
||||
|
||||
<!-- Min -->
|
||||
<string name="min_elevation_label">Минимальная высота</string>
|
||||
<string name="min_grade_label">Минимальный уклон</string>
|
||||
<string name="min_pace_label">Минимальный темп</string>
|
||||
|
||||
<!-- Max -->
|
||||
<string name="max_elevation_label">Максимальная высота</string>
|
||||
<string name="max_grade_label">Максимальный уклон</string>
|
||||
<string name="max_speed_label">Максимальная скорость</string>
|
||||
|
||||
<string name="loading_track">Загрузка трека...</string>
|
||||
|
||||
<!-- Chart Settings -->
|
||||
<string name="chart_settings">Настройки диаграммы</string>
|
||||
<!-- X Axis -->
|
||||
<string name="x_axis">Ось X</string>
|
||||
<string name="by_distance">По расстоянию</string>
|
||||
<string name="by_time">По времени</string>
|
||||
|
||||
<!-- Y Axis -->
|
||||
<string name="y_axis">Ось Y</string>
|
||||
|
||||
<!-- Units -->
|
||||
<!-- Time -->
|
||||
<string name="hour">час</string>
|
||||
<string name="hours">часов</string>
|
||||
<string name="hr">ч</string>
|
||||
<string name="min">мин</string>
|
||||
<string name="minute">минута</string>
|
||||
<string name="minutes">минут</string>
|
||||
<string name="second">секунда</string>
|
||||
<string name="seconds">секунд</string>
|
||||
<string name="milliseconds">мс</string>
|
||||
|
||||
<!-- Distance -->
|
||||
<string name="meter">м</string>
|
||||
<string name="kilometer">км</string>
|
||||
<string name="kilometers_long">километров</string>
|
||||
<string name="feet">футов</string>
|
||||
<string name="mile">миль</string>
|
||||
<string name="miles_long">мили</string>
|
||||
|
||||
<!-- Speed and Pace -->
|
||||
<string name="kilometer_per_hour">км/ч</string>
|
||||
<string name="kilometer_per_hour_long">километров в час</string>
|
||||
<string name="min_per_kilometer">мин/км</string>
|
||||
<string name="per_kilometer">за километр</string>
|
||||
<string name="mile_per_hour">миль/ч</string>
|
||||
<string name="mile_per_hour_long">миль в час</string>
|
||||
<string name="min_per_mile">мин/миля</string>
|
||||
<string name="per_mile">за милю</string>
|
||||
|
||||
<!-- Sensors -->
|
||||
<string name="watts">Вт</string>
|
||||
|
||||
<string name="revolutions_per_minute">об/мин</string>
|
||||
<string name="bpm">bpm</string>
|
||||
|
||||
<!-- Stats Labels -->
|
||||
<string name="moving_time_label">Время движения</string>
|
||||
<string name="total_time_label">Общее время</string>
|
||||
<string name="time_label">Время</string>
|
||||
<string name="sd_unavail">SD карта недоступна</string>
|
||||
<string name="speed">Скорость</string>
|
||||
<string name="start_trip">Вы должны начать путешествие.</string>
|
||||
<string name="statistics">Статистика</string>
|
||||
<string name="total_distance_label">Общее расстояние</string>
|
||||
<string name="distance_label">Расстояние</string>
|
||||
<string name="power">Мощность</string>
|
||||
<string name="cadence">Каденс</string>
|
||||
<string name="heart_rate">Пульс</string>
|
||||
<string name="max_heart_rate">Максимальный пульс</string>
|
||||
<string name="unknown">-</string>
|
||||
<string name="waiting">Ожидание...</string>
|
||||
|
||||
<!-- End User License Agreement -->
|
||||
<string name="eula_title">Лицензионное соглашение</string>
|
||||
<string name="accept">Принять</string>
|
||||
<string name="decline">Отклонить</string>
|
||||
|
||||
<!-- About -->
|
||||
<string name="about">О программе</string>
|
||||
<string name="help">Справка</string>
|
||||
<string name="about_team">Команда:</string>
|
||||
<string name="about_version">Версия:</string>
|
||||
<string name="about_support">Поддержка:</string>
|
||||
<string name="about_privacy">Приватность:</string>
|
||||
|
||||
<!-- Send to Google -->
|
||||
<string name="sendtogoogle_title">Отправить...</string>
|
||||
<string name="sendtogoogle_google_fusiontables">Google Fusion Tables</string>
|
||||
<string name="sendtogoogle_google_mymaps">Google \"Мои карты\"</string>
|
||||
<string name="sendtogoogle_google_docs">Google Документы</string>
|
||||
<string name="sendtogoogle_send_now">Отправить</string>
|
||||
<string name="sendtogoogle_create_new_map">Создать новую карту</string>
|
||||
<string name="sendtogoogle_pick_existing_map">Выбрать существующую карту</string>
|
||||
<string name="sendtogoogle_send_stats">Отправить статистику трека</string>
|
||||
<string name="sendtogoogle_send_stats_and_points">Отправить статистику и точки</string>
|
||||
|
||||
<!-- Getting the account to upload to. -->
|
||||
<string name="no_account_found_title">Учетная запись не найдена</string>
|
||||
<string name="no_account_found">Не найдена учетная запись для загрузки треков.</string>
|
||||
<string name="choose_account_title">Выбор учетной записи</string>
|
||||
|
||||
<!-- SD card -->
|
||||
<string name="io_no_external_storage_found">Не обнаружено внешнее устройство хранения данных. Убедитесь, что SD карта вставлена, и что ваш телефон не подключен к компьютеру.</string>
|
||||
<string name="io_write_failed">Невозможно записать файл.</string>
|
||||
<string name="io_read_failed">Невозможно прочитать из файла.</string>
|
||||
<string name="io_create_dir_failed">Невозможно создать папку на SD карте.</string>
|
||||
<string name="io_write_finished">Запись на SD карту закончена.</string>
|
||||
<string name="io_read_finished">Чтение с SD карты закончено.</string>
|
||||
|
||||
<!-- VersionChecker -->
|
||||
<string name="version_check_title">Проверить обновления</string>
|
||||
<string name="version_check_upgrade_button">Обновить сейчас</string>
|
||||
<string name="version_check_continue_button">Продолжить без обновления</string>
|
||||
<string name="upgrade_required">Ваша версия %1$S больше не может работать должным образом, и больше не поддерживается. Обновите %1$s для продолжения использования.</string>
|
||||
<string name="upgrade_recommended">Ваша версия %1$S больше не может работать должным образом. Вы можете обновить ее сейчас, либо продолжать использовать ее на свой страх и риск. Некоторые функции, такие как синхронизация с сервером может не функционировать до обновления.</string>
|
||||
<string name="upgrade_available">Доступна новая версия %1$s. Вы можете продолжать использовать текущую версию без проблем, но вы не получите новейшие функции, до тех пор, пока не обновитесь.</string>
|
||||
|
||||
<!-- Welcome -->
|
||||
<string name="welcome">Добро пожаловать</string>
|
||||
<string name="welcome_read_later">Ок</string>
|
||||
<string name="welcome_about">О My Tracks</string>
|
||||
|
||||
<!-- Announcement -->
|
||||
<string name="announce_no_distance">My Tracks нет расстояния</string>
|
||||
<!-- Format:
|
||||
$1 : Distance label
|
||||
$2 : Distance value (5)
|
||||
$3 : Distance units (mi, km)
|
||||
$4 : Time description (10 minutes 5 seconds)
|
||||
$5 : Speed value (5.6) : Pace value (5 minutes 6 seconds)
|
||||
$6 : Speed units (mph) : Pace units (per mile)
|
||||
-->
|
||||
<string name="announce_template">Мои треки %1$s %2$.2f %3$s в %4$s на %5$s %6$s</string>
|
||||
|
||||
<!-- Check Units -->
|
||||
<string name="check_units_title">Единицы измерения обратите внимание</string>
|
||||
<string name="check_units_message">По умолчанию используются метрические единицы. Вы хотели бы изменить этот параметр?</string>
|
||||
|
||||
<!-- Fake preference keys - never saved, but show options in the preferences screen -->
|
||||
<string name="method_bluetooth">Bluetooth</string>
|
||||
<string name="bluetooth_options">Параметры Bluetooth</string>
|
||||
<string name="bluetooth_pairing">Подключение устройства</string>
|
||||
<string name="bluetooth_pairing_summary">Открыть настройки Android по bluetooth для подключения устройства</string>
|
||||
<string name="sensor_bluetooth_options_key">bluetoothSensorsEnabled</string>
|
||||
<string name="ant_options">Параметры ANT</string>
|
||||
<string name="sensor_options">Параметры датчика</string>
|
||||
|
||||
<!-- Bluetooth Sensor -->
|
||||
<string name="bluetooth_connected">Подключен к %s</string>
|
||||
<string name="bluetooth_connecting">Подключение Bluetooth датчика...</string>
|
||||
<string name="bluetooth_not_connected">Bluetooth датчик не подключен</string>
|
||||
|
||||
<!-- Sensor State -->
|
||||
<string name="sensor_data_time">Датчик времени</string>
|
||||
<string name="power_meter_enabled">Измеритель мощности включен</string>
|
||||
<string name="heart_rate_monitor_enabled">Монитор пульса включен</string>
|
||||
<string name="no_sensor_manager">Нет диспетчера датчиков</string>
|
||||
<string name="enabled">Включено</string>
|
||||
<string name="connecting">Подключение</string>
|
||||
<string name="connected">Подключено</string>
|
||||
<string name="disconnected">Отключено</string>
|
||||
<string name="no_sensor_service">Нет службы датчиков</string>
|
||||
<string name="searching">Поиск</string>
|
||||
<string name="sending">Отправка</string>
|
||||
|
||||
<!-- Manifest description (not seen inside the app) -->
|
||||
<string name="notification_permission_label">получать уведомления о записи трека</string>
|
||||
<string name="read_tracks_permission_label">чтение записанных данных трека</string>
|
||||
<string name="write_tracks_permission_label">запись данных трека, старт/стоп записи треков</string>
|
||||
<string name="notification_permission_description">Получать уведомления, при старте или останове записи трека.</string>
|
||||
<string name="read_tracks_permission_description">Иметь возможность читать данные трека, такие как точки и путевые точки.</string>
|
||||
<string name="write_tracks_permission_description">Иметь возможность записать данные трека, такие как начало записи или добавление путевых точек.</string>
|
||||
</resources>
|
||||
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Av</item>
|
||||
<item>1 min</item>
|
||||
<item>2 min</item>
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>30 min</item>
|
||||
<item>60 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 m</item>
|
||||
@@ -67,7 +55,6 @@ limitations under the License.
|
||||
<item>3.1 miles</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Minimum recording interval -->
|
||||
<string-array name="min_recording_interval_options">
|
||||
<item>batterioptimerad (anpassningsbar)</item>
|
||||
@@ -113,9 +100,9 @@ limitations under the License.
|
||||
<item>3.1 miles (dålig GPS-signal)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>Ingen delning</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Av</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -131,8 +118,8 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>Ingen delning</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Av</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
|
||||
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>关闭</item>
|
||||
<item>1 分钟</item>
|
||||
<item>2 分钟</item>
|
||||
<item>5 分钟</item>
|
||||
<item>10 分钟</item>
|
||||
<item>15 分钟</item>
|
||||
<item>30 分钟</item>
|
||||
<item>60 分钟</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 米</item>
|
||||
@@ -112,9 +100,9 @@ limitations under the License.
|
||||
<item>3.1 英里 (糟糕的 GPS 信号)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>不分割</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>关闭</item>
|
||||
<item>100 千米</item>
|
||||
<item>50 千米</item>
|
||||
<item>25 千米</item>
|
||||
@@ -130,8 +118,8 @@ limitations under the License.
|
||||
<item>1 分钟</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>不分割</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>关闭</item>
|
||||
<item>100 英里</item>
|
||||
<item>50 英里</item>
|
||||
<item>25 英里</item>
|
||||
@@ -155,6 +143,7 @@ limitations under the License.
|
||||
<item>15 分钟</item>
|
||||
<item>总是</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Other non-preference arrays -->
|
||||
<array name="activity_types">
|
||||
<item>未知</item>
|
||||
|
||||
@@ -15,31 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Off</item>
|
||||
<item>1 min</item>
|
||||
<item>2 min</item>
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>30 min</item>
|
||||
<item>60 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<string-array name="task_frequency_values">
|
||||
<item>-1</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>5</item>
|
||||
<item>10</item>
|
||||
<item>15</item>
|
||||
<item>30</item>
|
||||
<item>60</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Minimum recording distance -->
|
||||
<string-array name="min_recording_distance_options">
|
||||
<item>1 m</item>
|
||||
@@ -61,18 +36,6 @@ limitations under the License.
|
||||
<item>328 ft</item>
|
||||
</string-array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<string-array name="min_recording_distance_values">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>10</item>
|
||||
<item>100</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Maximum recording distance -->
|
||||
<string-array name="max_recording_distance_options">
|
||||
<item>50 m</item>
|
||||
@@ -92,17 +55,6 @@ limitations under the License.
|
||||
<item>3.1 miles</item>
|
||||
</string-array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<string-array name="max_recording_distance_values">
|
||||
<item>50</item>
|
||||
<item>100</item>
|
||||
<item>200</item>
|
||||
<item>500</item>
|
||||
<item>1000</item>
|
||||
<item>5000</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Minimum recording interval -->
|
||||
<string-array name="min_recording_interval_options">
|
||||
<item>battery miser (adaptive)</item>
|
||||
@@ -123,27 +75,6 @@ limitations under the License.
|
||||
<item>30 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<string-array name="min_recording_interval_values">
|
||||
<item>-2</item>
|
||||
<item>-1</item>
|
||||
<item>0</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>10</item>
|
||||
<item>20</item>
|
||||
<item>30</item>
|
||||
<item>60</item>
|
||||
<item>120</item>
|
||||
<item>300</item>
|
||||
<item>480</item>
|
||||
<item>900</item>
|
||||
<item>1800</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Minimum required accuracy -->
|
||||
<string-array name="min_required_accuracy_options">
|
||||
<item>10 m (excellent GPS signal)</item>
|
||||
@@ -169,23 +100,9 @@ limitations under the License.
|
||||
<item>3.1 miles (poor GPS signal)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<string-array name="min_required_accuracy_values">
|
||||
<item>10</item>
|
||||
<item>20</item>
|
||||
<item>50</item>
|
||||
<item>100</item>
|
||||
<item>200</item>
|
||||
<item>500</item>
|
||||
<item>1000</item>
|
||||
<item>2000</item>
|
||||
<item>5000</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>No splitting</item>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Off</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
@@ -201,8 +118,8 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>No splitting</item>
|
||||
<string-array name="task_frequency_options_ft">
|
||||
<item>Off</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
@@ -218,24 +135,6 @@ limitations under the License.
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<string-array name="split_frequency_values">
|
||||
<item>0</item>
|
||||
<item>-100</item>
|
||||
<item>-50</item>
|
||||
<item>-25</item>
|
||||
<item>-10</item>
|
||||
<item>-5</item>
|
||||
<item>-1</item>
|
||||
<item>60</item>
|
||||
<item>30</item>
|
||||
<item>15</item>
|
||||
<item>10</item>
|
||||
<item>5</item>
|
||||
<item>2</item>
|
||||
<item>1</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Auto-resume track timeout -->
|
||||
<string-array name="auto_resume_track_timeout_options">
|
||||
<item>Never</item>
|
||||
@@ -245,16 +144,6 @@ limitations under the License.
|
||||
<item>Always</item>
|
||||
</string-array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<string-array name="auto_resume_track_timeout_values">
|
||||
<item>0</item>
|
||||
<item>5</item>
|
||||
<item>10</item>
|
||||
<item>15</item>
|
||||
<item>-1</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- Other non-preference arrays -->
|
||||
<array name="activity_types">
|
||||
<item>unknown</item>
|
||||
@@ -383,14 +272,6 @@ limitations under the License.
|
||||
<item>way point</item>
|
||||
</array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<array name="export_formats">
|
||||
<item>GPX</item>
|
||||
<item>KML</item>
|
||||
<item>CSV</item>
|
||||
<item>TCX</item>
|
||||
</array>
|
||||
|
||||
<array name="sensor_type_options">
|
||||
<item>None</item>
|
||||
<item>ANT+ Sensors</item>
|
||||
@@ -398,18 +279,4 @@ limitations under the License.
|
||||
<item>Zephyr Bluetooth</item>
|
||||
</array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<array name="sensor_type_values">
|
||||
<item>@string/none</item>
|
||||
<item>@string/ant_sensor_type</item>
|
||||
<item>@string/srm_ant_bridge_sensor_type</item>
|
||||
<item>@string/zephyr_sensor_type</item>
|
||||
</array>
|
||||
|
||||
<!-- DO NOT TRANSLATE -->
|
||||
<string-array name="ant_sensor_type_values">
|
||||
<item>@string/ant_sensor_type</item>
|
||||
<item>@string/srm_ant_bridge_sensor_type</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Do not translate any arrays in this file. -->
|
||||
<string-array name="min_required_accuracy_values">
|
||||
<item>10</item>
|
||||
<item>20</item>
|
||||
<item>50</item>
|
||||
<item>100</item>
|
||||
<item>200</item>
|
||||
<item>500</item>
|
||||
<item>1000</item>
|
||||
<item>2000</item>
|
||||
<item>5000</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="min_recording_distance_values">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>10</item>
|
||||
<item>100</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="min_recording_distance_values">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>10</item>
|
||||
<item>100</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="max_recording_distance_values">
|
||||
<item>50</item>
|
||||
<item>100</item>
|
||||
<item>200</item>
|
||||
<item>500</item>
|
||||
<item>1000</item>
|
||||
<item>5000</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="min_recording_interval_values">
|
||||
<item>-2</item>
|
||||
<item>-1</item>
|
||||
<item>0</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>10</item>
|
||||
<item>20</item>
|
||||
<item>30</item>
|
||||
<item>60</item>
|
||||
<item>120</item>
|
||||
<item>300</item>
|
||||
<item>480</item>
|
||||
<item>900</item>
|
||||
<item>1800</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="task_frequency_values">
|
||||
<item>0</item>
|
||||
<item>-100</item>
|
||||
<item>-50</item>
|
||||
<item>-25</item>
|
||||
<item>-10</item>
|
||||
<item>-5</item>
|
||||
<item>-1</item>
|
||||
<item>60</item>
|
||||
<item>30</item>
|
||||
<item>15</item>
|
||||
<item>10</item>
|
||||
<item>5</item>
|
||||
<item>2</item>
|
||||
<item>1</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="auto_resume_track_timeout_values">
|
||||
<item>0</item>
|
||||
<item>5</item>
|
||||
<item>10</item>
|
||||
<item>15</item>
|
||||
<item>-1</item>
|
||||
</string-array>
|
||||
|
||||
<array name="export_formats">
|
||||
<item>GPX</item>
|
||||
<item>KML</item>
|
||||
<item>CSV</item>
|
||||
<item>TCX</item>
|
||||
</array>
|
||||
|
||||
<array name="sensor_type_values">
|
||||
<item>@string/none</item>
|
||||
<item>@string/ant_sensor_type</item>
|
||||
<item>@string/srm_ant_bridge_sensor_type</item>
|
||||
<item>@string/zephyr_sensor_type</item>
|
||||
</array>
|
||||
|
||||
<string-array name="ant_sensor_type_values">
|
||||
<item>@string/ant_sensor_type</item>
|
||||
<item>@string/srm_ant_bridge_sensor_type</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -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" />
|
||||
|
||||
<com.google.android.apps.mytracks.IntegerListPreference
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.services.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.stats.DoubleBuffer;
|
||||
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.google.android.apps.mytracks.TrackDataHub.ListenerDataType;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.services.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
import com.google.android.apps.mytracks.util.GeoRect;
|
||||
|
||||
@@ -43,8 +43,8 @@ import com.google.android.apps.mytracks.io.sendtogoogle.SendDialog;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendResult;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendType;
|
||||
import com.google.android.apps.mytracks.services.ITrackRecordingService;
|
||||
import com.google.android.apps.mytracks.services.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingService;
|
||||
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.apps.mytracks.util.SystemUtils;
|
||||
|
||||
@@ -19,8 +19,8 @@ import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.io.backup.BackupActivityHelper;
|
||||
import com.google.android.apps.mytracks.io.backup.BackupPreferencesListener;
|
||||
import com.google.android.apps.mytracks.services.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.services.sensors.ant.AntUtils;
|
||||
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
import com.google.android.apps.mytracks.util.BluetoothDeviceUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
@@ -266,9 +266,6 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
final ListPreference minRequiredAccuracy =
|
||||
(ListPreference) findPreference(
|
||||
getString(R.string.min_required_accuracy_key));
|
||||
final ListPreference splitFrequency =
|
||||
(ListPreference) findPreference(
|
||||
getString(R.string.split_frequency_key));
|
||||
|
||||
minRecordingDistance.setEntries(isMetric
|
||||
? R.array.min_recording_distance_options
|
||||
@@ -279,11 +276,20 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
minRequiredAccuracy.setEntries(isMetric
|
||||
? R.array.min_required_accuracy_options
|
||||
: R.array.min_required_accuracy_options_ft);
|
||||
splitFrequency.setEntries(isMetric
|
||||
? R.array.split_frequency_options
|
||||
: R.array.split_frequency_options_ft);
|
||||
setTaskOptions(isMetric, R.string.announcement_frequency_key);
|
||||
setTaskOptions(isMetric, R.string.split_frequency_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user visible options for a periodic task.
|
||||
*/
|
||||
private void setTaskOptions(boolean isMetric, int listId) {
|
||||
final ListPreference taskFrequency =
|
||||
(ListPreference) findPreference(getString(listId));
|
||||
taskFrequency.setEntries(isMetric
|
||||
? R.array.task_frequency_options
|
||||
: R.array.task_frequency_options_ft);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures preference actions related to bluetooth.
|
||||
|
||||
@@ -20,7 +20,7 @@ import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
import com.google.android.apps.mytracks.TrackDataHub.ListenerDataType;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.services.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
|
||||
@@ -798,7 +798,7 @@ public class TrackDataHub {
|
||||
if (RECORDING_TRACK_KEY.equals(key)) {
|
||||
recordingTrackId = preferences.getLong(RECORDING_TRACK_KEY, -1);
|
||||
} else if (MIN_REQUIRED_ACCURACY_KEY.equals(key)) {
|
||||
minRequiredAccuracy = preferences.getInt(RECORDING_TRACK_KEY,
|
||||
minRequiredAccuracy = preferences.getInt(MIN_REQUIRED_ACCURACY_KEY,
|
||||
Constants.DEFAULT_MIN_REQUIRED_ACCURACY);
|
||||
} else if (METRIC_UNITS_KEY.equals(key)) {
|
||||
useMetricUnits = preferences.getBoolean(METRIC_UNITS_KEY, true);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Copyright 2011 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
|
||||
@@ -15,332 +15,54 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.apps.mytracks.util.LocationUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* The class which exports tracks to the SD card.
|
||||
* This writer is format-neutral - it handles creating the output file
|
||||
* and reading the track to be exported, but requires an instance of
|
||||
* Implementations of this class export tracks to the SD card. This class is
|
||||
* intended to be format-neutral - it handles creating the output file and
|
||||
* reading the track to be exported, but requires an instance of
|
||||
* {@link TrackFormatWriter} to actually format the data.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TrackWriter {
|
||||
|
||||
private final Context context;
|
||||
private final MyTracksProviderUtils providerUtils;
|
||||
private final Track track;
|
||||
private final TrackFormatWriter writer;
|
||||
private final FileUtils fileUtils;
|
||||
private Runnable onCompletion = null;
|
||||
private boolean success = false;
|
||||
private int errorMessage = -1;
|
||||
private File directory = null;
|
||||
private File file = null;
|
||||
|
||||
public TrackWriter(Context context, MyTracksProviderUtils providerUtils,
|
||||
Track track, TrackFormatWriter writer) {
|
||||
this.context = context;
|
||||
this.providerUtils = providerUtils;
|
||||
this.track = track;
|
||||
this.writer = writer;
|
||||
this.fileUtils = new FileUtils();
|
||||
}
|
||||
|
||||
public interface TrackWriter {
|
||||
/**
|
||||
* Sets a completion callback.
|
||||
*
|
||||
* @param onCompletion Runnable that will be executed when finished
|
||||
*/
|
||||
public void setOnCompletion(Runnable onCompletion) {
|
||||
this.onCompletion = onCompletion;
|
||||
}
|
||||
void setOnCompletion(Runnable onCompletion);
|
||||
|
||||
/**
|
||||
* Sets a custom directory where the file will be written.
|
||||
*/
|
||||
public void setDirectory(File directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
void setDirectory(File directory);
|
||||
|
||||
public String getAbsolutePath() {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
/**
|
||||
* Returns the absolute path to the file which was created.
|
||||
*/
|
||||
String getAbsolutePath();
|
||||
|
||||
/**
|
||||
* Writes the given track id to the SD card.
|
||||
* This is non-blocking.
|
||||
*/
|
||||
public void writeTrackAsync() {
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
writeTrack();
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
void writeTrackAsync();
|
||||
|
||||
/**
|
||||
* Writes the given track id to the SD card.
|
||||
* This is blocking.
|
||||
*/
|
||||
public void writeTrack() {
|
||||
// Open the input and output
|
||||
success = false;
|
||||
errorMessage = R.string.error_track_does_not_exist;
|
||||
if (track != null) {
|
||||
if (openFile()) {
|
||||
writeDocument();
|
||||
}
|
||||
}
|
||||
finished();
|
||||
}
|
||||
|
||||
public int getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public boolean wasSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper methods:
|
||||
* ===============
|
||||
*/
|
||||
|
||||
private void finished() {
|
||||
if (onCompletion != null) {
|
||||
runOnUiThread(onCompletion);
|
||||
return;
|
||||
}
|
||||
}
|
||||
void writeTrack();
|
||||
|
||||
/**
|
||||
* Runs the given runnable in the UI thread.
|
||||
* Returns true if the write completed successfully.
|
||||
*/
|
||||
protected void runOnUiThread(Runnable runnable) {
|
||||
if (context instanceof Activity) {
|
||||
((Activity) context).runOnUiThread(runnable);
|
||||
}
|
||||
}
|
||||
boolean wasSuccess();
|
||||
|
||||
/**
|
||||
* Opens the file and prepares the format writer for it.
|
||||
*
|
||||
* @return true on success, false otherwise (and errorMessage is set)
|
||||
* Returns the error message (if any) generated by a writer failure.
|
||||
*/
|
||||
protected boolean openFile() {
|
||||
if (!canWriteFile()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the file doesn't exist yet (possibly by changing the filename)
|
||||
String fileName = fileUtils.buildUniqueFileName(
|
||||
directory, track.getName(), writer.getExtension());
|
||||
if (fileName == null) {
|
||||
Log.e(Constants.TAG,
|
||||
"Unable to get a unique filename for " + fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.i(Constants.TAG, "Writing track to: " + fileName);
|
||||
try {
|
||||
writer.prepare(track, newOutputStream(fileName));
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(Constants.TAG, "Failed to open output file.", e);
|
||||
errorMessage = R.string.io_write_failed;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks and returns whether we're ready to create the output file.
|
||||
*/
|
||||
protected boolean canWriteFile() {
|
||||
if (directory == null) {
|
||||
String dirName =
|
||||
fileUtils.buildExternalDirectoryPath(writer.getExtension());
|
||||
directory = newFile(dirName);
|
||||
}
|
||||
|
||||
if (!fileUtils.isSdCardAvailable()) {
|
||||
Log.i(Constants.TAG, "Could not find SD card.");
|
||||
errorMessage = R.string.io_no_external_storage_found;
|
||||
return false;
|
||||
}
|
||||
if (!fileUtils.ensureDirectoryExists(directory)) {
|
||||
Log.i(Constants.TAG, "Could not create export directory.");
|
||||
errorMessage = R.string.io_create_dir_failed;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new output stream to write to the given filename.
|
||||
*
|
||||
* @throws FileNotFoundException if the file could't be created
|
||||
*/
|
||||
protected OutputStream newOutputStream(String fileName)
|
||||
throws FileNotFoundException {
|
||||
file = new File(directory, fileName);
|
||||
return new FileOutputStream(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file object for the given path.
|
||||
*/
|
||||
protected File newFile(String path) {
|
||||
return new File(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the waypoints for the given track.
|
||||
*
|
||||
* @param trackId the ID of the track to write waypoints for
|
||||
*/
|
||||
private void writeWaypoints(long trackId) {
|
||||
// TODO: Stream through he waypoints in chunks.
|
||||
// I am leaving the number of waypoints very high which should not be a
|
||||
// problem because we don't try to load them into objects all at the
|
||||
// same time.
|
||||
Cursor cursor = null;
|
||||
cursor = providerUtils.getWaypointsCursor(trackId, 0,
|
||||
Constants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
// Yes, this will skip the 1st way point and that is intentional
|
||||
// as the 1st points holds the stats for the current/last segment.
|
||||
while (cursor.moveToNext()) {
|
||||
Waypoint wpt = providerUtils.createWaypoint(cursor);
|
||||
writer.writeWaypoint(wpt);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual work of writing the track to the now open file.
|
||||
*/
|
||||
void writeDocument() {
|
||||
Log.d(Constants.TAG, "Started writing track.");
|
||||
writer.writeHeader();
|
||||
writeWaypoints(track.getId());
|
||||
writeLocations();
|
||||
writer.writeFooter();
|
||||
writer.close();
|
||||
success = true;
|
||||
Log.d(Constants.TAG, "Done writing track.");
|
||||
errorMessage = R.string.io_write_finished;
|
||||
}
|
||||
|
||||
private void writeLocations() {
|
||||
boolean wroteFirst = false;
|
||||
boolean segmentOpen = false;
|
||||
boolean isLastValid = false;
|
||||
|
||||
class TrackWriterLocationFactory implements MyTracksProviderUtils.LocationFactory {
|
||||
Location currentLocation;
|
||||
Location lastLocation;
|
||||
|
||||
@Override
|
||||
public Location createLocation() {
|
||||
if (currentLocation == null) {
|
||||
currentLocation = new MyTracksLocation("");
|
||||
}
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public void swapLocations() {
|
||||
Location tmpLoc = lastLocation;
|
||||
lastLocation = currentLocation;
|
||||
currentLocation = tmpLoc;
|
||||
if (currentLocation != null) {
|
||||
currentLocation.reset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TrackWriterLocationFactory locationFactory = new TrackWriterLocationFactory();
|
||||
LocationIterator it = providerUtils.getLocationIterator(track.getId(), 0, false,
|
||||
locationFactory);
|
||||
try {
|
||||
if (!it.hasNext()) {
|
||||
Log.w(Constants.TAG, "Unable to get any points to write");
|
||||
return;
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
Location loc = it.next();
|
||||
|
||||
boolean isValid = LocationUtils.isValidLocation(loc);
|
||||
boolean validSegment = isValid && isLastValid;
|
||||
if (!wroteFirst && validSegment) {
|
||||
// Found the first two consecutive points which are valid
|
||||
writer.writeBeginTrack(locationFactory.lastLocation);
|
||||
wroteFirst = true;
|
||||
}
|
||||
|
||||
if (validSegment) {
|
||||
if (!segmentOpen) {
|
||||
// Start a segment for this point
|
||||
writer.writeOpenSegment();
|
||||
segmentOpen = true;
|
||||
|
||||
// Write the previous point, which we had previously skipped
|
||||
writer.writeLocation(locationFactory.lastLocation);
|
||||
}
|
||||
|
||||
// Write the current point
|
||||
writer.writeLocation(loc);
|
||||
} else {
|
||||
if (segmentOpen) {
|
||||
writer.writeCloseSegment();
|
||||
segmentOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
locationFactory.swapLocations();
|
||||
isLastValid = isValid;
|
||||
}
|
||||
if (segmentOpen) {
|
||||
writer.writeCloseSegment();
|
||||
segmentOpen = false;
|
||||
}
|
||||
if (wroteFirst) {
|
||||
writer.writeEndTrack(locationFactory.lastLocation);
|
||||
}
|
||||
} finally {
|
||||
it.close();
|
||||
}
|
||||
}
|
||||
int getErrorMessage();
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ public class TrackWriterFactory {
|
||||
MyTracksProviderUtils providerUtils,
|
||||
Track track, TrackFileFormat format) {
|
||||
TrackFormatWriter writer = format.newFormatWriter(context);
|
||||
return new TrackWriter(context, providerUtils, track, writer);
|
||||
return new TrackWriterImpl(context, providerUtils, track, writer);
|
||||
}
|
||||
|
||||
private TrackWriterFactory() { }
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright 2008 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.io.file;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.apps.mytracks.util.LocationUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* This class exports tracks to the SD card. It is intended to be format-
|
||||
* neutral -- it handles creating the output file and reading the track to be
|
||||
* exported, but requires an instance of {@link TrackFormatWriter} to actually
|
||||
* format the data.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TrackWriterImpl implements TrackWriter {
|
||||
private final Context context;
|
||||
private final MyTracksProviderUtils providerUtils;
|
||||
private final Track track;
|
||||
private final TrackFormatWriter writer;
|
||||
private final FileUtils fileUtils;
|
||||
private Runnable onCompletion = null;
|
||||
private boolean success = false;
|
||||
private int errorMessage = -1;
|
||||
private File directory = null;
|
||||
private File file = null;
|
||||
|
||||
TrackWriterImpl(Context context, MyTracksProviderUtils providerUtils,
|
||||
Track track, TrackFormatWriter writer) {
|
||||
this.context = context;
|
||||
this.providerUtils = providerUtils;
|
||||
this.track = track;
|
||||
this.writer = writer;
|
||||
this.fileUtils = new FileUtils();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnCompletion(Runnable onCompletion) {
|
||||
this.onCompletion = onCompletion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirectory(File directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAbsolutePath() {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTrackAsync() {
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
writeTrack();
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTrack() {
|
||||
// Open the input and output
|
||||
success = false;
|
||||
errorMessage = R.string.error_track_does_not_exist;
|
||||
if (track != null) {
|
||||
if (openFile()) {
|
||||
writeDocument();
|
||||
}
|
||||
}
|
||||
finished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper methods:
|
||||
* ===============
|
||||
*/
|
||||
|
||||
private void finished() {
|
||||
if (onCompletion != null) {
|
||||
runOnUiThread(onCompletion);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given runnable in the UI thread.
|
||||
*/
|
||||
protected void runOnUiThread(Runnable runnable) {
|
||||
if (context instanceof Activity) {
|
||||
((Activity) context).runOnUiThread(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the file and prepares the format writer for it.
|
||||
*
|
||||
* @return true on success, false otherwise (and errorMessage is set)
|
||||
*/
|
||||
protected boolean openFile() {
|
||||
if (!canWriteFile()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the file doesn't exist yet (possibly by changing the filename)
|
||||
String fileName = fileUtils.buildUniqueFileName(
|
||||
directory, track.getName(), writer.getExtension());
|
||||
if (fileName == null) {
|
||||
Log.e(Constants.TAG,
|
||||
"Unable to get a unique filename for " + fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.i(Constants.TAG, "Writing track to: " + fileName);
|
||||
try {
|
||||
writer.prepare(track, newOutputStream(fileName));
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(Constants.TAG, "Failed to open output file.", e);
|
||||
errorMessage = R.string.io_write_failed;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks and returns whether we're ready to create the output file.
|
||||
*/
|
||||
protected boolean canWriteFile() {
|
||||
if (directory == null) {
|
||||
String dirName =
|
||||
fileUtils.buildExternalDirectoryPath(writer.getExtension());
|
||||
directory = newFile(dirName);
|
||||
}
|
||||
|
||||
if (!fileUtils.isSdCardAvailable()) {
|
||||
Log.i(Constants.TAG, "Could not find SD card.");
|
||||
errorMessage = R.string.io_no_external_storage_found;
|
||||
return false;
|
||||
}
|
||||
if (!fileUtils.ensureDirectoryExists(directory)) {
|
||||
Log.i(Constants.TAG, "Could not create export directory.");
|
||||
errorMessage = R.string.io_create_dir_failed;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new output stream to write to the given filename.
|
||||
*
|
||||
* @throws FileNotFoundException if the file could't be created
|
||||
*/
|
||||
protected OutputStream newOutputStream(String fileName)
|
||||
throws FileNotFoundException {
|
||||
file = new File(directory, fileName);
|
||||
return new FileOutputStream(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file object for the given path.
|
||||
*/
|
||||
protected File newFile(String path) {
|
||||
return new File(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the waypoints for the given track.
|
||||
*
|
||||
* @param trackId the ID of the track to write waypoints for
|
||||
*/
|
||||
private void writeWaypoints(long trackId) {
|
||||
// TODO: Stream through he waypoints in chunks.
|
||||
// I am leaving the number of waypoints very high which should not be a
|
||||
// problem because we don't try to load them into objects all at the
|
||||
// same time.
|
||||
Cursor cursor = null;
|
||||
cursor = providerUtils.getWaypointsCursor(trackId, 0,
|
||||
Constants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
// Yes, this will skip the 1st way point and that is intentional
|
||||
// as the 1st points holds the stats for the current/last segment.
|
||||
while (cursor.moveToNext()) {
|
||||
Waypoint wpt = providerUtils.createWaypoint(cursor);
|
||||
writer.writeWaypoint(wpt);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual work of writing the track to the now open file.
|
||||
*/
|
||||
void writeDocument() {
|
||||
Log.d(Constants.TAG, "Started writing track.");
|
||||
writer.writeHeader();
|
||||
writeWaypoints(track.getId());
|
||||
writeLocations();
|
||||
writer.writeFooter();
|
||||
writer.close();
|
||||
success = true;
|
||||
Log.d(Constants.TAG, "Done writing track.");
|
||||
errorMessage = R.string.io_write_finished;
|
||||
}
|
||||
|
||||
private void writeLocations() {
|
||||
boolean wroteFirst = false;
|
||||
boolean segmentOpen = false;
|
||||
boolean isLastValid = false;
|
||||
|
||||
class TrackWriterLocationFactory implements MyTracksProviderUtils.LocationFactory {
|
||||
Location currentLocation;
|
||||
Location lastLocation;
|
||||
|
||||
@Override
|
||||
public Location createLocation() {
|
||||
if (currentLocation == null) {
|
||||
currentLocation = new MyTracksLocation("");
|
||||
}
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public void swapLocations() {
|
||||
Location tmpLoc = lastLocation;
|
||||
lastLocation = currentLocation;
|
||||
currentLocation = tmpLoc;
|
||||
if (currentLocation != null) {
|
||||
currentLocation.reset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TrackWriterLocationFactory locationFactory = new TrackWriterLocationFactory();
|
||||
LocationIterator it = providerUtils.getLocationIterator(track.getId(), 0, false,
|
||||
locationFactory);
|
||||
try {
|
||||
if (!it.hasNext()) {
|
||||
Log.w(Constants.TAG, "Unable to get any points to write");
|
||||
return;
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
Location loc = it.next();
|
||||
|
||||
boolean isValid = LocationUtils.isValidLocation(loc);
|
||||
boolean validSegment = isValid && isLastValid;
|
||||
if (!wroteFirst && validSegment) {
|
||||
// Found the first two consecutive points which are valid
|
||||
writer.writeBeginTrack(locationFactory.lastLocation);
|
||||
wroteFirst = true;
|
||||
}
|
||||
|
||||
if (validSegment) {
|
||||
if (!segmentOpen) {
|
||||
// Start a segment for this point
|
||||
writer.writeOpenSegment();
|
||||
segmentOpen = true;
|
||||
|
||||
// Write the previous point, which we had previously skipped
|
||||
writer.writeLocation(locationFactory.lastLocation);
|
||||
}
|
||||
|
||||
// Write the current point
|
||||
writer.writeLocation(loc);
|
||||
} else {
|
||||
if (segmentOpen) {
|
||||
writer.writeCloseSegment();
|
||||
segmentOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
locationFactory.swapLocations();
|
||||
isLastValid = isValid;
|
||||
}
|
||||
if (segmentOpen) {
|
||||
writer.writeCloseSegment();
|
||||
segmentOpen = false;
|
||||
}
|
||||
if (wroteFirst) {
|
||||
writer.writeEndTrack(locationFactory.lastLocation);
|
||||
}
|
||||
} finally {
|
||||
it.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,11 +156,11 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
|
||||
}
|
||||
}
|
||||
if (key == null || key.equals(splitFrequencyKey)) {
|
||||
service.getSplitManager().setSplitFrequency(
|
||||
service.setSplitFrequency(
|
||||
sharedPreferences.getInt(splitFrequencyKey, 0));
|
||||
}
|
||||
if (key == null || key.equals(metricUnitsKey)) {
|
||||
service.getSplitManager().setMetricUnits(
|
||||
service.setMetricUnits(
|
||||
sharedPreferences.getBoolean(metricUnitsKey, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,160 +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 com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.util.UnitConversions;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* This class manages inserting time or distance splits.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class SplitManager {
|
||||
|
||||
/**
|
||||
* The frequency of splits.
|
||||
*/
|
||||
private int splitFrequency = 0;
|
||||
|
||||
/**
|
||||
* The next distance when a split should be taken.
|
||||
*/
|
||||
private double nextSplitDistance = 0;
|
||||
|
||||
/**
|
||||
* Splits executer.
|
||||
*/
|
||||
private PeriodicTaskExecuter splitExecuter = null;
|
||||
|
||||
private boolean metricUnits;
|
||||
|
||||
private final TrackRecordingService service;
|
||||
|
||||
public SplitManager(TrackRecordingService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the manager.
|
||||
*/
|
||||
public void restore() {
|
||||
if ((splitFrequency > 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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -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.
|
||||
+3
-1
@@ -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.
|
||||
+189
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
+20
-3
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-7
@@ -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()) {
|
||||
+4
-2
@@ -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,
|
||||
+10
-10
@@ -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();
|
||||
@@ -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"),
|
||||
|
||||
+6
-3
@@ -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);
|
||||
+2
-1
@@ -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;
|
||||
Reference in New Issue
Block a user