Merging Sandor's changes with backup (non-trivial merge)

This commit is contained in:
Rodrigo Damazio
2010-08-24 17:25:50 -03:00
parent 9befe8ae5f
commit 60ea4c5f77
35 changed files with 1736 additions and 498 deletions
+2 -1
View File
@@ -95,8 +95,9 @@ limitations under the License.
android:textSize="20sp" />
<TextView
android:layout_height="wrap_content"
android:id="@+id/about_version_register"
android:layout_width="wrap_content"
android:text="@string/version"
android:text="@string/unknown"
android:textSize="20sp" />
</TableRow>
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_start_recording"
android:icon="@drawable/menu_record"
android:title="@string/start_recording"/>
<item android:id="@+id/menu_stop_recording"
android:icon="@drawable/menu_stop"
android:title="@string/stop_recording"/>
<item android:id="@+id/menu_list_tracks"
android:icon="@drawable/menu_list_tracks"
android:title="@string/list_tracks"/>
<item android:id="@+id/menu_list_markers"
android:icon="@drawable/menu_marker"
android:title="@string/list_markers"/>
<item android:id="@+id/menu_settings"
android:icon="@android:drawable/ic_menu_preferences"
android:orderInCategory="1001"
android:title="@string/settings"/>
<item android:id="@+id/menu_help"
android:icon="@android:drawable/ic_menu_info_details"
android:orderInCategory="1002"
android:title="@string/help"/>
</menu>
+282
View File
@@ -0,0 +1,282 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2010 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Task frequency -->
<string-array name="task_frequency_options">
<item>不使用</item>
<item>1 分</item>
<item>2 分</item>
<item>5 分</item>
<item>10 分</item>
<item>15 分</item>
<item>30 分</item>
<item>60 分</item>
</string-array>
<!-- Minimum recording distance -->
<string-array name="min_recording_distance_options">
<item>1 m</item>
<item>2 m</item>
<item>3 m</item>
<item>4 m</item>
<item>5 m (推奨)</item>
<item>10 m</item>
<item>100 m</item>
</string-array>
<string-array name="min_recording_distance_options_ft">
<item>3 ft</item>
<item>6 ft</item>
<item>10 ft</item>
<item>13 ft</item>
<item>16 ft (推奨)</item>
<item>33 ft</item>
<item>328 ft</item>
</string-array>
<!-- Maximum recording distance -->
<string-array name="max_recording_distance_options">
<item>50 m</item>
<item>100 m</item>
<item>200 m (推奨)</item>
<item>500 m</item>
<item>1000 m</item>
<item>5000 m</item>
</string-array>
<string-array name="max_recording_distance_options_ft">
<item>164 ft</item>
<item>328 ft</item>
<item>656 ft (推奨)</item>
<item>1640 ft</item>
<item>0.6 mi</item>
<item>3.1 mi</item>
</string-array>
<!-- Minimum recording interval -->
<string-array name="min_recording_interval_options">
<item>電源節約 (動的制御)</item>
<item>高精度 (動的制御)</item>
<item>最高 (推奨)</item>
<item>2 秒</item>
<item>3 秒</item>
<item>4 秒</item>
<item>5 秒</item>
<item>10 秒</item>
<item>20 秒</item>
<item>30 秒</item>
<item>1 分</item>
<item>2 分</item>
<item>5 分</item>
<item>10 分</item>
<item>15 分</item>
<item>30 分</item>
</string-array>
<!-- Minimum required accuracy -->
<string-array name="min_required_accuracy_options">
<item>10 m (GPS信号強度良好)</item>
<item>20 m</item>
<item>50 m</item>
<item>100 m</item>
<item>200 m (推奨)</item>
<item>500 m</item>
<item>1000 m</item>
<item>2000 m</item>
<item>5000 m (GPS信号強度不良)</item>
</string-array>
<string-array name="min_required_accuracy_options_ft">
<item>33 ft (GPS信号強度良好)</item>
<item>66 ft</item>
<item>165 ft</item>
<item>328 ft</item>
<item>656 ft (推奨)</item>
<item>1640 ft</item>
<item>0.6 mi</item>
<item>1.2 mi</item>
<item>3.1 mi (GPS信号強度不良)</item>
</string-array>
<!-- Split frequency -->
<string-array name="split_frequency_options">
<item>分割なし</item>
<item>100 km</item>
<item>50 km</item>
<item>25 km</item>
<item>10 km</item>
<item>5 km</item>
<item>1 km</item>
<item>60 分</item>
<item>30 分</item>
<item>15 分</item>
<item>10 分</item>
<item>5 分</item>
<item>2 分</item>
<item>1 分</item>
</string-array>
<string-array name="split_frequency_options_ft">
<item>分割なし</item>
<item>100 mi</item>
<item>50 mi</item>
<item>25 mi</item>
<item>10 mi</item>
<item>5 mi</item>
<item>1 mi</item>
<item>60 分</item>
<item>30 分</item>
<item>15 分</item>
<item>10 分</item>
<item>5 分</item>
<item>2 分</item>
<item>1 分</item>
</string-array>
<!-- Other non-preference arrays -->
<array name="activity_types">
<item>不明</item>
<item>混合タイプ</item>
<item>その他</item>
<item>実行中</item>
<item>市街地ランニング</item>
<item>トラックランニング</item>
<item>山道ランニング</item>
<item>徒歩</item>
<item>早歩き</item>
<item>ハイキング</item>
<item>山道ハイキング</item>
<item>原野ハイキング</item>
<item>登山</item>
<item>サイクリング</item>
<item>ロードバイク</item>
<item>マウンテンバイク</item>
<item>トラック自転車</item>
<item>スケート</item>
<item>インラインスケート</item>
<item>スケートボード</item>
<item>スノーシュー</item>
<item>スキー</item>
<item>スノーボード</item>
<item>ソリ</item>
<item>アイスセーリング</item>
<item>帆走</item>
<item>パドリング</item>
<item>カヤック</item>
<item>漕艇</item>
<item>モーターボート</item>
<item>フェリー</item>
<item>ラジコンボート</item>
<item>サーフィン</item>
<item>ウィンドサーフィン</item>
<item>カイトサーフィン</item>
<item>水上スキー</item>
<item>ウェークボード</item>
<item>飛行機</item>
<item>水上機</item>
<item>商用航空機</item>
<item>ヘリコプター</item>
<item>熱気球</item>
<item>飛行船</item>
<item>ラジコン飛行機</item>
<item>ラジコンヘリコプター</item>
<item>スカイダイビング</item>
<item>グライダー</item>
<item>ハンググライダー</item>
<item>パラグライダー</item>
<item>騎乗</item>
<item>乗馬</item>
<item>ロバ騎乗</item>
<item>自動車運転</item>
<item>バス運転</item>
<item>鉄道</item>
<item>オートバイ</item>
<item>オフロードバイク</item>
<item>四輪バギー</item>
<item>ランドセーリング</item>
<item>フリスビー</item>
<item>アルティメットフリスビー</item>
</array>
<array name="waypoint_types">
<item>ATM</item>
<item>銀行</item>
<item>飲み屋</item>
<item>バーベキュー</item>
<item>建物</item>
<item>バス停</item>
<item>カフェ</item>
<item>キャンプファイアー</item>
<item>キャンプ場</item>
<item>教会</item>
<item>コーヒーハウス</item>
<item>コンビニ</item>
<item>水飲み場</item>
<item>がけ崩れ</item>
<item>フェリー</item>
<item>火事場</item>
<item>消防署</item>
<item>釣り場</item>
<item>ガソリンスタンド</item>
<item>ゴルフ場</item>
<item>雑貨店</item>
<item>美容室</item>
<item>散髪屋</item>
<item>ハイキング道</item>
<item>ホテル</item>
<item>家</item>
<item>情報</item>
<item>交差</item>
<item>メールボックス</item>
<item>市場</item>
<item>集合場所</item>
<item>歌劇場</item>
<item>駐車場</item>
<item>郵便局</item>
<item>洞穴</item>
<item>警察署</item>
<item>踏切</item>
<item>レストラン</item>
<item>ショッピング</item>
<item>名所</item>
<item>店</item>
<item>プール</item>
<item>電話</item>
<item>劇場</item>
<item>トイレ</item>
<item>観光案内</item>
<item>トンネル</item>
<item>樹木</item>
<item>滝</item>
<item>噴水</item>
<item>ウェイポイント</item>
</array>
</resources>
+395
View File
@@ -0,0 +1,395 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2010 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Used by the Menu -->
<string name="start_recording">トラック記録</string>
<string name="stop_recording">記録停止</string>
<string name="switch_to_sat">衛星モード</string>
<string name="switch_to_map">地図モード</string>
<string name="mylocation">現在地</string>
<string name="list_tracks">トラック</string>
<string name="list_markers">マーカ</string>
<string name="delete_all_tracks">全トラック消去</string>
<string name="settings">設定</string>
<string name="elevation">標高</string>
<string name="choose_track_message">表示するトラックを選択して下さい</string>
<string name="current_track">現在のトラック</string>
<string name="current_segment">最終セグメント</string>
<!-- Error messages -->
<string name="error_no_location_manager">この端末でロケーションマネージャを発見できませんでした</string>
<string name="error_no_gps_location_provider">この端末でGPSロケーションプロバイダを発見できました</string>
<string name="error_sending_to_mymap">Googleマイマップへのトラック送信でエラーが発生しました.しばらく待って試して下さい.</string>
<string name="error_sending_to_docs">Google Docsへのトラック送信でエラーが発生しました.しばらく待って試して下さい.</string>
<string name="error_unable_to_start_recording">記録作成開始できません.もう一度試して下さい.</string>
<string name="error_unable_to_stop_recording">記録停止できません.もう一度試して下さい.</string>
<string name="error_unable_to_read_file">ファイルからの読み込みができません.</string>
<string name="error_invalid_gpx_format">ファイルは正しいGPX書式ではありませんでした.</string>
<string name="error_generic">エラーが発生しました.もう一度試して下さい.</string>
<string name="error_track_does_not_exist">トラックが存在しません.</string>
<string name="error_out_of_memory">大きなファイルです(500KB未満でなければなりません).終了します.</string>
<string name="error_unable_to_insert_marker">マーカの挿入ができません.位置決定ができません.</string>
<!-- Status messages -->
<string name="wait_for_fix">GPS位置精度がよくなるまで待機しています.空が見えるところにいて下さい.</string>
<string name="status_now_recording">新しいトラックを記録中です.</string>
<string name="status_stopped_recording">トラック記録を停止しました.</string>
<string name="status_new_mymap_has_been_created">新しいGoogleマイマップを maps.google.com に作成しました.</string>
<string name="status_tracks_have_been_uploaded">トラックを maps.google.com に送信しました.</string>
<string name="status_tracks_have_been_uploaded_to_new_doc">トラックを docs.google.com の新しいスプレッドシートに送信しました.</string>
<string name="status_tracks_have_been_uploaded_to_docs">トラックを docs.google.com に送信しました.</string>
<string name="status_mymap_info">新しいトラックが見えるようになるまで数分程度かかります.</string>
<string name="status_enable_gps">ここをタップして,セキュリティ &amp;位置情報 を開いて,「GPS機能をONにする」にチェックして下さい.バックボタンで戻ってください.</string>
<string name="status_approximate_location">ご注意: 携帯電話中継局とWi-Fiネットワークから大まかな位置を特定します.</string>
<string name="status_no_location">現在位置決定ができません.位置取得源を増やし(セキュリティ&amp;位置情報をご覧ください),空が見えるようにして下さい.もう一度試して下さい.</string>
<string name="status_waypoint_inserted">ウェイポイントマーカを挿入しました.</string>
<string name="status_statistics_inserted">統計マーカを挿入しました.</string>
<!-- Progress dialog -->
<string name="progress_title">お待ちください...</string>
<string name="progress_message">トラックをGoogleに送信しました.</string>
<string name="progress_message_reading_track">トラックを読んでいます...</string>
<string name="progress_message_preparing_track">トラックを準備しています...</string>
<string name="progress_message_authenticating_mymaps">Googleマップの認証しています...</string>
<string name="progress_message_authenticating_docs">Google Docsへの認証を行っています...</string>
<string name="progress_message_sending_docs">トラックをGoogle Docsに送信しています...</string>
<string name="progress_message_sending_mymaps">トラックをGoogleマップに送信しています...</string>
<string name="progress_message_creating_map">新しいマイマップを生成しています...</string>
<string name="import_progress_message">GPSトラックをインポートしています.若干時間がかかります.</string>
<string name="write_progress_message">SDカードにデータを書き込んでいます.若干時間がかかります.</string>
<string name="progress_message_updating_track">トラック統計情報を更新しています...</string>
<!-- Used by DeleteAllDataHandler -->
<string name="are_you_sure_question">よろしいですか?</string>
<string name="all_data_will_be_permanently_deleted">全てのトラックとマーカをこの端末から削除しました.</string>
<string name="track_will_be_permanently_deleted">トラックとマーカをこの端末から完全に削除しました.</string>
<string name="marker_will_be_permanently_deleted">マーカをこの端末から完全に削除しました.</string>
<!-- Text and links when uploading to Google My Maps -->
<string name="new_map_description">Android用My Tracksで作成</string>
<string name="my_map_link">Android用&lt;a href=\'http://mytracks.appspot.com\'&gt;My Tracks&lt;/a&gt;で作成しました.</string>
<string name="new_map_title">新規マップ</string>
<!-- Formatting of track and marker descriptions -->
<string name="points">ポイント</string>
<string name="recorded_date">記録</string>
<string name="category">活動タイプ</string>
<string name="waypoint_category">マーカタイプ</string>
<string name="part">(Part %d)</string>
<!-- Used by the track recording service -->
<string name="recording_your_track">トラックを保存中...</string>
<string name="new_track">トラック %d</string>
<!-- Common -->
<string name="no">いいえ</string>
<string name="yes">はい</string>
<string name="ok">OK</string>
<string name="error">エラー</string>
<string name="success">成功</string>
<string name="waypoint">ウェイポイント</string>
<!-- Placemark labels for start and end of track -->
<string name="start">(開始)</string>
<string name="end">(終了)</string>
<!-- TrackList -->
<string name="tracklist_show_track">表示</string>
<string name="tracklist_send_to_mymaps">Google My Mapsへ送信</string>
<string name="tracklist_send_to_new_mymap">新規Googleマイマップへ送信</string>
<string name="tracklist_send_to_docs">Google Docsへ送信</string>
<string name="tracklist_send_to_google">Googleへ送信...</string>
<string name="tracklist_delete_track">端末から削除...</string>
<string name="tracklist_edit_track">詳細編集</string>
<string name="tracklist_write_to_sd">SDへの書き込み...</string>
<string name="tracklist_save_as_gpx">GPXファイルの保存</string>
<string name="tracklist_save_as_kml">KMLファイルの保存</string>
<string name="tracklist_save_as_csv">CVSファイルの保存</string>
<string name="tracklist_btn_send_all_to_mymaps">Googleマイマップへの送信</string>
<string name="tracklist_btn_delete_all">全てのトラックの削除</string>
<!-- Export All -->
<string name="tracklist_btn_export_all">全てのトラックのエクスポート</string>
<string name="export_done">エクスポート終了</string>
<string name="tracklist_pick_one">トラックを選択します.オプションを表示するには長押しして下さい.</string>
<string name="tracklist_all_tracks">全てのトラック:</string>
<string name="tracklist_this_track">このトラック</string>
<string name="tracklist_share_track">共有...</string>
<string name="tracklist_share_link">Googleマイマップへのリンク</string>
<string name="tracklist_share_gpx_file">GPXファイル</string>
<string name="tracklist_share_kml_file">KMLファイル</string>
<string name="tracklist_share_csv_file">CSVファイル</string>
<string name="tracklist_clear_map">マップの消去</string>
<!-- Waypoints list -->
<string name="waypointslist_btn_delete_all">全てのマーカの削除</string>
<string name="waypointslist_this_waypoint">このマーカ</string>
<string name="waypointslist_delete_waypoint">削除</string>
<string name="waypointslist_edit_waypoint">詳細編集</string>
<string name="waypointslist_show_waypoint">マップに表示</string>
<string name="waypointslist_btn_insert_waypoint">ウェイポイントの挿入</string>
<string name="waypointslist_btn_insert_statistics">統計情報の挿入</string>
<string name="waypointslist_pick_one">マーカを選択します.オプションを表示するには長押しして下さい.</string>
<!-- MyTracks Details -->
<string name="trackdetails_title">トラック詳細</string>
<string name="trackdetails_name">トラック名</string>
<string name="trackdetails_description">トラック説明</string>
<string name="trackdetails_category">活動タイプ(ハイキング, サイクリング, ランニング, 登山...)</string>
<!-- MyTracks Waypoint Details -->
<string name="waypointdetails_title">マーカ詳細</string>
<string name="waypointdetails_name">マーカ名</string>
<string name="waypointdetails_description">マーカ説明</string>
<string name="waypointdetails_category">マーカタイプ(建物, 洞穴, 名所...)</string>
<!-- MyTracks Settings -->
<string name="mytracks_settings">My Tracks設定</string>
<string name="settings_display">表示</string>
<string name="settings_recording">記録</string>
<string name="settings_sharing">共有</string>
<string name="settings_announcement_frequency">定期通知</string>
<string name="settings_announcement_frequency_summary">音声通知間隔の最小時間</string>
<string name="settings_announcement_not_available_summary">お使いのAndroidの版では音声読み上げ機能がありません</string>
<string name="settings_min_recording_distance">ポイント間の最短距離</string>
<string name="settings_min_recording_distance_summary">位置記録間の最短距離</string>
<string name="settings_max_recording_distance">ポイント間の最長距離</string>
<string name="settings_max_recording_distance_summary">これより間隔が長い場合はトラックは分割されます</string>
<string name="settings_min_recording_interval">ポイント間の最小時間間隔</string>
<string name="settings_min_recording_interval_summary">位置記録の最短インターバル</string>
<string name="settings_min_required_accuracy">最低精度</string>
<string name="settings_min_required_accuracy_summary">この精度以上でないと記録を休止します</string>
<string name="settings_metric_units">メートル法を使用</string>
<string name="settings_metric_units_summary_on">全ての距離をメートル法で表示します</string>
<string name="settings_metric_units_summary_off">全ての距離をヤード・ポンド法で表示します</string>
<string name="settings_map_public">マップの公開</string>
<string name="settings_map_public_summary_on">アップロードされたマップはmaps.google.comで誰でも閲覧できます</string>
<string name="settings_map_public_summary_off">アップロードされたマップはmaps.google.comのリストに公開されません.</string>
<string name="settings_report_speed_or_pace">速度表示</string>
<string name="settings_report_speed_or_pace_summary_on">速度が表示されます</string>
<string name="settings_report_speed_or_pace_summary_off">ペースが表示されます</string>
<string name="settings_share_url_only">URLのみ共有</string>
<string name="settings_share_url_only_summary_on">共有時にマップのURLのみ送信します</string>
<string name="settings_share_url_only_summary_off">共有時にトラックのコンテントが含まれます</string>
<string name="settings_signal_sampling_frequency">信号サンプリング周波数</string>
<string name="settings_signal_sampling_frequency_summary">端末の信号強度記録の時間間隔</string>
<string name="settings_split_frequency">分割頻度</string>
<string name="settings_split_frequency_summary">分割マーカを挿入する時間または距離の間隔</string>
<string name="pace_label">ペース</string>
<!-- MyTracksSky -->
<string name="mytracks_sky">GPS衛星</string>
<!-- My Maps -->
<string name="select_map_message">ご使用のアカウントからのマップ選択:</string>
<string name="create_new_map">新規マップ...</string>
<string name="map_list_title">Googleマイマップへの送信</string>
<string name="maps_list_loading">マップの読み込み中...</string>
<string name="maps_list_failed">マップを読み込めませんでした!</string>
<string name="open_map">このマップを選択</string>
<string name="edit_map_details">マップ詳細の編集</string>
<string name="share_map">マップの共有</string>
<string name="share_track">トラックの共有</string>
<string name="delete_map">アカウントからマップの削除</string>
<string name="map_title">マップタイトル:</string>
<string name="map_description">マップ説明:</string>
<string name="map_searchable_edit">このマップとコンテンツを検索結果に表示させる</string>
<string name="map_not_searchable_edit">このマップとコンテンツはどちらも検索結果に表示させない(直接URLで他の方が見ることは可能)</string>
<string name="map_searchable">このマップとコンテンツは検索結果に表示されます</string>
<string name="map_not_searchable">このマップとコンテンツはどちらも検索結果に表示されませんが,直接リンクで他の方が見ることができます.</string>
<string name="close">閉じる</string>
<string name="edit">編集</string>
<string name="cancel">キャンセル</string>
<string name="save">保存</string>
<!-- Sharing -->
<string name="share_map_subject">マップを共有したいと思います</string>
<string name="share_map_body_format">このマップに興味を持って頂けると思います:
%s</string>
<string name="send_track_subject">トラックを共有したいと思います</string>
<string name="send_track_body_format">このトラックに興味を持って頂けると思います.
このトラックを閲覧するには,Google Earthまたは他のマッピングソフトウェアが必要です.</string>
<!-- Visibility -->
<string name="public_map">公開</string>
<string name="unlisted_map">リストに出さない</string>
<string name="mapslist_no_maps_available">まだ地図がありません.</string>
<!-- Statistics View -->
<!-- Average Moving -->
<string name="average_moving_speed_label">平均移動速度</string>
<string name="average_moving_pace_label">平均移動ペース</string>
<!-- Average -->
<string name="average_speed_label">平均速度</string>
<string name="average_pace_label">平均ペース</string>
<string name="elevation_chart_name">標高チャート</string>
<string name="elevation_gain_label">標高差</string>
<string name="elevation_label">標高</string>
<string name="latitude_label">緯度</string>
<string name="longitude_label">経度</string>
<!-- Min -->
<string name="min_elevation_label">最小標高</string>
<string name="min_grade_label">最小勾配</string>
<string name="min_pace_label">最小ペース</string>
<!-- Max -->
<string name="max_elevation_label">最大標高</string>
<string name="max_grade_label">最大勾配</string>
<string name="max_speed_label">最大速度</string>
<string name="loading_track">トラックの読み込み中...</string>
<!-- Chart Settings -->
<string name="chart_settings">チャート設定</string>
<!-- X Axis -->
<string name="x_axis">X軸</string>
<string name="by_distance">距離ベース</string>
<string name="by_time">時間ベース</string>
<!-- Y Axis -->
<string name="y_axis">Y軸</string>
<!-- Units -->
<!-- Time -->
<string name="hour">時</string>
<string name="hours">時</string>
<string name="hr">時</string>
<string name="min">分</string>
<string name="minute">分</string>
<string name="minutes">分</string>
<string name="second">秒</string>
<string name="seconds">秒</string>
<!-- Distance -->
<string name="meter">m</string>
<string name="kilometer">km</string>
<string name="kilometers_long">キロメータ</string>
<string name="feet">ft</string>
<string name="mile">mi</string>
<string name="miles_long">マイル</string>
<!-- Speed and Pace -->
<string name="kilometer_per_hour">km/h</string>
<string name="kilometer_per_hour_long">キロメータ毎時</string>
<string name="min_per_kilometer">min/km</string>
<string name="per_kilometer">毎キロメータ</string>
<string name="mile_per_hour">mi/h</string>
<string name="mile_per_hour_long">マイル毎時</string>
<string name="min_per_mile">min/mi</string>
<string name="per_mile">毎マイル</string>
<!-- Stats Labels -->
<string name="moving_time_label">移動時間</string>
<string name="total_time_label">合計時間</string>
<string name="time_label">時間</string>
<string name="sd_unavail">SD が発見できません</string>
<string name="speed">速度</string>
<string name="start_trip">移動して下さい.</string>
<string name="statistics">統計</string>
<string name="total_distance_label">合計距離</string>
<string name="distance_label">距離</string>
<string name="unknown">-</string>
<string name="waiting">待機中...</string>
<!-- End User License Agreement -->
<string name="eula_title">エンドユーザライセンス契約書</string>
<string name="accept">同意する</string>
<string name="decline">拒否する</string>
<!-- About -->
<string name="about">このアプリケーションについて</string>
<string name="help">ヘルプ</string>
<string name="about_team">チーム:</string>
<string name="about_version">バージョン:</string>
<string name="about_email">サポート</string>
<string name="about_support">サポート:</string>
<!-- Send to Google -->
<string name="sendtogoogle_title">送信...</string>
<string name="sendtogoogle_google_mymaps">Googleマイマップ</string>
<string name="sendtogoogle_google_docs">Google Docs</string>
<string name="sendtogoogle_send_now">今すぐ送信</string>
<string name="sendtogoogle_create_new_map">新規マップ作成</string>
<string name="sendtogoogle_pick_existing_map">既存マップ選択</string>
<string name="sendtogoogle_send_stats">トラック統計情報送信</string>
<string name="sendtogoogle_send_stats_and_points">統計情報とポイント送信</string>
<!-- Getting the account to upload to. -->
<string name="no_account_found_title">アカウントを発見できませんでした.</string>
<string name="no_account_found">トラックをアップロードするためのアカウントを発見できませんでした.</string>
<string name="choose_account_title">アカウント選択</string>
<!-- SD card -->
<string name="io_no_external_storage_found">外部ストレージを発見できませんでした.SDカードが刺さっているか,端末がコンピュータにマウントされているか確認してください.</string>
<string name="io_write_failed">ファイルへの書き込みができません.</string>
<string name="io_create_dir_failed">SDカードにディレクトリを作成できません.</string>
<string name="io_write_finished">SDカードへの書き込み終了.</string>
<!-- VersionChecker -->
<string name="version_check_title">アップグレードチェック</string>
<string name="version_check_upgrade_button">今すぐアップデート</string>
<string name="version_check_continue_button">アップグレードせずに続行</string>
<string name="upgrade_required">お使いの版では,確実には動作せず,サポートもされません.ご使用を続けるには %1$s のアップグレードしてください.</string>
<string name="upgrade_recommended">お使いの版では,確実には動作しません.すぐにアップグレードすることをお勧めします.アップグレードされない場合は問題発生の可能性があることをご認識ください. サーバ同期するような機能の中には,アップグレードされるまで機能しないものがあります.</string>
<string name="upgrade_available">%1$s の新しい版が出ています.現版で問題なくご使用になれますが,アップグレードするまで最新の機能をお使いになれません.</string>
<!-- Welcome -->
<string name="welcome">ようこそ</string>
<string name="welcome_read_later">Ok</string>
<string name="welcome_about">My Tracksについて</string>
<!-- Announcement -->
<string name="announce_no_distance">My Tracks 移動していません</string>
<!-- Format:
$1 : Distance label
$2 : Distance value (5)
$3 : Distance units (mi, km)
$4 : Time description (10 minutes 5 seconds)
$5 : Speed value (5.6) : Pace value (5 minutes 6 seconds)
$6 : Speed units (mph) : Pace units (per mile)
-->
<string name="announce_template">My Tracks %1$s %2$.2f %3$s 時間 %4$s 速度/ペース %5$s %6$s</string>
<!-- Check Units -->
<string name="check_units_title">計測単位についてのご注意</string>
<string name="check_units_message">デフォルトの単位はメートルです.設定を変更しますか?</string>
<!-- Signal Strength -->
<string name="error_rate"> 誤り率: %1$d</string>
<string name="signal_to_noise_ratio"> S/N比: %1$d</string>
<string name="ecio"> Ec/Io比: %1$.1f dB</string>
<string name="gsm_strength">GSM 強度: %1$d</string>
<string name="cdma_strength">CDMA 強度: %1$d dBm</string>
<string name="evdo_strength">EVDO 強度: %1$d dBm</string>
</resources>
+1
View File
@@ -370,5 +370,6 @@ limitations under the License.
<item>GPX</item>
<item>KML</item>
<item>CSV</item>
<item>TCX</item>
</array>
</resources>
+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2010 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- These are constants used internally for preferences - DO NOT TRANSLATE -->
<string name="announcement_frequency_key">announcementFrequency</string>
<string name="bluetooth_device_key">bluetoothDevice</string>
<string name="bluetooth_pairing_key">bluetoothPairing</string>
<string name="bluetooth_sensor_key">bluetoothSensor</string>
<string name="default_map_public_key">defaultMapPublic</string>
<string name="max_recording_distance_key">maxRecordingDistance</string>
<string name="metric_units_key">metricUnits</string>
<string name="min_recording_distance_key">minRecordingDistance</string>
<string name="min_recording_interval_key">minRecordingInterval</string>
<string name="min_required_accuracy_key">minRequiredAccuracy</string>
<string name="modular_stats_display_key">modularStatsDisplay</string>
<string name="pick_existing_map_key">pickExistingMap</string>
<string name="recording_track_key">recordingTrack</string>
<string name="report_speed_key">reportSpeed</string>
<string name="selected_track_key">selectedTrack</string>
<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="sensor_id_key">sensorId</string>
<string name="sensor_type_key">sensorType</string>
<string name="share_url_only_key">shareUrlOnly</string>
<string name="signal_sampling_frequency_key">signalSamplingFrequency</string>
<string name="split_frequency_key">splitFrequency</string>
<string name="backup_to_sd_key">backupToSd</string>
<string name="restore_from_sd_key">restoreFromSd</string>
<string name="backup_to_cloud_key">backupToCloud</string>
</resources>
+50 -1
View File
@@ -122,6 +122,7 @@ limitations under the License.
<string name="tracklist_save_as_gpx">Save a GPX file</string>
<string name="tracklist_save_as_kml">Save a KML file</string>
<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_mymaps">Send to Google My Maps</string>
<string name="tracklist_btn_delete_all">Delete all tracks</string>
<!-- Export All -->
@@ -135,6 +136,7 @@ limitations under the License.
<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>
<string name="tracklist_share_tcx_file">A TCX file</string>
<string name="tracklist_clear_map">Clear map</string>
<!-- Waypoints list -->
@@ -205,6 +207,18 @@ limitations under the License.
<string name="settings_split_frequency_summary">Maximum time or distance after which a new split marker will be inserted</string>
<string name="pace_label">Pace</string>
<string name="eclair_required">Only supported in Android 2.0 or above</string>
<string name="settings_sensor_type">Sensor Type</string>
<string name="settings_sensor_type_summary">The type of sensor to connect to.</string>
<string name="settings_sensor_id">Sensor Id</string>
<string name="settings_sensor_id_summary">The Id sent to sensors.</string>
<string name="sensor_id_malformed">The Id must be an integer value.</string>
<string name="bluetooth_sensor_title">Bluetooth sensor</string>
<string name="bluetooth_sensor_summary">The bluetooth sensor to connect to.</string>
<string name="settings_modular_stats_display_title">Modular Stats Display</string>
<string name="settings_modular_stats_display_summary_on">The stats screen is split in various modes.</string>
<string name="settings_modular_stats_display_summary_off">Display all stats on one screen</string>
<string name="settings_backup">Backup</string>
<string name="settings_sd_backup">SD Card Backup</string>
<string name="settings_backup_to_sd">Backup now</string>
@@ -310,6 +324,7 @@ limitations under the License.
<string name="minutes">minutes</string>
<string name="second">second</string>
<string name="seconds">seconds</string>
<string name="milliseconds">ms</string>
<!-- Distance -->
<string name="meter">m</string>
@@ -329,6 +344,12 @@ limitations under the License.
<string name="min_per_mile">min/mi</string>
<string name="per_mile">per mile</string>
<!-- Power -->
<string name="watts">W</string>
<string name="revolutions_per_minute">rpm</string>
<string name="bpm">bpm</string>
<!-- Stats Labels -->
<string name="moving_time_label">Moving Time</string>
<string name="total_time_label">Total Time</string>
@@ -339,6 +360,10 @@ limitations under the License.
<string name="statistics">Statistics</string>
<string name="total_distance_label">Total Distance</string>
<string name="distance_label">Distance</string>
<string name="power">Power</string>
<string name="cadence">Cadence</string>
<string name="heart_rate">Heart Rate</string>
<string name="max_heart_rate">Max Heart Rate</string>
<string name="unknown">-</string>
<string name="waiting">Waiting...</string>
@@ -356,7 +381,6 @@ limitations under the License.
<string name="about_support">Support:</string>
<!-- DO NOT TRANSLATE -->
<string name="version">1.0.14</string>
<string name="about_googlegroups">mytracks@googlegroups.com</string>
<string name="about_weburl">mytracks.appspot.com</string>
<string name="about_copyright_message">Copyright 2009 Google Inc.</string>
@@ -424,4 +448,29 @@ limitations under the License.
<string name="gsm_strength">GSM Strength: %1$d</string>
<string name="cdma_strength">CDMA Strength: %1$d dBm</string>
<string name="evdo_strength">EVDO Strength: %1$d dBm</string>
<!-- Fake preference keys - never saved, but show options in the preferences screen -->
<string name="method_bluetooth">Bluetooth</string>
<string name="bluetooth_options">Bluetooth options</string>
<string name="bluetooth_pairing">Device pairing</string>
<string name="bluetooth_pairing_summary">Open Android\'s bluetooth settings to pair a device</string>
<string name="sensor_bluetooth_options_key">bluetoothSensorsEnabled</string>
<string name="sensor_options">Sensor Options</string>
<!-- Sensor Types => DO NOT TRANSLATE -->
<string name="none">NONE</string>
<string name="ant_sensor_type">ANT</string>
<string name="srm_sensor_type">SRM</string>
<string name="athlosoft_sensor_type">ATHLOSOFT</string>
<!-- Bluetooth Sensor -->
<string name="bluetooth_connected">Connected to %s</string>
<string name="bluetooth_connecting">Bluetooth sensor connecting ...</string>
<string name="bluetooth_not_connected">Bluetooth sensor not connected</string>
<!-- Sensor State -->
<string name="sensor_data_time">Sensor Data Time</string>
<string name="power_meter_enabled">Power meter enabled</string>
<string name="heart_rate_monitor_enabled">Heart rate monitor enabled</string>
</resources>
+20 -20
View File
@@ -18,26 +18,26 @@ limitations under the License.
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Display settings -->
<PreferenceCategory android:title="@string/settings_display">
<PreferenceScreen android:title="@string/settings_display">
<CheckBoxPreference
android:key="metricUnits"
android:key="@string/metric_units_key"
android:title="@string/settings_metric_units"
android:summaryOn="@string/settings_metric_units_summary_on"
android:summaryOff="@string/settings_metric_units_summary_off"
android:defaultValue="true" />
<CheckBoxPreference
android:key="reportSpeed"
android:key="@string/report_speed_key"
android:title="@string/settings_report_speed_or_pace"
android:summaryOn="@string/settings_report_speed_or_pace_summary_on"
android:summaryOff="@string/settings_report_speed_or_pace_summary_off"
android:defaultValue="true" />
</PreferenceCategory>
</PreferenceScreen>
<!-- Recording settings -->
<PreferenceCategory android:title="@string/settings_recording">
<PreferenceScreen android:title="@string/settings_recording">
<com.google.android.apps.mytracks.IntegerListPreference
android:key="announcementFrequency"
android:key="@string/announcement_frequency_key"
android:title="@string/settings_announcement_frequency"
android:summary="@string/settings_announcement_frequency_summary"
android:entries="@array/task_frequency_options"
@@ -45,7 +45,7 @@ limitations under the License.
android:defaultValue="-1" />
<com.google.android.apps.mytracks.IntegerListPreference
android:key="splitFrequency"
android:key="@string/split_frequency_key"
android:title="@string/settings_split_frequency"
android:summary="@string/settings_split_frequency_summary"
android:entries="@array/split_frequency_options"
@@ -53,7 +53,7 @@ limitations under the License.
android:defaultValue="0" />
<com.google.android.apps.mytracks.IntegerListPreference
android:key="minRecordingInterval"
android:key="@string/min_recording_interval_key"
android:title="@string/settings_min_recording_interval"
android:summary="@string/settings_min_recording_interval_summary"
android:entries="@array/min_recording_interval_options"
@@ -61,7 +61,7 @@ limitations under the License.
android:defaultValue="0" />
<com.google.android.apps.mytracks.IntegerListPreference
android:key="minRecordingDistance"
android:key="@string/min_recording_distance_key"
android:title="@string/settings_min_recording_distance"
android:summary="@string/settings_min_recording_distance_summary"
android:entries="@array/min_recording_distance_options"
@@ -69,7 +69,7 @@ limitations under the License.
android:defaultValue="5" />
<com.google.android.apps.mytracks.IntegerListPreference
android:key="maxRecordingDistance"
android:key="@string/max_recording_distance_key"
android:title="@string/settings_max_recording_distance"
android:summary="@string/settings_max_recording_distance_summary"
android:entries="@array/max_recording_distance_options"
@@ -77,7 +77,7 @@ limitations under the License.
android:defaultValue="200" />
<com.google.android.apps.mytracks.IntegerListPreference
android:key="minRequiredAccuracy"
android:key="@string/min_required_accuracy_key"
android:title="@string/settings_min_required_accuracy"
android:summary="@string/settings_min_required_accuracy_summary"
android:entries="@array/min_required_accuracy_options"
@@ -85,48 +85,48 @@ limitations under the License.
android:defaultValue="200" />
<com.google.android.apps.mytracks.IntegerListPreference
android:key="signalSamplingFrequency"
android:key="@string/signal_sampling_frequency_key"
android:title="@string/settings_signal_sampling_frequency"
android:summary="@string/settings_signal_sampling_frequency_summary"
android:entries="@array/task_frequency_options"
android:entryValues="@array/task_frequency_values"
android:defaultValue="-1" />
</PreferenceCategory>
</PreferenceScreen>
<!-- Sharing settings -->
<PreferenceCategory android:title="@string/settings_sharing">
<PreferenceScreen android:title="@string/settings_sharing">
<CheckBoxPreference
android:key="defaultMapPublic"
android:key="@string/default_map_public_key"
android:title="@string/settings_map_public"
android:summaryOn="@string/settings_map_public_summary_on"
android:summaryOff="@string/settings_map_public_summary_off"
android:defaultValue="true" />
<CheckBoxPreference
android:key="shareUrlOnly"
android:key="@string/share_url_only_key"
android:title="@string/settings_share_url_only"
android:summaryOn="@string/settings_share_url_only_summary_on"
android:summaryOff="@string/settings_share_url_only_summary_off"
android:defaultValue="false" />
</PreferenceCategory>
</PreferenceScreen>
<!-- Backup settings -->
<PreferenceScreen android:title="@string/settings_backup">
<PreferenceCategory android:title="@string/settings_sd_backup">
<Preference
android:key="backupToSd"
android:key="@string/backup_to_sd_key"
android:title="@string/settings_backup_to_sd"
android:summary="@string/settings_backup_to_sd_summary"
android:persistent="false" />
<Preference
android:key="restoreFromSd"
android:key="@string/restore_from_sd_key"
android:title="@string/settings_restore_from_sd"
android:summary="@string/settings_restore_from_sd_summary"
android:persistent="false" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/settings_cloud_backup">
<CheckBoxPreference
android:key="backupToCloud"
android:key="@string/backup_to_cloud_key"
android:title="@string/settings_backup_to_cloud"
android:summaryOn="@string/settings_backup_to_cloud_summary_on"
android:summaryOff="@string/settings_backup_to_cloud_summary_off"
@@ -29,6 +29,9 @@ import android.app.Dialog;
import android.app.TabActivity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
@@ -80,7 +83,17 @@ public class VersionChecker {
final boolean newVersion; // Returned new version available
final boolean newVersionRecommended; // Returned new version recommended
final boolean newVersionRequired; // Returned new version required
String currentVersion = parentActivity.getString(R.string.version);
String currentVersion = "";
try {
PackageInfo pi =
parentActivity.getPackageManager().getPackageInfo(
"com.google.android.maps.mytracks",
PackageManager.GET_META_DATA);
currentVersion = pi.versionName;
} catch (NameNotFoundException e) {
Log.w(MyTracksConstants.TAG, "Failed to get version info.", e);
return;
}
GDataParser parser = client.getParserForFeed(
Entry.class,
@@ -1,12 +1,12 @@
/*
* 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
@@ -49,7 +49,7 @@ import java.util.ArrayList;
/**
* An activity that displays a chart from the track point provider.
*
*
* @author Sandor Dornbush
*/
public class ChartActivity extends Activity implements
@@ -204,23 +204,27 @@ public class ChartActivity extends Activity implements
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key != null) {
if (key.equals(MyTracksSettings.SELECTED_TRACK)) {
if (key.equals(getString(R.string.selected_track_key))) {
selectedTrackId =
sharedPreferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
sharedPreferences.getLong(getString(R.string.selected_track_key),
-1);
readProfileAsync();
} else if (key.equals(MyTracksSettings.METRIC_UNITS)) {
} else if (key.equals(getString(R.string.metric_units_key))) {
metricUnits =
sharedPreferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
sharedPreferences.getBoolean(getString(R.string.metric_units_key),
true);
cv.setMetricUnits(metricUnits);
readProfileAsync();
} else if (key.equals(MyTracksSettings.REPORT_SPEED)) {
} else if (key.equals(getString(R.string.report_speed_key))) {
reportSpeed =
sharedPreferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
sharedPreferences.getBoolean(getString(R.string.report_speed_key),
true);
cv.setReportSpeed(reportSpeed, this);
readProfileAsync();
} else if (key.equals(MyTracksSettings.RECORDING_TRACK)) {
} else if (key.equals(getString(R.string.recording_track_key))) {
recordingTrackId =
sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
sharedPreferences.getLong(getString(R.string.recording_track_key),
-1);
runOnUiThread(updateChart);
}
}
@@ -246,12 +250,14 @@ public class ChartActivity extends Activity implements
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
selectedTrackId =
preferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
preferences.getLong(getString(R.string.selected_track_key), -1);
recordingTrackId =
preferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
preferences.getLong(getString(R.string.recording_track_key), -1);
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key),
true);
cv.setMetricUnits(metricUnits);
reportSpeed = preferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
reportSpeed = preferences.getBoolean(getString(R.string.report_speed_key),
true);
cv.setReportSpeed(reportSpeed, this);
preferences.registerOnSharedPreferenceChangeListener(this);
}
@@ -450,7 +456,7 @@ public class ChartActivity extends Activity implements
* data[0] = the time or distance
* data[1] = the elevation
* data[2] = the speed
*
*
* @param location a location
* @return the data point
*/
@@ -109,7 +109,8 @@ public class ExportAllTracks {
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
long recordingTrackId = -1;
if (prefs != null) {
recordingTrackId = prefs.getLong(MyTracksSettings.RECORDING_TRACK, -1);
recordingTrackId =
prefs.getLong(context.getString(R.string.recording_track_key), -1);
}
if (recordingTrackId != -1) {
acquireWakeLock();
@@ -0,0 +1,93 @@
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks;
import com.google.android.maps.mytracks.R;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
/**
* Manage the application menus.
*
* @author Sandor Dornbush
*/
class MenuManager {
private MyTracks activity;
public MenuManager(MyTracks activity) {
this.activity = activity;
}
public boolean onCreateOptionsMenu(Menu menu) {
activity.getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onPrepareOptionsMenu(Menu menu, boolean hasRecorded,
boolean isRecording, boolean hasSelectedTrack) {
menu.findItem(R.id.menu_list_tracks).setEnabled(hasRecorded);
menu.findItem(R.id.menu_list_markers)
.setEnabled(hasRecorded && hasSelectedTrack);
MenuItem startRecording = menu.findItem(R.id.menu_start_recording);
startRecording.setEnabled(!isRecording);
startRecording.setVisible(!isRecording);
MenuItem stopRecording = menu.findItem(R.id.menu_stop_recording);
stopRecording.setEnabled(isRecording);
stopRecording.setVisible(isRecording);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_start_recording: {
activity.startRecording();
return true;
}
case R.id.menu_stop_recording: {
activity.stopRecording();
return true;
}
case R.id.menu_list_tracks: {
Intent startIntent = new Intent(activity, MyTracksList.class);
activity.startActivityForResult(startIntent, MyTracksConstants.SHOW_TRACK);
return true;
}
case R.id.menu_list_markers: {
Intent startIntent = new Intent(activity, MyTracksWaypointsList.class);
startIntent.putExtra("trackid", activity.getSelectedTrack());
activity.startActivityForResult(startIntent, MyTracksConstants.SHOW_WAYPOINT);
return true;
}
case R.id.menu_settings: {
Intent startIntent = new Intent(activity, MyTracksSettings.class);
activity.startActivity(startIntent);
return true;
}
case R.id.menu_help: {
Intent startIntent = new Intent(activity, WelcomeActivity.class);
activity.startActivity(startIntent);
return true;
}
case MyTracksConstants.MENU_CLEAR_MAP: {
activity.setSelectedTrack(-1);
return true;
}
}
return false;
}
}
@@ -135,15 +135,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
private ChartSettingsDialog chartSettingsDialog;
/*
* Menu items:
* Menu manager.
*/
private MenuItem startRecording;
private MenuItem stopRecording;
private MenuItem listTracks;
private MenuItem listMarkers;
private MenuItem settings;
private MenuItem help;
private MenuManager menuManager;
/*
* Information on upload success to MyMaps/Docs.
@@ -284,6 +278,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
super.onCreate(savedInstanceState);
instance = this;
providerUtils = MyTracksProviderUtils.Factory.get(this);
menuManager = new MenuManager(this);
// The volume we want to control is the Text-To-Speech volume
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
@@ -322,8 +317,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
SharedPreferences prefs =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (prefs != null) {
selectedTrackId = prefs.getLong(MyTracksSettings.SELECTED_TRACK, -1);
recordingTrackId = prefs.getLong(MyTracksSettings.RECORDING_TRACK, -1);
selectedTrackId =
prefs.getLong(getString(R.string.selected_track_key), -1);
recordingTrackId =
prefs.getLong(getString(R.string.recording_track_key), -1);
prefs.registerOnSharedPreferenceChangeListener(this);
}
@@ -417,81 +414,21 @@ public class MyTracks extends TabActivity implements OnTouchListener,
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
startRecording = menu.add(0, MyTracksConstants.MENU_START_RECORDING, 0,
R.string.start_recording);
startRecording.setIcon(R.drawable.menu_record);
stopRecording = menu.add(0, MyTracksConstants.MENU_STOP_RECORDING, 0,
R.string.stop_recording);
stopRecording.setIcon(R.drawable.menu_stop);
listTracks = menu.add(0, MyTracksConstants.MENU_LIST_TRACKS, 0,
R.string.list_tracks);
listTracks.setIcon(R.drawable.menu_list_tracks);
listMarkers = menu.add(0, MyTracksConstants.MENU_LIST_MARKERS, 0,
R.string.list_markers);
listMarkers.setIcon(R.drawable.menu_marker);
settings = menu.add(0, MyTracksConstants.MENU_SETTINGS, 10001,
R.string.settings);
settings.setIcon(android.R.drawable.ic_menu_preferences);
help = menu.add(0, MyTracksConstants.MENU_HELP, 10002, R.string.help);
help.setIcon(android.R.drawable.ic_menu_info_details);
return true;
return menuManager.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean hasRecorded = providerUtils.getLastTrack() != null;
boolean isRecording = isRecording();
listTracks = menu.findItem(MyTracksConstants.MENU_LIST_TRACKS);
listTracks.setEnabled(hasRecorded);
listMarkers = menu.findItem(MyTracksConstants.MENU_LIST_MARKERS);
listMarkers.setEnabled(hasRecorded && selectedTrackId >= 0);
startRecording = menu.findItem(MyTracksConstants.MENU_START_RECORDING);
startRecording.setEnabled(!isRecording);
startRecording.setVisible(!isRecording);
stopRecording = menu.findItem(MyTracksConstants.MENU_STOP_RECORDING);
stopRecording.setEnabled(isRecording);
stopRecording.setVisible(isRecording);
menuManager.onPrepareOptionsMenu(menu, providerUtils.getLastTrack() != null,
isRecording(), selectedTrackId >= 0);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MyTracksConstants.MENU_START_RECORDING: {
startRecording();
return true;
}
case MyTracksConstants.MENU_STOP_RECORDING: {
stopRecording();
return true;
}
case MyTracksConstants.MENU_LIST_TRACKS: {
Intent startIntent = new Intent(this, MyTracksList.class);
startActivityForResult(startIntent, MyTracksConstants.SHOW_TRACK);
return true;
}
case MyTracksConstants.MENU_LIST_MARKERS: {
Intent startIntent = new Intent(this, MyTracksWaypointsList.class);
startIntent.putExtra("trackid", selectedTrackId);
startActivityForResult(startIntent, MyTracksConstants.SHOW_WAYPOINT);
return true;
}
case MyTracksConstants.MENU_SETTINGS: {
Intent startIntent = new Intent(this, MyTracksSettings.class);
startActivity(startIntent);
return true;
}
case MyTracksConstants.MENU_HELP: {
Intent startIntent = new Intent(this, WelcomeActivity.class);
startActivity(startIntent);
return true;
}
case MyTracksConstants.MENU_CLEAR_MAP: {
setSelectedTrack(-1);
return true;
}
}
return super.onOptionsItemSelected(item);
return (menuManager.onOptionsItemSelected(item)
? true
: super.onOptionsItemSelected(item));
}
/*
@@ -788,8 +725,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
case MyTracksConstants.SAVE_KML_FILE:
if (exportFormat == null) { exportFormat = TrackFileFormat.KML; }
//$FALL-THROUGH$
case MyTracksConstants.SAVE_CSV_FILE: {
case MyTracksConstants.SAVE_CSV_FILE:
if (exportFormat == null) { exportFormat = TrackFileFormat.CSV; }
//$FALL-THROUGH$
case MyTracksConstants.SAVE_TCX_FILE:
if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
if (results != null && resultCode == Activity.RESULT_OK) {
final long trackId = results.getLongExtra("trackid", selectedTrackId);
@@ -798,7 +738,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
}
break;
}
case MyTracksConstants.SHARE_LINK: {
Track selectedTrack = providerUtils.getTrack(selectedTrackId);
if (selectedTrack != null) {
@@ -812,15 +751,21 @@ public class MyTracks extends TabActivity implements OnTouchListener,
break;
}
case MyTracksConstants.SHARE_GPX_FILE:
case MyTracksConstants.SHARE_KML_FILE: {
if (results != null && resultCode == RESULT_OK) {
long trackId = results.getLongExtra("trackid", selectedTrackId);
if (exportFormat == null) { exportFormat = TrackFileFormat.GPX; }
//$FALL-THROUGH$
case MyTracksConstants.SHARE_KML_FILE:
if (exportFormat == null) { exportFormat = TrackFileFormat.KML; }
//$FALL-THROUGH$
case MyTracksConstants.SHARE_CSV_FILE:
if (exportFormat == null) { exportFormat = TrackFileFormat.CSV; }
//$FALL-THROUGH$
case MyTracksConstants.SHARE_TCX_FILE: {
if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
if (results != null && resultCode == Activity.RESULT_OK) {
final long trackId = results.getLongExtra("trackid", selectedTrackId);
if (trackId >= 0) {
TrackFileFormat format =
(requestCode == MyTracksConstants.SHARE_GPX_FILE)
? TrackFileFormat.GPX
: TrackFileFormat.KML;
sendTrack(trackId, format);
sendTrack(trackId, exportFormat);
}
}
break;
@@ -863,9 +808,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
+ "to shared preferences: ", e);
}
}
if (key != null && key.equals(MyTracksSettings.SELECTED_TRACK)) {
if (key != null && key.equals(getString(R.string.selected_track_key))) {
selectedTrackId =
sharedPreferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
sharedPreferences.getLong(getString(R.string.selected_track_key), -1);
}
}
@@ -1070,7 +1015,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
boolean shareUrlOnly = true;
if (prefs != null) {
shareUrlOnly = prefs.getBoolean(MyTracksSettings.SHARE_URL_ONLY, false);
shareUrlOnly =
prefs.getBoolean(getString(R.string.share_url_only_key), false);
}
String url = MyMapsConstants.MAPSHOP_BASE_URL + "?msa=0&msid=" + mapId;
@@ -1293,7 +1239,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
* Starts the track recording service (if not already running) and binds to
* it. Starts recording a new track.
*/
private void startRecording() {
public void startRecording() {
if (trackRecordingService == null) {
startNewTrackRequested = true;
Intent startIntent = new Intent(this, TrackRecordingService.class);
@@ -1319,7 +1265,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
* Stops the track recording service and unbinds from it. Will display a toast
* "Stopped recording" and pop up the Track Details activity.
*/
private void stopRecording() {
public void stopRecording() {
if (trackRecordingService != null) {
try {
trackRecordingService.endCurrentTrack();
@@ -1378,18 +1324,22 @@ public class MyTracks extends TabActivity implements OnTouchListener,
*
* @param trackId the id of the track
*/
private void setSelectedTrack(final long trackId) {
public void setSelectedTrack(final long trackId) {
runOnUiThread(new Runnable() {
public void run() {
SharedPreferences prefs =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong(MyTracksSettings.SELECTED_TRACK, trackId);
editor.putLong(getString(R.string.selected_track_key), trackId);
editor.commit();
}
});
}
protected long getSelectedTrack() {
return selectedTrackId;
}
/**
* Writes the recording track id to the shared preferences.
* Executed on the UI thread.
@@ -1402,7 +1352,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
SharedPreferences prefs =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong(MyTracksSettings.RECORDING_TRACK, trackId);
editor.putLong(getString(R.string.recording_track_key), trackId);
editor.commit();
}
});
@@ -1420,8 +1370,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (prefs != null) {
SharedPreferences.Editor editor = prefs.edit();
editor.putLong(MyTracksSettings.SELECTED_TRACK, theSelectedTrackId);
editor.putLong(MyTracksSettings.RECORDING_TRACK, theRecordingTrackId);
editor.putLong(getString(R.string.selected_track_key), theSelectedTrackId);
editor.putLong(getString(R.string.recording_track_key), theRecordingTrackId);
editor.commit();
}
}
@@ -67,29 +67,25 @@ public abstract class MyTracksConstants {
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 EDIT_DETAILS = 18;
public static final int SAVE_GPX_FILE = 19;
public static final int SAVE_KML_FILE = 20;
public static final int SAVE_CSV_FILE = 21;
public static final int CLEAR_MAP = 22;
public static final int SHOW_WAYPOINT = 23;
public static final int EDIT_WAYPOINT = 24;
public static final int WELCOME = 25;
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;
/*
* Menu ids:
*/
public static final int MENU_START_RECORDING = 1;
public static final int MENU_STOP_RECORDING = 2;
public static final int MENU_LIST_TRACKS = 3;
public static final int MENU_LIST_MARKERS = 4;
public static final int MENU_SETTINGS = 5;
public static final int MENU_MY_LOCATION = 6;
public static final int MENU_TOGGLE_LAYERS = 7;
public static final int MENU_CHART_SETTINGS = 8;
public static final int MENU_HELP = 9;
public static final int MENU_CURRENT_SEGMENT = 10;
public static final int MENU_MY_LOCATION = 1;
public static final int MENU_TOGGLE_LAYERS = 2;
public static final int MENU_CHART_SETTINGS = 3;
public static final int MENU_CURRENT_SEGMENT = 4;
/*
* Context menu ids:
@@ -104,11 +100,13 @@ public abstract class MyTracksConstants {
public static final int MENU_SHARE_GPX_FILE = 201;
public static final int MENU_SHARE_KML_FILE = 202;
public static final int MENU_SHARE_CSV_FILE = 203;
public static final int MENU_WRITE_TO_SD_CARD = 204;
public static final int MENU_SAVE_GPX_FILE = 205;
public static final int MENU_SAVE_KML_FILE = 206;
public static final int MENU_SAVE_CSV_FILE = 207;
public static final int MENU_CLEAR_MAP = 208;
public static final int MENU_SHARE_TCX_FILE = 204;
public static final int MENU_WRITE_TO_SD_CARD = 205;
public static final int MENU_SAVE_GPX_FILE = 206;
public static final int MENU_SAVE_KML_FILE = 207;
public static final int MENU_SAVE_CSV_FILE = 208;
public static final int MENU_SAVE_TCX_FILE = 209;
public static final int MENU_CLEAR_MAP = 210;
/**
* The number of distance readings to smooth to get a stable signal.
@@ -136,6 +134,12 @@ public abstract class MyTracksConstants {
*/
public static final int MAX_DISPLAYED_TRACK_POINTS = 10000;
/**
* Target number of track points displayed by the map overlay.
* We may display more than this number of points.
*/
public static final int TARGET_DISPLAYED_TRACK_POINTS = 5000;
/**
* Maximum number of track points ever loaded at once from the provider into
* memory.
@@ -192,12 +196,16 @@ public abstract class MyTracksConstants {
return MyTracksConstants.SHARE_GPX_FILE;
case MyTracksConstants.MENU_SHARE_CSV_FILE:
return MyTracksConstants.SHARE_CSV_FILE;
case MyTracksConstants.MENU_SHARE_TCX_FILE:
return MyTracksConstants.SHARE_TCX_FILE;
case MyTracksConstants.MENU_SAVE_GPX_FILE:
return MyTracksConstants.SAVE_GPX_FILE;
case MyTracksConstants.MENU_SAVE_KML_FILE:
return MyTracksConstants.SAVE_KML_FILE;
case MyTracksConstants.MENU_SAVE_CSV_FILE:
return MyTracksConstants.SAVE_CSV_FILE;
case MyTracksConstants.MENU_SAVE_TCX_FILE:
return MyTracksConstants.SAVE_TCX_FILE;
case MyTracksConstants.MENU_CLEAR_MAP:
return MyTracksConstants.CLEAR_MAP;
default:
@@ -62,7 +62,7 @@ public class MyTracksDeleteAllTracks extends Handler {
SharedPreferences prefs =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong(MyTracksSettings.SELECTED_TRACK, -1);
editor.putLong(context.getString(R.string.selected_track_key), -1);
editor.commit();
if (done != null) {
Handler h = new Handler();
@@ -90,6 +90,8 @@ public class MyTracksList extends ListActivity
R.string.tracklist_share_kml_file);
share.add(0, MyTracksConstants.MENU_SHARE_CSV_FILE, 0,
R.string.tracklist_share_csv_file);
share.add(0, MyTracksConstants.MENU_SHARE_TCX_FILE, 0,
R.string.tracklist_share_tcx_file);
SubMenu save = menu.addSubMenu(0,
MyTracksConstants.MENU_WRITE_TO_SD_CARD, 0,
R.string.tracklist_write_to_sd);
@@ -99,6 +101,8 @@ public class MyTracksList extends ListActivity
R.string.tracklist_save_as_kml);
save.add(0, MyTracksConstants.MENU_SAVE_CSV_FILE, 0,
R.string.tracklist_save_as_csv);
save.add(0, MyTracksConstants.MENU_SAVE_TCX_FILE, 0,
R.string.tracklist_save_as_tcx);
menu.add(0, MyTracksConstants.MENU_DELETE, 0,
R.string.tracklist_delete_track);
}
@@ -111,14 +115,16 @@ public class MyTracksList extends ListActivity
if (key == null) {
return;
}
if (key.equals(MyTracksSettings.METRIC_UNITS)) {
metricUnits = sharedPreferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
if (key.equals(getString(R.string.metric_units_key))) {
metricUnits = sharedPreferences.getBoolean(
getString(R.string.metric_units_key), true);
if (tracksCursor != null && !tracksCursor.isClosed()) {
tracksCursor.requery();
}
}
if (key.equals(MyTracksSettings.RECORDING_TRACK)) {
recordingTrackId = sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
if (key.equals(getString(R.string.recording_track_key))) {
recordingTrackId = sharedPreferences.getLong(
getString(R.string.recording_track_key), -1);
}
}
@@ -193,9 +199,10 @@ public class MyTracksList extends ListActivity
SharedPreferences preferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
preferences.registerOnSharedPreferenceChangeListener(this);
metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
metricUnits =
preferences.getBoolean(getString(R.string.metric_units_key), true);
recordingTrackId =
preferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
preferences.getLong(getString(R.string.recording_track_key), -1);
tracksCursor = getContentResolver().query(
TracksColumns.CONTENT_URI, null, null, null, "_id DESC");
@@ -136,6 +136,11 @@ public class MyTracksMap extends MapActivity
private Handler updateTrackHandler;
private MyTracksProviderUtils providerUtils;
/**
* This value is used to decide how many points to display.
*/
private int samplingFrequency = 1;
/**
* A runnable that updates the track from the provider (looking for points
@@ -147,35 +152,7 @@ public class MyTracksMap extends MapActivity
if (selectedTrack == null) {
return;
}
Cursor cursor = null;
try {
cursor = providerUtils.getLocationsCursor(
recordingTrackId,
lastSeenLocationId + 1,
MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS
- selectedTrack.getLocations().size(),
true);
if (cursor != null) {
if (cursor.moveToLast()) {
final int idColumnIdx =
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
do {
lastSeenLocationId = cursor.getLong(idColumnIdx);
Location location = providerUtils.createLocation(cursor);
if (location != null) {
selectedTrack.addLocation(location);
}
} while (cursor.moveToPrevious());
}
}
} catch (RuntimeException e) {
Log.w(MyTracksConstants.TAG, "Caught an unexpected exception: ", e);
} finally {
if (cursor != null) {
cursor.close();
}
mapView.postInvalidate();
}
readAllNewTrackPoints();
}
};
@@ -188,9 +165,9 @@ public class MyTracksMap extends MapActivity
if (selectedTrack == null) {
return;
}
lastSeenLocationId = providerUtils.getTrackPoints(selectedTrack,
MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS);
mapView.postInvalidate();
mapOverlay.clearPoints();
lastSeenLocationId = selectedTrack.getStartId();
readAllNewTrackPoints();
}
};
@@ -380,12 +357,12 @@ public class MyTracksMap extends MapActivity
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
minRequiredAccuracy = preferences.getInt(
MyTracksSettings.MIN_REQUIRED_ACCURACY,
getString(R.string.min_required_accuracy_key),
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY);
recordingTrackId =
preferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
preferences.getLong(getString(R.string.recording_track_key), -1);
long selectedTrackId =
preferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
preferences.getLong(getString(R.string.selected_track_key), -1);
if (selectedTrackId >= 0) {
setSelectedTrack(selectedTrackId);
}
@@ -783,6 +760,8 @@ public class MyTracksMap extends MapActivity
R.string.tracklist_share_kml_file);
share.add(0, MyTracksConstants.MENU_SHARE_CSV_FILE, 0,
R.string.tracklist_share_csv_file);
share.add(0, MyTracksConstants.MENU_SHARE_TCX_FILE, 0,
R.string.tracklist_share_tcx_file);
SubMenu save = menu.addSubMenu(0,
MyTracksConstants.MENU_WRITE_TO_SD_CARD, 0,
R.string.tracklist_write_to_sd);
@@ -792,6 +771,8 @@ public class MyTracksMap extends MapActivity
R.string.tracklist_save_as_kml);
save.add(0, MyTracksConstants.MENU_SAVE_CSV_FILE, 0,
R.string.tracklist_save_as_csv);
save.add(0, MyTracksConstants.MENU_SAVE_TCX_FILE, 0,
R.string.tracklist_save_as_tcx);
menu.add(0, MyTracksConstants.MENU_CLEAR_MAP, 0,
R.string.tracklist_clear_map);
menu.add(0, MyTracksConstants.MENU_DELETE, 0,
@@ -888,17 +869,19 @@ public class MyTracksMap extends MapActivity
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key != null) {
if (key.equals(MyTracksSettings.MIN_REQUIRED_ACCURACY)) {
if (key.equals(getString(R.string.min_required_accuracy_key))) {
minRequiredAccuracy = sharedPreferences.getInt(
MyTracksSettings.MIN_REQUIRED_ACCURACY,
getString(R.string.min_required_accuracy_key),
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY);
} else if (key.equals(MyTracksSettings.SELECTED_TRACK)) {
} else if (key.equals(getString(R.string.selected_track_key))) {
long selectedTrackId =
sharedPreferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
sharedPreferences.getLong(getString(R.string.selected_track_key),
-1);
setSelectedTrack(selectedTrackId);
} else if (key.equals(MyTracksSettings.RECORDING_TRACK)) {
} else if (key.equals(getString(R.string.recording_track_key))) {
recordingTrackId =
sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
sharedPreferences.getLong(getString(R.string.recording_track_key),
-1);
if (selectedTrack != null) {
mapOverlay.setShowEndMarker(
selectedTrack.getId() != recordingTrackId);
@@ -977,4 +960,63 @@ public class MyTracksMap extends MapActivity
public void onAccuracyChanged(Sensor s, int accuracy) {
// do nothing
}
/**
* Set the sampling frequency from the total number of points in the track.
*
* @param track The track to read the total number of points from.
*/
private void setSamplingFrequency(Track track) {
long totalLocations = track.getStopId() - track.getStartId();
// Limit the number of map points readings.
samplingFrequency =
(int) (1 +
totalLocations / MyTracksConstants.TARGET_DISPLAYED_TRACK_POINTS);
Log.i(MyTracksConstants.TAG, "Sampling locations: " + samplingFrequency);
}
private void readAllNewTrackPoints() {
Cursor cursor = null;
// Refetch the track to get the latest StopId
selectedTrack = providerUtils.getTrack(selectedTrack.getId());
long totalLocations = selectedTrack.getStopId() -
selectedTrack.getStartId();
setSamplingFrequency(selectedTrack);
int bufferSize = 1024;
int points = 0;
while (lastSeenLocationId < selectedTrack.getStopId()) {
cursor = providerUtils.getLocationsCursor(
selectedTrack.getId(), lastSeenLocationId, bufferSize, false);
if (cursor != null && cursor.moveToFirst()) {
final int idColumnIdx = cursor.getColumnIndexOrThrow(
TrackPointsColumns._ID);
while (cursor.moveToNext()) {
points++;
Location location = providerUtils.createLocation(cursor);
lastSeenLocationId = cursor.getLong(idColumnIdx);
// Include a point if it fits one of the following criteria:
// - Has the mod for the sampling frequency.
// - Is the first point.
// - Is the last point and we are not recording this track.
if (!MyTracksUtils.isValidLocation(location) ||
points % samplingFrequency == 0 ||
points == 0 ||
(recordingTrackId != selectedTrack.getId() &&
points == (totalLocations - 1))) {
mapOverlay.addLocation(location);
}
}
} else {
lastSeenLocationId += bufferSize;
}
cursor.close();
cursor = null;
}
if (cursor != null) {
cursor.close();
}
mapView.postInvalidate();
}
}
@@ -55,6 +55,7 @@ public class MyTracksOverlay extends Overlay {
private final Paint errorCirclePaint;
private final Context context;
private final ArrayList<Waypoint> waypoints = new ArrayList<Waypoint>();
private final ArrayList<Location> points = new ArrayList<Location>(1024);
private Track selectedTrack;
private int lastHeading = 0;
@@ -128,6 +129,17 @@ public class MyTracksOverlay extends Overlay {
return selectedTrack;
}
/**
* Add a location to the map overlay.
*
* NOTE: this method takes ownership of this location and may change it.
*
* @param l the location to add
*/
public void addLocation(Location l) {
points.add(l);
}
public void addWaypoint(Waypoint wpt) {
waypoints.add(wpt);
}
@@ -136,6 +148,10 @@ public class MyTracksOverlay extends Overlay {
waypoints.clear();
}
public void clearPoints() {
points.clear();
}
public void setShowEndMarker(boolean showEndMarker) {
this.showEndMarker = showEndMarker;
}
@@ -153,7 +169,8 @@ public class MyTracksOverlay extends Overlay {
// Draw the waypoints:
ArrayList<Waypoint> currentWaypoints = waypoints;
for (int i = 1; i < currentWaypoints.size(); i++) {
Location loc = currentWaypoints.get(i).getLocation();
Waypoint wpt = currentWaypoints.get(i);
Location loc = wpt.getLocation();
if (loc == null) {
continue;
}
@@ -162,7 +179,7 @@ public class MyTracksOverlay extends Overlay {
mapView.getProjection().toPixels(geoPoint, pt);
canvas.save();
canvas.translate(pt.x - (markerWidth / 2) + 3, pt.y - (markerHeight));
if (currentWaypoints.get(i).getType() == Waypoint.TYPE_STATISTICS) {
if (wpt.getType() == Waypoint.TYPE_STATISTICS) {
statsMarker.draw(canvas);
} else {
waypointMarker.draw(canvas);
@@ -196,7 +213,6 @@ public class MyTracksOverlay extends Overlay {
if (track == null) {
return;
}
ArrayList<Location> points = track.getLocations();
if (points.size() < 2) {
return;
}
@@ -206,7 +222,7 @@ public class MyTracksOverlay extends Overlay {
int h = mapView.getLatitudeSpan();
int cx = mapView.getMapCenter().getLongitudeE6();
int cy = mapView.getMapCenter().getLatitudeE6();
Rect rect = new Rect(cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2);
Rect rect = new Rect(cx - w, cy - h, cx + w, cy + h);
Point pt = new Point();
GeoPoint geoPoint;
@@ -222,14 +238,6 @@ public class MyTracksOverlay extends Overlay {
int lastLocLon = (int) (points.get(0).getLongitude() * 1E6);
int lastLocLat = (int) (points.get(0).getLatitude() * 1E6);
// Line decimation for dummies:
// Skip di additional points, where di depends on zoom level:
int di = 0;
int dl = 17 - mapView.getZoomLevel();
if (dl > 0) {
di += (dl * dl);
}
// Loop over track points:
path = new Path();
for (int i = 1; i < points.size(); i++) {
@@ -241,23 +249,6 @@ public class MyTracksOverlay extends Overlay {
locLon = (int) (loc.getLongitude() * 1E6);
locLat = (int) (loc.getLatitude() * 1E6);
// Skip to every n-th point (depends on zoom level, see above):
for (int j = 0; j < di && i < points.size() - 1; j++) {
// TODO Check the thread synchronization.
// There is no reason that points.get(i + 1) should be null but users
// have reported it causing null pointer exceptions.
if ((locLat > 90E6) ||
(lastLocLat > 90E6) ||
(points.get(i + 1) == null) ||
(points.get(i + 1).getLatitude() > 90)) {
break;
}
i++;
loc = points.get(i);
locLon = (int) (loc.getLongitude() * 1E6);
locLat = (int) (loc.getLatitude() * 1E6);
}
// Draw a line segment if it's inside the viewing window:
if (locLat < 90E6 && lastLocLat < 90E6) {
lastValidLocation = loc;
@@ -1,12 +1,12 @@
/*
* 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
@@ -39,26 +39,6 @@ public class MyTracksSettings extends PreferenceActivity {
public static final String SETTINGS_NAME = "MyTracksSettings";
public static final String ANNOUNCEMENT_FREQUENCY = "announcementFrequency";
public static final String DEFAULT_MAP_PUBLIC = "defaultMapPublic";
public static final String MAX_RECORDING_DISTANCE = "maxRecordingDistance";
public static final String METRIC_UNITS = "metricUnits";
public static final String MIN_RECORDING_DISTANCE = "minRecordingDistance";
public static final String MIN_RECORDING_INTERVAL = "minRecordingInterval";
public static final String MIN_REQUIRED_ACCURACY = "minRequiredAccuracy";
public static final String PICK_EXISTING_MAP = "pickExistingMap";
public static final String RECORDING_TRACK = "recordingTrack";
public static final String REPORT_SPEED = "reportSpeed";
public static final String SELECTED_TRACK = "selectedTrack";
public static final String SEND_STATS_AND_POINTS = "sendStatsAndPoints";
public static final String SEND_TO_DOCS = "sendToDocs";
public static final String SEND_TO_MYMAPS = "sendToMyMaps";
public static final String SHARE_URL_ONLY = "shareUrlOnly";
public static final String SIGNAL_SAMPLING_FREQUENCY =
"signalSamplingFrequency";
public static final String SPLIT_FREQUENCY = "splitFrequency";
public static final String WRITE_TO_SD_CARD = "writeToSdCard";
/*
* Default values - keep in sync with those in preferences.xml.
*/
@@ -98,7 +78,7 @@ public class MyTracksSettings extends PreferenceActivity {
// Hook up switching of displayed list entries between metric and imperial
// units
CheckBoxPreference metricUnitsPreference =
(CheckBoxPreference) findPreference(METRIC_UNITS);
(CheckBoxPreference) findPreference(getString(R.string.metric_units_key));
metricUnitsPreference.setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {
@Override
@@ -114,7 +94,8 @@ public class MyTracksSettings extends PreferenceActivity {
// Disable TTS announcement preference if not available
if (!mTTSAvailable) {
IntegerListPreference announcementFrequency =
(IntegerListPreference) findPreference(ANNOUNCEMENT_FREQUENCY);
(IntegerListPreference) findPreference(
getString(R.string.announcement_frequency_key));
announcementFrequency.setEnabled(false);
announcementFrequency.setValue("-1");
announcementFrequency.setSummary(
@@ -123,14 +104,14 @@ public class MyTracksSettings extends PreferenceActivity {
// Disable cloud backup options if not supported
if (MyTracksConstants.ANDROID_API_LEVEL < 8) {
// TODO: Merge by moving pref names to XML
CheckBoxPreference cloudBackupPreference = (CheckBoxPreference) findPreference("backupToCloud");
CheckBoxPreference cloudBackupPreference =
(CheckBoxPreference) findPreference(getString(R.string.backup_to_cloud_key));
cloudBackupPreference.setEnabled(false);
cloudBackupPreference.setChecked(false);
cloudBackupPreference.setSummaryOff(R.string.settings_not_available_summary);
}
Preference backupNowPreference = findPreference("backupToSd");
Preference backupNowPreference = findPreference(getString(R.string.backup_to_sd_key));
backupNowPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
@@ -140,7 +121,7 @@ public class MyTracksSettings extends PreferenceActivity {
}
});
Preference restoreNowPreference = findPreference("restoreFromSd");
Preference restoreNowPreference = findPreference(getString(R.string.restore_from_sd_key));
restoreNowPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
@@ -159,13 +140,17 @@ public class MyTracksSettings extends PreferenceActivity {
*/
private void updatePreferenceUnits(boolean isMetric) {
final ListPreference minRecordingDistance =
(ListPreference) findPreference(MIN_RECORDING_DISTANCE);
(ListPreference) findPreference(
getString(R.string.min_recording_distance_key));
final ListPreference maxRecordingDistance =
(ListPreference) findPreference(MAX_RECORDING_DISTANCE);
(ListPreference) findPreference(
getString(R.string.max_recording_distance_key));
final ListPreference minRequiredAccuracy =
(ListPreference) findPreference(MIN_REQUIRED_ACCURACY);
(ListPreference) findPreference(
getString(R.string.min_required_accuracy_key));
final ListPreference splitFrequency =
(ListPreference) findPreference(SPLIT_FREQUENCY);
(ListPreference) findPreference(
getString(R.string.split_frequency_key));
minRecordingDistance.setEntries(isMetric
? R.array.min_recording_distance_options
@@ -66,11 +66,11 @@ public class MyTracksWaypointDetails extends Activity
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
boolean useMetric =
preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
preferences.getBoolean(getString(R.string.metric_units_key), true);
utils.setMetricUnits(useMetric);
boolean displaySpeed =
preferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
preferences.getBoolean(getString(R.string.report_speed_key), true);
utils.setReportSpeed(displaySpeed);
utils.updateWaypointUnits();
@@ -139,9 +139,9 @@ public class MyTracksWaypointsList extends ListActivity
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
recordingTrackId =
preferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
preferences.getLong(getString(R.string.recording_track_key), -1);
selectedTrackId =
preferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
preferences.getLong(getString(R.string.selected_track_key), -1);
}
boolean selectedRecording = selectedTrackId > 0
&& selectedTrackId == recordingTrackId;
@@ -105,17 +105,25 @@ public class SendToGoogleDialog extends Dialog {
getContext().getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (prefs != null) {
sendToMyMapsCheckBox.setChecked(
prefs.getBoolean(MyTracksSettings.SEND_TO_MYMAPS, true));
prefs.getBoolean(
getContext().getString(R.string.send_to_my_maps_key), true));
sendToDocsCheckBox.setChecked(
prefs.getBoolean(MyTracksSettings.SEND_TO_DOCS, true));
prefs.getBoolean(
getContext().getString(R.string.send_to_docs_key), true));
pickMapRadioButton.setChecked(
prefs.getBoolean(MyTracksSettings.PICK_EXISTING_MAP, false));
prefs.getBoolean(
getContext().getString(R.string.pick_existing_map_key), false));
createNewMapRadioButton.setChecked(
!prefs.getBoolean(MyTracksSettings.PICK_EXISTING_MAP, false));
!prefs.getBoolean(
getContext().getString(R.string.pick_existing_map_key), false));
sendStatsAndPointsRadioButton.setChecked(
prefs.getBoolean(MyTracksSettings.SEND_STATS_AND_POINTS, false));
prefs.getBoolean(
getContext().getString(R.string.send_stats_and_points_key),
false));
sendStatsRadioButton.setChecked(
!prefs.getBoolean(MyTracksSettings.SEND_STATS_AND_POINTS, false));
!prefs.getBoolean(
getContext().getString(R.string.send_stats_and_points_key),
false));
}
}
@@ -127,13 +135,16 @@ public class SendToGoogleDialog extends Dialog {
Editor editor = prefs.edit();
if (editor != null) {
editor.putBoolean(
MyTracksSettings.SEND_TO_MYMAPS, sendToMyMapsCheckBox.isChecked());
getContext().getString(R.string.send_to_my_maps_key),
sendToMyMapsCheckBox.isChecked());
editor.putBoolean(
MyTracksSettings.SEND_TO_DOCS, sendToDocsCheckBox.isChecked());
getContext().getString(R.string.send_to_docs_key),
sendToDocsCheckBox.isChecked());
editor.putBoolean(
MyTracksSettings.PICK_EXISTING_MAP, pickMapRadioButton.isChecked());
getContext().getString(R.string.pick_existing_map_key),
pickMapRadioButton.isChecked());
editor.putBoolean(
MyTracksSettings.SEND_STATS_AND_POINTS,
getContext().getString(R.string.send_stats_and_points_key),
sendStatsAndPointsRadioButton.isChecked());
editor.commit();
}
@@ -1,12 +1,12 @@
/*
* 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
@@ -15,6 +15,9 @@
*/
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsImpl;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.maps.mytracks.R;
@@ -24,7 +27,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.ContentObserver;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@@ -48,23 +50,6 @@ import android.widget.Toast;
public class StatsActivity extends Activity
implements OnSharedPreferenceChangeListener, LocationListener {
/**
* Columns we need from the provider
*/
private static final String[] PROJECTION_COLUMNS = {
TracksColumns._ID,
TracksColumns.STARTTIME,
TracksColumns.TOTALTIME,
TracksColumns.MOVINGTIME,
TracksColumns.TOTALDISTANCE,
TracksColumns.AVGSPEED,
TracksColumns.AVGMOVINGSPEED,
TracksColumns.MAXSPEED,
TracksColumns.MINELEVATION,
TracksColumns.MAXELEVATION,
TracksColumns.ELEVATIONGAIN,
TracksColumns.MINGRADE,
TracksColumns.MAXGRADE };
private final StatsUtilities utils;
private UIUpdateThread thread;
@@ -109,6 +94,9 @@ public class StatsActivity extends Activity
*/
private boolean showCurrentSegment = false;
private final MyTracksProviderUtils providerUtils;
private Track track = null;
/**
* A runnable for posting to the UI thread. Will update the total time field.
*/
@@ -147,7 +135,8 @@ public class StatsActivity extends Activity
}
public StatsActivity() {
this.utils = new StatsUtilities(this);
utils = new StatsUtilities(this);
providerUtils = new MyTracksProviderUtilsImpl(this);
}
/** Called when the activity is first created. */
@@ -176,20 +165,20 @@ public class StatsActivity extends Activity
SharedPreferences preferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
selectedTrackId = preferences.getLong(MyTracksSettings.SELECTED_TRACK,
-1);
recordingTrackId = preferences.getLong(MyTracksSettings.RECORDING_TRACK,
-1);
metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS,
true);
selectedTrackId = preferences.getLong(
getString(R.string.selected_track_key), -1);
recordingTrackId = preferences.getLong(
getString(R.string.recording_track_key), -1);
metricUnits = preferences.getBoolean(
getString(R.string.metric_units_key), true);
displaySpeed =
preferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
preferences.getBoolean(getString(R.string.report_speed_key), true);
checkLiveTrack();
restoreStats();
updateLocation(null);
preferences.registerOnSharedPreferenceChangeListener(this);
}
locationManager =
locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
utils.setMetricUnits(metricUnits);
utils.setReportSpeed(displaySpeed);
@@ -231,27 +220,31 @@ public class StatsActivity extends Activity
Log.d(MyTracksConstants.TAG,
"StatsActivity: onSharedPreferences changed " + key);
if (key != null) {
if (key.equals(MyTracksSettings.SELECTED_TRACK)) {
if (key.equals(getString(R.string.selected_track_key))) {
selectedTrackId =
sharedPreferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
sharedPreferences.getLong(getString(R.string.selected_track_key),
-1);
checkLiveTrack();
restoreStats();
updateLocation(null);
} else if (key.equals(MyTracksSettings.RECORDING_TRACK)) {
} else if (key.equals(getString(R.string.recording_track_key))) {
recordingTrackId =
sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
sharedPreferences.getLong(getString(R.string.recording_track_key),
-1);
checkLiveTrack();
restoreStats();
updateLocation(null);
} else if (key.equals(MyTracksSettings.METRIC_UNITS)) {
} else if (key.equals(getString(R.string.metric_units_key))) {
metricUnits =
sharedPreferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
sharedPreferences.getBoolean(
getString(R.string.metric_units_key), true);
utils.setMetricUnits(metricUnits);
utils.updateUnits();
restoreStats();
} else if (key.equals(MyTracksSettings.REPORT_SPEED)) {
} else if (key.equals(getString(R.string.report_speed_key))) {
displaySpeed =
sharedPreferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
sharedPreferences.getBoolean(getString(R.string.report_speed_key),
true);
utils.setReportSpeed(displaySpeed);
utils.updateUnits();
utils.setSpeedLabel(
@@ -359,60 +352,13 @@ public class StatsActivity extends Activity
return;
}
Cursor cursor = null;
try {
cursor = getContentResolver().query(
showCurrentSegment
? WaypointsColumns.CONTENT_URI
: TracksColumns.CONTENT_URI,
PROJECTION_COLUMNS,
showCurrentSegment
? WaypointsColumns.TRACKID + "=" + selectedTrackId
: "_id=" + selectedTrackId,
null,
"_id LIMIT 1");
if (cursor != null && cursor.moveToFirst()) {
final int idxStartTime =
cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
final int idxTotalTime =
cursor.getColumnIndexOrThrow(TracksColumns.TOTALTIME);
final int idxMovingTime =
cursor.getColumnIndexOrThrow(TracksColumns.MOVINGTIME);
final int idxTotalDistance =
cursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE);
final int idxAverageSpeed =
cursor.getColumnIndexOrThrow(TracksColumns.AVGSPEED);
final int idxAverageMovingSpeed =
cursor.getColumnIndexOrThrow(TracksColumns.AVGMOVINGSPEED);
final int idxMaxSpeed =
cursor.getColumnIndexOrThrow(TracksColumns.MAXSPEED);
final int idxMinElevation =
cursor.getColumnIndexOrThrow(TracksColumns.MINELEVATION);
final int idxMaxElevation =
cursor.getColumnIndexOrThrow(TracksColumns.MAXELEVATION);
final int idxElevationGain =
cursor.getColumnIndexOrThrow(TracksColumns.ELEVATIONGAIN);
final int idxMinGrade =
cursor.getColumnIndexOrThrow(TracksColumns.MINGRADE);
final int idxMaxGrade =
cursor.getColumnIndexOrThrow(TracksColumns.MAXGRADE);
startTime = cursor.getLong(idxStartTime);
if (!selectedTrackIsRecording()) {
utils.setTime(R.id.total_time_register, cursor.getLong(idxTotalTime));
}
utils.setAllStats(cursor.getLong(idxMovingTime),
cursor.getFloat(idxTotalDistance), cursor.getFloat(idxAverageSpeed),
cursor.getFloat(idxAverageMovingSpeed),
cursor.getFloat(idxMaxSpeed), cursor.getFloat(idxMinElevation),
cursor.getFloat(idxMaxElevation), cursor.getFloat(idxElevationGain),
cursor.getFloat(idxMinGrade), cursor.getFloat(idxMaxGrade));
}
} finally {
if (cursor != null) {
cursor.close();
}
track = providerUtils.getTrack(selectedTrackId);
startTime = track.getStatistics().getStartTime();
if(!selectedTrackIsRecording()) {
utils.setTime(R.id.total_time_register,
track.getStatistics().getTotalTime());
}
utils.setAllStats(track.getStatistics());
}
/**
@@ -112,7 +112,9 @@ public class SendToDocs {
SharedPreferences preferences = activity.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
metricUnits =
preferences.getBoolean(activity.getString(R.string.metric_units_key),
true);
} else {
metricUnits = true;
}
@@ -264,7 +264,9 @@ public class SendToMyMaps {
MyTracksSettings.SETTINGS_NAME, 0);
boolean metricUnits = true;
if (preferences != null) {
metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
metricUnits =
preferences.getBoolean(context.getString(R.string.metric_units_key),
true);
}
// For the progress monitor:
@@ -390,7 +392,7 @@ public class SendToMyMaps {
boolean mapPublic = true;
if (preferences != null) {
mapPublic = preferences.getBoolean(
MyTracksSettings.DEFAULT_MAP_PUBLIC, true);
context.getString(R.string.default_map_public_key), true);
}
metaData.setSearchable(mapPublic);
Entry entry = MyMapsGDataConverter.getMapEntryForMetadata(metaData);
@@ -0,0 +1,184 @@
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
import android.location.Location;
import android.os.Build;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* Write out a a track in the Garmin training center database, tcx format.
* As defined by:
* http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2
*
* @author Sandor Dornbush
*/
public class TcxTrackWriter implements TrackFormatWriter {
private PrintWriter pw = null;
private Track track;
static final SimpleDateFormat TIMESTAMP_FORMAT =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
static {
TIMESTAMP_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
}
public TcxTrackWriter() {
}
@Override
public void prepare(Track track, OutputStream out) {
this.track = track;
this.pw = new PrintWriter(out);
}
@Override
public void close() {
if (pw != null) {
pw.close();
pw = null;
}
}
@Override
public String getExtension() {
return TrackFileFormat.TCX.getExtension();
}
@Override
public void writeHeader() {
if (pw == null) {
return;
}
pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>");
pw.print("<TrainingCenterDatabase ");
pw.print("xmlns=\"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2\" ");
pw.print("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
pw.print("xsi:schemaLocation=\"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 ");
pw.println("http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd\">");
pw.println();
}
@Override
public void writeBeginTrack(Location firstPoint) {
if (pw == null) {
return;
}
pw.println(" <Activities>");
pw.print(" <Activity Sport=\"");
if (track.getCategory() != null) {
pw.print(track.getCategory());
}
pw.println("\">");
pw.print(" <Id>");
pw.print(TIMESTAMP_FORMAT.format(track.getStatistics().getStartTime()));
pw.println("</Id>");
pw.println(" <Lap>");
pw.print(" <TotalTimeSeconds>");
pw.print(track.getStatistics().getTotalTime() / 1000);
pw.println("</TotalTimeSeconds>");
pw.print(" <DistanceMeters>");
pw.print(track.getStatistics().getTotalDistance());
pw.println("</DistanceMeters>");
// TODO max speed etc.
// Calories are a required element just put in 0.
pw.print("<Calories>0</Calories>");
pw.println("<Intensity>Active</Intensity>");
pw.println("<TriggerMethod>Manual</TriggerMethod>)");
}
@Override
public void writeOpenSegment() {
if (pw != null) {
pw.println(" <Track>");
}
}
@Override
public void writeLocation(Location location) {
if (pw == null) {
return;
}
pw.println(" <Trackpoint>");
Date d = new Date(location.getTime());
pw.println(" <Time>" + TIMESTAMP_FORMAT.format(d) + "</Time>");
pw.println(" <Position>");
pw.print(" <LatitudeDegrees>");
pw.print(location.getLatitude());
pw.println("</LatitudeDegrees>");
pw.print(" <LongitudeDegrees>");
pw.print(location.getLongitude());
pw.println("</LongitudeDegrees>");
pw.println(" </Position>");
pw.print(" <AltitudeMeters>");
pw.print(location.getAltitude());
pw.println("</AltitudeMeters>");
pw.println(" </Trackpoint>");
}
@Override
public void writeCloseSegment() {
if (pw != null) {
pw.println(" </Track>");
}
}
@Override
public void writeEndTrack(Location lastPoint) {
if (pw == null) {
return;
}
pw.println(" </Lap>");
pw.print(" <Creator xsi:type=\"Device_t\">");
pw.print("<Name>");
pw.print(Build.MODEL);
pw.print("</Name>");
pw.println("</Creator>)");
pw.println(" </Activity>");
pw.println(" </Activities>");
}
@Override
public void writeFooter() {
if (pw == null) {
return;
}
pw.print(" <Author xsi:type=\"Application_t\">");
pw.print("<Name>My Tracks by Google</Name>");
pw.println("</Author>");
pw.println("</TrainingCenterDatabase>");
}
@Override
public void writeWaypoint(Waypoint waypoint) {
// TODO Write out the waypoints somewhere.
}
}
@@ -49,6 +49,12 @@ public class TrackWriterFactory {
public TrackFormatWriter newFormatWriter(Context context) {
return new CsvTrackWriter();
}
},
TCX {
@Override
public TrackFormatWriter newFormatWriter(Context context) {
return new TcxTrackWriter();
}
};
/**
@@ -23,6 +23,7 @@ import com.google.android.apps.mytracks.content.TrackPointsColumns;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.io.backup.BackupStateManager.TrackState;
import com.google.android.maps.mytracks.R;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
@@ -85,8 +86,7 @@ public class MyTracksBackupAgent extends BackupAgent {
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) throws IOException {
SharedPreferences preferences = this.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
// TODO: Pref name to XML
if (!preferences.getBoolean("backupToCloud", true)) {
if (!preferences.getBoolean(getString(R.string.backup_to_cloud_key), true)) {
Log.i(MyTracksConstants.TAG, "Cloud backup disabled - not doing it.");
return;
}
@@ -0,0 +1,142 @@
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.services;
import android.content.SharedPreferences;
import android.util.Log;
import com.google.android.apps.mytracks.MyTracksConstants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.maps.mytracks.R;
/**
* A class that manages reading the shared preferences for the service.
*
* @author Sandor Dornbush
*/
public class PreferenceManager {
private TrackRecordingService service;
private String announcement_frequency_key;
private String max_recording_distance_key;
private String metric_units_key;
private String min_recording_distance_key;
private String min_recording_interval_key;
private String min_required_accuracy_key;
private String signal_sampling_frequency_key;
private String split_frequency_key;
public PreferenceManager(TrackRecordingService service) {
this.service = service;
announcement_frequency_key =
service.getString(R.string.announcement_frequency_key);
max_recording_distance_key =
service.getString(R.string.max_recording_distance_key);
metric_units_key =
service.getString(R.string.metric_units_key);
min_recording_distance_key =
service.getString(R.string.min_recording_distance_key);
min_recording_interval_key =
service.getString(R.string.min_recording_interval_key);
min_required_accuracy_key =
service.getString(R.string.min_required_accuracy_key);
split_frequency_key =
service.getString(R.string.split_frequency_key);
signal_sampling_frequency_key =
service.getString(R.string.signal_sampling_frequency_key);
}
/**
* Notifies that preferences have changed.
* Call this with key == null to update all preferences in one call.
*
* @param key the key that changed (may be null to update all preferences)
*/
public void onSharedPreferenceChanged(String key) {
SharedPreferences sharedPreferences =
service.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (sharedPreferences == null) {
Log.w(MyTracksConstants.TAG,
"TrackRecordingService: Couldn't get shared preferences.");
return;
}
if (key == null || key.equals(min_recording_distance_key)) {
service.setMinRecordingDistance(
sharedPreferences.getInt(
min_recording_distance_key,
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE));
Log.d(MyTracksConstants.TAG,
"TrackRecordingService: minRecordingDistance = "
+ service.getMinRecordingDistance());
}
if (key == null || key.equals(max_recording_distance_key)) {
service.setMaxRecordingDistance(
sharedPreferences.getInt(
max_recording_distance_key,
MyTracksSettings.DEFAULT_MAX_RECORDING_DISTANCE));
}
if (key == null || key.equals(min_recording_interval_key)) {
int minRecordingInterval = sharedPreferences.getInt(
min_recording_interval_key,
MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL);
switch (minRecordingInterval) {
case -2:
// Battery Miser
// min: 30 seconds
// max: 5 minutes
// minDist: 5 meters Choose battery life over moving time accuracy.
service.setLocationListenerPolicy(
new AdaptiveLocationListenerPolicy(30000, 300000, 5));
break;
case -1:
// High Accuracy
// min: 1 second
// max: 30 seconds
// minDist: 0 meters get all updates to properly measure moving time.
service.setLocationListenerPolicy(
new AdaptiveLocationListenerPolicy(1000, 30000, 0));
break;
default:
service.setLocationListenerPolicy(
new AbsoluteLocationListenerPolicy(minRecordingInterval * 1000));
}
}
if (key == null || key.equals(min_required_accuracy_key)) {
service.setMinRequiredAccuracy(
sharedPreferences.getInt(
min_required_accuracy_key,
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY));
}
if (key == null || key.equals(announcement_frequency_key)) {
service.setAnnouncementFrequency(
sharedPreferences.getInt(announcement_frequency_key,
-1));
}
if (key == null || key.equals(split_frequency_key)) {
service.getSplitManager().setSplitFrequency(
sharedPreferences.getInt(split_frequency_key, 0));
}
if (key == null || key.equals(signal_sampling_frequency_key)) {
service.getSignalManager().setFrequency(
sharedPreferences.getInt(
signal_sampling_frequency_key, -1), service);
}
if (key == null || key.equals(metric_units_key)) {
service.getSplitManager().setMetricUnits(sharedPreferences.getBoolean(
metric_units_key, true));
}
}
}
@@ -116,10 +116,12 @@ public class StatusAnnouncerTask
boolean metricUnits = true;
boolean reportSpeed = true;
if (preferences != null) {
metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS,
true);
reportSpeed = preferences.getBoolean(MyTracksSettings.REPORT_SPEED,
true);
metricUnits =
preferences.getBoolean(context.getString(R.string.metric_units_key),
true);
reportSpeed =
preferences.getBoolean(context.getString(R.string.report_speed_key),
true);
}
double d = stats.getTotalDistance() / 1000;
@@ -1,12 +1,12 @@
/*
* 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
@@ -56,7 +56,7 @@ import java.util.TimerTask;
/**
* A background service that registers a location listener and records track
* points. Track points are saved to the MyTracksProvider.
*
*
* @author Leif Hendrik Wilden
*/
public class TrackRecordingService extends Service implements LocationListener {
@@ -68,8 +68,6 @@ public class TrackRecordingService extends Service implements LocationListener {
private LocationManager locationManager;
private WakeLock wakeLock;
private int minRecordingInterval =
MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL;
private int minRecordingDistance =
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE;
private int maxRecordingDistance =
@@ -110,8 +108,10 @@ public class TrackRecordingService extends Service implements LocationListener {
private TaskExecuterManager signalManager;
private SplitManager splitManager;
private PreferenceManager prefManager;
/**
* The interval in milliseconds that we have requested to be notfied of gps
* The interval in milliseconds that we have requested to be notified of gps
* readings.
*/
private long currentRecordingInterval = 0;
@@ -126,7 +126,7 @@ public class TrackRecordingService extends Service implements LocationListener {
* Task invoked by a timer periodically to make sure the location listener is
* still registered.
*/
private TimerTask checkLocationListener = new TimerTask() {
private final TimerTask checkLocationListener = new TimerTask() {
@Override
public void run() {
if (!onCreateWasCalled) {
@@ -198,7 +198,7 @@ public class TrackRecordingService extends Service implements LocationListener {
/**
* Inserts a new location in the track points db and updates the corresponding
* track in the track db.
*
*
* @param recordingTrack the track that is currently being recorded
* @param location the location to be inserted
* @param lastRecordedLocation the last recorded location before this one (or
@@ -475,8 +475,7 @@ public class TrackRecordingService extends Service implements LocationListener {
}
// This should never happen, but just in case (we really don't want the
// service
// to crash):
// service to crash):
if (location == null) {
Log.w(MyTracksConstants.TAG,
"Location changed, but location is null.");
@@ -559,8 +558,7 @@ public class TrackRecordingService extends Service implements LocationListener {
}
// If separation from last recorded point is too large insert a
// separator
// to indicate end of a segment:
// separator to indicate end of a segment:
boolean startNewSegment =
lastRecordedLocation != null
&& lastRecordedLocation.getLatitude() < 90
@@ -620,7 +618,7 @@ public class TrackRecordingService extends Service implements LocationListener {
*/
/**
* Notifies that preferences have changed.
* Notifies that preferences have changed.
* Call this with key == null to update all preferences in one call.
*
* @param key the key that changed (may be null to update all preferences)
@@ -628,93 +626,7 @@ public class TrackRecordingService extends Service implements LocationListener {
public void onSharedPreferenceChanged(String key) {
Log.d(MyTracksConstants.TAG,
"TrackRecordingService.onSharedPreferenceChanged");
SharedPreferences sharedPreferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (sharedPreferences == null) {
Log.w(MyTracksConstants.TAG,
"TrackRecordingService: Couldn't get shared preferences.");
return;
}
if (key == null || key.equals(MyTracksSettings.MIN_RECORDING_DISTANCE)) {
minRecordingDistance = sharedPreferences.getInt(
MyTracksSettings.MIN_RECORDING_DISTANCE,
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE);
Log.d(MyTracksConstants.TAG,
"TrackRecordingService: minRecordingDistance = "
+ minRecordingDistance);
}
if (key == null || key.equals(MyTracksSettings.MAX_RECORDING_DISTANCE)) {
maxRecordingDistance = sharedPreferences.getInt(
MyTracksSettings.MAX_RECORDING_DISTANCE,
MyTracksSettings.DEFAULT_MAX_RECORDING_DISTANCE);
}
if (key == null || key.equals(MyTracksSettings.MIN_RECORDING_INTERVAL)) {
minRecordingInterval = sharedPreferences.getInt(
MyTracksSettings.MIN_RECORDING_INTERVAL,
MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL);
switch (minRecordingInterval) {
case -2:
// Battery Miser
// min: 30 seconds
// max: 5 minutes
// minDist: 5 meters Choose battery life over moving time accuracy.
locationListenerPolicy =
new AdaptiveLocationListenerPolicy(30000, 300000, 5);
break;
case -1:
// High Accuracy
// min: 1 second
// max: 30 seconds
// minDist: 0 meters get all updates to properly measure moving time.
locationListenerPolicy =
new AdaptiveLocationListenerPolicy(1000, 30000, 0);
break;
default:
locationListenerPolicy =
new AbsoluteLocationListenerPolicy(minRecordingInterval * 1000);
}
}
if (key == null || key.equals(MyTracksSettings.MIN_REQUIRED_ACCURACY)) {
minRequiredAccuracy = sharedPreferences.getInt(
MyTracksSettings.MIN_REQUIRED_ACCURACY,
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY);
}
if (key == null || key.equals(MyTracksSettings.RECORDING_TRACK)) {
recordingTrackId =
sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
}
if (key == null || key.equals(MyTracksSettings.ANNOUNCEMENT_FREQUENCY)) {
announcementFrequency =
sharedPreferences.getInt(MyTracksSettings.ANNOUNCEMENT_FREQUENCY, -1);
if (mTTSAvailable) {
if (announcementFrequency == -1) {
if (executer != null) {
executer.shutdown();
executer = null;
}
} else {
if (executer == null) {
SafeStatusAnnouncerTask announcer =
new SafeStatusAnnouncerTask(this);
executer = new PeriodicTaskExecuter(announcer, this);
}
executer.scheduleTask(announcementFrequency * 60000);
}
}
}
if (key == null || key.equals(MyTracksSettings.SPLIT_FREQUENCY)) {
splitManager.setSplitFrequency(
sharedPreferences.getInt(MyTracksSettings.SPLIT_FREQUENCY, 0));
}
if (key == null || key.equals(MyTracksSettings.SIGNAL_SAMPLING_FREQUENCY)) {
signalManager.setFrequency(sharedPreferences.getInt(
MyTracksSettings.SIGNAL_SAMPLING_FREQUENCY, -1), this);
}
if (key == null || key.equals(MyTracksSettings.METRIC_UNITS)) {
splitManager.setMetricUnits(
sharedPreferences.getBoolean(MyTracksSettings.METRIC_UNITS, true));
}
prefManager.onSharedPreferenceChanged(key);
if (isRecording) {
registerLocationListener();
@@ -730,7 +642,6 @@ public class TrackRecordingService extends Service implements LocationListener {
Log.d(MyTracksConstants.TAG, "TrackRecordingService.onCreate");
super.onCreate();
onCreateWasCalled = true;
setForeground(true);
providerUtils = MyTracksProviderUtils.Factory.get(this);
notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
@@ -748,6 +659,7 @@ public class TrackRecordingService extends Service implements LocationListener {
signalManager =
new TaskExecuterManager(-1, new SignalStrengthTask(this), this);
}
prefManager = new PreferenceManager(this);
onSharedPreferenceChanged(null);
restoreStats();
registerLocationListener();
@@ -815,7 +727,7 @@ public class TrackRecordingService extends Service implements LocationListener {
/**
* Inserts a statistics marker. A statistics marker holds the stats for the
* last segment up to this marker.
*
*
* @param location the location where to insert
* @return the unique id of the inserted marker
*/
@@ -872,7 +784,7 @@ public class TrackRecordingService extends Service implements LocationListener {
public boolean hasRecorded() {
return providerUtils.getLastTrackId() >= 0;
}
@Override
public long startNewTrack() {
Log.d(MyTracksConstants.TAG, "TrackRecordingService.startNewTrack");
@@ -903,11 +815,11 @@ public class TrackRecordingService extends Service implements LocationListener {
signalManager.restore();
return trackId;
}
/**
* Insert the given waypoint marker. Users can insert waypoint markers
* to tag locations with a name, description, category etc.
*
*
* @param waypoint a waypoint
* @return the unique id of the inserted marker
*/
@@ -915,11 +827,11 @@ public class TrackRecordingService extends Service implements LocationListener {
public long insertWaypointMarker(Waypoint waypoint) {
return TrackRecordingService.this.insertWaypointMarker(waypoint);
}
/**
* Insert a statistics marker. A statistics marker holds the stats for
* the last segment up to this marker.
*
*
* @param location the location where to insert
* @return the unique id of the inserted marker
*/
@@ -927,7 +839,7 @@ public class TrackRecordingService extends Service implements LocationListener {
public long insertStatisticsMarker(Location location) {
return TrackRecordingService.this.insertStatisticsMarker(location);
}
@Override
public void endCurrentTrack() {
Log.d(MyTracksConstants.TAG, "TrackRecordingService.endCurrentTrack");
@@ -952,18 +864,18 @@ public class TrackRecordingService extends Service implements LocationListener {
showNotification();
recordingTrackId = -1;
}
@Override
public void deleteAllTracks() {
endCurrentTrack();
providerUtils.deleteAllTracks();
}
@Override
public void recordLocation(Location loc) {
onLocationChanged(loc);
}
@Override
public void sharedPreferenceChanged(String key) {
Log.d(MyTracksConstants.TAG,
@@ -983,4 +895,68 @@ public class TrackRecordingService extends Service implements LocationListener {
long getRecordingTrackId() {
return recordingTrackId;
}
public int getAnnouncementFrequency() {
return announcementFrequency;
}
public void setAnnouncementFrequency(int announcementFrequency) {
this.announcementFrequency = announcementFrequency;
if (mTTSAvailable) {
if (announcementFrequency == -1) {
if (executer != null) {
executer.shutdown();
executer = null;
}
} else {
if (executer == null) {
SafeStatusAnnouncerTask announcer =
new SafeStatusAnnouncerTask(this);
executer = new PeriodicTaskExecuter(announcer, this);
}
executer.scheduleTask(announcementFrequency * 60000);
}
}
}
public int getMaxRecordingDistance() {
return maxRecordingDistance;
}
public void setMaxRecordingDistance(int maxRecordingDistance) {
this.maxRecordingDistance = maxRecordingDistance;
}
public int getMinRecordingDistance() {
return minRecordingDistance;
}
public void setMinRecordingDistance(int minRecordingDistance) {
this.minRecordingDistance = minRecordingDistance;
}
public int getMinRequiredAccuracy() {
return minRequiredAccuracy;
}
public void setMinRequiredAccuracy(int minRequiredAccuracy) {
this.minRequiredAccuracy = minRequiredAccuracy;
}
public LocationListenerPolicy getLocationListenerPolicy() {
return locationListenerPolicy;
}
public void setLocationListenerPolicy(
LocationListenerPolicy locationListenerPolicy) {
this.locationListenerPolicy = locationListenerPolicy;
}
public SplitManager getSplitManager() {
return splitManager;
}
public TaskExecuterManager getSignalManager() {
return signalManager;
}
}
@@ -347,6 +347,8 @@ public class TripStatisticsBuilder {
* Returns the amount of time the user has been idle or 0 if they are moving.
*/
public long getIdleTime() {
if (lastLocation == null || lastMovingLocation == null)
return 0;
return lastLocation.getTime() - lastMovingLocation.getTime();
}
@@ -53,7 +53,8 @@ public class ChartURLGenerator {
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
boolean metricUnits = true;
if (preferences != null) {
metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
metricUnits = preferences.getBoolean(
context.getString(R.string.metric_units_key), true);
}
return getChartUrl(distances, elevations, track,
@@ -173,7 +173,7 @@ public class StringUtils implements DescriptionGenerator {
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
displaySpeed =
preferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
preferences.getBoolean(context.getString(R.string.report_speed_key), true);
}
TripStatistics trackStats = track.getStatistics();
@@ -0,0 +1,66 @@
// Copyright 2010 Google Inc. All Rights Reserved.
package com.google.android.apps.mytracks.io;
import android.location.Location;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.util.Date;
import java.util.List;
/**
* Tests for the GPX track exporter.
*
* @author Sandor Dornbush
*/
public class TcxTrackWriterTest extends TrackFormatWriterTest {
public void testXmlOutput() throws Exception {
TrackFormatWriter writer = new TcxTrackWriter();
String result = writeTrack(writer);
Document doc = parseXmlDocument(result);
Element root = getChildElement(doc, "TrainingCenterDatabase");
Element activitiesTag = getChildElement(root, "Activities");
Element activityTag = getChildElement(activitiesTag, "Activity");
Element lapTag = getChildElement(activityTag, "Lap");
List<Element> segmentTags = getChildElements(lapTag, "Track", 2);
Element segment1Tag = segmentTags.get(0);
Element segment2Tag = segmentTags.get(1);
List<Element> seg1PointTags = getChildElements(segment1Tag, "Trackpoint", 2);
List<Element> seg2PointTags = getChildElements(segment2Tag, "Trackpoint", 2);
assertTagsMatchPoints(seg1PointTags, location1, location2);
assertTagsMatchPoints(seg2PointTags, location3, location4);
}
/**
* Asserts that the given tags describe the given points, in the same order.
*/
private void assertTagsMatchPoints(List<Element> tags, Location... locs) {
assertEquals(locs.length, tags.size());
for (int i = 0; i < locs.length; i++) {
Element tag = tags.get(i);
Location loc = locs[i];
assertTagMatchesLocation(tag, loc);
}
}
/**
* Asserts that the given tag describes the given location.
*/
private void assertTagMatchesLocation(Element tag, Location loc) {
Element posTag = getChildElement(tag, "Position");
assertEquals(Double.toString(loc.getLatitude()),
getChildTextValue(posTag, "LatitudeDegrees"));
assertEquals(Double.toString(loc.getLongitude()),
getChildTextValue(posTag, "LongitudeDegrees"));
assertEquals(
TcxTrackWriter.TIMESTAMP_FORMAT.format(new Date(loc.getTime())),
getChildTextValue(tag, "Time"));
assertEquals(Double.toString(loc.getAltitude()),
getChildTextValue(tag, "AltitudeMeters"));
}
}