forked from upstream-mirrors/OpenTracks
Merging to head
This commit is contained in:
@@ -9,5 +9,6 @@
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry exported="true" kind="lib" path="/MyTracksLib/libs/protobuf-java-2.3.0-lite.jar"/>
|
||||
<classpathentry kind="src" path="MyTracksLib_src"/>
|
||||
<classpathentry kind="lib" path="libs/libmymaps.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
@@ -56,6 +56,11 @@ limitations under the License.
|
||||
android:label="MyTracks"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name="com.google.android.apps.mytracks.MyMapsList"
|
||||
android:label="@string/map_list_title"
|
||||
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name="com.google.android.apps.mytracks.MyTracksList"
|
||||
android:label="Recorded Tracks" />
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
The libraries contained here in binary format are licensed according to their
|
||||
own licenses, which allow their usage for the My Tracks application. Any other
|
||||
applications that wish to use these files should consult the appropriate
|
||||
licenses or the JAR's authors.
|
||||
|
||||
References are provided to the libraries:
|
||||
|
||||
accounts.jar (Android accounts library):
|
||||
http://code.google.com/p/libs-for-android/wiki/AccountsLibrary
|
||||
|
||||
google-api-client-*.jar (GData client):
|
||||
http://code.google.com/p/google-api-java-client/
|
||||
|
||||
google-common.jar,
|
||||
googleloginclient-helper.jar,
|
||||
libmymaps.jar (Google My Maps upload library):
|
||||
Licensed exclusively for use in My Tracks and derived Android applications.
|
||||
Binary file not shown.
@@ -0,0 +1,103 @@
|
||||
<?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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apl/res/com.google.android.maps"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_bar"
|
||||
android:layout_weight="0"
|
||||
android:padding="3dip">
|
||||
<TextView android:id="@+id/message"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16dip"
|
||||
android:textColor="#fff"
|
||||
android:text="@string/select_map_message"
|
||||
android:layout_weight="0"/>
|
||||
</LinearLayout>
|
||||
<ListView android:id="@+id/maplist"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
<TextView android:id="@+id/mapslist_empty"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:padding="3dip"
|
||||
android:textSize="16dip"
|
||||
android:textColor="#c00"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/mapslist_no_maps_available"
|
||||
android:visibility="gone"/>
|
||||
<TextView android:id="@+id/failed"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:padding="3dip"
|
||||
android:textSize="16dip"
|
||||
android:textColor="#c00"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/maps_list_failed"
|
||||
android:visibility="gone"/>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_bar"
|
||||
android:layout_weight="0"
|
||||
android:padding="3dip">
|
||||
<LinearLayout android:id="@+id/loading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="3dip"
|
||||
android:layout_gravity="center">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
<ProgressBar
|
||||
android:layout_height="20dip"
|
||||
android:layout_width="20dip"
|
||||
android:layout_gravity="center"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:paddingLeft="3dip"
|
||||
android:textSize="16dip"
|
||||
android:textColor="#fff"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/maps_list_loading"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -41,6 +41,39 @@ limitations under the License.
|
||||
android:stretchColumns="1"
|
||||
android:layout_marginTop="5dip"
|
||||
android:layout_marginLeft="5dip">
|
||||
|
||||
<!-- My Maps -->
|
||||
<TableRow>
|
||||
<ImageView android:src="@drawable/mymaps_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginLeft="10dip">
|
||||
<CheckBox android:id="@+id/sendtogoogle_google_mymaps"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sendtogoogle_google_mymaps"
|
||||
android:textSize="20dip"
|
||||
android:checked="true"/>
|
||||
<RadioGroup android:id="@+id/sendtogoogle_group_mymaps"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<RadioButton android:id="@+id/sendtogoogle_create_new_map"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sendtogoogle_create_new_map"/>
|
||||
<RadioButton android:id="@+id/sendtogoogle_pick_existing_map"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sendtogoogle_pick_existing_map"/>
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<!-- Fusion Tables -->
|
||||
<TableRow>
|
||||
<ImageView android:src="@drawable/googledocs_icon"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -58,6 +91,8 @@ limitations under the License.
|
||||
android:checked="true"/>
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<!-- Google Docs -->
|
||||
<TableRow>
|
||||
<ImageView android:src="@drawable/googledocs_icon"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -133,7 +133,6 @@ limitations under the License.
|
||||
<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_linkfusion">Un enllaç a Google Fusion Table</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>
|
||||
|
||||
@@ -129,8 +129,7 @@ limitations under the License.
|
||||
<string name="tracklist_pick_one">Einen Track auswählen. Lange berühren für mehr Optionen.</string>
|
||||
<string name="tracklist_all_tracks">Alle Tracks</string>
|
||||
<string name="tracklist_this_track">Dieser Track</string>
|
||||
<string name="tracklist_share_track">Mit Freunden teilen…</string>
|
||||
<string name="tracklist_share_linkfusion">Ein Link zur Google Fusion Tables-Karte</string>
|
||||
<string name="tracklist_share_track">Mit Freunden teilen…</string>
|
||||
<string name="tracklist_share_gpx_file">Eine GPX-Datei</string>
|
||||
<string name="tracklist_share_kml_file">Eine KML-Datei</string>
|
||||
<string name="tracklist_share_csv_file">Eine CSV-Datei</string>
|
||||
|
||||
@@ -47,7 +47,6 @@ limitations under the License.
|
||||
<string name="tracklist_save_as_tcx">Guardar en archivo TCX</string>
|
||||
<string name="tracklist_btn_send_all_to_fusiontables">Enviar a Google Fusion Tables</string>
|
||||
<!-- Export All -->
|
||||
<string name="tracklist_share_linkfusion">Un enlace a Google Fusion Tables</string>
|
||||
<string name="tracklist_share_csv_file">Un archivo CSV</string>
|
||||
<string name="tracklist_share_tcx_file">Un archivo TCX</string>
|
||||
|
||||
|
||||
@@ -121,7 +121,6 @@ limitations under the License.
|
||||
<string name="tracklist_all_tracks">Todos los recorridos:"</string>
|
||||
<string name="tracklist_this_track">Este recorrido"</string>
|
||||
<string name="tracklist_share_track">Compartir con amigos..."</string>
|
||||
<string name="tracklist_share_linkfusion">Un enlace a Google Fusion Tables</string>
|
||||
<string name="tracklist_share_gpx_file">Un archivo GPX"</string>
|
||||
<string name="tracklist_share_kml_file">Un archivo KML"</string>
|
||||
<string name="tracklist_clear_map">"Limpiar mapa"</string>
|
||||
|
||||
@@ -127,7 +127,6 @@ limitations under the License.
|
||||
<string name="tracklist_all_tracks">Tous les parcours:</string>
|
||||
<string name="tracklist_this_track">Ce parcours</string>
|
||||
<string name="tracklist_share_track">Partager...</string>
|
||||
<string name="tracklist_share_linkfusion">Lien sur Google Fusion Tables</string>
|
||||
<string name="tracklist_share_gpx_file">Fichier GPX</string>
|
||||
<string name="tracklist_share_kml_file">Fichier KML</string>
|
||||
<string name="tracklist_clear_map">Effacer la carte</string>
|
||||
|
||||
@@ -129,7 +129,7 @@ limitations under the License.
|
||||
<string name="tracklist_all_tracks">Tutti i percorsi:</string>
|
||||
<string name="tracklist_this_track">Questo percorso</string>
|
||||
<string name="tracklist_share_track">Condividi con amici...</string>
|
||||
<!-- <string name="tracklist_share_linkfusion">Un link alla mappa in «Le mie mappe» di Google</string> -->
|
||||
<string name="tracklist_share_link">Un link alla mappa</string>
|
||||
<string name="tracklist_share_gpx_file">Un file GPX</string>
|
||||
<string name="tracklist_share_kml_file">Un file KML</string>
|
||||
<string name="tracklist_clear_map">Cancella la mappa</string>
|
||||
|
||||
@@ -133,7 +133,6 @@ limitations under the License.
|
||||
<string name="tracklist_all_tracks">全てのトラック:</string>
|
||||
<string name="tracklist_this_track">このトラック</string>
|
||||
<string name="tracklist_share_track">共有...</string>
|
||||
<string name="tracklist_share_linkfusion">Google Fusion Tablesへのリンク</string>
|
||||
<string name="tracklist_share_gpx_file">GPXファイル</string>
|
||||
<string name="tracklist_share_kml_file">KMLファイル</string>
|
||||
<string name="tracklist_share_csv_file">CSVファイル</string>
|
||||
|
||||
@@ -131,7 +131,6 @@ limitations under the License.
|
||||
<string name="tracklist_all_tracks">Wszystkie trasy:</string>
|
||||
<string name="tracklist_this_track">Ta trasa</string>
|
||||
<string name="tracklist_share_track">Podziel się z przyjaciółmi...</string>
|
||||
<!-- <string name="tracklist_share_linkfusion">Link do Moich Map Google</string> -->
|
||||
<string name="tracklist_share_gpx_file">Plik GPX</string>
|
||||
<string name="tracklist_share_kml_file">PLik KML</string>
|
||||
<string name="tracklist_share_csv_file">Plik CSV</string>
|
||||
|
||||
@@ -18,9 +18,9 @@ limitations under the License.
|
||||
<!-- Used by the Menu -->
|
||||
<string name="start_recording">Gravar caminho</string>
|
||||
<string name="stop_recording">Para gravação</string>
|
||||
<string name="switch_to_sat">Modo do satélite"</string>
|
||||
<string name="switch_to_map">Modo do mapa"</string>
|
||||
<string name="mylocation">Minha Localização"</string>
|
||||
<string name="switch_to_sat">Modo do satélite</string>
|
||||
<string name="switch_to_map">Modo do mapa</string>
|
||||
<string name="mylocation">Minha Localização</string>
|
||||
<string name="list_tracks">Caminhos</string>
|
||||
<string name="list_markers">Marcadores</string>
|
||||
<string name="delete_all_tracks">Apagar todos os caminhos</string>
|
||||
@@ -31,10 +31,10 @@ limitations under the License.
|
||||
<string name="current_segment">Último segmento</string>
|
||||
|
||||
<!-- Error messages -->
|
||||
<string name="error_no_location_manager">Gerenciador de localização não encontrado neste dispositivo!"</string>
|
||||
<string name="error_no_gps_location_provider">"Provedor de posição de GPS não encontrado neste dispositivo."</string>
|
||||
<string name="error_sending_to_fusiontables">Ocorreu um erro ao enviar seu caminho para o Google Fusion Tables. Por favor tente novamente mais tarde."</string>
|
||||
<string name="error_sending_to_docs">Ocorreu um erro ao enviar seu caminho para o Google Docs. Por favor tente novamente mais tarde."</string>
|
||||
<string name="error_no_location_manager">Gerenciador de localização não encontrado neste dispositivo!</string>
|
||||
<string name="error_no_gps_location_provider">"Provedor de posição de GPS não encontrado neste dispositivo.</string>
|
||||
<string name="error_sending_to_fusiontables">Ocorreu um erro ao enviar seu caminho para o Google Fusion Tables. Por favor tente novamente mais tarde.</string>
|
||||
<string name="error_sending_to_docs">Ocorreu um erro ao enviar seu caminho para o Google Docs. Por favor tente novamente mais tarde.</string>
|
||||
<string name="error_unable_to_start_recording">Impossível iniciar a gravação. Tente novamente.</string>
|
||||
<string name="error_unable_to_stop_recording">Impossível interromper a gravação. Tente novamente.</string>
|
||||
<string name="error_unable_to_read_file">Impossível ler do arquivo.</string>
|
||||
@@ -52,7 +52,7 @@ limitations under the License.
|
||||
<string name="status_tracks_have_been_uploaded">Seu caminho foi enviado para maps.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_new_doc">Seu caminho foi enviado para uma nova planilha em docs.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_docs">Seu caminho foi enviado para docs.google.com.</string>
|
||||
<string name="status_enable_gps">"Por favor pressione aqui para ir aos ajustes de segurança e localização e verifique que o GPS esteja habilitado. Pressione o botão de voltar para retornar."</string>
|
||||
<string name="status_enable_gps">"Por favor pressione aqui para ir aos ajustes de segurança e localização e verifique que o GPS esteja habilitado. Pressione o botão de voltar para retornar.</string>
|
||||
<string name="status_approximate_location">Nota: Uma localização aproximada, determinada por torres de telefonia celular, está sendo mostrada.</string>
|
||||
<string name="status_no_location">Sua localização não pôde ser determinada. Habilite fontes adicionais de localização (veja configurações de Segurança e Localização) e assegure-se de que o céu está visível.</string>
|
||||
<string name="status_waypoint_inserted">Um marcador de ponto de passagem foi inserido.</string>
|
||||
@@ -79,19 +79,19 @@ limitations under the License.
|
||||
<string name="marker_will_be_permanently_deleted">O marcador será permanentemente apagado deste telefone.</string>
|
||||
|
||||
<!-- Text and links when uploading to Google My Maps -->
|
||||
<string name="new_map_description">"Criado por My Tracks no Android."</string>
|
||||
<string name="fusiontable_link">"Criado por <a href='http://mytracks.appspot.com'>My Tracks</a> no Android."</string>
|
||||
<string name="new_map_description">"Criado por My Tracks no Android.</string>
|
||||
<string name="fusiontable_link">"Criado por <a href='http://mytracks.appspot.com'>My Tracks</a> no Android.</string>
|
||||
|
||||
<!-- Formatting of track and marker descriptions -->
|
||||
<string name="points">Pontos</string>
|
||||
<string name="recorded_date">Gravado"</string>
|
||||
<string name="category">"Tipo de atividade"</string>
|
||||
<string name="waypoint_category">"Tipo de marcador"</string>
|
||||
<string name="part">"(Parte %d)"</string>
|
||||
<string name="recorded_date">Gravado</string>
|
||||
<string name="category">"Tipo de atividade</string>
|
||||
<string name="waypoint_category">"Tipo de marcador</string>
|
||||
<string name="part">"(Parte %d)</string>
|
||||
|
||||
<!-- Used by the track recording service -->
|
||||
<string name="recording_your_track">"Gravando seu caminho..."</string>
|
||||
<string name="new_track">"Caminho %d"</string>
|
||||
<string name="recording_your_track">"Gravando seu caminho...</string>
|
||||
<string name="new_track">"Caminho %d</string>
|
||||
|
||||
<!-- Common -->
|
||||
<string name="no">Não</string>
|
||||
@@ -122,22 +122,22 @@ limitations under the License.
|
||||
<string name="tracklist_btn_send_all_to_fusiontables">Enviar para o Google Fusion Tables</string>
|
||||
<string name="tracklist_btn_delete_all">Apagar todos os caminhos</string>
|
||||
<string name="tracklist_pick_one">Escolha um caminho. Pressione&segure para mais opções.</string>
|
||||
<string name="tracklist_all_tracks">Todos os Caminhos:"</string>
|
||||
<string name="tracklist_this_track">Este Caminho"</string>
|
||||
<string name="tracklist_share_track">Compartilhar com amigos..."</string>
|
||||
<string name="tracklist_share_linkfusion">Um link para a Google Fusion Table"</string>
|
||||
<string name="tracklist_share_gpx_file">Um arquivo GPX"</string>
|
||||
<string name="tracklist_share_kml_file">Um arquivo KML"</string>
|
||||
<string name="tracklist_clear_map">"Limpar mapa"</string>
|
||||
<string name="tracklist_all_tracks">Todos os Caminhos:</string>
|
||||
<string name="tracklist_this_track">Este Caminho</string>
|
||||
<string name="tracklist_share_track">Compartilhar com amigos...</string>
|
||||
<string name="tracklist_share_link">Um link para a mapa</string>
|
||||
<string name="tracklist_share_gpx_file">Um arquivo GPX</string>
|
||||
<string name="tracklist_share_kml_file">Um arquivo KML</string>
|
||||
<string name="tracklist_clear_map">Limpar mapa</string>
|
||||
|
||||
<!-- Waypoints list -->
|
||||
<string name="waypointslist_btn_delete_all">Apagar todos os marcadores</string>
|
||||
<string name="waypointslist_this_waypoint">Este Marcador</string>
|
||||
<string name="waypointslist_delete_waypoint">Apagar</string>
|
||||
<string name="waypointslist_edit_waypoint">Editar detalhes"</string>
|
||||
<string name="waypointslist_show_waypoint">Mostrar no mapa"</string>
|
||||
<string name="waypointslist_btn_insert_waypoint">Inserir ponto no caminho"</string>
|
||||
<string name="waypointslist_btn_insert_statistics">Inserir estatísticas"</string>
|
||||
<string name="waypointslist_edit_waypoint">Editar detalhes</string>
|
||||
<string name="waypointslist_show_waypoint">Mostrar no mapa</string>
|
||||
<string name="waypointslist_btn_insert_waypoint">Inserir ponto no caminho</string>
|
||||
<string name="waypointslist_btn_insert_statistics">Inserir estatísticas</string>
|
||||
<string name="waypointslist_pick_one">Escolha um marcador. Pressione&segure para mais opções.</string>
|
||||
|
||||
<!-- MyTracks Details -->
|
||||
|
||||
@@ -131,7 +131,6 @@ limitations under the License.
|
||||
<string name="tracklist_all_tracks">Alla spår:</string>
|
||||
<string name="tracklist_this_track">Det här spåret</string>
|
||||
<string name="tracklist_share_track">Dela med vänner...</string>
|
||||
<!-- <string name="tracklist_share_linkfusion">En länk till Google Mina Kartor</string> -->
|
||||
<string name="tracklist_share_gpx_file">En GPX-fil</string>
|
||||
<string name="tracklist_share_kml_file">En KML-fil</string>
|
||||
<string name="tracklist_share_csv_file">En CSV-fil</string>
|
||||
|
||||
@@ -132,7 +132,6 @@ limitations under the License.
|
||||
<string name="tracklist_all_tracks">全部轨迹:</string>
|
||||
<string name="tracklist_this_track">此轨迹</string>
|
||||
<string name="tracklist_share_track">与朋友分享...</string>
|
||||
<string name="tracklist_share_linkfusion">链接到 Google Fusion Table</string>
|
||||
<string name="tracklist_share_gpx_file">GPX 文件</string>
|
||||
<string name="tracklist_share_kml_file">KML 文件</string>
|
||||
<string name="tracklist_share_csv_file">CSV 文件</string>
|
||||
|
||||
@@ -36,6 +36,7 @@ limitations under the License.
|
||||
<string name="send_stats_and_points_key">sendStatsAndPoints</string>
|
||||
<string name="send_to_docs_key">sendToDocs</string>
|
||||
<string name="send_to_my_maps_key">sendToMyMaps</string>
|
||||
<string name="send_to_fusion_tables_key">sendToFusionTables</string>
|
||||
<string name="sensor_type_key">sensorType</string>
|
||||
<string name="share_url_only_key">shareUrlOnly</string>
|
||||
<string name="split_frequency_key">splitFrequency</string>
|
||||
|
||||
@@ -35,6 +35,7 @@ limitations under the License.
|
||||
<!-- Error messages -->
|
||||
<string name="error_no_location_manager">No location manager was found on this device!</string>
|
||||
<string name="error_no_gps_location_provider">No GPS location provider was found on this device.</string>
|
||||
<string name="error_sending_to_mymap">There was an error while sending your track to Google My Map. Please try again later.</string>
|
||||
<string name="error_sending_to_fusiontables">There was an error while sending your track to Google Fusion Tables. Please try again later.</string>
|
||||
<string name="error_sending_to_docs">There was an error while sending your track to Google Docs. Please try again later.</string>
|
||||
<string name="error_unable_to_start_recording">Unable to start recording. Try again.</string>
|
||||
@@ -50,10 +51,12 @@ limitations under the License.
|
||||
<string name="wait_for_fix">Waiting for a better GPS fix. Make sure the sky is visible.</string>
|
||||
<string name="status_now_recording">Now recording a new track.</string>
|
||||
<string name="status_stopped_recording">Stopped recording your track.</string>
|
||||
<string name="status_new_mymap_has_been_created">A new Google My Map has been created at maps.google.com.</string>
|
||||
<string name="status_new_fusiontable_has_been_created">A new Google Fusion table has been created at google.com/fusiontables.</string>
|
||||
<string name="status_tracks_have_been_uploaded">Your track has been sent to maps.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_new_doc">Your track has been sent to a new spreadsheet at docs.google.com.</string>
|
||||
<string name="status_tracks_have_been_uploaded_to_docs">Your track has been sent to docs.google.com.</string>
|
||||
<string name="status_mymap_info">It may sometimes take a few minutes before new tracks appear.</string>
|
||||
<string name="status_enable_gps">Please tap here to go to Security and Location Settings and check \'enable GPS satellites\'. Press back button to return.</string>
|
||||
<string name="status_approximate_location">Note: An approximate location as determined from cell towers and WIFI networks is shown.</string>
|
||||
<string name="status_no_location">A location can currently not be determined. Enable more location sources (see Security and Location Settings) and make sure the sky is visible. Try again later.</string>
|
||||
@@ -64,9 +67,13 @@ limitations under the License.
|
||||
<string name="progress_title">Please wait...</string>
|
||||
<string name="progress_message">Sending your track to Google.</string>
|
||||
<string name="progress_message_reading_track">Reading track...</string>
|
||||
<string name="progress_message_preparing_track">Preparing track...</string>
|
||||
<string name="progress_message_authenticating_fusiontables">Authenticating to Google Fusion Tables...</string>
|
||||
<string name="progress_message_authenticating_mymaps">Authenticating to Google Maps...</string>
|
||||
<string name="progress_message_authenticating_docs">Authenticating to Google Docs...</string>
|
||||
<string name="progress_message_sending_docs">Sending track to Google Docs...</string>
|
||||
<string name="progress_message_sending_mymaps">Sending track to Google Maps...</string>
|
||||
<string name="progress_message_creating_map">Creating new My Map...</string>
|
||||
<string name="progress_message_sending_fusiontables">Sending track to Fusion Tables...</string>
|
||||
<string name="progress_message_creating_fusiontable">Creating new Fusion table...</string>
|
||||
<string name="import_progress_message">Importing a GPS track. This may take a while.</string>
|
||||
@@ -83,6 +90,10 @@ limitations under the License.
|
||||
<string name="new_map_description">Created by My Tracks on Android.</string>
|
||||
<string name="fusiontable_link">Created by <a href=\'http://mytracks.appspot.com\'>My Tracks</a> on Android.</string>
|
||||
|
||||
<!-- Text and links when uploading to Google My Maps -->
|
||||
<string name="my_map_link">Created by <a href=\'http://mytracks.appspot.com\'>My Tracks</a> on Android.</string>
|
||||
<string name="new_map_title">New map</string>
|
||||
|
||||
<!-- Formatting of track and marker descriptions -->
|
||||
<string name="points">Points</string>
|
||||
<string name="recorded_date">Recorded</string>
|
||||
@@ -113,6 +124,8 @@ limitations under the License.
|
||||
|
||||
<!-- TrackList -->
|
||||
<string name="tracklist_show_track">Show</string>
|
||||
<string name="tracklist_send_to_mymaps">Send to Google My Maps</string>
|
||||
<string name="tracklist_send_to_new_mymap">Send to New Google My Map</string>
|
||||
<string name="tracklist_send_to_fusiontables">Send to Google Fusion Tables</string>
|
||||
<string name="tracklist_send_to_new_fusiontable">Send to New Google Fusion Table</string>
|
||||
<string name="tracklist_send_to_docs">Send to Google Docs</string>
|
||||
@@ -125,6 +138,7 @@ limitations under the License.
|
||||
<string name="tracklist_save_as_csv">Save a CSV file</string>
|
||||
<string name="tracklist_save_as_tcx">Save a TCX file</string>
|
||||
<string name="tracklist_btn_send_all_to_fusiontables">Send to Google Fusion Tables</string>
|
||||
<string name="tracklist_btn_send_all_to_mymaps">Send to Google My Maps</string>
|
||||
<string name="tracklist_btn_delete_all">Delete all</string>
|
||||
<!-- Export All -->
|
||||
<string name="tracklist_btn_export_all">Export all</string>
|
||||
@@ -133,7 +147,7 @@ limitations under the License.
|
||||
<string name="tracklist_all_tracks">All Tracks:</string>
|
||||
<string name="tracklist_this_track">This Track</string>
|
||||
<string name="tracklist_share_track">Share with Friends...</string>
|
||||
<string name="tracklist_share_linkfusion">A link to Google Fusion Tables</string>
|
||||
<string name="tracklist_share_link">A link to the map</string>
|
||||
<string name="tracklist_share_gpx_file">A GPX file</string>
|
||||
<string name="tracklist_share_kml_file">A KML file</string>
|
||||
<string name="tracklist_share_csv_file">A CSV file</string>
|
||||
@@ -254,6 +268,23 @@ limitations under the License.
|
||||
<!-- MyTracksSky -->
|
||||
<string name="mytracks_sky">GPS Satellites</string>
|
||||
|
||||
<!-- My Maps -->
|
||||
<string name="select_map_message">Pick a map from your account:</string>
|
||||
<string name="create_new_map">Create new map...</string>
|
||||
<string name="map_list_title">Send to Google My Maps</string>
|
||||
<string name="maps_list_loading">Loading maps...</string>
|
||||
<string name="maps_list_failed">Your maps could not be loaded at this time!</string>
|
||||
<string name="open_map">Select this Map</string>
|
||||
<string name="edit_map_details">Edit Map Details</string>
|
||||
<string name="share_track">Share Track with Friends</string>
|
||||
<string name="delete_map">Delete Map from your Account</string>
|
||||
<string name="map_title">Map Title:</string>
|
||||
<string name="map_description">Map Description:</string>
|
||||
<string name="map_searchable_edit">Make this map and its contents show up in search results</string>
|
||||
<string name="map_not_searchable_edit">Do not let this map or its contents show up in search results, though they may still be viewed be others through the direct URL</string>
|
||||
<string name="map_searchable">This map and its contents will show in search results</string>
|
||||
<string name="map_not_searchable">Neither this map nor its contents will show in search results, but they may still be viewed by others through a direct link</string>
|
||||
|
||||
<!-- Sharing -->
|
||||
<string name="share_map">Share map with friends</string>
|
||||
<string name="share_map_subject">I would like to share a track with you</string>
|
||||
@@ -377,8 +408,11 @@ limitations under the License.
|
||||
<!-- Send to Google -->
|
||||
<string name="sendtogoogle_title">Send to...</string>
|
||||
<string name="sendtogoogle_google_fusiontables">Google Fusion Tables</string>
|
||||
<string name="sendtogoogle_google_mymaps">Google My Maps</string>
|
||||
<string name="sendtogoogle_google_docs">Google Docs</string>
|
||||
<string name="sendtogoogle_send_now">Send now</string>
|
||||
<string name="sendtogoogle_create_new_map">Create a new map</string>
|
||||
<string name="sendtogoogle_pick_existing_map">Pick an existing map</string>
|
||||
<string name="sendtogoogle_send_stats">Send track statistics</string>
|
||||
<string name="sendtogoogle_send_stats_and_points">Send statistics and points</string>
|
||||
|
||||
|
||||
@@ -88,7 +88,10 @@ public class DialogManager {
|
||||
builder.setNeutralButton(activity.getString(R.string.share_track),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
activity.shareLinkToFusionTable(activity.sendToTrackId);
|
||||
SendToGoogleDialog sendToGoogleDialog = getSendToGoogleDialog();
|
||||
final boolean sentToMyMaps = sendToGoogleDialog.getSendToMyMaps();
|
||||
final boolean sentToFusionTables = sendToGoogleDialog.getSendToFusionTables();
|
||||
activity.shareLinkToMap(sentToMyMaps, sentToFusionTables);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
@@ -119,9 +122,11 @@ public class DialogManager {
|
||||
sendToGoogleResultDialog.setIcon(success
|
||||
? android.R.drawable.ic_dialog_info
|
||||
: android.R.drawable.ic_dialog_alert);
|
||||
sendToGoogleResultDialog.setMessage(activity.getFusionTablesResultMessage());
|
||||
sendToGoogleResultDialog.setMessage(activity.getSendToGoogleResultMessage());
|
||||
|
||||
boolean canShare = activity.getSendToFusionTablesTableId() != null;
|
||||
boolean canShare =
|
||||
activity.getSendToFusionTablesTableId() != null &&
|
||||
activity.getSendToMyMapsMapId() != null;
|
||||
View share =
|
||||
sendToGoogleResultDialog.findViewById(android.R.id.button3);
|
||||
if (share != null) {
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.accounts.Account;
|
||||
import com.google.android.apps.mytracks.io.AuthManager;
|
||||
import com.google.android.apps.mytracks.io.AuthManagerFactory;
|
||||
import com.google.android.apps.mytracks.io.MyMapsFactory;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsService;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnCreateContextMenuListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Activity which displays the list of current My Maps tracks for the user.
|
||||
* Returns RESULT_OK if the user picked a map, and returns "mapid" as an extra.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class MyMapsList extends Activity implements MapsFacade.MapsListCallback {
|
||||
private static final int MENU_OPEN = 0;
|
||||
private static final int MENU_SHARE = 2;
|
||||
private static final int GET_LOGIN = 1;
|
||||
|
||||
private MapsFacade mapsClient;
|
||||
private AuthManager auth;
|
||||
private MyMapsListAdapter listAdapter;
|
||||
|
||||
private int contextPosition;
|
||||
|
||||
private final OnCreateContextMenuListener contextMenuListener =
|
||||
new OnCreateContextMenuListener() {
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v,
|
||||
ContextMenuInfo menuInfo) {
|
||||
AdapterView.AdapterContextMenuInfo info =
|
||||
(AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
contextPosition = info.position;
|
||||
menu.add(0, MENU_OPEN, 0, R.string.open_map);
|
||||
menu.add(0, MENU_SHARE, 0, R.string.share_map);
|
||||
}
|
||||
};
|
||||
|
||||
private final OnItemClickListener clickListener =
|
||||
new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View v, int position,
|
||||
long id) {
|
||||
Intent result = new Intent();
|
||||
result.putExtra("mapid", (String) listAdapter.getItem(position));
|
||||
setResult(RESULT_OK, result);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
auth = AuthManagerFactory.getAuthManager(this, GET_LOGIN, null, true,
|
||||
MapsService.getServiceName());
|
||||
|
||||
setContentView(R.layout.list);
|
||||
|
||||
listAdapter = new MyMapsListAdapter(this);
|
||||
|
||||
ListView list = (ListView) findViewById(R.id.maplist);
|
||||
list.setOnItemClickListener(clickListener);
|
||||
list.setOnCreateContextMenuListener(contextMenuListener);
|
||||
list.setAdapter(listAdapter);
|
||||
|
||||
startLogin();
|
||||
}
|
||||
|
||||
private void startLogin() {
|
||||
// Starts in the UI thread.
|
||||
// TODO fix this for non-froyo devices.
|
||||
if (AuthManagerFactory.useModernAuthManager()) {
|
||||
MyTracks.getInstance().getAccountChooser().chooseAccount(
|
||||
MyMapsList.this,
|
||||
new AccountChooser.AccountHandler() {
|
||||
@Override
|
||||
public void handleAccountSelected(Account account) {
|
||||
// Account selection happens in the UI thread.
|
||||
if (account != null) {
|
||||
// The user did not quit and there was a valid google
|
||||
// account.
|
||||
doLogin(account);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
doLogin(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void doLogin(final Account account) {
|
||||
// Starts in the UI thread.
|
||||
auth.doLogin(new Runnable() {
|
||||
public void run() {
|
||||
// Runs in UI thread.
|
||||
mapsClient = MyMapsFactory.newMapsClient(MyMapsList.this, auth);
|
||||
|
||||
startLookup();
|
||||
}
|
||||
}, account);
|
||||
}
|
||||
|
||||
private void startLookup() {
|
||||
// Starts in the UI thread.
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Communication with Maps happens in its own thread.
|
||||
// This will call onReceivedMapListing below.
|
||||
final boolean success = mapsClient.getMapsList(MyMapsList.this);
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Updating the UI when done happens in the UI thread.
|
||||
onLookupDone(success);
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedMapListing(final String mapId, final String title,
|
||||
final String description, final boolean isPublic) {
|
||||
// Starts in the communication thread.
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Updating the list with new contents happens in the UI thread.
|
||||
listAdapter.addMapListing(mapId, title, description, isPublic);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onLookupDone(boolean success) {
|
||||
// Starts in the UI thread.
|
||||
findViewById(R.id.loading).setVisibility(View.GONE);
|
||||
if (!success) {
|
||||
findViewById(R.id.failed).setVisibility(View.VISIBLE);
|
||||
}
|
||||
TextView emptyView = (TextView) findViewById(R.id.mapslist_empty);
|
||||
ListView list = (ListView) findViewById(R.id.maplist);
|
||||
list.setEmptyView(emptyView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode,
|
||||
Intent data) {
|
||||
if (requestCode == GET_LOGIN) {
|
||||
auth.authResult(resultCode, data);
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_OPEN:
|
||||
clickListener.onItemClick(null, null, contextPosition, 0);
|
||||
return true;
|
||||
case MENU_SHARE:
|
||||
Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||
shareIntent.setType("text/plain");
|
||||
shareIntent.putExtra(Intent.EXTRA_SUBJECT,
|
||||
getText(R.string.share_map_subject));
|
||||
String[] listItem = (String[]) listAdapter.getMapListingArray(contextPosition);
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, String.format(
|
||||
getText(R.string.share_map_body_format).toString(),
|
||||
listItem[1],
|
||||
MapsService.buildMapUrl(listItem[0])));
|
||||
startActivity(Intent.createChooser(shareIntent,
|
||||
getText(R.string.share_map).toString()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.database.DataSetObserver;
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
public class MyMapsListAdapter implements ListAdapter {
|
||||
private Vector<String[]> mapsList;
|
||||
private Vector<Boolean> publicList;
|
||||
private Set<DataSetObserver> observerSet;
|
||||
private final Activity activity;
|
||||
|
||||
public MyMapsListAdapter(Activity activity) {
|
||||
this.activity = activity;
|
||||
|
||||
mapsList = new Vector<String[]>();
|
||||
publicList = new Vector<Boolean>();
|
||||
observerSet = new HashSet<DataSetObserver>();
|
||||
}
|
||||
|
||||
public void addMapListing(String mapId, String title,
|
||||
String description, boolean isPublic) {
|
||||
synchronized (mapsList) {
|
||||
// Search through the maps list to see if it has the mapid and
|
||||
// remove it if so, so that we can replace it with updated info
|
||||
for (int i = 0; i < mapsList.size(); ++i) {
|
||||
if (mapId.equals(mapsList.get(i)[0])) {
|
||||
mapsList.remove(i);
|
||||
publicList.remove(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
mapsList.add(new String[] { mapId, title, description });
|
||||
publicList.add(isPublic);
|
||||
}
|
||||
|
||||
Iterator<DataSetObserver> iter = observerSet.iterator();
|
||||
while (iter.hasNext()) {
|
||||
iter.next().onChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getMapListingArray(int position) {
|
||||
return mapsList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areAllItemsEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mapsList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return mapsList.get(position)[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (convertView == null) {
|
||||
convertView =
|
||||
activity.getLayoutInflater().inflate(R.layout.listitem, parent, false);
|
||||
}
|
||||
|
||||
String[] map = mapsList.get(position);
|
||||
((TextView) convertView.findViewById(R.id.maplistitem)).setText(map[1]);
|
||||
((TextView) convertView.findViewById(R.id.maplistdesc)).setText(map[2]);
|
||||
TextView publicUnlisted =
|
||||
(TextView) convertView.findViewById(R.id.maplistpublic);
|
||||
if (publicList.get(position)) {
|
||||
publicUnlisted.setTextColor(Color.RED);
|
||||
publicUnlisted.setText(R.string.public_map);
|
||||
} else {
|
||||
publicUnlisted.setTextColor(Color.GREEN);
|
||||
publicUnlisted.setText(R.string.unlisted_map);
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return mapsList.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDataSetObserver(DataSetObserver observer) {
|
||||
observerSet.add(observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterDataSetObserver(DataSetObserver observer) {
|
||||
observerSet.remove(observer);
|
||||
}
|
||||
}
|
||||
@@ -29,11 +29,13 @@ import com.google.android.apps.mytracks.io.AuthManagerFactory;
|
||||
import com.google.android.apps.mytracks.io.GpxImporter;
|
||||
import com.google.android.apps.mytracks.io.SendToDocs;
|
||||
import com.google.android.apps.mytracks.io.SendToFusionTables;
|
||||
import com.google.android.apps.mytracks.io.SendToFusionTables.OnSendCompletedListener;
|
||||
import com.google.android.apps.mytracks.io.SendToMyMaps;
|
||||
import com.google.android.apps.mytracks.io.TempFileCleaner;
|
||||
import com.google.android.apps.mytracks.io.TrackWriter;
|
||||
import com.google.android.apps.mytracks.io.TrackWriterFactory;
|
||||
import com.google.android.apps.mytracks.io.SendToFusionTables.OnSendCompletedListener;
|
||||
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsService;
|
||||
import com.google.android.apps.mytracks.services.ITrackRecordingService;
|
||||
import com.google.android.apps.mytracks.services.StatusAnnouncerFactory;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingService;
|
||||
@@ -67,9 +69,9 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.Window;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.Toast;
|
||||
@@ -122,8 +124,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
*/
|
||||
|
||||
public long sendToTrackId = -1;
|
||||
public boolean sendToMyMapsSuccess = false;
|
||||
public boolean sendToFusionTablesSuccess = false;
|
||||
public boolean sendToDocsSuccess = false;
|
||||
public String sendToMyMapsMapId;
|
||||
public String sendToMyMapsMessage = "";
|
||||
public String sendToFusionTablesTableId;
|
||||
public String sendToFusionTablesMessage = "";
|
||||
public String sendToDocsMessage = "";
|
||||
@@ -446,27 +451,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
final Intent results) {
|
||||
TrackFileFormat exportFormat = null;
|
||||
switch (requestCode) {
|
||||
case MyTracksConstants.GET_MAP: {
|
||||
if (resultCode == RESULT_OK) {
|
||||
results.putExtra("trackid", selectedTrackId);
|
||||
if (results.hasExtra("tableid")) {
|
||||
sendToFusionTablesTableId = results.getStringExtra("tableid");
|
||||
}
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_fusiontables);
|
||||
authenticate(results, MyTracksConstants.SEND_TO_GOOGLE,
|
||||
SendToFusionTables.SERVICE_ID);
|
||||
} else {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.GET_LOGIN: {
|
||||
if (resultCode == RESULT_OK && auth != null) {
|
||||
if (!auth.authResult(resultCode, results)) {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
}
|
||||
} else {
|
||||
if (resultCode != RESULT_OK || auth == null || !auth.authResult(resultCode, results)) {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
}
|
||||
break;
|
||||
@@ -515,67 +501,48 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_DOCLIST: {
|
||||
if (resultCode == RESULT_OK) {
|
||||
setProgressValue(0);
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_docs);
|
||||
authenticate(results,
|
||||
MyTracksConstants.AUTHENTICATE_TO_TRIX,
|
||||
SendToDocs.GDATA_SERVICE_NAME_DOCLIST);
|
||||
} else {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_TRIX: {
|
||||
if (resultCode == RESULT_OK) {
|
||||
setProgressValue(30);
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_docs);
|
||||
authenticate(results, MyTracksConstants.SEND_TO_DOCS,
|
||||
SendToDocs.GDATA_SERVICE_NAME_TRIX);
|
||||
} else {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.SEND_TO_DOCS: {
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
Log.d(MyTracksConstants.TAG, "Sending to Docs....");
|
||||
setProgressValue(50);
|
||||
setProgressMessage(R.string.progress_message_sending_docs);
|
||||
final long trackId = results.getLongExtra("trackid", selectedTrackId);
|
||||
final SendToDocs sender = new SendToDocs(this,
|
||||
authMap.get(SendToDocs.GDATA_SERVICE_NAME_TRIX),
|
||||
authMap.get(SendToDocs.GDATA_SERVICE_NAME_DOCLIST), trackId);
|
||||
sendToTrackId = trackId;
|
||||
Runnable onCompletion = new Runnable() {
|
||||
public void run() {
|
||||
setProgressValue(100);
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
sendToDocsMessage = sender.getStatusMessage();
|
||||
sendToDocsSuccess = sender.wasSuccess();
|
||||
handleFusionTablesFinish(trackId);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
sender.setOnCompletion(onCompletion);
|
||||
sender.run();
|
||||
} else {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.SEND_TO_GOOGLE_DIALOG: {
|
||||
shareRequested = false;
|
||||
shareRequested = false;
|
||||
dialogManager.showDialogSafely(DIALOG_SEND_TO_GOOGLE);
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.SEND_TO_GOOGLE: {
|
||||
case MyTracksConstants.GET_MAP: {
|
||||
// User picked a map to upload to
|
||||
if (resultCode == RESULT_OK) {
|
||||
results.putExtra("trackid", selectedTrackId);
|
||||
if (results.hasExtra("mapid")) {
|
||||
sendToMyMapsMapId = results.getStringExtra("mapid");
|
||||
}
|
||||
authenticateToGoogleMaps(results);
|
||||
} else {
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_MY_MAPS: {
|
||||
// Authenticated with Google My Maps
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
final String mapId;
|
||||
final long trackId;
|
||||
if (results.hasExtra("mapid")) {
|
||||
mapId = results.getStringExtra("mapid");
|
||||
} else {
|
||||
mapId = "new";
|
||||
}
|
||||
if (results.hasExtra("trackid")) {
|
||||
trackId = results.getLongExtra("trackid", -1);
|
||||
} else {
|
||||
trackId = selectedTrackId;
|
||||
}
|
||||
|
||||
sendToGoogleMaps(trackId, mapId);
|
||||
} else {
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_FUSION_TABLES: {
|
||||
// Authenticated with Google Fusion Tables
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
final long trackId;
|
||||
if (results.hasExtra("trackid")) {
|
||||
@@ -583,48 +550,29 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
} else {
|
||||
trackId = selectedTrackId;
|
||||
}
|
||||
OnSendCompletedListener onCompletion = new OnSendCompletedListener() {
|
||||
@Override
|
||||
public void onSendCompleted(String tableId, boolean success,
|
||||
int statusMessage) {
|
||||
sendToFusionTablesMessage = getString(statusMessage);
|
||||
sendToFusionTablesSuccess = success;
|
||||
if (sendToFusionTablesSuccess) {
|
||||
sendToFusionTablesTableId = tableId;
|
||||
// Update the table id for this track:
|
||||
try {
|
||||
Track track = providerUtils.getTrack(trackId);
|
||||
track.setTableId(tableId);
|
||||
providerUtils.updateTrack(track);
|
||||
} catch (RuntimeException e) {
|
||||
// If that fails whatever reasons we'll just log an error, but
|
||||
// continue.
|
||||
Log.w(MyTracksConstants.TAG, "Updating table id failed.", e);
|
||||
}
|
||||
}
|
||||
if (dialogManager.getSendToGoogleDialog().getSendToDocs()) {
|
||||
onActivityResult(MyTracksConstants.AUTHENTICATE_TO_DOCLIST,
|
||||
RESULT_OK, new Intent());
|
||||
} else {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
handleFusionTablesFinish(trackId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
sendToTrackId = trackId;
|
||||
final SendToFusionTables sender = new SendToFusionTables(this, auth,
|
||||
trackId, this/*progressIndicator*/, onCompletion);
|
||||
|
||||
HandlerThread handlerThread = new HandlerThread("SendToFusionTables");
|
||||
handlerThread.start();
|
||||
Handler handler = new Handler(handlerThread.getLooper());
|
||||
handler.post(sender);
|
||||
sendToFusionTables(trackId);
|
||||
} else {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_DOCLIST: {
|
||||
// Authenticated with Google Docs
|
||||
if (resultCode == RESULT_OK) {
|
||||
authenticateToGoogleTrix();
|
||||
} else {
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_TRIX: {
|
||||
// Authenticated with Trix
|
||||
if (resultCode == RESULT_OK) {
|
||||
final long trackId = results.getLongExtra("trackid", selectedTrackId);
|
||||
sendToGoogleDocs(trackId);
|
||||
} else {
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -650,8 +598,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
case MyTracksConstants.SHARE_LINK: {
|
||||
Track selectedTrack = providerUtils.getTrack(selectedTrackId);
|
||||
if (selectedTrack != null) {
|
||||
if (selectedTrack.getTableId().length() > 0) {
|
||||
shareLinkToFusionTable(selectedTrackId);
|
||||
if (!selectedTrack.getMapId().isEmpty()) {
|
||||
shareLinkToMap(MapsService.buildMapUrl(selectedTrack.getMapId()));
|
||||
} else if (!selectedTrack.getTableId().isEmpty()) {
|
||||
shareLinkToMap(getFusionTablesUrl(selectedTrackId));
|
||||
} else {
|
||||
shareRequested = true;
|
||||
dialogManager.showDialogSafely(DIALOG_SEND_TO_GOOGLE);
|
||||
@@ -720,6 +670,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
* Resets status information for sending to MyMaps/Docs.
|
||||
*/
|
||||
public void resetSendToGoogleStatus() {
|
||||
sendToMyMapsMapId = null;
|
||||
sendToMyMapsMessage = "";
|
||||
sendToMyMapsSuccess = true;
|
||||
sendToFusionTablesMessage = "";
|
||||
sendToFusionTablesSuccess = true;
|
||||
sendToDocsMessage = "";
|
||||
@@ -792,10 +745,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares a link to a fusion table via external app (email, gmail, ...)
|
||||
* Shares a link to a My Map or Fusion Table via external app (email, gmail, ...)
|
||||
* A chooser with apps that support text/plain will be shown to the user.
|
||||
*/
|
||||
public void shareLinkToFusionTable(long trackId) {
|
||||
public void shareLinkToMap(String url) {
|
||||
Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||
shareIntent.setType("text/plain");
|
||||
shareIntent.putExtra(Intent.EXTRA_SUBJECT,
|
||||
@@ -807,8 +760,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
getString(R.string.share_url_only_key), false);
|
||||
}
|
||||
|
||||
Track track = providerUtils.getTrack(trackId);
|
||||
String url = SendToFusionTables.getMapVisualizationUrl(track);
|
||||
String msg = shareUrlOnly ? url : String.format(
|
||||
getResources().getText(R.string.share_map_body_format).toString(), url);
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, msg);
|
||||
@@ -1027,6 +978,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
* Initiates the process to send tracks to google.
|
||||
* This is called once the user has selected sending options via the
|
||||
* SendToGoogleDialog.
|
||||
*
|
||||
* TODO: Change this whole flow to an actual state machine.
|
||||
*/
|
||||
public void sendToGoogle() {
|
||||
SendToGoogleDialog sendToGoogleDialog =
|
||||
@@ -1037,17 +990,253 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
setProgressValue(0);
|
||||
clearProgressMessage();
|
||||
dialogManager.showDialogSafely(DIALOG_PROGRESS);
|
||||
if (sendToGoogleDialog.getSendToFusionTables()) {
|
||||
setProgressValue(0);
|
||||
setProgressMessage(R.string.progress_message_authenticating_fusiontables);
|
||||
authenticate(new Intent(), MyTracksConstants.SEND_TO_GOOGLE,
|
||||
SendToFusionTables.SERVICE_ID);
|
||||
} else {
|
||||
onActivityResult(MyTracksConstants.AUTHENTICATE_TO_DOCLIST, RESULT_OK,
|
||||
new Intent());
|
||||
|
||||
if (sendToGoogleDialog.getSendToMyMaps()) {
|
||||
sendToGoogleMapsOrPickMap(sendToGoogleDialog);
|
||||
} else if (sendToGoogleDialog.getSendToFusionTables()) {
|
||||
authenticateToFusionTables(null);
|
||||
} else if (sendToGoogleDialog.getSendToDocs()) {
|
||||
authenticateToGoogleDocs();
|
||||
} else {
|
||||
Log.w(MyTracksConstants.TAG, "Nowhere to upload to");
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendToGoogleMapsOrPickMap(SendToGoogleDialog sendToGoogleDialog) {
|
||||
if (!sendToGoogleDialog.getCreateNewMap()) {
|
||||
// Ask the user to choose a map to upload into
|
||||
Intent listIntent = new Intent(this, MyMapsList.class);
|
||||
startActivityForResult(listIntent, MyTracksConstants.GET_MAP);
|
||||
// The callback for GET_MAP calls authenticateToGoogleMaps
|
||||
} else {
|
||||
authenticateToGoogleMaps(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void authenticateToGoogleMaps(Intent results) {
|
||||
if (results == null) { results = new Intent(); }
|
||||
|
||||
setProgressValue(0);
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_mymaps);
|
||||
authenticate(results, MyTracksConstants.AUTHENTICATE_TO_MY_MAPS,
|
||||
MapsService.getServiceName());
|
||||
// AUTHENTICATE_TO_MY_MAPS callback calls sendToGoogleMaps
|
||||
}
|
||||
|
||||
private void sendToGoogleMaps(final long trackId, String mapId) {
|
||||
SendToMyMaps.OnSendCompletedListener onCompletion = new SendToMyMaps.OnSendCompletedListener() {
|
||||
@Override
|
||||
public void onSendCompleted(String mapId, boolean success, int statusMessage) {
|
||||
sendToMyMapsMessage = getString(statusMessage);
|
||||
sendToMyMapsSuccess = success;
|
||||
if (sendToMyMapsSuccess) {
|
||||
sendToMyMapsMapId = mapId;
|
||||
// Update the map id for this track:
|
||||
try {
|
||||
Track track = providerUtils.getTrack(trackId);
|
||||
track.setMapId(mapId);
|
||||
providerUtils.updateTrack(track);
|
||||
} catch (RuntimeException e) {
|
||||
// If that fails whatever reasons we'll just log an error, but
|
||||
// continue.
|
||||
Log.w(MyTracksConstants.TAG, "Updating map id failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
onSendToGoogleMapsDone();
|
||||
}
|
||||
};
|
||||
final SendToMyMaps sender = new SendToMyMaps(this, mapId, auth,
|
||||
trackId, this /*progressIndicator*/, onCompletion);
|
||||
|
||||
HandlerThread handlerThread = new HandlerThread("SendToMyMaps");
|
||||
handlerThread.start();
|
||||
Handler handler = new Handler(handlerThread.getLooper());
|
||||
handler.post(sender);
|
||||
}
|
||||
|
||||
private void onSendToGoogleMapsDone() {
|
||||
SendToGoogleDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
|
||||
if (sendToGoogleDialog.getSendToFusionTables()) {
|
||||
authenticateToFusionTables(null);
|
||||
} else if (sendToGoogleDialog.getSendToDocs()) {
|
||||
authenticateToGoogleDocs();
|
||||
} else {
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
}
|
||||
|
||||
private void authenticateToFusionTables(Intent results) {
|
||||
if (results == null) { results = new Intent(); }
|
||||
|
||||
setProgressValue(0);
|
||||
setProgressMessage(R.string.progress_message_authenticating_fusiontables);
|
||||
authenticate(results, MyTracksConstants.AUTHENTICATE_TO_FUSION_TABLES,
|
||||
SendToFusionTables.SERVICE_ID);
|
||||
// AUTHENTICATE_TO_FUSION_TABLES callback calls sendToFusionTables
|
||||
}
|
||||
|
||||
private void sendToFusionTables(final long trackId) {
|
||||
OnSendCompletedListener onCompletion = new OnSendCompletedListener() {
|
||||
@Override
|
||||
public void onSendCompleted(String tableId, boolean success,
|
||||
int statusMessage) {
|
||||
sendToFusionTablesMessage = getString(statusMessage);
|
||||
sendToFusionTablesSuccess = success;
|
||||
if (sendToFusionTablesSuccess) {
|
||||
sendToFusionTablesTableId = tableId;
|
||||
// Update the table id for this track:
|
||||
try {
|
||||
Track track = providerUtils.getTrack(trackId);
|
||||
track.setTableId(tableId);
|
||||
providerUtils.updateTrack(track);
|
||||
} catch (RuntimeException e) {
|
||||
// If that fails whatever reasons we'll just log an error, but
|
||||
// continue.
|
||||
Log.w(MyTracksConstants.TAG, "Updating table id failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
onSendToFusionTablesDone();
|
||||
}
|
||||
};
|
||||
sendToTrackId = trackId;
|
||||
final SendToFusionTables sender = new SendToFusionTables(this, auth,
|
||||
trackId, this/*progressIndicator*/, onCompletion);
|
||||
|
||||
HandlerThread handlerThread = new HandlerThread("SendToFusionTables");
|
||||
handlerThread.start();
|
||||
Handler handler = new Handler(handlerThread.getLooper());
|
||||
handler.post(sender);
|
||||
}
|
||||
|
||||
private void onSendToFusionTablesDone() {
|
||||
SendToGoogleDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
|
||||
if (sendToGoogleDialog.getSendToDocs()) {
|
||||
authenticateToGoogleDocs();
|
||||
} else {
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
}
|
||||
|
||||
private void authenticateToGoogleDocs() {
|
||||
setProgressValue(0);
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_docs);
|
||||
authenticate(new Intent(),
|
||||
MyTracksConstants.AUTHENTICATE_TO_DOCLIST,
|
||||
SendToDocs.GDATA_SERVICE_NAME_DOCLIST);
|
||||
// AUTHENTICATE_TO_DOCLIST callback calls authenticateToGoogleTrix
|
||||
}
|
||||
|
||||
private void authenticateToGoogleTrix() {
|
||||
setProgressValue(30);
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_docs);
|
||||
authenticate(new Intent(),
|
||||
MyTracksConstants.AUTHENTICATE_TO_TRIX,
|
||||
SendToDocs.GDATA_SERVICE_NAME_TRIX);
|
||||
// AUTHENTICATE_TO_TRIX callback calls sendToGoogleDocs
|
||||
}
|
||||
|
||||
private void sendToGoogleDocs(final long trackId) {
|
||||
Log.d(MyTracksConstants.TAG, "Sending to Docs....");
|
||||
setProgressValue(50);
|
||||
setProgressMessage(R.string.progress_message_sending_docs);
|
||||
final SendToDocs sender = new SendToDocs(this,
|
||||
authMap.get(SendToDocs.GDATA_SERVICE_NAME_TRIX),
|
||||
authMap.get(SendToDocs.GDATA_SERVICE_NAME_DOCLIST), trackId);
|
||||
sendToTrackId = trackId;
|
||||
Runnable onCompletion = new Runnable() {
|
||||
public void run() {
|
||||
setProgressValue(100);
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
sendToDocsMessage = sender.getStatusMessage();
|
||||
sendToDocsSuccess = sender.wasSuccess();
|
||||
|
||||
onSendToGoogleDocsDone();
|
||||
}
|
||||
};
|
||||
sender.setOnCompletion(onCompletion);
|
||||
sender.run();
|
||||
}
|
||||
|
||||
private void onSendToGoogleDocsDone() {
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
|
||||
private void onSendToGoogleDone() {
|
||||
SendToGoogleDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
|
||||
final boolean sentToMyMaps = sendToGoogleDialog.getSendToMyMaps();
|
||||
final boolean sentToFusionTables = sendToGoogleDialog.getSendToFusionTables();
|
||||
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (shareRequested) {
|
||||
Toast.makeText(MyTracks.this, getSendToGoogleResultMessage(), Toast.LENGTH_LONG)
|
||||
.show();
|
||||
|
||||
if (shareLinkToMap(sentToMyMaps, sentToFusionTables)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If anything failed or sharing was not requested, show the dialog
|
||||
dialogManager.showDialogSafely(
|
||||
DialogManager.DIALOG_SEND_TO_GOOGLE_RESULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) {
|
||||
String url = null;
|
||||
if (sentToMyMaps && sendToMyMapsSuccess) {
|
||||
// Prefer a link to My Maps
|
||||
url = MapsService.buildMapUrl(sendToMyMapsMapId);
|
||||
} else if (sentToFusionTables && sendToFusionTablesSuccess) {
|
||||
// Otherwise try using the link to fusion tables
|
||||
url = getFusionTablesUrl(sendToTrackId);
|
||||
}
|
||||
|
||||
if (url != null) {
|
||||
shareLinkToMap(url);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected String getFusionTablesUrl(long sendToTrackId2) {
|
||||
Track track = providerUtils.getTrack(sendToTrackId);
|
||||
return SendToFusionTables.getMapVisualizationUrl(track);
|
||||
}
|
||||
|
||||
String getSendToGoogleResultMessage() {
|
||||
StringBuilder message = new StringBuilder();
|
||||
SendToGoogleDialog sendToGoogleDialog =
|
||||
dialogManager.getSendToGoogleDialog();
|
||||
if (sendToGoogleDialog.getSendToMyMaps()) {
|
||||
message.append(sendToMyMapsMessage);
|
||||
}
|
||||
if (sendToGoogleDialog.getSendToFusionTables()) {
|
||||
message.append(sendToFusionTablesMessage);
|
||||
}
|
||||
if (sendToGoogleDialog.getSendToDocs()) {
|
||||
if (message.length() > 0) {
|
||||
message.append(' ');
|
||||
}
|
||||
message.append(sendToDocsMessage);
|
||||
}
|
||||
if (sendToMyMapsSuccess && sendToFusionTablesSuccess && sendToDocsSuccess) {
|
||||
message.append(' ');
|
||||
message.append(getString(R.string.status_mymap_info));
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the selected track id to the shared preferences.
|
||||
* Executed on the UI thread.
|
||||
@@ -1157,35 +1346,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
writer.writeTrackAsync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that uploading to fusion tables is finished.
|
||||
*/
|
||||
private void handleFusionTablesFinish(long trackId) {
|
||||
if (shareRequested && sendToFusionTablesSuccess) {
|
||||
// Just share
|
||||
Toast.makeText(this, getFusionTablesResultMessage(), Toast.LENGTH_LONG).show();
|
||||
shareLinkToFusionTable(trackId);
|
||||
} else {
|
||||
dialogManager.showDialogSafely(DialogManager.DIALOG_SEND_TO_GOOGLE_RESULT);
|
||||
}
|
||||
}
|
||||
|
||||
public String getFusionTablesResultMessage() {
|
||||
StringBuilder message = new StringBuilder();
|
||||
SendToGoogleDialog sendToGoogleDialog =
|
||||
dialogManager.getSendToGoogleDialog();
|
||||
if (sendToGoogleDialog.getSendToFusionTables()) {
|
||||
message.append(sendToFusionTablesMessage);
|
||||
}
|
||||
if (sendToGoogleDialog.getSendToDocs()) {
|
||||
if (message.length() > 0) {
|
||||
message.append(' ');
|
||||
}
|
||||
message.append(sendToDocsMessage);
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
public AccountChooser getAccountChooser() {
|
||||
return accountChooser;
|
||||
}
|
||||
@@ -1202,6 +1362,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
return dialogManager;
|
||||
}
|
||||
|
||||
public String getSendToMyMapsMapId() {
|
||||
return sendToMyMapsMapId;
|
||||
}
|
||||
|
||||
public String getSendToFusionTablesTableId() {
|
||||
return sendToFusionTablesTableId;
|
||||
}
|
||||
|
||||
@@ -50,26 +50,26 @@ public abstract class MyTracksConstants {
|
||||
public static final int FEATURE_DETAILS = 5;
|
||||
public static final int START_RECORDING = 6;
|
||||
public static final int STOP_RECORDING = 7;
|
||||
public static final int AUTHENTICATE_TO_DOCLIST = 8;
|
||||
public static final int AUTHENTICATE_TO_TRIX = 9;
|
||||
public static final int SEND_TO_DOCS = 10;
|
||||
public static final int DELETE_TRACK = 11;
|
||||
public static final int SEND_TO_GOOGLE = 12;
|
||||
public static final int SEND_TO_GOOGLE_DIALOG = 13;
|
||||
public static final int SHARE_LINK = 14;
|
||||
public static final int SHARE_GPX_FILE = 15;
|
||||
public static final int SHARE_KML_FILE = 16;
|
||||
public static final int SHARE_CSV_FILE = 17;
|
||||
public static final int SHARE_TCX_FILE = 18;
|
||||
public static final int EDIT_DETAILS = 19;
|
||||
public static final int SAVE_GPX_FILE = 20;
|
||||
public static final int SAVE_KML_FILE = 21;
|
||||
public static final int SAVE_CSV_FILE = 22;
|
||||
public static final int SAVE_TCX_FILE = 23;
|
||||
public static final int CLEAR_MAP = 24;
|
||||
public static final int SHOW_WAYPOINT = 25;
|
||||
public static final int EDIT_WAYPOINT = 26;
|
||||
public static final int WELCOME = 27;
|
||||
public static final int AUTHENTICATE_TO_MY_MAPS = 8;
|
||||
public static final int AUTHENTICATE_TO_FUSION_TABLES = 9;
|
||||
public static final int AUTHENTICATE_TO_DOCLIST = 10;
|
||||
public static final int AUTHENTICATE_TO_TRIX = 11;
|
||||
public static final int DELETE_TRACK = 13;
|
||||
public static final int SEND_TO_GOOGLE_DIALOG = 14;
|
||||
public static final int SHARE_LINK = 15;
|
||||
public static final int SHARE_GPX_FILE = 16;
|
||||
public static final int SHARE_KML_FILE = 17;
|
||||
public static final int SHARE_CSV_FILE = 18;
|
||||
public static final int SHARE_TCX_FILE = 19;
|
||||
public static final int EDIT_DETAILS = 20;
|
||||
public static final int SAVE_GPX_FILE = 21;
|
||||
public static final int SAVE_KML_FILE = 22;
|
||||
public static final int SAVE_CSV_FILE = 23;
|
||||
public static final int SAVE_TCX_FILE = 24;
|
||||
public static final int CLEAR_MAP = 25;
|
||||
public static final int SHOW_WAYPOINT = 26;
|
||||
public static final int EDIT_WAYPOINT = 27;
|
||||
public static final int WELCOME = 28;
|
||||
|
||||
/*
|
||||
* Menu ids:
|
||||
|
||||
@@ -83,7 +83,7 @@ public class MyTracksList extends ListActivity
|
||||
SubMenu share = menu.addSubMenu(0, MyTracksConstants.MENU_SHARE, 0,
|
||||
R.string.tracklist_share_track);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_LINK, 0,
|
||||
R.string.tracklist_share_linkfusion);
|
||||
R.string.tracklist_share_link);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_GPX_FILE, 0,
|
||||
R.string.tracklist_share_gpx_file);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_KML_FILE, 0,
|
||||
|
||||
@@ -792,7 +792,7 @@ public class MyTracksMap extends MapActivity
|
||||
SubMenu share = menu.addSubMenu(0, MyTracksConstants.MENU_SHARE, 0,
|
||||
R.string.tracklist_share_track);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_LINK, 0,
|
||||
R.string.tracklist_share_linkfusion);
|
||||
R.string.tracklist_share_link);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_GPX_FILE, 0,
|
||||
R.string.tracklist_share_gpx_file);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_KML_FILE, 0,
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
/**
|
||||
* A dialog where the user can choose where to send the tracks to, i.e.
|
||||
@@ -38,6 +39,10 @@ import android.widget.RadioButton;
|
||||
*/
|
||||
public class SendToGoogleDialog extends Dialog {
|
||||
|
||||
private RadioGroup groupMyMaps;
|
||||
private RadioButton createNewMapRadioButton;
|
||||
private RadioButton pickMapRadioButton;
|
||||
private CheckBox sendToMyMapsCheckBox;
|
||||
private CheckBox sendToFusionTablesCheckBox;
|
||||
private CheckBox sendToDocsCheckBox;
|
||||
private RadioButton sendStatsRadioButton;
|
||||
@@ -72,19 +77,29 @@ public class SendToGoogleDialog extends Dialog {
|
||||
OnCheckedChangeListener checkBoxListener = new OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton button, boolean checked) {
|
||||
sendButton.setEnabled(
|
||||
sendToMyMapsCheckBox.isChecked() ||
|
||||
sendToFusionTablesCheckBox.isChecked() ||
|
||||
sendToDocsCheckBox.isChecked());
|
||||
groupMyMaps.setVisibility(sendToMyMapsCheckBox.isChecked() ? View.VISIBLE : View.INVISIBLE);
|
||||
//groupDocs.setVisibility(
|
||||
// sendToDocsCheckBox.isChecked() ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
};
|
||||
|
||||
sendButton = (Button) findViewById(R.id.sendtogoogle_send_now);
|
||||
groupMyMaps = (RadioGroup) findViewById(R.id.sendtogoogle_group_mymaps);
|
||||
sendToMyMapsCheckBox =
|
||||
(CheckBox) findViewById(R.id.sendtogoogle_google_mymaps);
|
||||
sendToMyMapsCheckBox.setOnCheckedChangeListener(checkBoxListener);
|
||||
sendToFusionTablesCheckBox =
|
||||
(CheckBox) findViewById(R.id.sendtogoogle_google_fusiontables);
|
||||
sendToFusionTablesCheckBox.setOnCheckedChangeListener(checkBoxListener);
|
||||
sendToDocsCheckBox = (CheckBox) findViewById(R.id.sendtogoogle_google_docs);
|
||||
sendToDocsCheckBox.setOnCheckedChangeListener(checkBoxListener);
|
||||
createNewMapRadioButton =
|
||||
(RadioButton) findViewById(R.id.sendtogoogle_create_new_map);
|
||||
pickMapRadioButton =
|
||||
(RadioButton) findViewById(R.id.sendtogoogle_pick_existing_map);
|
||||
sendStatsRadioButton =
|
||||
(RadioButton) findViewById(R.id.sendtogoogle_send_stats);
|
||||
sendStatsAndPointsRadioButton = (RadioButton) findViewById(
|
||||
@@ -93,12 +108,21 @@ public class SendToGoogleDialog extends Dialog {
|
||||
SharedPreferences prefs =
|
||||
getContext().getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
|
||||
if (prefs != null) {
|
||||
sendToFusionTablesCheckBox.setChecked(
|
||||
sendToMyMapsCheckBox.setChecked(
|
||||
prefs.getBoolean(
|
||||
getContext().getString(R.string.send_to_my_maps_key), true));
|
||||
sendToFusionTablesCheckBox.setChecked(
|
||||
prefs.getBoolean(
|
||||
getContext().getString(R.string.send_to_fusion_tables_key), true));
|
||||
sendToDocsCheckBox.setChecked(
|
||||
prefs.getBoolean(
|
||||
getContext().getString(R.string.send_to_docs_key), true));
|
||||
pickMapRadioButton.setChecked(
|
||||
prefs.getBoolean(
|
||||
getContext().getString(R.string.pick_existing_map_key), false));
|
||||
createNewMapRadioButton.setChecked(
|
||||
!prefs.getBoolean(
|
||||
getContext().getString(R.string.pick_existing_map_key), false));
|
||||
sendStatsAndPointsRadioButton.setChecked(
|
||||
prefs.getBoolean(
|
||||
getContext().getString(R.string.send_stats_and_points_key),
|
||||
@@ -119,10 +143,16 @@ public class SendToGoogleDialog extends Dialog {
|
||||
if (editor != null) {
|
||||
editor.putBoolean(
|
||||
getContext().getString(R.string.send_to_my_maps_key),
|
||||
sendToMyMapsCheckBox.isChecked());
|
||||
editor.putBoolean(
|
||||
getContext().getString(R.string.send_to_fusion_tables_key),
|
||||
sendToFusionTablesCheckBox.isChecked());
|
||||
editor.putBoolean(
|
||||
getContext().getString(R.string.send_to_docs_key),
|
||||
sendToDocsCheckBox.isChecked());
|
||||
editor.putBoolean(
|
||||
getContext().getString(R.string.pick_existing_map_key),
|
||||
pickMapRadioButton.isChecked());
|
||||
editor.putBoolean(
|
||||
getContext().getString(R.string.send_stats_and_points_key),
|
||||
sendStatsAndPointsRadioButton.isChecked());
|
||||
@@ -132,6 +162,10 @@ public class SendToGoogleDialog extends Dialog {
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
public boolean getSendToMyMaps() {
|
||||
return sendToMyMapsCheckBox.isChecked();
|
||||
}
|
||||
|
||||
public boolean getSendToFusionTables() {
|
||||
return sendToFusionTablesCheckBox.isChecked();
|
||||
}
|
||||
@@ -140,6 +174,10 @@ public class SendToGoogleDialog extends Dialog {
|
||||
return sendToDocsCheckBox.isChecked();
|
||||
}
|
||||
|
||||
public boolean getCreateNewMap() {
|
||||
return createNewMapRadioButton.isChecked();
|
||||
}
|
||||
|
||||
public boolean getSendStatsAndPoints() {
|
||||
return sendStatsAndPointsRadioButton.isChecked();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.io.gdata.GDataClientFactory;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsService;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsStringsProvider;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade.AuthenticationRefresher;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Factory to easily instantiate a {@link MapsFacade}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class MyMapsFactory {
|
||||
|
||||
/**
|
||||
* Simple provider for reading strings from resources.
|
||||
*/
|
||||
private static class MyMapsStringProvider implements MapsStringsProvider {
|
||||
private final Context context;
|
||||
|
||||
public MyMapsStringProvider(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNewMapDescription() {
|
||||
return context.getString(R.string.new_map_description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStart() {
|
||||
return context.getString(R.string.start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEnd() {
|
||||
return context.getString(R.string.end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Maps fa�ade interface instance.
|
||||
*
|
||||
* @param context current context
|
||||
* @param auth a valid authentication manager
|
||||
* @return the fa�ade
|
||||
*/
|
||||
public static MapsFacade newMapsClient(Activity context, final AuthManager auth) {
|
||||
MapsFacade client = MapsService.newClient(context,
|
||||
GDataClientFactory.getGDataClient(context),
|
||||
new MyMapsStringProvider(context),
|
||||
auth.getAuthToken());
|
||||
client.setAuthenticationRefresher(new AuthenticationRefresher() {
|
||||
@Override
|
||||
public void invalidateAndRefresh(Runnable done) {
|
||||
auth.invalidateAndRefresh(done);
|
||||
}
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
private MyMapsFactory() {}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import com.google.android.maps.mytracks.R;
|
||||
import com.google.wireless.gdata.client.GDataClient;
|
||||
import com.google.wireless.gdata.docs.DocumentsClient;
|
||||
import com.google.wireless.gdata.docs.SpreadsheetsClient;
|
||||
import com.google.wireless.gdata.maps.xml.XmlMapsGDataParserFactory;
|
||||
import com.google.wireless.gdata.docs.XmlDocsGDataParserFactory;
|
||||
import com.google.wireless.gdata.client.GDataServiceClient;
|
||||
|
||||
import android.app.Activity;
|
||||
@@ -99,6 +99,7 @@ public class SendToDocs {
|
||||
}
|
||||
|
||||
private void doUpload() {
|
||||
// TODO
|
||||
statusMessage = activity.getString(R.string.error_sending_to_fusiontables);
|
||||
success = false;
|
||||
|
||||
@@ -173,7 +174,7 @@ public class SendToDocs {
|
||||
try {
|
||||
androidClient = GDataClientFactory.getGDataClient(activity);
|
||||
SpreadsheetsClient gdataClient = new SpreadsheetsClient(androidClient,
|
||||
new XmlMapsGDataParserFactory(new AndroidXmlParserFactory()));
|
||||
new XmlDocsGDataParserFactory(new AndroidXmlParserFactory()));
|
||||
trixWrapper.setClient(gdataClient);
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"GData connection prepared: " + this.docListAuth);
|
||||
@@ -184,7 +185,7 @@ public class SendToDocs {
|
||||
}
|
||||
|
||||
DocumentsClient docsGdataClient = new DocumentsClient(androidClient,
|
||||
new XmlMapsGDataParserFactory(new AndroidXmlParserFactory()));
|
||||
new XmlDocsGDataParserFactory(new AndroidXmlParserFactory()));
|
||||
docListWrapper.setClient(docsGdataClient);
|
||||
|
||||
// First try to find the spreadsheet:
|
||||
|
||||
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.ProgressIndicator;
|
||||
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.io.mymaps.MapsFacade;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade.WaypointData;
|
||||
import com.google.android.apps.mytracks.stats.DoubleBuffer;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.MyTracksUtils;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
import com.google.android.apps.mytracks.util.UnitConversions;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* A helper class used to transmit tracks to Google MyMaps.
|
||||
* A new instance should be used for each upload.
|
||||
*
|
||||
* IMPORTANT: while this code is Apache-licensed, please notice that usage of
|
||||
* the Google Maps servers through this API is only allowed for the My Tracks
|
||||
* application. Other applications looking to upload maps data should look
|
||||
* into using the Fusion Tables API.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class SendToMyMaps implements Runnable {
|
||||
|
||||
public static final String NEW_MAP_ID = "new";
|
||||
private static final int MAX_POINTS_PER_UPLOAD = 2048;
|
||||
|
||||
private final Activity context;
|
||||
private final AuthManager auth;
|
||||
private final long trackId;
|
||||
private final ProgressIndicator progressIndicator;
|
||||
private final OnSendCompletedListener onCompletion;
|
||||
private final StringUtils stringUtils;
|
||||
private final MyTracksProviderUtils providerUtils;
|
||||
private String mapId;
|
||||
|
||||
private MapsFacade mapsClient;
|
||||
|
||||
// Progress status
|
||||
private int totalLocationsRead;
|
||||
private int totalLocationsPrepared;
|
||||
private int totalLocationsUploaded;
|
||||
private int totalLocations;
|
||||
private int totalSegmentsUploaded;
|
||||
|
||||
public interface OnSendCompletedListener {
|
||||
void onSendCompleted(String mapId, boolean success, int statusMessage);
|
||||
}
|
||||
|
||||
public SendToMyMaps(Activity context, String mapId, AuthManager auth,
|
||||
long trackId, ProgressIndicator progressIndicator,
|
||||
OnSendCompletedListener onCompletion) {
|
||||
this.context = context;
|
||||
this.mapId = mapId;
|
||||
this.auth = auth;
|
||||
this.trackId = trackId;
|
||||
this.progressIndicator = progressIndicator;
|
||||
this.onCompletion = onCompletion;
|
||||
this.stringUtils = new StringUtils(context);
|
||||
this.providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(MyTracksConstants.TAG, "Sending to MyMaps: trackId = " + trackId);
|
||||
doUpload();
|
||||
}
|
||||
|
||||
private void doUpload() {
|
||||
int statusMessageId = R.string.error_sending_to_mymap;
|
||||
boolean success = true;
|
||||
try {
|
||||
progressIndicator.setProgressValue(1);
|
||||
progressIndicator.setProgressMessage(
|
||||
R.string.progress_message_reading_track);
|
||||
|
||||
// Get the track meta-data
|
||||
Track track = providerUtils.getTrack(trackId);
|
||||
String originalDescription = track.getDescription();
|
||||
track.setDescription("<p>" + track.getDescription() + "</p><p>"
|
||||
+ stringUtils.generateTrackDescription(track, null, null) + "</p>");
|
||||
|
||||
mapsClient = MyMapsFactory.newMapsClient(context, auth);
|
||||
|
||||
// Create a new map if necessary:
|
||||
boolean isNewMap = mapId.equals(NEW_MAP_ID);
|
||||
if (isNewMap) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(
|
||||
MyTracksSettings.SETTINGS_NAME, 0);
|
||||
boolean mapPublic = true;
|
||||
if (preferences != null) {
|
||||
mapPublic = preferences.getBoolean(
|
||||
context.getString(R.string.default_map_public_key), true);
|
||||
}
|
||||
|
||||
progressIndicator.setProgressMessage(
|
||||
R.string.progress_message_creating_map);
|
||||
|
||||
StringBuilder mapIdBuilder = new StringBuilder();
|
||||
success = mapsClient.createNewMap(
|
||||
track.getName(), track.getCategory(), originalDescription, mapPublic, mapIdBuilder);
|
||||
mapId = mapIdBuilder.toString();
|
||||
}
|
||||
|
||||
// Upload all of the segments of the track plus start/end markers
|
||||
if (success) {
|
||||
success = uploadAllTrackPoints(track, originalDescription);
|
||||
}
|
||||
|
||||
// Put waypoints.
|
||||
if (success) {
|
||||
Cursor c = providerUtils.getWaypointsCursor(
|
||||
track.getId(), 0,
|
||||
MyTracksConstants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
if (c != null) {
|
||||
try {
|
||||
if (c.getCount() > 1 && c.moveToFirst()) {
|
||||
// This will skip the 1st waypoint (it carries the stats for the
|
||||
// last segment).
|
||||
ArrayList<WaypointData> waypoints = new ArrayList<WaypointData>(c.getCount() - 1);
|
||||
while (c.moveToNext()) {
|
||||
Waypoint wpt = providerUtils.createWaypoint(c);
|
||||
waypoints.add(new WaypointData(
|
||||
wpt.getName(), wpt.getDescription(), wpt.getIcon(), wpt.getLocation()));
|
||||
}
|
||||
|
||||
success = mapsClient.uploadWaypoints(mapId, waypoints);
|
||||
}
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: upload waypoints failed.");
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
statusMessageId = isNewMap
|
||||
? R.string.status_new_mymap_has_been_created
|
||||
: R.string.status_tracks_have_been_uploaded;
|
||||
}
|
||||
Log.d(MyTracksConstants.TAG, "SendToMyMaps: Done: " + success);
|
||||
progressIndicator.setProgressValue(100);
|
||||
} finally {
|
||||
if (mapsClient != null) {
|
||||
mapsClient.cleanUp();
|
||||
}
|
||||
|
||||
final boolean finalSuccess = success;
|
||||
final int finalStatusMessageId = statusMessageId;
|
||||
context.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (onCompletion != null) {
|
||||
onCompletion.onSendCompleted(
|
||||
mapId, finalSuccess, finalStatusMessageId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean uploadAllTrackPoints(
|
||||
final Track track, String originalDescription) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(
|
||||
MyTracksSettings.SETTINGS_NAME, 0);
|
||||
boolean metricUnits = true;
|
||||
if (preferences != null) {
|
||||
metricUnits =
|
||||
preferences.getBoolean(context.getString(R.string.metric_units_key),
|
||||
true);
|
||||
}
|
||||
|
||||
Cursor locationsCursor =
|
||||
providerUtils.getLocationsCursor(track.getId(), 0, -1, false);
|
||||
try {
|
||||
if (!locationsCursor.moveToFirst()) {
|
||||
Log.w(MyTracksConstants.TAG, "Unable to get any points to upload");
|
||||
return false;
|
||||
}
|
||||
|
||||
totalLocationsRead = 0;
|
||||
totalLocationsPrepared = 0;
|
||||
totalLocationsUploaded = 0;
|
||||
totalLocations = locationsCursor.getCount();
|
||||
totalSegmentsUploaded = 0;
|
||||
|
||||
// Limit the number of elevation readings. Ideally we would want around 250.
|
||||
int elevationSamplingFrequency =
|
||||
Math.max(1, (int) (totalLocations / 250.0));
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"Using elevation sampling factor: " + elevationSamplingFrequency
|
||||
+ " on " + totalLocations);
|
||||
double totalDistance = 0;
|
||||
|
||||
Vector<Double> distances = new Vector<Double>();
|
||||
Vector<Double> elevations = new Vector<Double>();
|
||||
DoubleBuffer elevationBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
|
||||
List<Location> locations = new ArrayList<Location>(MAX_POINTS_PER_UPLOAD);
|
||||
progressIndicator.setProgressMessage(
|
||||
R.string.progress_message_reading_track);
|
||||
Location lastLocation = null;
|
||||
do {
|
||||
if (totalLocationsRead % 100 == 0) {
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
Location loc = providerUtils.createLocation(locationsCursor);
|
||||
locations.add(loc);
|
||||
|
||||
if (totalLocationsRead == 0) {
|
||||
// Put a marker at the first point of the first valid segment:
|
||||
mapsClient.uploadMarker(mapId, track.getName(), track.getDescription(), loc, true);
|
||||
}
|
||||
|
||||
// Add to the elevation profile.
|
||||
if (loc != null && MyTracksUtils.isValidLocation(loc)) {
|
||||
// All points go into the smoothing buffer...
|
||||
elevationBuffer.setNext(metricUnits ? loc.getAltitude()
|
||||
: loc.getAltitude() * UnitConversions.M_TO_FT);
|
||||
if (lastLocation != null) {
|
||||
double dist = lastLocation.distanceTo(loc);
|
||||
totalDistance += dist;
|
||||
}
|
||||
|
||||
// ...but only a few points are really used to keep the url short.
|
||||
if (totalLocationsRead % elevationSamplingFrequency == 0) {
|
||||
distances.add(totalDistance);
|
||||
elevations.add(elevationBuffer.getAverage());
|
||||
}
|
||||
}
|
||||
|
||||
// If the location was not valid, it's a segment split, so make sure the
|
||||
// distance between the previous segment and the new one is not accounted
|
||||
// for in the next iteration.
|
||||
lastLocation = loc;
|
||||
|
||||
// Every now and then, upload the accumulated points
|
||||
if (totalLocationsRead % MAX_POINTS_PER_UPLOAD
|
||||
== MAX_POINTS_PER_UPLOAD - 1) {
|
||||
if (!prepareAndUploadPoints(track, locations)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
totalLocationsRead++;
|
||||
} while (locationsCursor.moveToNext());
|
||||
|
||||
// Do a final upload with what's left
|
||||
if (!prepareAndUploadPoints(track, locations)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Put an end marker at the last point of the last valid segment:
|
||||
if (lastLocation != null) {
|
||||
track.setDescription("<p>" + originalDescription + "</p><p>"
|
||||
+ stringUtils.generateTrackDescription(
|
||||
track, distances, elevations)
|
||||
+ "</p>");
|
||||
return mapsClient.uploadMarker(mapId, track.getName(), track.getDescription(),
|
||||
lastLocation, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
} finally {
|
||||
locationsCursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean prepareAndUploadPoints(Track track, List<Location> locations) {
|
||||
progressIndicator.setProgressMessage(
|
||||
R.string.progress_message_preparing_track);
|
||||
updateProgress();
|
||||
|
||||
int numLocations = locations.size();
|
||||
if (numLocations < 2) {
|
||||
Log.d(MyTracksConstants.TAG, "Not preparing/uploading too few points");
|
||||
totalLocationsUploaded += numLocations;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prepare/pre-process the points
|
||||
ArrayList<Track> splitTracks = prepareLocations(track, locations);
|
||||
|
||||
// Start uploading them
|
||||
progressIndicator.setProgressMessage(
|
||||
R.string.progress_message_sending_mymaps);
|
||||
for (Track splitTrack : splitTracks) {
|
||||
if (totalSegmentsUploaded > 1) {
|
||||
splitTrack.setName(splitTrack.getName() + " "
|
||||
+ String.format(
|
||||
context.getString(R.string.part), totalSegmentsUploaded));
|
||||
}
|
||||
totalSegmentsUploaded++;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: Prepared feature for upload w/ "
|
||||
+ splitTrack.getLocations().size() + " points.");
|
||||
|
||||
// Transmit tracks via GData feed:
|
||||
// -------------------------------
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: Uploading to map " + mapId + " w/ auth " + auth);
|
||||
if (!mapsClient.uploadTrackPoints(mapId, splitTrack.getName(), splitTrack.getLocations())) {
|
||||
Log.e(MyTracksConstants.TAG, "Uploading failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
locations.clear();
|
||||
totalLocationsUploaded += numLocations;
|
||||
updateProgress();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a buffer of locations for transmission to google maps.
|
||||
*
|
||||
* @param track the original track with meta data
|
||||
* @param buffer a buffer of locations on the track
|
||||
* @return an array of tracks each with a sub section of the points in the
|
||||
* original buffer
|
||||
*/
|
||||
private ArrayList<Track> prepareLocations(
|
||||
Track track, Iterable<Location> locations) {
|
||||
ArrayList<Track> splitTracks = new ArrayList<Track>();
|
||||
|
||||
// Create segments from each full track:
|
||||
Track segment = new Track();
|
||||
TripStatistics segmentStats = segment.getStatistics();
|
||||
TripStatistics trackStats = track.getStatistics();
|
||||
segment.setId(track.getId());
|
||||
segment.setName(track.getName());
|
||||
segment.setDescription(/* track.getDescription() */ "");
|
||||
segment.setCategory(track.getCategory());
|
||||
segmentStats.setStartTime(trackStats.getStartTime());
|
||||
segmentStats.setStopTime(trackStats.getStopTime());
|
||||
boolean startNewTrackSegment = false;
|
||||
for (Location loc : locations) {
|
||||
if (totalLocationsPrepared % 100 == 0) {
|
||||
updateProgress();
|
||||
}
|
||||
if (loc.getLatitude() > 90) {
|
||||
startNewTrackSegment = true;
|
||||
}
|
||||
|
||||
if (startNewTrackSegment) {
|
||||
// Close up the last segment.
|
||||
prepareTrackSegment(segment, splitTracks);
|
||||
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"MyTracksSendToMyMaps: Starting new track segment...");
|
||||
startNewTrackSegment = false;
|
||||
segment = new Track();
|
||||
segment.setId(track.getId());
|
||||
segment.setName(track.getName());
|
||||
segment.setDescription(/* track.getDescription() */ "");
|
||||
segment.setCategory(track.getCategory());
|
||||
}
|
||||
|
||||
if (loc.getLatitude() <= 90) {
|
||||
segment.addLocation(loc);
|
||||
if (segmentStats.getStartTime() < 0) {
|
||||
segmentStats.setStartTime(loc.getTime());
|
||||
}
|
||||
}
|
||||
totalLocationsPrepared++;
|
||||
}
|
||||
|
||||
prepareTrackSegment(segment, splitTracks);
|
||||
|
||||
return splitTracks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a track segment for sending to google maps.
|
||||
* The main steps are:
|
||||
* - correcting end time
|
||||
* - decimating locations
|
||||
* - splitting into smaller tracks.
|
||||
*
|
||||
* The final track pieces will be put in the array list splitTracks.
|
||||
*
|
||||
* @param segment the original segment of the track
|
||||
* @param splitTracks an array of smaller track segments
|
||||
*/
|
||||
private void prepareTrackSegment(
|
||||
Track segment, ArrayList<Track> splitTracks) {
|
||||
TripStatistics segmentStats = segment.getStatistics();
|
||||
if (segmentStats.getStopTime() < 0
|
||||
&& segment.getLocations().size() > 0) {
|
||||
segmentStats.setStopTime(segment.getLocations().size() - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decimate to 2 meter precision. Mapshop doesn't like too many
|
||||
* points:
|
||||
*/
|
||||
MyTracksUtils.decimate(segment, 2.0);
|
||||
|
||||
/* It the track still has > 500 points, split it in pieces: */
|
||||
if (segment.getLocations().size() > 500) {
|
||||
splitTracks.addAll(MyTracksUtils.split(segment, 500));
|
||||
} else if (segment.getLocations().size() >= 2) {
|
||||
splitTracks.add(segment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current upload progress.
|
||||
*/
|
||||
private void updateProgress() {
|
||||
// The percent of the total that represents the completed part of this
|
||||
// segment.
|
||||
int totalPercentage =
|
||||
(totalLocationsRead + totalLocationsPrepared + totalLocationsUploaded)
|
||||
/ (totalLocations * 3);
|
||||
totalPercentage = Math.min(99, totalPercentage);
|
||||
progressIndicator.setProgressValue(totalPercentage);
|
||||
}
|
||||
}
|
||||
@@ -1097,7 +1097,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
recordingTrackId, startTime));
|
||||
isRecording = true;
|
||||
isMoving = true;
|
||||
|
||||
|
||||
providerUtils.updateTrack(track);
|
||||
statsBuilder = new TripStatisticsBuilder(startTime);
|
||||
statsBuilder.setMinRecordingDistance(minRecordingDistance);
|
||||
|
||||
+7
-44
@@ -13,12 +13,10 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.wireless.gdata.maps.xml;
|
||||
package com.google.wireless.gdata.docs;
|
||||
|
||||
import com.google.wireless.gdata.client.GDataParserFactory;
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
import com.google.wireless.gdata.maps.MapFeatureEntry;
|
||||
import com.google.wireless.gdata.maps.MapsClient;
|
||||
import com.google.wireless.gdata.parser.GDataParser;
|
||||
import com.google.wireless.gdata.parser.ParseException;
|
||||
import com.google.wireless.gdata.parser.xml.XmlGDataParser;
|
||||
@@ -26,27 +24,22 @@ import com.google.wireless.gdata.parser.xml.XmlParserFactory;
|
||||
import com.google.wireless.gdata.serializer.GDataSerializer;
|
||||
import com.google.wireless.gdata.serializer.xml.XmlEntryGDataSerializer;
|
||||
|
||||
import android.util.Log;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Factory of Xml parsers for gdata maps data.
|
||||
*/
|
||||
public class XmlMapsGDataParserFactory implements GDataParserFactory {
|
||||
public class XmlDocsGDataParserFactory implements GDataParserFactory {
|
||||
private XmlParserFactory xmlFactory;
|
||||
|
||||
public XmlMapsGDataParserFactory(XmlParserFactory xmlFactory) {
|
||||
public XmlDocsGDataParserFactory(XmlParserFactory xmlFactory) {
|
||||
this.xmlFactory = xmlFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GDataParser createParser(InputStream is) throws ParseException {
|
||||
is = maybeLogCommunication(is);
|
||||
try {
|
||||
return new XmlGDataParser(is, xmlFactory.createParser());
|
||||
} catch (XmlPullParserException e) {
|
||||
@@ -59,7 +52,6 @@ public class XmlMapsGDataParserFactory implements GDataParserFactory {
|
||||
@Override
|
||||
public GDataParser createParser(Class cls, InputStream is)
|
||||
throws ParseException {
|
||||
is = maybeLogCommunication(is);
|
||||
try {
|
||||
return createParserForClass(cls, is);
|
||||
} catch (XmlPullParserException e) {
|
||||
@@ -68,43 +60,14 @@ public class XmlMapsGDataParserFactory implements GDataParserFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream maybeLogCommunication(InputStream is)
|
||||
throws ParseException {
|
||||
if (MapsClient.LOG_COMMUNICATION) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
byte[] buffer = new byte[2048];
|
||||
try {
|
||||
for (int n = is.read(buffer); n >= 0; n = is.read(buffer)) {
|
||||
String part = new String(buffer, 0, n);
|
||||
builder.append(part);
|
||||
Log.d("Response part", part);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ParseException("Could not read stream", e);
|
||||
}
|
||||
String whole = builder.toString();
|
||||
Log.d("Response", whole);
|
||||
is = new ByteArrayInputStream(whole.getBytes());
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
private GDataParser createParserForClass(
|
||||
Class<? extends Entry> cls, InputStream is)
|
||||
throws ParseException, XmlPullParserException {
|
||||
if (cls == MapFeatureEntry.class) {
|
||||
return new XmlMapsGDataParser(is, xmlFactory.createParser());
|
||||
} else {
|
||||
return new XmlGDataParser(is, xmlFactory.createParser());
|
||||
}
|
||||
return new XmlGDataParser(is, xmlFactory.createParser());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GDataSerializer createSerializer(Entry en) {
|
||||
if (en.getClass() == MapFeatureEntry.class) {
|
||||
return new XmlMapsGDataSerializer(xmlFactory, en);
|
||||
} else {
|
||||
return new XmlEntryGDataSerializer(xmlFactory, en);
|
||||
}
|
||||
return new XmlEntryGDataSerializer(xmlFactory, en);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.wireless.gdata.maps;
|
||||
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* GData entry for a map feature.
|
||||
*/
|
||||
public class MapFeatureEntry extends Entry {
|
||||
|
||||
private String mPrivacy = null;
|
||||
private Map<String, String> mAttributes = new HashMap<String, String>();
|
||||
|
||||
public void setPrivacy(String privacy) {
|
||||
mPrivacy = privacy;
|
||||
}
|
||||
|
||||
public String getPrivacy() {
|
||||
return mPrivacy;
|
||||
}
|
||||
|
||||
public void setAttribute(String name, String value) {
|
||||
mAttributes.put(name, value);
|
||||
}
|
||||
|
||||
public void removeAttribute(String name) {
|
||||
mAttributes.remove(name);
|
||||
}
|
||||
|
||||
public Map<String, String> getAllAttributes() {
|
||||
return mAttributes;
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.wireless.gdata.maps;
|
||||
|
||||
import com.google.wireless.gdata.client.GDataClient;
|
||||
import com.google.wireless.gdata.client.GDataParserFactory;
|
||||
import com.google.wireless.gdata.client.GDataServiceClient;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Client to talk to Google Maps via GData.
|
||||
*/
|
||||
public class MapsClient extends GDataServiceClient {
|
||||
public static final String SERVICE = "local";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
public static final boolean LOG_COMMUNICATION = false;
|
||||
|
||||
private static final String MAPS_BASE_FEED_URL =
|
||||
"http://maps.google.com/maps/feeds/";
|
||||
private static final String MAPS_MAP_FEED_PATH = "maps/default/full";
|
||||
private static final String MAPS_FEATURE_FEED_PATH_BEFORE_MAPID = "features/";
|
||||
private static final String MAPS_FEATURE_FEED_PATH_AFTER_MAPID = "/full";
|
||||
private static final String MAPS_VERSION_FEED_PATH_FORMAT =
|
||||
"%smaps/%s/versions/%s/full/%s";
|
||||
|
||||
private static final String MAP_ENTRY_ID_BEFORE_USER_ID = "maps/feeds/maps/";
|
||||
private static final String MAP_ENTRY_ID_BETWEEN_USER_ID_AND_MAP_ID = "/";
|
||||
private static final String V2_ONLY_PARAM = "?v=2.0";
|
||||
|
||||
public MapsClient(GDataClient dataClient,
|
||||
GDataParserFactory dataParserFactory) {
|
||||
super(dataClient, dataParserFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return SERVICE;
|
||||
}
|
||||
|
||||
public static String getMapsFeed() {
|
||||
if (DEBUG) {
|
||||
Log.d("Maps Client", "Requesting map feed:");
|
||||
}
|
||||
return MAPS_BASE_FEED_URL + MAPS_MAP_FEED_PATH + V2_ONLY_PARAM;
|
||||
}
|
||||
|
||||
public static String getFeaturesFeed(String mapid) {
|
||||
StringBuilder feed = new StringBuilder();
|
||||
feed.append(MAPS_BASE_FEED_URL);
|
||||
feed.append(MAPS_FEATURE_FEED_PATH_BEFORE_MAPID);
|
||||
feed.append(mapid);
|
||||
feed.append(MAPS_FEATURE_FEED_PATH_AFTER_MAPID);
|
||||
feed.append(V2_ONLY_PARAM);
|
||||
return feed.toString();
|
||||
}
|
||||
|
||||
public static String getMapIdFromMapEntryId(String entryId) {
|
||||
String userId = null;
|
||||
String mapId = null;
|
||||
if (DEBUG) {
|
||||
Log.d("Maps GData Client", "Getting mapid from entry id: " + entryId);
|
||||
}
|
||||
int userIdStart =
|
||||
entryId.indexOf(MAP_ENTRY_ID_BEFORE_USER_ID)
|
||||
+ MAP_ENTRY_ID_BEFORE_USER_ID.length();
|
||||
int userIdEnd =
|
||||
entryId.indexOf(MAP_ENTRY_ID_BETWEEN_USER_ID_AND_MAP_ID, userIdStart);
|
||||
if (userIdStart >= 0 && userIdEnd < entryId.length()
|
||||
&& userIdStart <= userIdEnd) {
|
||||
userId = entryId.substring(userIdStart, userIdEnd);
|
||||
}
|
||||
int mapIdStart =
|
||||
entryId.indexOf(MAP_ENTRY_ID_BETWEEN_USER_ID_AND_MAP_ID, userIdEnd)
|
||||
+ MAP_ENTRY_ID_BETWEEN_USER_ID_AND_MAP_ID.length();
|
||||
if (mapIdStart >= 0 && mapIdStart < entryId.length()) {
|
||||
mapId = entryId.substring(mapIdStart);
|
||||
}
|
||||
if (userId == null) {
|
||||
userId = "";
|
||||
}
|
||||
if (mapId == null) {
|
||||
mapId = "";
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d("Maps GData Client", "Got user id: " + userId);
|
||||
Log.d("Maps GData Client", "Got map id: " + mapId);
|
||||
}
|
||||
return userId + "." + mapId;
|
||||
}
|
||||
|
||||
public static String getVersionFeed(String versionUserId,
|
||||
String versionClient, String currentVersion) {
|
||||
return String.format(MAPS_VERSION_FEED_PATH_FORMAT,
|
||||
MAPS_BASE_FEED_URL, versionUserId,
|
||||
versionClient, currentVersion);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009 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.wireless.gdata.maps.xml;
|
||||
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
import com.google.wireless.gdata.data.Feed;
|
||||
import com.google.wireless.gdata.data.XmlUtils;
|
||||
import com.google.wireless.gdata.maps.MapFeatureEntry;
|
||||
import com.google.wireless.gdata.parser.ParseException;
|
||||
import com.google.wireless.gdata.parser.xml.XmlGDataParser;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Parser for XML gdata maps data.
|
||||
*/
|
||||
public class XmlMapsGDataParser extends XmlGDataParser {
|
||||
|
||||
public XmlMapsGDataParser(InputStream is, XmlPullParser xpp)
|
||||
throws ParseException {
|
||||
super(is, xpp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Feed createFeed() {
|
||||
return new Feed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry createEntry() {
|
||||
return new MapFeatureEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleExtraElementInFeed(Feed feed) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleExtraLinkInEntry(
|
||||
String rel, String type, String href, Entry entry)
|
||||
throws XmlPullParserException, IOException {
|
||||
if (!(entry instanceof MapFeatureEntry)) {
|
||||
throw new IllegalArgumentException("Expected MapFeatureEntry!");
|
||||
}
|
||||
if (rel.endsWith("#view")) {
|
||||
return;
|
||||
}
|
||||
super.handleExtraLinkInEntry(rel, type, href, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current entry in the XML document. Assumes that the parser is
|
||||
* currently pointing just after an <entry>.
|
||||
*
|
||||
* @param plainEntry The entry that will be filled.
|
||||
* @throws XmlPullParserException Thrown if the XML cannot be parsed.
|
||||
* @throws IOException Thrown if the underlying inputstream cannot be read.
|
||||
*/
|
||||
@Override
|
||||
protected void handleEntry(Entry plainEntry)
|
||||
throws XmlPullParserException, IOException, ParseException {
|
||||
XmlPullParser parser = getParser();
|
||||
if (!(plainEntry instanceof MapFeatureEntry)) {
|
||||
throw new IllegalArgumentException("Expected MapFeatureEntry!");
|
||||
}
|
||||
MapFeatureEntry entry = (MapFeatureEntry) plainEntry;
|
||||
|
||||
int eventType = parser.getEventType();
|
||||
entry.setPrivacy("public");
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
switch (eventType) {
|
||||
case XmlPullParser.START_TAG:
|
||||
String name = parser.getName();
|
||||
if ("entry".equals(name)) {
|
||||
// stop parsing here.
|
||||
return;
|
||||
} else if ("id".equals(name)) {
|
||||
entry.setId(XmlUtils.extractChildText(parser));
|
||||
} else if ("title".equals(name)) {
|
||||
entry.setTitle(XmlUtils.extractChildText(parser));
|
||||
} else if ("link".equals(name)) {
|
||||
String rel = parser.getAttributeValue(null /* ns */, "rel");
|
||||
String type = parser.getAttributeValue(null /* ns */, "type");
|
||||
String href = parser.getAttributeValue(null /* ns */, "href");
|
||||
if ("edit".equals(rel)) {
|
||||
entry.setEditUri(href);
|
||||
} else if ("alternate".equals(rel) && "text/html".equals(type)) {
|
||||
entry.setHtmlUri(href);
|
||||
} else {
|
||||
handleExtraLinkInEntry(rel, type, href, entry);
|
||||
}
|
||||
} else if ("summary".equals(name)) {
|
||||
entry.setSummary(XmlUtils.extractChildText(parser));
|
||||
} else if ("content".equals(name)) {
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
int parentDepth = parser.getDepth();
|
||||
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
|
||||
int etype = parser.next();
|
||||
switch (etype) {
|
||||
case XmlPullParser.START_TAG:
|
||||
contentBuilder.append('<');
|
||||
contentBuilder.append(parser.getName());
|
||||
contentBuilder.append('>');
|
||||
break;
|
||||
case XmlPullParser.TEXT:
|
||||
contentBuilder.append("<![CDATA[");
|
||||
contentBuilder.append(parser.getText());
|
||||
contentBuilder.append("]]>");
|
||||
break;
|
||||
case XmlPullParser.END_TAG:
|
||||
if (parser.getDepth() > parentDepth) {
|
||||
contentBuilder.append("</");
|
||||
contentBuilder.append(parser.getName());
|
||||
contentBuilder.append('>');
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (etype == XmlPullParser.END_TAG
|
||||
&& parser.getDepth() == parentDepth) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
entry.setContent(contentBuilder.toString());
|
||||
} else if ("category".equals(name)) {
|
||||
String category = parser.getAttributeValue(null /* ns */, "term");
|
||||
if (category != null && category.length() > 0) {
|
||||
entry.setCategory(category);
|
||||
}
|
||||
String categoryScheme =
|
||||
parser.getAttributeValue(null /* ns */, "scheme");
|
||||
if (categoryScheme != null && category.length() > 0) {
|
||||
entry.setCategoryScheme(categoryScheme);
|
||||
}
|
||||
} else if ("published".equals(name)) {
|
||||
entry.setPublicationDate(XmlUtils.extractChildText(parser));
|
||||
} else if ("updated".equals(name)) {
|
||||
entry.setUpdateDate(XmlUtils.extractChildText(parser));
|
||||
} else if ("deleted".equals(name)) {
|
||||
entry.setDeleted(true);
|
||||
} else if ("draft".equals(name)) {
|
||||
String draft = XmlUtils.extractChildText(parser);
|
||||
entry.setPrivacy("yes".equals(draft) ? "unlisted" : "public");
|
||||
} else if ("customProperty".equals(name)) {
|
||||
String attrName = parser.getAttributeValue(null, "name");
|
||||
String attrValue = XmlUtils.extractChildText(parser);
|
||||
entry.setAttribute(attrName, attrValue);
|
||||
} else if ("deleted".equals(name)) {
|
||||
entry.setDeleted(true);
|
||||
} else {
|
||||
handleExtraElementInEntry(entry);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
eventType = parser.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,277 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.wireless.gdata.maps.xml;
|
||||
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
import com.google.wireless.gdata.data.StringUtils;
|
||||
import com.google.wireless.gdata.maps.MapFeatureEntry;
|
||||
import com.google.wireless.gdata.maps.MapsClient;
|
||||
import com.google.wireless.gdata.parser.ParseException;
|
||||
import com.google.wireless.gdata.parser.xml.XmlGDataParser;
|
||||
import com.google.wireless.gdata.parser.xml.XmlParserFactory;
|
||||
import com.google.wireless.gdata.serializer.xml.XmlEntryGDataSerializer;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Serializer of maps data for GData.
|
||||
*/
|
||||
public class XmlMapsGDataSerializer extends XmlEntryGDataSerializer {
|
||||
|
||||
private static final String APP_NAMESPACE = "http://www.w3.org/2007/app";
|
||||
|
||||
private MapFeatureEntry entry;
|
||||
private XmlParserFactory factory;
|
||||
private OutputStream stream;
|
||||
|
||||
public XmlMapsGDataSerializer(XmlParserFactory factory, Entry entry) {
|
||||
super(factory, entry);
|
||||
|
||||
this.factory = factory;
|
||||
this.entry = (MapFeatureEntry) entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(OutputStream out, int format)
|
||||
throws IOException, ParseException {
|
||||
XmlSerializer serializer = null;
|
||||
try {
|
||||
serializer = factory.createSerializer();
|
||||
} catch (XmlPullParserException e) {
|
||||
throw new ParseException("Unable to create XmlSerializer.", e);
|
||||
}
|
||||
|
||||
// TODO: make the output compact
|
||||
|
||||
ByteArrayOutputStream printStream;
|
||||
|
||||
if (MapsClient.LOG_COMMUNICATION) {
|
||||
printStream = new ByteArrayOutputStream();
|
||||
|
||||
serializer.setOutput(printStream, "UTF-8");
|
||||
} else {
|
||||
serializer.setOutput(out, "UTF-8");
|
||||
}
|
||||
|
||||
serializer.startDocument("UTF-8", Boolean.FALSE);
|
||||
|
||||
declareEntryNamespaces(serializer);
|
||||
serializer.startTag(XmlGDataParser.NAMESPACE_ATOM_URI, "entry");
|
||||
|
||||
stream = MapsClient.LOG_COMMUNICATION ? printStream : out;
|
||||
serializeEntryContents(serializer, format);
|
||||
|
||||
serializer.endTag(XmlGDataParser.NAMESPACE_ATOM_URI, "entry");
|
||||
serializer.endDocument();
|
||||
serializer.flush();
|
||||
|
||||
if (MapsClient.LOG_COMMUNICATION) {
|
||||
Log.d("Request", printStream.toString());
|
||||
out.write(printStream.toByteArray());
|
||||
stream = out;
|
||||
}
|
||||
}
|
||||
|
||||
private final void declareEntryNamespaces(XmlSerializer serializer)
|
||||
throws IOException {
|
||||
serializer.setPrefix(
|
||||
"" /* default ns */, XmlGDataParser.NAMESPACE_ATOM_URI);
|
||||
serializer.setPrefix(
|
||||
XmlGDataParser.NAMESPACE_GD, XmlGDataParser.NAMESPACE_GD_URI);
|
||||
declareExtraEntryNamespaces(serializer);
|
||||
}
|
||||
|
||||
private final void serializeEntryContents(XmlSerializer serializer,
|
||||
int format) throws IOException {
|
||||
if (format != FORMAT_CREATE) {
|
||||
serializeId(serializer, entry.getId());
|
||||
}
|
||||
|
||||
serializeTitle(serializer, entry.getTitle());
|
||||
|
||||
if (format != FORMAT_CREATE) {
|
||||
serializeLink(serializer,
|
||||
"edit" /* rel */, entry.getEditUri(), null /* type */);
|
||||
serializeLink(serializer,
|
||||
"alternate" /* rel */, entry.getHtmlUri(), "text/html" /* type */);
|
||||
}
|
||||
|
||||
serializeSummary(serializer, entry.getSummary());
|
||||
serializeContent(serializer, entry.getContent());
|
||||
serializeAuthor(serializer, entry.getAuthor(), entry.getEmail());
|
||||
serializeCategory(serializer,
|
||||
entry.getCategory(), entry.getCategoryScheme());
|
||||
|
||||
if (format == FORMAT_FULL) {
|
||||
serializePublicationDate(serializer, entry.getPublicationDate());
|
||||
}
|
||||
|
||||
if (format != FORMAT_CREATE) {
|
||||
serializeUpdateDate(serializer, entry.getUpdateDate());
|
||||
}
|
||||
|
||||
serializeExtraEntryContents(serializer, format);
|
||||
}
|
||||
|
||||
private static void serializeId(XmlSerializer serializer, String id)
|
||||
throws IOException {
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "id");
|
||||
serializer.text(id);
|
||||
serializer.endTag(null /* ns */, "id");
|
||||
}
|
||||
|
||||
private static void serializeTitle(XmlSerializer serializer, String title)
|
||||
throws IOException {
|
||||
if (StringUtils.isEmpty(title)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "title");
|
||||
serializer.text(title);
|
||||
serializer.endTag(null /* ns */, "title");
|
||||
}
|
||||
|
||||
public static void serializeLink(XmlSerializer serializer, String rel,
|
||||
String href, String type) throws IOException {
|
||||
if (StringUtils.isEmpty(href)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "link");
|
||||
serializer.attribute(null /* ns */, "rel", rel);
|
||||
serializer.attribute(null /* ns */, "href", href);
|
||||
if (!StringUtils.isEmpty(type)) {
|
||||
serializer.attribute(null /* ns */, "type", type);
|
||||
}
|
||||
serializer.endTag(null /* ns */, "link");
|
||||
}
|
||||
|
||||
private static void serializeSummary(XmlSerializer serializer, String summary)
|
||||
throws IOException {
|
||||
if (StringUtils.isEmpty(summary)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "summary");
|
||||
serializer.text(summary);
|
||||
serializer.endTag(null /* ns */, "summary");
|
||||
}
|
||||
|
||||
private void serializeContent(XmlSerializer serializer, String content)
|
||||
throws IOException {
|
||||
if (content == null) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "content");
|
||||
if (content.contains("</Placemark>")) {
|
||||
serializer.attribute(
|
||||
null /* ns */, "type", "application/vnd.google-earth.kml+xml");
|
||||
serializer.flush();
|
||||
stream.write(content.getBytes());
|
||||
} else {
|
||||
serializer.text(content);
|
||||
}
|
||||
serializer.endTag(null /* ns */, "content");
|
||||
}
|
||||
|
||||
private static void serializeAuthor(XmlSerializer serializer, String author,
|
||||
String email) throws IOException {
|
||||
if (StringUtils.isEmpty(author) || StringUtils.isEmpty(email)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "author");
|
||||
serializer.startTag(null /* ns */, "name");
|
||||
serializer.text(author);
|
||||
serializer.endTag(null /* ns */, "name");
|
||||
serializer.startTag(null /* ns */, "email");
|
||||
serializer.text(email);
|
||||
serializer.endTag(null /* ns */, "email");
|
||||
serializer.endTag(null /* ns */, "author");
|
||||
}
|
||||
|
||||
private static void serializeCategory(XmlSerializer serializer,
|
||||
String category, String categoryScheme) throws IOException {
|
||||
if (StringUtils.isEmpty(category) && StringUtils.isEmpty(categoryScheme)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "category");
|
||||
if (!StringUtils.isEmpty(category)) {
|
||||
serializer.attribute(null /* ns */, "term", category);
|
||||
}
|
||||
if (!StringUtils.isEmpty(categoryScheme)) {
|
||||
serializer.attribute(null /* ns */, "scheme", categoryScheme);
|
||||
}
|
||||
serializer.endTag(null /* ns */, "category");
|
||||
}
|
||||
|
||||
private static void serializePublicationDate(XmlSerializer serializer,
|
||||
String publicationDate) throws IOException {
|
||||
if (StringUtils.isEmpty(publicationDate)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "published");
|
||||
serializer.text(publicationDate);
|
||||
serializer.endTag(null /* ns */, "published");
|
||||
}
|
||||
|
||||
private static void serializeUpdateDate(XmlSerializer serializer,
|
||||
String updateDate) throws IOException {
|
||||
if (StringUtils.isEmpty(updateDate)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "updated");
|
||||
serializer.text(updateDate);
|
||||
serializer.endTag(null /* ns */, "updated");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void serializeExtraEntryContents(XmlSerializer serializer,
|
||||
int format) throws IOException {
|
||||
Map<String, String> attrs = entry.getAllAttributes();
|
||||
for (Map.Entry<String, String> attr : attrs.entrySet()) {
|
||||
serializer.startTag("http://schemas.google.com/g/2005", "customProperty");
|
||||
serializer.attribute(null, "name", attr.getKey());
|
||||
serializer.text(attr.getValue());
|
||||
serializer.endTag("http://schemas.google.com/g/2005", "customProperty");
|
||||
}
|
||||
String privacy = entry.getPrivacy();
|
||||
if (!StringUtils.isEmpty(privacy)) {
|
||||
serializer.setPrefix("app", APP_NAMESPACE);
|
||||
if ("public".equals(privacy)) {
|
||||
serializer.startTag(APP_NAMESPACE, "control");
|
||||
serializer.startTag(APP_NAMESPACE, "draft");
|
||||
serializer.text("no");
|
||||
serializer.endTag(APP_NAMESPACE, "draft");
|
||||
serializer.endTag(APP_NAMESPACE, "control");
|
||||
}
|
||||
if ("unlisted".equals(privacy)) {
|
||||
serializer.startTag(APP_NAMESPACE, "control");
|
||||
serializer.startTag(APP_NAMESPACE, "draft");
|
||||
serializer.text("yes");
|
||||
serializer.endTag(APP_NAMESPACE, "draft");
|
||||
serializer.endTag(APP_NAMESPACE, "control");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user