mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 09:33:06 +02:00
Merge from head
This commit is contained in:
@@ -161,7 +161,7 @@ limitations under the License.
|
||||
<uses-feature android:name="android.hardware.location" android:required="true"/>
|
||||
<uses-feature android:name="android.hardware.location.gps" android:required="true"/>
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="true"/>
|
||||
|
||||
|
||||
<!-- Features optional -->
|
||||
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.location.network" android:required="false"/>
|
||||
|
||||
@@ -58,6 +58,11 @@ limitations under the License.
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/about_bart"
|
||||
android:textSize="20sp" />
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
<?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>
|
||||
<!-- Task frequency -->
|
||||
<string-array name="task_frequency_options">
|
||||
<item>Inactiu</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>
|
||||
<item>2 m</item>
|
||||
<item>3 m</item>
|
||||
<item>4 m</item>
|
||||
<item>5 m (recomanat)</item>
|
||||
<item>10 m</item>
|
||||
<item>100 m</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="min_recording_distance_options_ft">
|
||||
<item>3 ft</item>
|
||||
<item>6 ft</item>
|
||||
<item>10 ft</item>
|
||||
<item>13 ft</item>
|
||||
<item>16 ft (recomanat)</item>
|
||||
<item>33 ft</item>
|
||||
<item>328 ft</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Maximum recording distance -->
|
||||
<string-array name="max_recording_distance_options">
|
||||
<item>50 m</item>
|
||||
<item>100 m</item>
|
||||
<item>200 m (recomanat)</item>
|
||||
<item>500 m</item>
|
||||
<item>1000 m</item>
|
||||
<item>5000 m</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="max_recording_distance_options_ft">
|
||||
<item>164 ft</item>
|
||||
<item>328 ft</item>
|
||||
<item>656 ft (recomanat)</item>
|
||||
<item>1640 ft</item>
|
||||
<item>0.6 miles</item>
|
||||
<item>3.1 miles</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum recording interval -->
|
||||
<string-array name="min_recording_interval_options">
|
||||
<item>poca precisió (adaptable)</item>
|
||||
<item>gran precisió (adaptable)</item>
|
||||
<item>el millor (recomanat)</item>
|
||||
<item>2 s</item>
|
||||
<item>3 s</item>
|
||||
<item>4 s</item>
|
||||
<item>5 s</item>
|
||||
<item>10 s</item>
|
||||
<item>20 s</item>
|
||||
<item>30 s</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>
|
||||
</string-array>
|
||||
|
||||
<!-- Minimum required accuracy -->
|
||||
<string-array name="min_required_accuracy_options">
|
||||
<item>10 m (senyal GPS excel·lent)</item>
|
||||
<item>20 m</item>
|
||||
<item>50 m</item>
|
||||
<item>100 m</item>
|
||||
<item>200 m (recomanat)</item>
|
||||
<item>500 m</item>
|
||||
<item>1000 m</item>
|
||||
<item>2000 m</item>
|
||||
<item>5000 m (senyal GPS pobre)</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="min_required_accuracy_options_ft">
|
||||
<item>33 ft (senyal GPS excel·lent)</item>
|
||||
<item>66 ft</item>
|
||||
<item>165 ft</item>
|
||||
<item>328 ft</item>
|
||||
<item>656 ft (recomanat)</item>
|
||||
<item>1640 ft</item>
|
||||
<item>0.6 miles</item>
|
||||
<item>1.2 miles</item>
|
||||
<item>3.1 miles (senyal GPS pobre)</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Split frequency -->
|
||||
<string-array name="split_frequency_options">
|
||||
<item>Sense divisió</item>
|
||||
<item>100 km</item>
|
||||
<item>50 km</item>
|
||||
<item>25 km</item>
|
||||
<item>10 km</item>
|
||||
<item>5 km</item>
|
||||
<item>1 km</item>
|
||||
<item>60 min</item>
|
||||
<item>30 min</item>
|
||||
<item>15 min</item>
|
||||
<item>10 min</item>
|
||||
<item>5 min</item>
|
||||
<item>2 min</item>
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="split_frequency_options_ft">
|
||||
<item>No splitting</item>
|
||||
<item>100 mi</item>
|
||||
<item>50 mi</item>
|
||||
<item>25 mi</item>
|
||||
<item>10 mi</item>
|
||||
<item>5 mi</item>
|
||||
<item>1 mi</item>
|
||||
<item>60 min</item>
|
||||
<item>30 min</item>
|
||||
<item>15 min</item>
|
||||
<item>10 min</item>
|
||||
<item>5 min</item>
|
||||
<item>2 min</item>
|
||||
<item>1 min</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Auto-resume track timeout -->
|
||||
<string-array name="auto_resume_track_timeout_options">
|
||||
<item>Mai</item>
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>Always</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Other non-preference arrays -->
|
||||
<array name="activity_types">
|
||||
<item>desconegut</item>
|
||||
<item>tipus barrejats</item>
|
||||
<item>altre</item>
|
||||
|
||||
<item>córrer</item>
|
||||
<item>córrer al carrer</item>
|
||||
<item>pista d\'atletisme</item>
|
||||
<item>córrer en ruta</item>
|
||||
<item>a peu</item>
|
||||
<item>caminar de presa</item>
|
||||
<item>senderisme</item>
|
||||
<item>ruta de senderisme</item>
|
||||
<item>senderisme fora de ruta</item>
|
||||
<item>escalada</item>
|
||||
|
||||
<item>ciclisme</item>
|
||||
<item>bici al carrer</item>
|
||||
<item>bici de muntanya</item>
|
||||
<item>ruta de bici</item>
|
||||
|
||||
<item>patinatge</item>
|
||||
<item>patinatge en línia</item>
|
||||
<item>skate</item>
|
||||
|
||||
<item>snow shoeing</item>
|
||||
<item>skiing</item>
|
||||
<item>snow boarding</item>
|
||||
<item>sled</item>
|
||||
<item>ice sailing</item>
|
||||
|
||||
<item>pesca</item>
|
||||
<item>rem</item>
|
||||
<item>caiac</item>
|
||||
<item>rem</item>
|
||||
<item>llanxa motora</item>
|
||||
<item>ferry</item>
|
||||
<item>RC boat</item>
|
||||
<item>surf</item>
|
||||
<item>windsurf</item>
|
||||
<item>kitesurf</item>
|
||||
<item>esquí aquàtic</item>
|
||||
<item>wakeboard</item>
|
||||
|
||||
<item>avió</item>
|
||||
<item>hidroavió</item>
|
||||
<item>avió comercial</item>
|
||||
<item>helicòpter</item>
|
||||
<item>globus aerostàtic</item>
|
||||
<item>dirigible</item>
|
||||
<item>avió RC</item>
|
||||
<item>helicòpter RC</item>
|
||||
<item>salt d\'esquí</item>
|
||||
<item>vol sense motor</item>
|
||||
<item>ala delta</item>
|
||||
<item>parapent</item>
|
||||
|
||||
<item>riding</item>
|
||||
<item>horse back riding</item>
|
||||
<item>donkey back riding</item>
|
||||
|
||||
<item>conducció d\'automòbil</item>
|
||||
<item>conducció de bus</item>
|
||||
<item>tren</item>
|
||||
<item>moto</item>
|
||||
<item>dirtbike</item>
|
||||
<item>ATV</item>
|
||||
|
||||
<item>landsailing</item>
|
||||
<item>frisbee</item>
|
||||
<item>ultimate frisbee</item>
|
||||
</array>
|
||||
|
||||
<array name="waypoint_types">
|
||||
<item>ATM</item>
|
||||
<item>banc</item>
|
||||
<item>bar</item>
|
||||
<item>barbeque</item>
|
||||
<item>edifici</item>
|
||||
<item>parada de bús</item>
|
||||
<item>cafeteria</item>
|
||||
<item>acampada</item>
|
||||
<item>càmping</item>
|
||||
<item>església</item>
|
||||
<item>cafeteria</item>
|
||||
<item>botiga de conveniència</item>
|
||||
<item>aigua potable</item>
|
||||
<item>caiguda de roques</item>
|
||||
<item>ferry</item>
|
||||
<item>llar de foc</item>
|
||||
<item>estació de bombers</item>
|
||||
<item>pesca</item>
|
||||
<item>benzinera</item>
|
||||
<item>camp de golf</item>
|
||||
<item>botiga de queviures</item>
|
||||
<item>perruqueria</item>
|
||||
<item>port</item>
|
||||
<item>ruta de senderisme</item>
|
||||
<item>hotel</item>
|
||||
<item>casa</item>
|
||||
<item>informació</item>
|
||||
<item>intersecció</item>
|
||||
<item>bústia</item>
|
||||
<item>mercat</item>
|
||||
<item>punt de trobada</item>
|
||||
<item>opera</item>
|
||||
<item>parking</item>
|
||||
<item>oficina de correus</item>
|
||||
<item>sot</item>
|
||||
<item>comissaria dels mossos</item>
|
||||
<item>encreuament ferroviari</item>
|
||||
<item>restaurant</item>
|
||||
<item>compres</item>
|
||||
<item>vista</item>
|
||||
<item>magatzem</item>
|
||||
<item>piscina</item>
|
||||
<item>telèfon</item>
|
||||
<item>teatre</item>
|
||||
<item>serveis</item>
|
||||
<item>informació turística</item>
|
||||
<item>túnel</item>
|
||||
<item>arbre</item>
|
||||
<item>cascada</item>
|
||||
<item>font d\'aigua</item>
|
||||
<item>punt de referència</item>
|
||||
</array>
|
||||
|
||||
<array name="sensor_type_options">
|
||||
<item>Cap</item>
|
||||
<item>Zephyr Bluetooth</item>
|
||||
</array>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,449 @@
|
||||
<?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">Enregistra la ruta</string>
|
||||
<string name="stop_recording">Atura l\'enregistrament</string>
|
||||
<string name="switch_to_sat">Mode de satèl·lit</string>
|
||||
<string name="switch_to_map">Mode de mapa</string>
|
||||
<string name="mylocation">La meva ubicació</string>
|
||||
<string name="list_tracks">Rutes</string>
|
||||
<string name="list_markers">Marcadors</string>
|
||||
<string name="delete_all_tracks">Elimina totes les rutes</string>
|
||||
<string name="settings">Paràmetres</string>
|
||||
<string name="elevation">Elevació</string>
|
||||
<string name="choose_track_message">Seleccioneu la ruta que es visualitzarà</string>
|
||||
<string name="current_track">Ruta actual</string>
|
||||
<string name="current_segment">Darrer segment</string>
|
||||
<string name="sensor_state">Estat del sensor</string>
|
||||
<string name="aggregated_stats">Estadístiques agregades</string>
|
||||
|
||||
<!-- Error messages -->
|
||||
<string name="error_no_location_manager">No s\'ha trobat cap gestor d\'ubicacions en aquest dispositiu.</string>
|
||||
<string name="error_no_gps_location_provider">No s\'ha trobat cap proveïdor d\'ubicació GPS en aquest dispositiu.</string>
|
||||
<string name="error_sending_to_mymap">S\'ha produït un error quan s\'enviava la ruta a Google My Map. Proveu més tard.</string>
|
||||
<string name="error_sending_to_docs">S\'ha prdouït un error quan s\'enviava la ruta a Google Docs. Proveu més tard.</string>
|
||||
<string name="error_unable_to_start_recording">No es pot iniciar l\'enregistrament. Proveu de nou.</string>
|
||||
<string name="error_unable_to_stop_recording">No es pot aturar l\'enregistrament. Proveu de nou.</string>
|
||||
<string name="error_unable_to_read_file">No es pot llegir des del fitxer.</string>
|
||||
<string name="error_invalid_gpx_format">El fitxer no conté un format GPX vàlid.</string>
|
||||
<string name="error_generic">S\'ha produït un error. Proveu de nou.</string>
|
||||
<string name="error_track_does_not_exist">No existeix la ruta.</string>
|
||||
<string name="error_out_of_memory">Aquest fitxer és massa gran (ha d\'ésser inferior a 500KB. S\'està cancel·lant.</string>
|
||||
<string name="error_unable_to_insert_marker">No es pot inserir un marcador. No hi ha cap ubicació fixa disponible.</string>
|
||||
|
||||
<!-- Status messages -->
|
||||
<string name="wait_for_fix">S\'està esperant per tenir una posició GPS fixa. Assegureu-vos que el cel és visible.</string>
|
||||
<string name="status_now_recording">Ara s\'està enregistrant una ruta nova.</string>
|
||||
<string name="status_stopped_recording">S\'ha aturat l\'enregistrament de la ruta.</string>
|
||||
<string name="status_new_mymap_has_been_created">S\'ha creat un Google My Map nou a maps.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded">S\'ha enviat la ruta a maps.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_new_doc">S\'ha enviat la ruta a un full de càlcul a docs.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_docs">S\'ha enviat la ruta a docs.google.com.</string>
|
||||
<string name="status_mymap_info">Poden passar uns minuts abans que les rutes noves apareguin.</string>
|
||||
<string name="status_enable_gps">Piqueu aquí per anar als paràmetres de seguretat i ubicació i activeu \'habilita els satèl·lits GPS\'. Premeu el botó d\'anar enrere per tornar.</string>
|
||||
<string name="status_approximate_location">Nota: Es mostra una ubicació determinada a partir de les xarxes sense fils i antenes telefòniques.</string>
|
||||
<string name="status_no_location">No es pot determinar la ubicació. Habiliteu més fonts d\'ubicació (vegeu els paràmetres de seguretat i ubicació) i assegureu-vos que el cel és visible. Proveu de nou més tard.</string>
|
||||
<string name="status_waypoint_inserted">S\'ha inserit un marcader de punt de ruta.</string>
|
||||
<string name="status_statistics_inserted">S\'ha inserit un marcador d\'estadístiques.</string>
|
||||
|
||||
<!-- Progress dialog -->
|
||||
<string name="progress_title">Espereu...</string>
|
||||
<string name="progress_message">S\'està enviant la ruta a Google.</string>
|
||||
<string name="progress_message_reading_track">S\'està llegint la ruta...</string>
|
||||
<string name="progress_message_preparing_track">S\'està preparant la ruta...</string>
|
||||
<string name="progress_message_authenticating_mymaps">S\'està to Google Maps...</string>
|
||||
<string name="progress_message_authenticating_docs">S\'està autenticant a Google Docs...</string>
|
||||
<string name="progress_message_sending_docs">S\'està enviant la ruta a Google Docs...</string>
|
||||
<string name="progress_message_sending_mymaps">S\'està enviant a Google Maps...</string>
|
||||
<string name="progress_message_creating_map">S\'està creant un My Map nou...</string>
|
||||
<string name="import_progress_message">S\'està imporant una ruta GPS. Això pot trigar una estona.</string>
|
||||
<string name="write_progress_message">S\'està escrivint a la targeta SD. Això pot trigar una estona.</string>
|
||||
<string name="progress_message_updating_track">S\'estan actualitzant les estadístiques de la ruta...</string>
|
||||
|
||||
<!-- Used by DeleteAllDataHandler -->
|
||||
<string name="are_you_sure_question">Esteu segur?</string>
|
||||
<string name="all_data_will_be_permanently_deleted">Tots els marcadors i rutes s\'eliminaran d\'aquest telèfon.</string>
|
||||
<string name="track_will_be_permanently_deleted">La ruta i els seus marcadors s\'eliminaran de forma permanent d\'aquest telèfon.</string>
|
||||
<string name="marker_will_be_permanently_deleted">El marcador s\'eliminarà de forma permanent d\'aquest telèfon.</string>
|
||||
|
||||
<!-- Text and links when uploading to Google My Maps -->
|
||||
<string name="new_map_description">Creat per My Tracks a l\'Android.</string>
|
||||
<string name="my_map_link">Creat per <a href=\'http://mytracks.appspot.com\'>My Tracks</a> a l\'Android.</string>
|
||||
<string name="new_map_title">Mapa nou</string>
|
||||
|
||||
<!-- Formatting of track and marker descriptions -->
|
||||
<string name="points">Punts</string>
|
||||
<string name="recorded_date">Enregistrat</string>
|
||||
<string name="category">Tipus d\'activitat</string>
|
||||
<string name="waypoint_category">Tipus de marcador</string>
|
||||
<string name="part">(Part %d)</string>
|
||||
|
||||
<!-- Used by the track recording service -->
|
||||
<string name="recording_your_track">S\'està enregistrant la ruta...</string>
|
||||
<string name="new_track">Ruta %d</string>
|
||||
|
||||
<!-- Common -->
|
||||
<string name="no">No</string>
|
||||
<string name="yes">Sí</string>
|
||||
<string name="ok">D\'acord</string>
|
||||
<string name="error">Error</string>
|
||||
<string name="success">Fet</string>
|
||||
<string name="waypoint">Punt de referència</string>
|
||||
|
||||
<!-- Placemark labels for start and end of track -->
|
||||
<string name="start">(Inici)</string>
|
||||
<string name="end">(Fi)</string>
|
||||
|
||||
<!-- TrackList -->
|
||||
<string name="tracklist_show_track">Mostra</string>
|
||||
<string name="tracklist_send_to_mymaps">Envia a Google My Maps</string>
|
||||
<string name="tracklist_send_to_new_mymap">Envia a un Google My Map nou</string>
|
||||
<string name="tracklist_send_to_docs">Envia a Google Docs</string>
|
||||
<string name="tracklist_send_to_google">Envia a Google...</string>
|
||||
<string name="tracklist_delete_track">Elimina del telèfon...</string>
|
||||
<string name="tracklist_edit_track">Edita els detalls</string>
|
||||
<string name="tracklist_write_to_sd">Escriu a la targeta SD...</string>
|
||||
<string name="tracklist_save_as_gpx">Anomena i desa com un fitxer GPX</string>
|
||||
<string name="tracklist_save_as_kml">Anomena i desa com un fitxer KML</string>
|
||||
<string name="tracklist_save_as_csv">Anomena i desa com un fitxer CSV</string>
|
||||
<string name="tracklist_save_as_tcx">Anomena i desa com un fitxer TCX</string>
|
||||
<string name="tracklist_btn_send_all_to_mymaps">Envia a Google My Maps</string>
|
||||
<string name="tracklist_btn_delete_all">Elimina totes les rutes</string>
|
||||
<!-- Export All -->
|
||||
<string name="tracklist_btn_export_all">Exporta totes les rutes</string>
|
||||
<string name="export_done">Exporta les finalitzades</string>
|
||||
<string name="tracklist_pick_one">Seleccioneu una ruta. Mantingueu el dit per veure més opcions.</string>
|
||||
<string name="tracklist_all_tracks">Totes les rutes:</string>
|
||||
<string name="tracklist_this_track">Aquesta ruta</string>
|
||||
<string name="tracklist_share_track">Comparteix amb amics...</string>
|
||||
<string name="tracklist_share_link">Un enllaç a Google My Map</string>
|
||||
<string name="tracklist_share_gpx_file">Un fitxer GPX</string>
|
||||
<string name="tracklist_share_kml_file">Un fitxer KML</string>
|
||||
<string name="tracklist_share_csv_file">Un fitxer CSV</string>
|
||||
<string name="tracklist_share_tcx_file">Un fitxer TCX</string>
|
||||
<string name="tracklist_clear_map">Neteja el mapa</string>
|
||||
|
||||
<!-- Waypoints list -->
|
||||
<string name="waypointslist_btn_delete_all">Elimina tots els marcadors</string>
|
||||
<string name="waypointslist_this_waypoint">Aquest marcador</string>
|
||||
<string name="waypointslist_delete_waypoint">Elimina</string>
|
||||
<string name="waypointslist_edit_waypoint">Edita els detalls</string>
|
||||
<string name="waypointslist_show_waypoint">Mostra al mapa</string>
|
||||
<string name="waypointslist_btn_insert_waypoint">Insereix un punt de referència</string>
|
||||
<string name="waypointslist_btn_insert_statistics">Insereix estadístiques</string>
|
||||
<string name="waypointslist_pick_one">Seleccioneu un marcador. Mantingueu el dit per veure més opcions.</string>
|
||||
|
||||
<!-- MyTracks Details -->
|
||||
<string name="trackdetails_title">Detalls de la ruta</string>
|
||||
<string name="trackdetails_name">Nom de la ruta</string>
|
||||
<string name="trackdetails_description">Descripció de la ruta</string>
|
||||
<string name="trackdetails_category">Tipus d\'activitat (p.e. senderisme, bicicleta, còrrer, escalada...)</string>
|
||||
|
||||
<!-- MyTracks Waypoint Details -->
|
||||
<string name="waypointdetails_title">Detalls del marcador</string>
|
||||
<string name="waypointdetails_name">Nom del marcador</string>
|
||||
<string name="waypointdetails_description">Descripció del marcador</string>
|
||||
<string name="waypointdetails_category">Tipus de marcador (e.g. edifici, sot, vista...)</string>
|
||||
|
||||
<!-- MyTracks Settings -->
|
||||
<string name="mytracks_settings">Paràmetres de My Tracks</string>
|
||||
<string name="settings_display">Visualització</string>
|
||||
<string name="settings_recording">Enregistrament</string>
|
||||
<string name="settings_sharing">Compartició</string>
|
||||
|
||||
<string name="settings_not_available_summary">No es troba disponible a la vostra versió de l\'Android</string>
|
||||
|
||||
<string name="settings_announcement_frequency">Freqüència d\'avís</string>
|
||||
<string name="settings_announcement_frequency_summary">Temps mínin entre dos avisos de veu</string>
|
||||
|
||||
<string name="settings_min_recording_distance">Distància mínima entre punts</string>
|
||||
<string name="settings_min_recording_distance_summary">La distància més petita entre dos punts enregistrats de la vostra posició</string>
|
||||
|
||||
<string name="settings_max_recording_distance">Distància màxima entre punts</string>
|
||||
<string name="settings_max_recording_distance_summary">Si dos punts estan més lluny d\'això, es dividirà la ruta</string>
|
||||
|
||||
<string name="settings_min_recording_interval">Temps mínim entre punts</string>
|
||||
<string name="settings_min_recording_interval_summary">Interval de temps mínim entre dos enregistraments de la vostra posició</string>
|
||||
|
||||
<string name="settings_min_required_accuracy">Precisió míima</string>
|
||||
<string name="settings_min_required_accuracy_summary">S\'aturarà l\'enregistrament si la vostra posició no és així de precisa com a mínim</string>
|
||||
|
||||
<string name="settings_metric_units">Fes servir unitats mètriques</string>
|
||||
<string name="settings_metric_units_summary_on">Totes les distàncies es mostraran en unitats mètriques</string>
|
||||
<string name="settings_metric_units_summary_off">Totes les distàncies es mostraran en unitats imperials</string>
|
||||
|
||||
<string name="settings_map_public">Fes el mapa públic</string>
|
||||
<string name="settings_map_public_summary_on">Els mapes pujats seran visibles per tothom a maps.google.com</string>
|
||||
<string name="settings_map_public_summary_off">Els mapes pujats no es llistaran públicament a maps.google.com</string>
|
||||
|
||||
<string name="settings_report_speed_or_pace">Mostra la velocitat</string>
|
||||
<string name="settings_report_speed_or_pace_summary_on">Es mostrarà la velocitat</string>
|
||||
<string name="settings_report_speed_or_pace_summary_off">Es mostrarà el ritme de pas</string>
|
||||
|
||||
<string name="settings_share_url_only">Comparteix només l\'URL</string>
|
||||
<string name="settings_share_url_only_summary_on">Només s\'enviarà l\'URL del mapa quan es comparteixi</string>
|
||||
<string name="settings_share_url_only_summary_off">També s\'inclouran els continguts de la ruta quan es comparteixi</string>
|
||||
|
||||
<string name="settings_split_frequency">Freqüència de divisió</string>
|
||||
<string name="settings_split_frequency_summary">Temps o distància màxima a partir de la qual s\'insertarà un marcador de divisió nou</string>
|
||||
|
||||
<string name="settings_auto_resume_track_timeout">Temps d\'espera per reprende la ruta</string>
|
||||
<string name="settings_auto_resume_track_timeout_summary">Temps màxim en minuts a partir del qual l\'anterior ruta enregistrada no es reprendrà en actualitzar el telèfon</string>
|
||||
|
||||
<string name="settings_timestamp_track_name">Data i hora com a nom de la ruta</string>
|
||||
<string name="settings_timestamp_track_name_summary_on">El nom per defecte de la ruta serà la data i hora en que s\'ha iniciat.</string>
|
||||
<string name="settings_timestamp_track_name_summary_off">Els noms de les rutes seran números que s\'incrementaran per a cada nova ruta.</string>
|
||||
|
||||
<string name="pace_label">Ritme de pas</string>
|
||||
|
||||
<string name="eclair_required">Suportat només en Android 2.0 i superior</string>
|
||||
<string name="settings_sensor_type">Tipus de sensor</string>
|
||||
<string name="settings_sensor_type_summary">El tipus de sensor al qual es connecta.</string>
|
||||
<string name="settings_sensor_id">Identificador del sensor</string>
|
||||
<string name="settings_sensor_id_summary">L\'identificador enviat als sensors.</string>
|
||||
<string name="sensor_id_malformed">L\'identificador ha de ser un valor sencer.</string>
|
||||
<string name="bluetooth_sensor_title">Sensor bluetooth</string>
|
||||
<string name="bluetooth_sensor_summary">El sensor bluetooth al qual es connecta.</string>
|
||||
<string name="settings_modular_stats_display_title">Pantalla d\'estadístiques modulars</string>
|
||||
<string name="settings_modular_stats_display_summary_on">La pantalla d\'estadístiques es divideix en mòduls diferents.</string>
|
||||
<string name="settings_modular_stats_display_summary_off">Mostra totes les estadístiques en una sola pantalla.</string>
|
||||
|
||||
<string name="settings_backup">Còpia de seguretat (BETA)</string>
|
||||
<string name="settings_sd_backup">Còpia de seguretat a la targeta SD</string>
|
||||
<string name="settings_backup_to_sd">Fes la còpia ara</string>
|
||||
<string name="settings_backup_to_sd_summary">Escriu una còpia completa de totes les rutes i els paràmetres a la targeta SD</string>
|
||||
<string name="settings_restore_from_sd">Restaura ara</string>
|
||||
<string name="settings_restore_from_sd_summary">Restaura totes les rutes i els paràmetres des de la targeta SD.</string>
|
||||
<string name="settings_no_backup_while_recording">No es poden gestionar les còpies de seguretat mentre s\'enregistra una ruta.</string>
|
||||
|
||||
<!-- Backups -->
|
||||
<string name="restore_overwrites_warning">La restauració d\'una còpia de seguretat des de la targeta SD sobreescriurà totes les rutes i paràmetres. Esteu segur?</string>
|
||||
<string name="select_backup_to_restore">Seleccioneu la còpia que es restaurarà</string>
|
||||
<string name="no_backups">No s\'ha trobat cap còpia de seguretat.</string>
|
||||
<string name="backup_write_progress_message">S\'estan escrivint totes les rutes i els paràmetres a la targeta SD. Això pot trigar una estona...</string>
|
||||
<string name="backup_import_progress_message">S\'estan llegint totes les rutes i els paràmetres de la targeta SD. Això pot trigar una estona...</string>
|
||||
|
||||
<!-- MyTracksSky -->
|
||||
<string name="mytracks_sky">Satèl·lits GPS</string>
|
||||
|
||||
<!-- My Maps -->
|
||||
<string name="select_map_message">Seleccioneu un mapa del vostre compte:</string>
|
||||
<string name="create_new_map">Crea un mapa nou...</string>
|
||||
<string name="map_list_title">Envia a Google My Maps</string>
|
||||
<string name="maps_list_loading">S\'estan carregant els mapes...</string>
|
||||
<string name="maps_list_failed">No s\'han pogut carregar els vostres mapes en aquest moment</string>
|
||||
<string name="open_map">Selecciona aquest mapa</string>
|
||||
<string name="edit_map_details">Edita els detalls del mapa</string>
|
||||
<string name="share_map">Comparteix el mapa amb amics</string>
|
||||
<string name="share_track">Comparteix la ruta amb amics</string>
|
||||
<string name="delete_map">Elimina el mapa del vostre compte</string>
|
||||
<string name="map_title">Títol del mapa:</string>
|
||||
<string name="map_description">Descripció del mapa:</string>
|
||||
<string name="map_searchable_edit">Fes que aquest mapa i els seus continguts apareguen als resultats de cerca</string>
|
||||
<string name="map_not_searchable_edit">No permetis que aquest mapa ni els seus continguts es mostrin als resultats de cerca, tot i que sí es podrà visualitzar per altres amb l\'adreça URL directa</string>
|
||||
<string name="map_searchable">Aquest mapa i els seus continguts es mostraran als resultats de cerca</string>
|
||||
<string name="map_not_searchable">Ni els mapes ni els seus continguts es mostraran als resultats de cerca, però podran visualitzar-se per altres a través d\'un enllaç directe.</string>
|
||||
<string name="close">Tanca</string>
|
||||
<string name="edit">Edita</string>
|
||||
<string name="cancel">Cancel·la</string>
|
||||
<string name="save">Desa</string>
|
||||
|
||||
<!-- Sharing -->
|
||||
<string name="share_map_subject">M\'agradaria compartir un mapa amb tu</string>
|
||||
<string name="share_map_body_format">Crec que estaràs interessat en aquest mapa:
|
||||
|
||||
%s</string>
|
||||
<string name="send_track_subject">M\'agradaria compartir una ruta amb tu</string>
|
||||
<string name="send_track_body_format">Crec que estaràs interessat en aquesta ruta.
|
||||
|
||||
Per verue aquesta ruta fes servir Google Earth o altre programari de mapes.</string>
|
||||
|
||||
<!-- Visibility -->
|
||||
<string name="public_map">Públic</string>
|
||||
<string name="unlisted_map">No llistat</string>
|
||||
<string name="mapslist_no_maps_available">Encara no teniu cap mapa.</string>
|
||||
|
||||
<!-- Statistics View -->
|
||||
<!-- Average Moving -->
|
||||
<string name="average_moving_speed_label">Average Moving Speed</string>
|
||||
<string name="average_moving_pace_label">Average Moving Pace</string>
|
||||
|
||||
<!-- Average -->
|
||||
<string name="average_speed_label">Velocitat mitjana</string>
|
||||
<string name="average_pace_label">Ritme de pas mitjà</string>
|
||||
|
||||
<string name="elevation_chart_name">Gràfic d\'elevació</string>
|
||||
<string name="elevation_gain_label">Guany d\'elevació</string>
|
||||
<string name="elevation_label">Elevació</string>
|
||||
<string name="latitude_label">Latitud</string>
|
||||
<string name="longitude_label">Longitud</string>
|
||||
|
||||
<!-- Min -->
|
||||
<string name="min_elevation_label">Elevació mínima</string>
|
||||
<string name="min_grade_label">Grau mínim</string>
|
||||
<string name="min_pace_label">Ritme de pas mínima</string>
|
||||
|
||||
<!-- Max -->
|
||||
<string name="max_elevation_label">Elevació màxima</string>
|
||||
<string name="max_grade_label">Grau màxim</string>
|
||||
<string name="max_speed_label">Velocitat màxima</string>
|
||||
|
||||
<string name="loading_track">S\'està carregant la ruta...</string>
|
||||
|
||||
<!-- Chart Settings -->
|
||||
<string name="chart_settings">Configuració del gràfic</string>
|
||||
<!-- X Axis -->
|
||||
<string name="x_axis">Eix X</string>
|
||||
<string name="by_distance">Per distància</string>
|
||||
<string name="by_time">Per temps</string>
|
||||
|
||||
<!-- Y Axis -->
|
||||
<string name="y_axis">Eix Y</string>
|
||||
|
||||
<!-- Units -->
|
||||
<!-- Time -->
|
||||
<string name="hour">hora</string>
|
||||
<string name="hours">hores</string>
|
||||
<string name="minute">minut</string>
|
||||
<string name="minutes">minuts</string>
|
||||
<string name="second">segon</string>
|
||||
<string name="seconds">segons</string>
|
||||
|
||||
<!-- Distance -->
|
||||
<string name="kilometers_long">kilòmetres</string>
|
||||
<string name="miles_long">milles</string>
|
||||
|
||||
<!-- Speed and Pace -->
|
||||
<string name="kilometer_per_hour_long">kilòmetres per hora</string>
|
||||
<string name="per_kilometer">per kilòmetre</string>
|
||||
<string name="mile_per_hour_long">milles per hora</string>
|
||||
<string name="per_mile">per milla</string>
|
||||
|
||||
<!-- Stats Labels -->
|
||||
<string name="moving_time_label">Temps en moviment</string>
|
||||
<string name="total_time_label">Temps total</string>
|
||||
<string name="time_label">Temps</string>
|
||||
<string name="sd_unavail">La targeta SD no està disponible</string>
|
||||
<string name="speed">Velocitat</string>
|
||||
<string name="start_trip">Heu d\'iniciar la marxa.</string>
|
||||
<string name="statistics">Estadístiques</string>
|
||||
<string name="total_distance_label">Distància total</string>
|
||||
<string name="distance_label">Distància</string>
|
||||
<string name="power">Energia</string>
|
||||
<string name="cadence">Cadència</string>
|
||||
<string name="heart_rate">Freqüència cardíaca</string>
|
||||
<string name="max_heart_rate">Freqüència cardíaca màxima</string>
|
||||
<string name="waiting">S\'està esperant...</string>
|
||||
|
||||
<!-- End User License Agreement -->
|
||||
<string name="eula_title">Acord de llicencia d\'usuari final</string>
|
||||
<string name="accept">Accepta</string>
|
||||
<string name="decline">Rebutja</string>
|
||||
|
||||
<!-- About -->
|
||||
<string name="about">Quant a</string>
|
||||
<string name="help">Ajuda</string>
|
||||
<string name="about_team">Equip:</string>
|
||||
<string name="about_version">Versió:</string>
|
||||
<string name="about_email">Assistència</string>
|
||||
<string name="about_support">Assistència:</string>
|
||||
|
||||
<!-- Send to Google -->
|
||||
<string name="sendtogoogle_title">Envia a...</string>
|
||||
<string name="sendtogoogle_send_now">Envia ara</string>
|
||||
<string name="sendtogoogle_create_new_map">Crea un mapa nou</string>
|
||||
<string name="sendtogoogle_pick_existing_map">Seleccioneu un mapa existent</string>
|
||||
<string name="sendtogoogle_send_stats">Envia les estadístiques de la ruta</string>
|
||||
<string name="sendtogoogle_send_stats_and_points">Envia les estadístiques i els punts</string>
|
||||
|
||||
<!-- Getting the account to upload to. -->
|
||||
<string name="no_account_found_title">No s\'ha trobat cap compte</string>
|
||||
<string name="no_account_found">No s\'ha trobat cap compte on pujar les rutes.</string>
|
||||
<string name="choose_account_title">Trieu un compte</string>
|
||||
|
||||
<!-- SD card -->
|
||||
<string name="io_no_external_storage_found">No s\'ha trobat cap dispositiu d\'emmagatzematge extern. Assegureu-vos que la targeta SD està inserida i que el telèfon no està connectat a un ordinador.</string>
|
||||
<string name="io_write_failed">No es pot escriure a un fitxer.</string>
|
||||
<string name="io_read_failed">No es pot llegir des del fitxer.</string>
|
||||
<string name="io_create_dir_failed">No es pot crear el directori a la targeta SD.</string>
|
||||
<string name="io_write_finished">S\'ha finalitzat l\'escriptura a la targeta SD.</string>
|
||||
<string name="io_read_finished">S\'ha finalitzat la lectura a la targeta SD.</string>
|
||||
|
||||
<!-- VersionChecker -->
|
||||
<string name="version_check_title">Comprovació d\'actualitzacions</string>
|
||||
<string name="version_check_upgrade_button">Actualitza ara</string>
|
||||
<string name="version_check_continue_button">Continua sense actualitzar</string>
|
||||
<string name="upgrade_required">La vostra versió de %1$s podria no funcionar correctament a partir d\'ara i no està suportada. Actualitzeu per continuar fent servir %1$s.</string>
|
||||
<string name="upgrade_recommended">La vostra versió de %1$s podria no funcionar correctament a partir d\'ara. Heu d\'actualitzar-la ara o continuar fent-la servir pel vostre compte. Algunes funcionalitats com la sincronització podrien no funcionar fins que no actualitzeu.</string>
|
||||
<string name="upgrade_available">Hi ha una nova versió disponible de %1$s. Podeu continuar fent servir la vostra versió sense cap problema, però no aconseguireu les darreres funcionalitats fins que no actualitzeu.</string>
|
||||
|
||||
<!-- Welcome -->
|
||||
<string name="welcome">Benvingut</string>
|
||||
<string name="welcome_read_later">D\'acord</string>
|
||||
<string name="welcome_about">Quant a My Tracks</string>
|
||||
|
||||
<!-- Announcement -->
|
||||
<string name="announce_no_distance">Sense distància 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">My Tracks %1$s %2$.2f %3$s en %4$s at %5$s %6$s</string>
|
||||
|
||||
<!-- Check Units -->
|
||||
<string name="check_units_title">Avís de les unitats de mesura</string>
|
||||
<string name="check_units_message">Les unitats són mètriques per defecte. Voleu canviar aquest paràmetre?</string>
|
||||
|
||||
<!-- Signal Strength -->
|
||||
<string name="error_rate"> Rati d\'error: %1$d</string>
|
||||
<string name="signal_to_noise_ratio"> Relació senyal/soroll: %1$d</string>
|
||||
<string name="ecio"> Ec/lo: %1$.1f dB</string>
|
||||
<string name="gsm_strength">Intensistat GSM: %1$d</string>
|
||||
<string name="cdma_strength">Intensitat CDMA: %1$d dBm</string>
|
||||
<string name="evdo_strength">Intensitat EVDO: %1$d dBm</string>
|
||||
|
||||
<!-- Fake preference keys - never saved, but show options in the preferences screen -->
|
||||
<string name="bluetooth_options">Opcions del Bluetooth</string>
|
||||
<string name="bluetooth_pairing">Associació de dispositius</string>
|
||||
<string name="bluetooth_pairing_summary">Obriu els paràmetres de bluetooth de l\'Android per associar un dispositiu</string>
|
||||
<string name="sensor_bluetooth_options_key">bluetoothSensorsEnabled</string>
|
||||
<string name="sensor_options">Opcions del sensor</string>
|
||||
|
||||
<!-- Bluetooth Sensor -->
|
||||
<string name="bluetooth_connected">Connectat a %s</string>
|
||||
<string name="bluetooth_connecting">Connexió del sensor bluetooth...</string>
|
||||
<string name="bluetooth_not_connected">El sensor bluetooth no està connectat</string>
|
||||
|
||||
<!-- Sensor State -->
|
||||
<string name="sensor_data_time">Dades del sensor de temps</string>
|
||||
<string name="power_meter_enabled">S\'ha habilitat el mesurador de potència</string>
|
||||
<string name="heart_rate_monitor_enabled">S\'ha habilitat el monitor de la freqüència cardíaca</string>
|
||||
<string name="no_sensor_manager">Cap gestor de sensors</string>
|
||||
<string name="enabled">Habilitat</string>
|
||||
<string name="connecting">S\'està connectant</string>
|
||||
<string name="connected">S\'ha connectat</string>
|
||||
<string name="disconnected">S\'ha desconnectat</string>
|
||||
<string name="no_sensor_service">Cap servei de sensor</string>
|
||||
<string name="searching">S\'està cercant</string>
|
||||
<string name="sending">S\'està enviant</string>
|
||||
|
||||
</resources>
|
||||
@@ -361,6 +361,8 @@ limitations under the License.
|
||||
<string name="about_version">Wersja:</string>
|
||||
<string name="about_email">Wsparcie</string>
|
||||
<string name="about_support">Wsparcie:</string>
|
||||
|
||||
<string name="about_bart">Bartłomiej Niechwiej</string>
|
||||
|
||||
<!-- Send to Google -->
|
||||
<string name="sendtogoogle_title">Wyślij do...</string>
|
||||
|
||||
@@ -388,6 +388,7 @@ limitations under the License.
|
||||
<string name="about_googlegroups">mytracks@googlegroups.com</string>
|
||||
<string name="about_weburl">mytracks.appspot.com</string>
|
||||
<string name="about_copyright_message">Copyright 2009 Google Inc.</string>
|
||||
<string name="about_bart">Bartlomiej Niechwiej</string>
|
||||
<string name="about_dylan">Dylan Casey</string>
|
||||
<string name="about_leif">Leif Hendrik Wilden</string>
|
||||
<string name="about_rdamazio">Rodrigo Damazio Bovendorp</string>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?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 -->
|
||||
<string name="waypoint_icon_url">http://maps.google.com/mapfiles/ms/micons/blue-pushpin.png</string>
|
||||
<string name="stats_icon_url">http://maps.google.com/mapfiles/ms/micons/ylw-pushpin.png</string>
|
||||
</resources>
|
||||
@@ -25,7 +25,7 @@ import com.google.android.apps.mymaps.MyMapsConstants;
|
||||
import com.google.android.apps.mymaps.MyMapsList;
|
||||
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.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.io.AuthManager;
|
||||
import com.google.android.apps.mytracks.io.AuthManagerFactory;
|
||||
import com.google.android.apps.mytracks.io.GpxImporter;
|
||||
@@ -63,6 +63,7 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@@ -93,9 +94,6 @@ import org.xml.sax.SAXException;
|
||||
public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
OnSharedPreferenceChangeListener, ProgressIndicator {
|
||||
|
||||
private static final String WAYPOINT_ICON_URL =
|
||||
"http://maps.google.com/mapfiles/ms/micons/blue-pushpin.png";
|
||||
|
||||
/**
|
||||
* Singleton instance
|
||||
*/
|
||||
@@ -432,7 +430,13 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
public boolean onTrackballEvent(MotionEvent event) {
|
||||
if (isRecording()) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
insertStatisticsMarker();
|
||||
try {
|
||||
insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert statistics marker.", e);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert statistics marker.", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -888,90 +892,25 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
/**
|
||||
* Inserts a waypoint marker.
|
||||
*
|
||||
* @return the id of the inserted statistics marker, or
|
||||
* -1 unable to find location
|
||||
* -2 track recording service is not running?
|
||||
* -3 remote exception when contacting track recording service
|
||||
* -4 inserting marker into provider failed
|
||||
* @return Id of the inserted statistics marker.
|
||||
* @throws RemoteException If the call on the service failed.
|
||||
*/
|
||||
public long insertWaypointMarker() {
|
||||
Location location = getCurrentLocation();
|
||||
if (location == null) {
|
||||
public long insertWaypoint(WaypointCreationRequest request) throws RemoteException {
|
||||
if (trackRecordingService == null) {
|
||||
throw new IllegalStateException("The recording service is not bound.");
|
||||
}
|
||||
try {
|
||||
long waypointId = trackRecordingService.insertWaypoint(request);
|
||||
if (waypointId >= 0) {
|
||||
Toast.makeText(this, R.string.status_statistics_inserted,
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
return waypointId;
|
||||
} catch (RemoteException e) {
|
||||
Toast.makeText(this, R.string.error_unable_to_insert_marker,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return -1;
|
||||
throw e;
|
||||
}
|
||||
if (trackRecordingService != null) {
|
||||
try {
|
||||
Waypoint wpt = new Waypoint();
|
||||
wpt.setName(getString(R.string.waypoint));
|
||||
wpt.setType(Waypoint.TYPE_WAYPOINT);
|
||||
wpt.setTrackId(recordingTrackId);
|
||||
wpt.setIcon(WAYPOINT_ICON_URL);
|
||||
wpt.setLocation(location);
|
||||
long waypointId = trackRecordingService.insertWaypointMarker(wpt);
|
||||
if (waypointId >= 0) {
|
||||
Toast.makeText(this, R.string.status_waypoint_inserted,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return waypointId;
|
||||
} else {
|
||||
Toast.makeText(this, R.string.error_unable_to_insert_marker,
|
||||
Toast.LENGTH_LONG).show();
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert waypoint marker?");
|
||||
return -4;
|
||||
}
|
||||
// TODO: We catch Exception, because after eliminating the service process
|
||||
// all exceptions it may throw are no longer wrapped in a RemoteException.
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(this, R.string.error_unable_to_insert_marker,
|
||||
Toast.LENGTH_LONG).show();
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert waypoint marker.", e);
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a statistics marker.
|
||||
*
|
||||
* @return the id of the inserted statistics marker, or
|
||||
* -1 unable to find location
|
||||
* -2 track recording service is not running?
|
||||
* -3 remote exception when contacting track recording service
|
||||
* -4 inserting marker into provider failed
|
||||
*/
|
||||
public long insertStatisticsMarker() {
|
||||
Location location = getLastLocation();
|
||||
if (location == null) {
|
||||
Toast.makeText(this, R.string.error_unable_to_insert_marker,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return -1;
|
||||
}
|
||||
if (trackRecordingService != null) {
|
||||
try {
|
||||
long waypointId =
|
||||
trackRecordingService.insertStatisticsMarker(location);
|
||||
if (waypointId >= 0) {
|
||||
Toast.makeText(this, R.string.status_statistics_inserted,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return waypointId;
|
||||
} else {
|
||||
Toast.makeText(this, R.string.error_unable_to_insert_marker,
|
||||
Toast.LENGTH_LONG).show();
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert statistics marker?");
|
||||
return -4;
|
||||
}
|
||||
// TODO: We catch Exception, because after eliminating the service process
|
||||
// all exceptions it may throw are no longer wrapped in a RemoteException.
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(this, R.string.error_unable_to_insert_marker,
|
||||
Toast.LENGTH_LONG).show();
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert statistics marker?", e);
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,8 @@ import android.widget.ImageView;
|
||||
public class MyTracksWaypointDetails extends Activity
|
||||
implements OnClickListener {
|
||||
|
||||
public static final String WAYPOINT_ID_EXTRA = "com.google.android.apps.mytracks.WAYPOINT_ID";
|
||||
|
||||
/**
|
||||
* The id of the way point being edited (taken from bundle, "waypointid")
|
||||
*/
|
||||
@@ -78,7 +80,7 @@ public class MyTracksWaypointDetails extends Activity
|
||||
}
|
||||
|
||||
// Required extra when launching this intent:
|
||||
waypointId = getIntent().getLongExtra("waypointid", -1);
|
||||
waypointId = getIntent().getLongExtra(WAYPOINT_ID_EXTRA, -1);
|
||||
if (waypointId < 0) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"MyTracksWaypointsDetails intent was launched w/o waypoint id.");
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.content.WaypointsColumns;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
@@ -28,6 +29,8 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.MenuItem;
|
||||
@@ -87,7 +90,7 @@ public class MyTracksWaypointsList extends ListActivity
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
Intent result = new Intent();
|
||||
result.putExtra("trackid", trackId);
|
||||
result.putExtra("waypointid", id);
|
||||
result.putExtra(MyTracksWaypointDetails.WAYPOINT_ID_EXTRA, id);
|
||||
setResult(MyTracksConstants.EDIT_WAYPOINT, result);
|
||||
finish();
|
||||
}
|
||||
@@ -103,7 +106,7 @@ public class MyTracksWaypointsList extends ListActivity
|
||||
case MyTracksConstants.MENU_EDIT: {
|
||||
Intent intent = new Intent(this, MyTracksWaypointDetails.class);
|
||||
intent.putExtra("trackid", trackId);
|
||||
intent.putExtra("waypointid", waypointId);
|
||||
intent.putExtra(MyTracksWaypointDetails.WAYPOINT_ID_EXTRA, waypointId);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
@@ -165,27 +168,34 @@ public class MyTracksWaypointsList extends ListActivity
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
WaypointCreationRequest request;
|
||||
switch (v.getId()) {
|
||||
case R.id.waypointslist_btn_insert_waypoint: {
|
||||
long id = MyTracks.getInstance().insertWaypointMarker();
|
||||
if (id >= 0) {
|
||||
Intent intent = new Intent(this, MyTracksWaypointDetails.class);
|
||||
intent.putExtra("waypointid", id);
|
||||
startActivity(intent);
|
||||
}
|
||||
case R.id.waypointslist_btn_insert_waypoint:
|
||||
request = WaypointCreationRequest.DEFAULT_MARKER;
|
||||
break;
|
||||
}
|
||||
case R.id.waypointslist_btn_insert_statistics: {
|
||||
long id = MyTracks.getInstance().insertStatisticsMarker();
|
||||
if (id >= 0) {
|
||||
Intent intent = new Intent(this, MyTracksWaypointDetails.class);
|
||||
intent.putExtra("waypointid", id);
|
||||
startActivity(intent);
|
||||
}
|
||||
case R.id.waypointslist_btn_insert_statistics:
|
||||
request = WaypointCreationRequest.DEFAULT_STATISTICS;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
long id;
|
||||
try {
|
||||
id = MyTracks.getInstance().insertWaypoint(request);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert marker.", e);
|
||||
return;
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert marker.", e);
|
||||
return;
|
||||
}
|
||||
if (id < 0) {
|
||||
Log.e(MyTracksConstants.TAG, "Failed to insert marker.");
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent(this, MyTracksWaypointDetails.class);
|
||||
intent.putExtra(MyTracksWaypointDetails.WAYPOINT_ID_EXTRA, id);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void setListAdapter() {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.util.UnitConversions;
|
||||
|
||||
import android.util.Log;
|
||||
@@ -111,7 +112,7 @@ public class SplitManager {
|
||||
}
|
||||
|
||||
if (distance > this.nextSplitDistance) {
|
||||
service.insertStatisticsMarker(service.getLastLocation());
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
calculateNextSplit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
|
||||
|
||||
/**
|
||||
* A simple task to insert statistics markers every n minutes.
|
||||
* @author Sandor Dornbush
|
||||
@@ -24,7 +27,7 @@ public class TimeSplitTask implements PeriodicTask {
|
||||
|
||||
@Override
|
||||
public void run(TrackRecordingService service) {
|
||||
service.insertStatisticsMarker(service.getLastLocation());
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
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;
|
||||
@@ -70,9 +71,6 @@ import java.util.TimerTask;
|
||||
*/
|
||||
public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
private static final String STATISTICS_ICON_URL =
|
||||
"http://maps.google.com/mapfiles/ms/micons/ylw-pushpin.png";
|
||||
|
||||
static final int MAX_AUTO_RESUME_TRACK_RETRY_ATTEMPTS = 3;
|
||||
|
||||
private NotificationManager notificationManager;
|
||||
@@ -429,7 +427,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
lastValidLocation = null;
|
||||
|
||||
Waypoint waypoint = providerUtils.getFirstWaypoint(recordingTrackId);
|
||||
if (waypoint != null) {
|
||||
if (waypoint != null && waypoint.getStatistics() != null) {
|
||||
currentWaypointId = waypoint.getId();
|
||||
waypointStatsBuilder = new TripStatisticsBuilder(
|
||||
waypoint.getStatistics());
|
||||
@@ -860,50 +858,62 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
return isRecording;
|
||||
}
|
||||
|
||||
public long insertWaypointMarker(Waypoint waypoint) {
|
||||
public long insertWaypoint(WaypointCreationRequest request) {
|
||||
if (!isRecording()) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to insert waypoint marker while not recording!");
|
||||
}
|
||||
|
||||
if (waypoint.getLocation() == null) {
|
||||
if (lastValidLocation == null) {
|
||||
Log.w(MyTracksConstants.TAG, "Cannot insert waypoint with no location");
|
||||
return -1;
|
||||
}
|
||||
|
||||
waypoint.setLocation(lastValidLocation);
|
||||
if (request == null) {
|
||||
request = WaypointCreationRequest.DEFAULT_MARKER;
|
||||
}
|
||||
|
||||
if (waypoint.getTrackId() < 0) {
|
||||
waypoint.setTrackId(recordingTrackId);
|
||||
Waypoint wpt = new Waypoint();
|
||||
switch (request.getType()) {
|
||||
case MARKER:
|
||||
buildMarker(wpt, request);
|
||||
break;
|
||||
case STATISTICS:
|
||||
buildStatisticsMarker(wpt);
|
||||
break;
|
||||
}
|
||||
|
||||
waypoint.setLength(length);
|
||||
waypoint.setDuration(waypoint.getLocation().getTime()
|
||||
- statsBuilder.getStatistics().getStartTime());
|
||||
Uri uri = providerUtils.insertWaypoint(waypoint);
|
||||
wpt.setTrackId(recordingTrackId);
|
||||
wpt.setLength(length);
|
||||
if (lastValidLocation != null) {
|
||||
// A null location is ok, and expected on track start.
|
||||
wpt.setLocation(lastLocation);
|
||||
wpt.setDuration(lastLocation.getTime()
|
||||
- statsBuilder.getStatistics().getStartTime());
|
||||
}
|
||||
Uri uri = providerUtils.insertWaypoint(wpt);
|
||||
return Long.parseLong(uri.getLastPathSegment());
|
||||
}
|
||||
|
||||
private void buildMarker(Waypoint wpt, WaypointCreationRequest request) {
|
||||
wpt.setType(Waypoint.TYPE_WAYPOINT);
|
||||
if (request.getIconUrl() == null) {
|
||||
wpt.setIcon(getString(R.string.waypoint_icon_url));
|
||||
} else {
|
||||
wpt.setIcon(request.getIconUrl());
|
||||
}
|
||||
if (request.getName() == null) {
|
||||
wpt.setName(getString(R.string.waypoint));
|
||||
} else {
|
||||
wpt.setName(request.getName());
|
||||
}
|
||||
if (request.getDescription() != null) {
|
||||
wpt.setDescription(request.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a statistics marker. A statistics marker holds the stats for the
|
||||
* last segment up to this marker.
|
||||
* Build a statistics marker.
|
||||
* A statistics marker holds the stats for the* last segment up to this marker.
|
||||
*
|
||||
* @param location the location where to insert
|
||||
* @param Waypoint The waypoint which will be populated with stats data.
|
||||
* @return the unique id of the inserted marker
|
||||
*/
|
||||
public long insertStatisticsMarker(Location location) {
|
||||
if (!isRecording()) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to insert statistics marker while not recording!");
|
||||
}
|
||||
|
||||
private void buildStatisticsMarker(Waypoint waypoint) {
|
||||
StringUtils utils = new StringUtils(TrackRecordingService.this);
|
||||
|
||||
// Create a new waypoint to save
|
||||
Waypoint waypoint = new Waypoint();
|
||||
|
||||
// Set stop and total time in the stats data
|
||||
final long time = System.currentTimeMillis();
|
||||
waypointStatsBuilder.pauseAt(time);
|
||||
@@ -913,24 +923,18 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
waypoint.setDuration(time - statsBuilder.getStatistics().getStartTime());
|
||||
|
||||
// Set the rest of the waypoint data
|
||||
waypoint.setTrackId(recordingTrackId);
|
||||
waypoint.setType(Waypoint.TYPE_STATISTICS);
|
||||
waypoint.setName(TrackRecordingService.this.getString(R.string.statistics));
|
||||
waypoint.setName(getString(R.string.statistics));
|
||||
waypoint.setStatistics(waypointStatsBuilder.getStatistics());
|
||||
waypoint.setDescription(utils.generateWaypointDescription(waypoint));
|
||||
waypoint.setLocation(location);
|
||||
waypoint.setIcon(STATISTICS_ICON_URL);
|
||||
waypoint.setLength(length);
|
||||
waypoint.setIcon(getString(R.string.stats_icon_url));
|
||||
|
||||
waypoint.setStartId(providerUtils.getLastLocationId(recordingTrackId));
|
||||
Uri uri = providerUtils.insertWaypoint(waypoint);
|
||||
|
||||
// Create a new stats keeper for the next marker
|
||||
// Create a new stats keeper for the next marker.
|
||||
waypointStatsBuilder = new TripStatisticsBuilder(time);
|
||||
updateCurrentWaypoint();
|
||||
return Long.parseLong(uri.getLastPathSegment());
|
||||
}
|
||||
|
||||
|
||||
private ServiceBinder binder = new ServiceBinder(this);
|
||||
|
||||
/**
|
||||
@@ -961,79 +965,54 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
@Override
|
||||
public boolean isRecording() {
|
||||
checkService();
|
||||
return service.isRecording();
|
||||
}
|
||||
|
||||
private void checkService() {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
return service.isRecording();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRecordingTrackId() {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
checkService();
|
||||
return service.recordingTrackId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRecorded() {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
checkService();
|
||||
return service.providerUtils.getLastTrackId() >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long startNewTrack() {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
checkService();
|
||||
return service.startNewTrack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the given waypoint marker. Users can insert waypoint markers
|
||||
* to tag locations with a name, description, category etc.
|
||||
* Inserts a waypoint marker in the track being recorded.
|
||||
*
|
||||
* @param waypoint a waypoint
|
||||
* @return the unique id of the inserted marker
|
||||
* @param request Details of the waypoint to insert
|
||||
* @return the unique ID of the inserted marker
|
||||
*/
|
||||
@Override
|
||||
public long insertWaypointMarker(Waypoint waypoint) {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
return service.insertWaypointMarker(waypoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a statistics marker. A statistics marker holds the stats for
|
||||
* the last segment up to this marker.
|
||||
*
|
||||
* @param location the location where to insert
|
||||
* @return the unique id of the inserted marker
|
||||
*/
|
||||
@Override
|
||||
public long insertStatisticsMarker(Location location) {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
return service.insertStatisticsMarker(location);
|
||||
public long insertWaypoint(WaypointCreationRequest request) {
|
||||
checkService();
|
||||
return service.insertWaypoint(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endCurrentTrack() {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
checkService();
|
||||
service.endCurrentTrack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAllTracks() {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
checkService();
|
||||
if (isRecording()) {
|
||||
throw new IllegalStateException("Cannot delete all tracks while recording!");
|
||||
}
|
||||
@@ -1042,14 +1021,13 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
@Override
|
||||
public void recordLocation(Location loc) {
|
||||
if (service == null) {
|
||||
throw new IllegalStateException("The service has been already detached!");
|
||||
}
|
||||
checkService();
|
||||
service.onLocationChanged(loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getSensorData() {
|
||||
checkService();
|
||||
if (service.sensorManager == null) {
|
||||
Log.d(MyTracksConstants.TAG, "No sensor manager for data.");
|
||||
return null;
|
||||
@@ -1063,6 +1041,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
@Override
|
||||
public int getSensorState() {
|
||||
checkService();
|
||||
if (service.sensorManager == null) {
|
||||
Log.d(MyTracksConstants.TAG, "No sensor manager for data.");
|
||||
return Sensor.SensorState.NONE.getNumber();
|
||||
@@ -1095,7 +1074,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
providerUtils.updateTrack(track);
|
||||
statsBuilder = new TripStatisticsBuilder(startTime);
|
||||
waypointStatsBuilder = new TripStatisticsBuilder(startTime);
|
||||
currentWaypointId = insertStatisticsMarker(null);
|
||||
currentWaypointId = insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
setUpAnnouncer();
|
||||
length = 0;
|
||||
showNotification();
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -309,6 +310,87 @@ public interface MyTracksProviderUtils {
|
||||
* @return a new waypoint object
|
||||
*/
|
||||
Waypoint createWaypoint(Cursor cursor);
|
||||
|
||||
/**
|
||||
* A lightweight wrapper around the original {@link Cursor} with a method to clean up.
|
||||
*/
|
||||
interface LocationIterator extends Iterator<Location> {
|
||||
/**
|
||||
* Returns ID of the most recently retrieved track point through a call to {@link #next()}.
|
||||
*
|
||||
* @return the ID of the most recent track point ID.
|
||||
*/
|
||||
long getLocationId();
|
||||
|
||||
/**
|
||||
* Should be called in case the underlying iterator hasn't reached the last record.
|
||||
*/
|
||||
void close();
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory for creating new {@class Location}s.
|
||||
*/
|
||||
interface LocationFactory {
|
||||
/**
|
||||
* Creates a new {@link Location} object to be populated from the underlying database record.
|
||||
* It's up to the implementing class to decide whether to create a new instance or reuse
|
||||
* existing to optimize for speed.
|
||||
*
|
||||
* @return a {@link Location} to be populated from the database.
|
||||
*/
|
||||
Location createLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* The default {@class Location}s factory, which creates a new location of 'gps' type.
|
||||
*/
|
||||
LocationFactory DEFAULT_LOCATION_FACTORY = new LocationFactory() {
|
||||
@Override
|
||||
public Location createLocation() {
|
||||
return new Location("gps");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new read-only iterator over all track points for the given track. It provides
|
||||
* a lightweight way of iterating over long tracks without failing due to the underlying cursor
|
||||
* limitations. Since it's a read-only iterator, {@link Iterator#remove()} always throws
|
||||
* {@class UnsupportedOperationException}.
|
||||
*
|
||||
* Each call to {@link LocationIterator#next()} may advance to the next DB record, and if so,
|
||||
* the iterator calls {@link LocationFactory#createLocation()} and populates it with information
|
||||
* retrieved from the record.
|
||||
*
|
||||
* When done with iteration, you must call {@link LocationIterator#close()} to make sure that all
|
||||
* resources are properly deallocated.
|
||||
*
|
||||
* Example use:
|
||||
* <code>
|
||||
* ...
|
||||
* LocationIterator it = providerUtils.getLocationIterator(
|
||||
* 1, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
* try {
|
||||
* for (Location loc : it) {
|
||||
* ... // Do something useful with the location.
|
||||
* }
|
||||
* } finally {
|
||||
* it.close();
|
||||
* }
|
||||
* ...
|
||||
* </code>
|
||||
*
|
||||
* @param trackId the ID of a track to retrieve locations for.
|
||||
* @param startTrackPointId the ID of the first track point to load, or -1 to start from
|
||||
* the first point.
|
||||
* @param descending if true the results will be returned in descending ID
|
||||
* order (latest location first).
|
||||
* @param locationFactory the factory for creating new locations.
|
||||
*
|
||||
* @return the read-only iterator over the given track's points.
|
||||
*/
|
||||
LocationIterator getLocationIterator(long trackId, long startTrackPointId, boolean descending,
|
||||
LocationFactory locationFactory);
|
||||
|
||||
/**
|
||||
* A factory which can produce instances of {@link MyTracksProviderUtils},
|
||||
|
||||
+177
-55
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import static com.google.android.apps.mytracks.lib.MyTracksLibConstants.*;
|
||||
import static com.google.android.apps.mytracks.lib.MyTracksLibConstants.TAG;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
@@ -29,6 +29,7 @@ import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Helper class providing easy access to locations and tracks in the
|
||||
@@ -39,6 +40,8 @@ import java.util.List;
|
||||
public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
private final ContentResolver contentResolver;
|
||||
|
||||
private int defaultCursorBatchSize = 2000;
|
||||
|
||||
public MyTracksProviderUtilsImpl(ContentResolver contentResolver) {
|
||||
this.contentResolver = contentResolver;
|
||||
@@ -124,7 +127,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
private static ContentValues createContentValues(Waypoint waypoint) {
|
||||
ContentValues values = new ContentValues();
|
||||
TripStatistics stats = waypoint.getStatistics();
|
||||
|
||||
// Values id < 0 indicate no id is available:
|
||||
if (waypoint.getId() >= 0) {
|
||||
@@ -138,21 +140,24 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
values.put(WaypointsColumns.TYPE, waypoint.getType());
|
||||
values.put(WaypointsColumns.LENGTH, waypoint.getLength());
|
||||
values.put(WaypointsColumns.DURATION, waypoint.getDuration());
|
||||
values.put(WaypointsColumns.STARTTIME, stats.getStartTime());
|
||||
values.put(WaypointsColumns.STARTID, waypoint.getStartId());
|
||||
values.put(WaypointsColumns.STOPID, waypoint.getStopId());
|
||||
|
||||
values.put(WaypointsColumns.TOTALDISTANCE, stats.getTotalDistance());
|
||||
values.put(WaypointsColumns.TOTALTIME, stats.getTotalTime());
|
||||
values.put(WaypointsColumns.MOVINGTIME, stats.getMovingTime());
|
||||
values.put(WaypointsColumns.AVGSPEED, stats.getAverageSpeed());
|
||||
values.put(WaypointsColumns.AVGMOVINGSPEED, stats.getAverageMovingSpeed());
|
||||
values.put(WaypointsColumns.MAXSPEED, stats.getMaxSpeed());
|
||||
values.put(WaypointsColumns.MINELEVATION, stats.getMinElevation());
|
||||
values.put(WaypointsColumns.MAXELEVATION, stats.getMaxElevation());
|
||||
values.put(WaypointsColumns.ELEVATIONGAIN, stats.getTotalElevationGain());
|
||||
values.put(WaypointsColumns.MINGRADE, stats.getMinGrade());
|
||||
values.put(WaypointsColumns.MAXGRADE, stats.getMaxGrade());
|
||||
TripStatistics stats = waypoint.getStatistics();
|
||||
if (stats != null) {
|
||||
values.put(WaypointsColumns.TOTALDISTANCE, stats.getTotalDistance());
|
||||
values.put(WaypointsColumns.TOTALTIME, stats.getTotalTime());
|
||||
values.put(WaypointsColumns.MOVINGTIME, stats.getMovingTime());
|
||||
values.put(WaypointsColumns.AVGSPEED, stats.getAverageSpeed());
|
||||
values.put(WaypointsColumns.AVGMOVINGSPEED, stats.getAverageMovingSpeed());
|
||||
values.put(WaypointsColumns.MAXSPEED, stats.getMaxSpeed());
|
||||
values.put(WaypointsColumns.MINELEVATION, stats.getMinElevation());
|
||||
values.put(WaypointsColumns.MAXELEVATION, stats.getMaxElevation());
|
||||
values.put(WaypointsColumns.ELEVATIONGAIN, stats.getTotalElevationGain());
|
||||
values.put(WaypointsColumns.MINGRADE, stats.getMinGrade());
|
||||
values.put(WaypointsColumns.MAXGRADE, stats.getMaxGrade());
|
||||
values.put(WaypointsColumns.STARTTIME, stats.getStartTime());
|
||||
}
|
||||
|
||||
Location location = waypoint.getLocation();
|
||||
if (location != null) {
|
||||
@@ -184,55 +189,78 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
fillLocation(cursor, location);
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* A cache of track column indices.
|
||||
*/
|
||||
private static class CachedTrackColumnIndices {
|
||||
public final int idxId;
|
||||
public final int idxLatitude;
|
||||
public final int idxLongitude;
|
||||
public final int idxAltitude;
|
||||
public final int idxTime;
|
||||
public final int idxBearing;
|
||||
public final int idxAccuracy;
|
||||
public final int idxSpeed;
|
||||
public final int idxSensor;
|
||||
|
||||
@Override
|
||||
public void fillLocation(Cursor cursor, Location location) {
|
||||
public CachedTrackColumnIndices(Cursor cursor) {
|
||||
idxId = cursor.getColumnIndex(TrackPointsColumns._ID);
|
||||
idxLatitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.LATITUDE);
|
||||
idxLongitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.LONGITUDE);
|
||||
idxAltitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALTITUDE);
|
||||
idxTime = cursor.getColumnIndexOrThrow(TrackPointsColumns.TIME);
|
||||
idxBearing = cursor.getColumnIndexOrThrow(TrackPointsColumns.BEARING);
|
||||
idxAccuracy = cursor.getColumnIndexOrThrow(TrackPointsColumns.ACCURACY);
|
||||
idxSpeed = cursor.getColumnIndexOrThrow(TrackPointsColumns.SPEED);
|
||||
idxSensor = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillLocation(Cursor cursor, CachedTrackColumnIndices columnIndices,
|
||||
Location location) {
|
||||
location.reset();
|
||||
|
||||
int idxLatitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.LATITUDE);
|
||||
int idxLongitude =
|
||||
cursor.getColumnIndexOrThrow(TrackPointsColumns.LONGITUDE);
|
||||
int idxAltitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALTITUDE);
|
||||
int idxTime = cursor.getColumnIndexOrThrow(TrackPointsColumns.TIME);
|
||||
int idxBearing = cursor.getColumnIndexOrThrow(TrackPointsColumns.BEARING);
|
||||
int idxAccuracy = cursor.getColumnIndexOrThrow(TrackPointsColumns.ACCURACY);
|
||||
int idxSpeed = cursor.getColumnIndexOrThrow(TrackPointsColumns.SPEED);
|
||||
int idxSensor = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR);
|
||||
|
||||
if (!cursor.isNull(idxLatitude)) {
|
||||
location.setLatitude(1. * cursor.getInt(idxLatitude) / 1E6);
|
||||
|
||||
if (!cursor.isNull(columnIndices.idxLatitude)) {
|
||||
location.setLatitude(1. * cursor.getInt(columnIndices.idxLatitude) / 1E6);
|
||||
}
|
||||
if (!cursor.isNull(idxLongitude)) {
|
||||
location.setLongitude(1. * cursor.getInt(idxLongitude) / 1E6);
|
||||
if (!cursor.isNull(columnIndices.idxLongitude)) {
|
||||
location.setLongitude(1. * cursor.getInt(columnIndices.idxLongitude) / 1E6);
|
||||
}
|
||||
if (!cursor.isNull(idxAltitude)) {
|
||||
location.setAltitude(cursor.getFloat(idxAltitude));
|
||||
if (!cursor.isNull(columnIndices.idxAltitude)) {
|
||||
location.setAltitude(cursor.getFloat(columnIndices.idxAltitude));
|
||||
}
|
||||
if (!cursor.isNull(idxTime)) {
|
||||
location.setTime(cursor.getLong(idxTime));
|
||||
if (!cursor.isNull(columnIndices.idxTime)) {
|
||||
location.setTime(cursor.getLong(columnIndices.idxTime));
|
||||
}
|
||||
if (!cursor.isNull(idxBearing)) {
|
||||
location.setBearing(cursor.getFloat(idxBearing));
|
||||
if (!cursor.isNull(columnIndices.idxBearing)) {
|
||||
location.setBearing(cursor.getFloat(columnIndices.idxBearing));
|
||||
}
|
||||
if (!cursor.isNull(idxSpeed)) {
|
||||
location.setSpeed(cursor.getFloat(idxSpeed));
|
||||
if (!cursor.isNull(columnIndices.idxSpeed)) {
|
||||
location.setSpeed(cursor.getFloat(columnIndices.idxSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxAccuracy)) {
|
||||
location.setAccuracy(cursor.getFloat(idxAccuracy));
|
||||
if (!cursor.isNull(columnIndices.idxAccuracy)) {
|
||||
location.setAccuracy(cursor.getFloat(columnIndices.idxAccuracy));
|
||||
}
|
||||
if (location instanceof MyTracksLocation &&
|
||||
!cursor.isNull(idxSensor)) {
|
||||
!cursor.isNull(columnIndices.idxSensor)) {
|
||||
MyTracksLocation mtLocation = (MyTracksLocation) location;
|
||||
// TODO get the right buffer.
|
||||
Sensor.SensorDataSet sensorData;
|
||||
try {
|
||||
sensorData = Sensor.SensorDataSet.parseFrom(cursor.getBlob(idxSensor));
|
||||
sensorData = Sensor.SensorDataSet.parseFrom(cursor.getBlob(columnIndices.idxSensor));
|
||||
mtLocation.setSensorData(sensorData);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
Log.w(TAG, "Failed to parse sensor data.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillLocation(Cursor cursor, Location location) {
|
||||
CachedTrackColumnIndices columnIndicies = new CachedTrackColumnIndices(cursor);
|
||||
fillLocation(cursor, columnIndicies, location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Track createTrack(Cursor cursor) {
|
||||
@@ -378,7 +406,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
int idxSpeed = cursor.getColumnIndexOrThrow(WaypointsColumns.SPEED);
|
||||
|
||||
Waypoint waypoint = new Waypoint();
|
||||
TripStatistics stats = waypoint.getStatistics();
|
||||
|
||||
if (!cursor.isNull(idxId)) {
|
||||
waypoint.setId(cursor.getLong(idxId));
|
||||
@@ -407,41 +434,57 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
if (!cursor.isNull(idxDuration)) {
|
||||
waypoint.setDuration(cursor.getLong(idxDuration));
|
||||
}
|
||||
if (!cursor.isNull(idxStartTime)) {
|
||||
stats.setStartTime(cursor.getLong(idxStartTime));
|
||||
}
|
||||
if (!cursor.isNull(idxStartId)) {
|
||||
waypoint.setStartId(cursor.getLong(idxStartId));
|
||||
}
|
||||
if (!cursor.isNull(idxStopId)) {
|
||||
waypoint.setStopId(cursor.getLong(idxStopId));
|
||||
}
|
||||
|
||||
TripStatistics stats = new TripStatistics();
|
||||
boolean hasStats = false;
|
||||
if (!cursor.isNull(idxStartTime)) {
|
||||
stats.setStartTime(cursor.getLong(idxStartTime));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxTotalDistance)) {
|
||||
stats.setTotalDistance(cursor.getFloat(idxTotalDistance));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxTotalTime)) {
|
||||
stats.setTotalTime(cursor.getLong(idxTotalTime));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxMovingTime)) {
|
||||
stats.setMovingTime(cursor.getLong(idxMovingTime));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxMaxSpeed)) {
|
||||
stats.setMaxSpeed(cursor.getFloat(idxMaxSpeed));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxMinElevation)) {
|
||||
stats.setMinElevation(cursor.getFloat(idxMinElevation));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxMaxElevation)) {
|
||||
stats.setMaxElevation(cursor.getFloat(idxMaxElevation));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxElevationGain)) {
|
||||
stats.setTotalElevationGain(cursor.getFloat(idxElevationGain));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxMinGrade)) {
|
||||
stats.setMinGrade(cursor.getFloat(idxMinGrade));
|
||||
hasStats = true;
|
||||
}
|
||||
if (!cursor.isNull(idxMaxGrade)) {
|
||||
stats.setMaxGrade(cursor.getFloat(idxMaxGrade));
|
||||
hasStats = true;
|
||||
}
|
||||
if (hasStats) {
|
||||
waypoint.setStatistics(stats);
|
||||
}
|
||||
|
||||
Location location = new Location("");
|
||||
@@ -775,13 +818,12 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
public Cursor getLocationsCursor(long trackId, long minTrackPointId,
|
||||
int maxLocations, boolean descending) {
|
||||
String selection;
|
||||
if (minTrackPointId > 0) {
|
||||
selection = String.format("%s=%d AND %s>=%d",
|
||||
TrackPointsColumns.TRACKID, trackId,
|
||||
TrackPointsColumns._ID, minTrackPointId);
|
||||
if (minTrackPointId >= 0) {
|
||||
selection = String.format("%s=%d AND %s%s%d",
|
||||
TrackPointsColumns.TRACKID, trackId, TrackPointsColumns._ID,
|
||||
descending ? "<=" : ">=", minTrackPointId);
|
||||
} else {
|
||||
selection = String.format("%s=%d",
|
||||
TrackPointsColumns.TRACKID, trackId);
|
||||
selection = String.format("%s=%d", TrackPointsColumns.TRACKID, trackId);
|
||||
}
|
||||
|
||||
String sortOrder = "_id " + (descending ? "DESC" : "ASC");
|
||||
@@ -789,8 +831,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
sortOrder += " LIMIT " + maxLocations;
|
||||
}
|
||||
|
||||
return contentResolver.query(
|
||||
TrackPointsColumns.CONTENT_URI, null, selection, null, sortOrder);
|
||||
return contentResolver.query(TrackPointsColumns.CONTENT_URI, null, selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -938,4 +979,85 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
contentResolver.update(TracksColumns.CONTENT_URI,
|
||||
createContentValues(track), "_id=" + track.getId(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationIterator getLocationIterator(final long trackId, final long startTrackPointId,
|
||||
final boolean descending, final LocationFactory locationFactory) {
|
||||
if (locationFactory == null) {
|
||||
throw new IllegalArgumentException("Expecting non-null locationFactory");
|
||||
}
|
||||
return new LocationIterator() {
|
||||
private long lastTrackPointId = startTrackPointId;
|
||||
private Cursor cursor = getCursor(startTrackPointId);
|
||||
private final CachedTrackColumnIndices columnIndices = cursor != null ?
|
||||
new CachedTrackColumnIndices(cursor) : null;
|
||||
|
||||
private Cursor getCursor(long trackPointId) {
|
||||
return getLocationsCursor(trackId, trackPointId, defaultCursorBatchSize, descending);
|
||||
}
|
||||
|
||||
private boolean advanceCursorToNextBatch() {
|
||||
long pointId = lastTrackPointId + (descending ? -1 : 1);
|
||||
Log.d(TAG, "Advancing cursor point ID: " + pointId);
|
||||
cursor.close();
|
||||
cursor = getCursor(pointId);
|
||||
return cursor != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLocationId() {
|
||||
return lastTrackPointId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (cursor == null) {
|
||||
return false;
|
||||
}
|
||||
if (cursor.isAfterLast()) {
|
||||
return false;
|
||||
}
|
||||
if (cursor.isLast()) {
|
||||
// If the current batch size was less that max, we can safely return, otherwise
|
||||
// we need to advance to the next batch.
|
||||
return cursor.getCount() == defaultCursorBatchSize &&
|
||||
advanceCursorToNextBatch() && !cursor.isAfterLast();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location next() {
|
||||
if (cursor == null ||
|
||||
!(cursor.moveToNext() || advanceCursorToNextBatch() || cursor.moveToNext())) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
lastTrackPointId = cursor.getLong(columnIndices.idxId);
|
||||
Location location = locationFactory.createLocation();
|
||||
fillLocation(cursor, columnIndices, location);
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
cursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// @VisibleForTesting
|
||||
void setDefaultCursorBatchSize(int defaultCursorBatchSize) {
|
||||
this.defaultCursorBatchSize = defaultCursorBatchSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public final class Waypoint implements Parcelable {
|
||||
/** Stop track point id */
|
||||
private long stopId = -1;
|
||||
|
||||
private TripStatistics stats = new TripStatistics();
|
||||
private TripStatistics stats;
|
||||
|
||||
/** The length of the track, without smoothing. */
|
||||
private double length;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
package com.google.android.apps.mytracks.content;
|
||||
parcelable WaypointCreationRequest;
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.content;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* A request for the service to create a waypoint at the current location.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class WaypointCreationRequest implements Parcelable {
|
||||
|
||||
public static enum WaypointType {
|
||||
MARKER,
|
||||
STATISTICS;
|
||||
}
|
||||
|
||||
private WaypointType type;
|
||||
private String name;
|
||||
private String description;
|
||||
private String iconUrl;
|
||||
|
||||
public final static WaypointCreationRequest DEFAULT_MARKER =
|
||||
new WaypointCreationRequest(WaypointType.MARKER);
|
||||
public final static WaypointCreationRequest DEFAULT_STATISTICS =
|
||||
new WaypointCreationRequest(WaypointType.STATISTICS);
|
||||
|
||||
private WaypointCreationRequest(WaypointType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public WaypointCreationRequest(WaypointType type, String name,
|
||||
String description, String iconUrl) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.iconUrl = iconUrl;
|
||||
}
|
||||
|
||||
public static class Creator implements Parcelable.Creator<WaypointCreationRequest> {
|
||||
|
||||
@Override
|
||||
public WaypointCreationRequest createFromParcel(Parcel source) {
|
||||
int i = source.readInt();
|
||||
if (i > WaypointType.values().length) {
|
||||
throw new IllegalArgumentException("Could not find waypoint type: " + i);
|
||||
}
|
||||
WaypointCreationRequest request = new WaypointCreationRequest(WaypointType.values()[i]);
|
||||
request.description = source.readString();
|
||||
request.iconUrl = source.readString();
|
||||
request.name = source.readString();
|
||||
return request;
|
||||
}
|
||||
|
||||
public WaypointCreationRequest[] newArray(int size) {
|
||||
return new WaypointCreationRequest[size];
|
||||
}
|
||||
}
|
||||
|
||||
public static final Creator CREATOR = new Creator();
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int arg1) {
|
||||
parcel.writeInt(type.ordinal());
|
||||
parcel.writeString(description);
|
||||
parcel.writeString(iconUrl);
|
||||
parcel.writeString(name);
|
||||
}
|
||||
|
||||
public WaypointType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getIconUrl() {
|
||||
return iconUrl;
|
||||
}
|
||||
}
|
||||
+3
-11
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
|
||||
/**
|
||||
* MyTracks service.
|
||||
@@ -45,18 +45,10 @@ interface ITrackRecordingService {
|
||||
/**
|
||||
* Inserts a waypoint marker in the track being recorded.
|
||||
*
|
||||
* @param waypoint the waypoint to insert
|
||||
* @param request Details for the waypoint to be inserted.
|
||||
* @return the unique ID of the inserted marker
|
||||
*/
|
||||
long insertWaypointMarker(in Waypoint waypoint);
|
||||
|
||||
/**
|
||||
* Inserts a statistics marker in the track being recorded.
|
||||
*
|
||||
* @param location the location at which to insert the marker
|
||||
* @return the unique ID of the inserted marker
|
||||
*/
|
||||
long insertStatisticsMarker(in Location location);
|
||||
long insertWaypoint(in WaypointCreationRequest request);
|
||||
|
||||
/**
|
||||
* Inserts a location in the track being recorded.
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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.content;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationFactory;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* A unit test for {@link MyTracksProviderUtilsImpl}.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
*/
|
||||
public class MyTracksProviderUtilsImplTest extends AndroidTestCase {
|
||||
private Context context;
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
MockContentResolver mockContentResolver = new MockContentResolver();
|
||||
RenamingDelegatingContext targetContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
context = new MockContext(mockContentResolver, targetContext);
|
||||
MyTracksProvider provider = new MyTracksProvider();
|
||||
provider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, provider);
|
||||
setContext(context);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
}
|
||||
|
||||
public void testLocationIterator_noPoints() {
|
||||
testIterator(1, 0, 1, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_customFactory() {
|
||||
final Location location = new Location("test_location");
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
testIterator(1, 15, 4, false, new LocationFactory() {
|
||||
@Override
|
||||
public Location createLocation() {
|
||||
counter.incrementAndGet();
|
||||
return location;
|
||||
}
|
||||
});
|
||||
// Make sure we were called exactly as many times as we had track points.
|
||||
assertEquals(15, counter.get());
|
||||
}
|
||||
|
||||
public void testLocationIterator_nullFactory() {
|
||||
try {
|
||||
testIterator(1, 15, 4, false, null);
|
||||
fail("Expecting IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Expected.
|
||||
}
|
||||
}
|
||||
|
||||
public void testLocationIterator_noBatchAscending() {
|
||||
testIterator(1, 50, 100, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
testIterator(2, 50, 50, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_noBatchDescending() {
|
||||
testIterator(1, 50, 100, true, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
testIterator(2, 50, 50, true, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_batchAscending() {
|
||||
testIterator(1, 50, 11, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
testIterator(2, 50, 25, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_batchDescending() {
|
||||
testIterator(1, 50, 11, true, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
testIterator(2, 50, 25, true, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_largeTrack() {
|
||||
testIterator(1, 20000, 2000, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
private List<Location> testIterator(long trackId, int numPoints, int batchSize,
|
||||
boolean descending, LocationFactory locationFactory) {
|
||||
long lastPointId = initializeTrack(trackId, numPoints);
|
||||
((MyTracksProviderUtilsImpl) providerUtils).setDefaultCursorBatchSize(batchSize);
|
||||
List<Location> locations = new ArrayList<Location>(numPoints);
|
||||
LocationIterator it = providerUtils.getLocationIterator(trackId, -1, descending, locationFactory);
|
||||
try {
|
||||
while (it.hasNext()) {
|
||||
Location loc = it.next();
|
||||
assertNotNull(loc);
|
||||
locations.add(loc);
|
||||
// Make sure the IDs are returned in the right order.
|
||||
assertEquals(descending ? lastPointId - locations.size() + 1
|
||||
: lastPointId - numPoints + locations.size(), it.getLocationId());
|
||||
}
|
||||
assertEquals(numPoints, locations.size());
|
||||
} finally {
|
||||
it.close();
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
private long initializeTrack(long id, int numPoints) {
|
||||
Track track = new Track();
|
||||
track.setId(id);
|
||||
track.setName("Test: " + id);
|
||||
track.setNumberOfPoints(numPoints);
|
||||
providerUtils.insertTrack(track);
|
||||
track = providerUtils.getTrack(id);
|
||||
assertNotNull(track);
|
||||
|
||||
Location[] locations = new Location[numPoints];
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
Location loc = new Location("test");
|
||||
loc.setLatitude(37.0 + (double) i / 10000.0);
|
||||
loc.setLongitude(57.0 - (double) i / 10000.0);
|
||||
loc.setAccuracy((float) i / 100.0f);
|
||||
loc.setAltitude(i * 2.5);
|
||||
locations[i] = loc;
|
||||
}
|
||||
providerUtils.bulkInsertTrackPoints(locations, numPoints, id);
|
||||
|
||||
// Load all inserted locations.
|
||||
long lastPointId = -1;
|
||||
int counter = 0;
|
||||
LocationIterator it = providerUtils.getLocationIterator(id, -1, false,
|
||||
MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
try {
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
lastPointId = it.getLocationId();
|
||||
counter++;
|
||||
}
|
||||
} finally {
|
||||
it.close();
|
||||
}
|
||||
|
||||
assertTrue(numPoints == 0 || lastPointId > 0);
|
||||
assertEquals(numPoints, track.getNumberOfPoints());
|
||||
assertEquals(numPoints, counter);
|
||||
|
||||
return lastPointId;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.content;
|
||||
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest.WaypointType;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests for the WaypointCreationRequest class.
|
||||
* {@link WaypointCreationRequest}
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class WaypointCreationRequestTest extends AndroidTestCase {
|
||||
|
||||
public void testTypeParceling() {
|
||||
WaypointCreationRequest original = WaypointCreationRequest.DEFAULT_MARKER;
|
||||
Parcel p = Parcel.obtain();
|
||||
original.writeToParcel(p, 0);
|
||||
p.setDataPosition(0);
|
||||
WaypointCreationRequest copy = WaypointCreationRequest.CREATOR.createFromParcel(p);
|
||||
assertEquals(original.getType(), copy.getType());
|
||||
assertNull(copy.getName());
|
||||
assertNull(copy.getDescription());
|
||||
assertNull(copy.getIconUrl());
|
||||
}
|
||||
|
||||
public void testAllAttributesParceling() {
|
||||
WaypointCreationRequest original =
|
||||
new WaypointCreationRequest(WaypointType.MARKER, "name", "description", "img.png");
|
||||
Parcel p = Parcel.obtain();
|
||||
original.writeToParcel(p, 0);
|
||||
p.setDataPosition(0);
|
||||
WaypointCreationRequest copy = WaypointCreationRequest.CREATOR.createFromParcel(p);
|
||||
assertEquals(original.getType(), copy.getType());
|
||||
assertEquals("name", copy.getName());
|
||||
assertEquals("description", copy.getDescription());
|
||||
assertEquals("img.png", copy.getIconUrl());
|
||||
}
|
||||
}
|
||||
+35
-33
@@ -22,6 +22,7 @@ import com.google.android.apps.mytracks.content.MyTracksProvider;
|
||||
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.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
@@ -77,9 +78,11 @@ public class TrackRecordingServiceTest
|
||||
}
|
||||
|
||||
/**
|
||||
* A context wrapper with the user provided {@link ContentResolver}.
|
||||
* A context wrapper with the user provided {@link ContentResolver}.
|
||||
*
|
||||
* TODO: Move to test utils package.
|
||||
*/
|
||||
private static class MockContext extends ContextWrapper {
|
||||
public static class MockContext extends ContextWrapper {
|
||||
private final ContentResolver contentResolver;
|
||||
|
||||
public MockContext(ContentResolver contentResolver, Context base) {
|
||||
@@ -546,9 +549,8 @@ public class TrackRecordingServiceTest
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
Location loc = new Location("gps");
|
||||
try {
|
||||
service.insertStatisticsMarker(loc);
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
fail("Expecting IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// Expected.
|
||||
@@ -562,11 +564,22 @@ public class TrackRecordingServiceTest
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertTrue(service.isRecording());
|
||||
|
||||
Location loc = new Location("gps");
|
||||
assertEquals(1, service.insertStatisticsMarker(loc));
|
||||
assertEquals(2, service.insertStatisticsMarker(loc));
|
||||
assertEquals(1, service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS));
|
||||
assertEquals(2, service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS));
|
||||
|
||||
// TODO: Add more checks.
|
||||
Waypoint wpt = providerUtils.getWaypoint(1);
|
||||
assertEquals(getContext().getString(R.string.stats_icon_url),
|
||||
wpt.getIcon());
|
||||
assertEquals(getContext().getString(R.string.statistics),
|
||||
wpt.getName());
|
||||
assertEquals(Waypoint.TYPE_STATISTICS, wpt.getType());
|
||||
assertEquals(123, wpt.getTrackId());
|
||||
assertEquals(0.0, wpt.getLength());
|
||||
assertNotNull(wpt.getLocation());
|
||||
assertNotNull(wpt.getStatistics());
|
||||
// TODO check the rest of the params.
|
||||
|
||||
// TODO: Check waypoint 2.
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@@ -574,29 +587,14 @@ public class TrackRecordingServiceTest
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
Location loc = new Location("gps");
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.setId(1);
|
||||
waypoint.setLocation(loc);
|
||||
try {
|
||||
service.insertWaypointMarker(waypoint);
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_MARKER);
|
||||
fail("Expecting IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// Expected.
|
||||
}
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testInsertWaypointMarker_invalidWaypoint() throws Exception {
|
||||
createDummyTrack(123, -1, true);
|
||||
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertTrue(service.isRecording());
|
||||
|
||||
Waypoint waypoint = new Waypoint();
|
||||
assertEquals(-1, service.insertWaypointMarker(waypoint));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testInsertWaypointMarker_validWaypoint() throws Exception {
|
||||
createDummyTrack(123, -1, true);
|
||||
@@ -604,11 +602,17 @@ public class TrackRecordingServiceTest
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertTrue(service.isRecording());
|
||||
|
||||
Location loc = new Location("gps");
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.setId(1);
|
||||
waypoint.setLocation(loc);
|
||||
assertEquals(1, service.insertWaypointMarker(waypoint));
|
||||
assertEquals(1, service.insertWaypoint(WaypointCreationRequest.DEFAULT_MARKER));
|
||||
Waypoint wpt = providerUtils.getWaypoint(1);
|
||||
assertEquals(getContext().getString(R.string.waypoint_icon_url),
|
||||
wpt.getIcon());
|
||||
assertEquals(getContext().getString(R.string.waypoint),
|
||||
wpt.getName());
|
||||
assertEquals(Waypoint.TYPE_WAYPOINT, wpt.getType());
|
||||
assertEquals(123, wpt.getTrackId());
|
||||
assertEquals(0.0, wpt.getLength());
|
||||
assertNotNull(wpt.getLocation());
|
||||
assertNull(wpt.getStatistics());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@@ -804,11 +808,9 @@ public class TrackRecordingServiceTest
|
||||
service.recordLocation(loc);
|
||||
|
||||
if (i % 10 == 0) {
|
||||
service.insertStatisticsMarker(loc);
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
} else if (i % 7 == 0) {
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.setLocation(loc);
|
||||
service.insertWaypointMarker(waypoint);
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_MARKER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="src" path="MyTracksLib_src"/>
|
||||
<classpathentry exported="true" kind="lib" path="/MyTracksLib/libs/protobuf-java-2.3.0-lite.jar"/>
|
||||
<classpathentry kind="src" path="MyTracksLib_src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
+10
-8
@@ -17,7 +17,10 @@ package com.google.android.apps.mytracks.signalstrength;
|
||||
|
||||
import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsImpl;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.services.ITrackRecordingService;
|
||||
import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener.SignalStrengthCallback;
|
||||
|
||||
@@ -53,6 +56,7 @@ public class SignalStrengthService extends Service
|
||||
private ITrackRecordingService mytracksService;
|
||||
private long lastSamplingTime;
|
||||
private long samplingPeriod;
|
||||
private MyTracksProviderUtils utils;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
@@ -63,6 +67,7 @@ public class SignalStrengthService extends Service
|
||||
getString(R.string.mytracks_service_class));
|
||||
preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
signalListenerFactory = new SignalStrengthListenerFactory();
|
||||
utils = new MyTracksProviderUtilsImpl(this.getContentResolver());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,13 +159,6 @@ public class SignalStrengthService extends Service
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't set location or track id - My Tracks can fill those
|
||||
Waypoint wpt = new Waypoint();
|
||||
wpt.setName("Signal Strength");
|
||||
wpt.setType(Waypoint.TYPE_WAYPOINT);
|
||||
wpt.setIcon(icon);
|
||||
wpt.setDescription(description);
|
||||
|
||||
try {
|
||||
long waypointId;
|
||||
synchronized (this) {
|
||||
@@ -169,7 +167,11 @@ public class SignalStrengthService extends Service
|
||||
return;
|
||||
}
|
||||
|
||||
waypointId = mytracksService.insertWaypointMarker(wpt);
|
||||
// Create a waypoint.
|
||||
WaypointCreationRequest request =
|
||||
new WaypointCreationRequest(WaypointCreationRequest.WaypointType.MARKER,
|
||||
"Signal Strength", icon, description);
|
||||
waypointId = mytracksService.insertWaypoint(request);
|
||||
}
|
||||
|
||||
if (waypointId >= 0) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/SignalStrengthSampler"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/SignalStrengthSampler"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="lib" path="libs/AndroidMockRuntime.jar"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
Reference in New Issue
Block a user