diff --git a/MyTracks/res/layout/about.xml b/MyTracks/res/layout/about.xml
index e3fe3cfb8..51f432b90 100644
--- a/MyTracks/res/layout/about.xml
+++ b/MyTracks/res/layout/about.xml
@@ -95,8 +95,9 @@ limitations under the License.
android:textSize="20sp" />
diff --git a/MyTracks/res/menu/main.xml b/MyTracks/res/menu/main.xml
new file mode 100644
index 000000000..23053e2d5
--- /dev/null
+++ b/MyTracks/res/menu/main.xml
@@ -0,0 +1,29 @@
+
+
diff --git a/MyTracks/res/values-ja/arrays.xml b/MyTracks/res/values-ja/arrays.xml
new file mode 100644
index 000000000..3b469da0b
--- /dev/null
+++ b/MyTracks/res/values-ja/arrays.xml
@@ -0,0 +1,282 @@
+
+
+
+
+
+ - 不使用
+ - 1 分
+ - 2 分
+ - 5 分
+ - 10 分
+ - 15 分
+ - 30 分
+ - 60 分
+
+
+
+
+ - 1 m
+ - 2 m
+ - 3 m
+ - 4 m
+ - 5 m (推奨)
+ - 10 m
+ - 100 m
+
+
+
+ - 3 ft
+ - 6 ft
+ - 10 ft
+ - 13 ft
+ - 16 ft (推奨)
+ - 33 ft
+ - 328 ft
+
+
+
+
+
+ - 50 m
+ - 100 m
+ - 200 m (推奨)
+ - 500 m
+ - 1000 m
+ - 5000 m
+
+
+
+ - 164 ft
+ - 328 ft
+ - 656 ft (推奨)
+ - 1640 ft
+ - 0.6 mi
+ - 3.1 mi
+
+
+
+
+
+ - 電源節約 (動的制御)
+ - 高精度 (動的制御)
+ - 最高 (推奨)
+ - 2 秒
+ - 3 秒
+ - 4 秒
+ - 5 秒
+ - 10 秒
+ - 20 秒
+ - 30 秒
+ - 1 分
+ - 2 分
+ - 5 分
+ - 10 分
+ - 15 分
+ - 30 分
+
+
+
+
+
+ - 10 m (GPS信号強度良好)
+ - 20 m
+ - 50 m
+ - 100 m
+ - 200 m (推奨)
+ - 500 m
+ - 1000 m
+ - 2000 m
+ - 5000 m (GPS信号強度不良)
+
+
+
+ - 33 ft (GPS信号強度良好)
+ - 66 ft
+ - 165 ft
+ - 328 ft
+ - 656 ft (推奨)
+ - 1640 ft
+ - 0.6 mi
+ - 1.2 mi
+ - 3.1 mi (GPS信号強度不良)
+
+
+
+
+
+ - 分割なし
+ - 100 km
+ - 50 km
+ - 25 km
+ - 10 km
+ - 5 km
+ - 1 km
+ - 60 分
+ - 30 分
+ - 15 分
+ - 10 分
+ - 5 分
+ - 2 分
+ - 1 分
+
+
+
+ - 分割なし
+ - 100 mi
+ - 50 mi
+ - 25 mi
+ - 10 mi
+ - 5 mi
+ - 1 mi
+ - 60 分
+ - 30 分
+ - 15 分
+ - 10 分
+ - 5 分
+ - 2 分
+ - 1 分
+
+
+
+
+
+ - 不明
+ - 混合タイプ
+ - その他
+
+ - 実行中
+ - 市街地ランニング
+ - トラックランニング
+ - 山道ランニング
+ - 徒歩
+ - 早歩き
+ - ハイキング
+ - 山道ハイキング
+ - 原野ハイキング
+ - 登山
+
+ - サイクリング
+ - ロードバイク
+ - マウンテンバイク
+ - トラック自転車
+
+ - スケート
+ - インラインスケート
+ - スケートボード
+
+ - スノーシュー
+ - スキー
+ - スノーボード
+ - ソリ
+ - アイスセーリング
+
+ - 帆走
+ - パドリング
+ - カヤック
+ - 漕艇
+ - モーターボート
+ - フェリー
+ - ラジコンボート
+ - サーフィン
+ - ウィンドサーフィン
+ - カイトサーフィン
+ - 水上スキー
+ - ウェークボード
+
+ - 飛行機
+ - 水上機
+ - 商用航空機
+ - ヘリコプター
+ - 熱気球
+ - 飛行船
+ - ラジコン飛行機
+ - ラジコンヘリコプター
+ - スカイダイビング
+ - グライダー
+ - ハンググライダー
+ - パラグライダー
+
+ - 騎乗
+ - 乗馬
+ - ロバ騎乗
+
+ - 自動車運転
+ - バス運転
+ - 鉄道
+ - オートバイ
+ - オフロードバイク
+ - 四輪バギー
+
+ - ランドセーリング
+ - フリスビー
+ - アルティメットフリスビー
+
+
+
+ - ATM
+ - 銀行
+ - 飲み屋
+ - バーベキュー
+ - 建物
+ - バス停
+ - カフェ
+ - キャンプファイアー
+ - キャンプ場
+ - 教会
+ - コーヒーハウス
+ - コンビニ
+ - 水飲み場
+ - がけ崩れ
+ - フェリー
+ - 火事場
+ - 消防署
+ - 釣り場
+ - ガソリンスタンド
+ - ゴルフ場
+ - 雑貨店
+ - 美容室
+ - 散髪屋
+ - ハイキング道
+ - ホテル
+ - 家
+ - 情報
+ - 交差
+ - メールボックス
+ - 市場
+ - 集合場所
+ - 歌劇場
+ - 駐車場
+ - 郵便局
+ - 洞穴
+ - 警察署
+ - 踏切
+ - レストラン
+ - ショッピング
+ - 名所
+ - 店
+ - プール
+ - 電話
+ - 劇場
+ - トイレ
+ - 観光案内
+ - トンネル
+ - 樹木
+ - 滝
+ - 噴水
+ - ウェイポイント
+
+
diff --git a/MyTracks/res/values-ja/strings.xml b/MyTracks/res/values-ja/strings.xml
new file mode 100644
index 000000000..447a48540
--- /dev/null
+++ b/MyTracks/res/values-ja/strings.xml
@@ -0,0 +1,395 @@
+
+
+
+
+ トラック記録
+ 記録停止
+ 衛星モード
+ 地図モード
+ 現在地
+ トラック
+ マーカ
+ 全トラック消去
+ 設定
+ 標高
+ 表示するトラックを選択して下さい
+ 現在のトラック
+ 最終セグメント
+
+
+ この端末でロケーションマネージャを発見できませんでした
+ この端末でGPSロケーションプロバイダを発見できました
+ Googleマイマップへのトラック送信でエラーが発生しました.しばらく待って試して下さい.
+ Google Docsへのトラック送信でエラーが発生しました.しばらく待って試して下さい.
+ 記録作成開始できません.もう一度試して下さい.
+ 記録停止できません.もう一度試して下さい.
+ ファイルからの読み込みができません.
+ ファイルは正しいGPX書式ではありませんでした.
+ エラーが発生しました.もう一度試して下さい.
+ トラックが存在しません.
+ 大きなファイルです(500KB未満でなければなりません).終了します.
+ マーカの挿入ができません.位置決定ができません.
+
+
+ GPS位置精度がよくなるまで待機しています.空が見えるところにいて下さい.
+ 新しいトラックを記録中です.
+ トラック記録を停止しました.
+ 新しいGoogleマイマップを maps.google.com に作成しました.
+ トラックを maps.google.com に送信しました.
+ トラックを docs.google.com の新しいスプレッドシートに送信しました.
+ トラックを docs.google.com に送信しました.
+ 新しいトラックが見えるようになるまで数分程度かかります.
+ ここをタップして,セキュリティ &位置情報 を開いて,「GPS機能をONにする」にチェックして下さい.バックボタンで戻ってください.
+ ご注意: 携帯電話中継局とWi-Fiネットワークから大まかな位置を特定します.
+ 現在位置決定ができません.位置取得源を増やし(セキュリティ&位置情報をご覧ください),空が見えるようにして下さい.もう一度試して下さい.
+ ウェイポイントマーカを挿入しました.
+ 統計マーカを挿入しました.
+
+
+ お待ちください...
+ トラックをGoogleに送信しました.
+ トラックを読んでいます...
+ トラックを準備しています...
+ Googleマップの認証しています...
+ Google Docsへの認証を行っています...
+ トラックをGoogle Docsに送信しています...
+ トラックをGoogleマップに送信しています...
+ 新しいマイマップを生成しています...
+ GPSトラックをインポートしています.若干時間がかかります.
+ SDカードにデータを書き込んでいます.若干時間がかかります.
+ トラック統計情報を更新しています...
+
+
+ よろしいですか?
+ 全てのトラックとマーカをこの端末から削除しました.
+ トラックとマーカをこの端末から完全に削除しました.
+ マーカをこの端末から完全に削除しました.
+
+
+ Android用My Tracksで作成
+ Android用<a href=\'http://mytracks.appspot.com\'>My Tracks</a>で作成しました.
+ 新規マップ
+
+
+ ポイント
+ 記録
+ 活動タイプ
+ マーカタイプ
+ (Part %d)
+
+
+ トラックを保存中...
+ トラック %d
+
+
+ いいえ
+ はい
+ OK
+ エラー
+ 成功
+ ウェイポイント
+
+
+ (開始)
+ (終了)
+
+
+ 表示
+ Google My Mapsへ送信
+ 新規Googleマイマップへ送信
+ Google Docsへ送信
+ Googleへ送信...
+ 端末から削除...
+ 詳細編集
+ SDへの書き込み...
+ GPXファイルの保存
+ KMLファイルの保存
+ CVSファイルの保存
+ Googleマイマップへの送信
+ 全てのトラックの削除
+
+ 全てのトラックのエクスポート
+ エクスポート終了
+ トラックを選択します.オプションを表示するには長押しして下さい.
+ 全てのトラック:
+ このトラック
+ 共有...
+ Googleマイマップへのリンク
+ GPXファイル
+ KMLファイル
+ CSVファイル
+ マップの消去
+
+
+ 全てのマーカの削除
+ このマーカ
+ 削除
+ 詳細編集
+ マップに表示
+ ウェイポイントの挿入
+ 統計情報の挿入
+ マーカを選択します.オプションを表示するには長押しして下さい.
+
+
+ トラック詳細
+ トラック名
+ トラック説明
+ 活動タイプ(ハイキング, サイクリング, ランニング, 登山...)
+
+
+ マーカ詳細
+ マーカ名
+ マーカ説明
+ マーカタイプ(建物, 洞穴, 名所...)
+
+
+ My Tracks設定
+ 表示
+ 記録
+ 共有
+
+ 定期通知
+ 音声通知間隔の最小時間
+ お使いのAndroidの版では音声読み上げ機能がありません
+
+ ポイント間の最短距離
+ 位置記録間の最短距離
+
+ ポイント間の最長距離
+ これより間隔が長い場合はトラックは分割されます
+
+ ポイント間の最小時間間隔
+ 位置記録の最短インターバル
+
+ 最低精度
+ この精度以上でないと記録を休止します
+
+ メートル法を使用
+ 全ての距離をメートル法で表示します
+ 全ての距離をヤード・ポンド法で表示します
+
+ マップの公開
+ アップロードされたマップはmaps.google.comで誰でも閲覧できます
+ アップロードされたマップはmaps.google.comのリストに公開されません.
+
+ 速度表示
+ 速度が表示されます
+ ペースが表示されます
+
+ URLのみ共有
+ 共有時にマップのURLのみ送信します
+ 共有時にトラックのコンテントが含まれます
+
+ 信号サンプリング周波数
+ 端末の信号強度記録の時間間隔
+
+ 分割頻度
+ 分割マーカを挿入する時間または距離の間隔
+ ペース
+
+
+ GPS衛星
+
+
+ ご使用のアカウントからのマップ選択:
+ 新規マップ...
+ Googleマイマップへの送信
+ マップの読み込み中...
+ マップを読み込めませんでした!
+ このマップを選択
+ マップ詳細の編集
+ マップの共有
+ トラックの共有
+ アカウントからマップの削除
+ マップタイトル:
+ マップ説明:
+
+
+ このマップとコンテンツを検索結果に表示させる
+ このマップとコンテンツはどちらも検索結果に表示させない(直接URLで他の方が見ることは可能)
+ このマップとコンテンツは検索結果に表示されます
+ このマップとコンテンツはどちらも検索結果に表示されませんが,直接リンクで他の方が見ることができます.
+ 閉じる
+ 編集
+ キャンセル
+ 保存
+
+
+ マップを共有したいと思います
+ このマップに興味を持って頂けると思います:
+
+ %s
+ トラックを共有したいと思います
+ このトラックに興味を持って頂けると思います.
+
+ このトラックを閲覧するには,Google Earthまたは他のマッピングソフトウェアが必要です.
+
+
+ 公開
+ リストに出さない
+ まだ地図がありません.
+
+
+
+ 平均移動速度
+ 平均移動ペース
+
+
+ 平均速度
+ 平均ペース
+
+ 標高チャート
+ 標高差
+ 標高
+ 緯度
+ 経度
+
+
+ 最小標高
+ 最小勾配
+ 最小ペース
+
+
+ 最大標高
+ 最大勾配
+ 最大速度
+
+ トラックの読み込み中...
+
+
+ チャート設定
+
+ X軸
+ 距離ベース
+ 時間ベース
+
+
+ Y軸
+
+
+
+ 時
+ 時
+ 時
+ 分
+ 分
+ 分
+ 秒
+ 秒
+
+
+ m
+ km
+ キロメータ
+ ft
+ mi
+ マイル
+
+
+ km/h
+ キロメータ毎時
+ min/km
+ 毎キロメータ
+ mi/h
+ マイル毎時
+ min/mi
+ 毎マイル
+
+
+ 移動時間
+ 合計時間
+ 時間
+ SD が発見できません
+ 速度
+ 移動して下さい.
+ 統計
+ 合計距離
+ 距離
+ -
+ 待機中...
+
+
+ エンドユーザライセンス契約書
+ 同意する
+ 拒否する
+
+
+ このアプリケーションについて
+ ヘルプ
+ チーム:
+ バージョン:
+ サポート
+ サポート:
+
+
+ 送信...
+ Googleマイマップ
+ Google Docs
+ 今すぐ送信
+ 新規マップ作成
+ 既存マップ選択
+ トラック統計情報送信
+ 統計情報とポイント送信
+
+
+ アカウントを発見できませんでした.
+ トラックをアップロードするためのアカウントを発見できませんでした.
+ アカウント選択
+
+
+ 外部ストレージを発見できませんでした.SDカードが刺さっているか,端末がコンピュータにマウントされているか確認してください.
+ ファイルへの書き込みができません.
+ SDカードにディレクトリを作成できません.
+ SDカードへの書き込み終了.
+
+
+ アップグレードチェック
+ 今すぐアップデート
+ アップグレードせずに続行
+ お使いの版では,確実には動作せず,サポートもされません.ご使用を続けるには %1$s のアップグレードしてください.
+ お使いの版では,確実には動作しません.すぐにアップグレードすることをお勧めします.アップグレードされない場合は問題発生の可能性があることをご認識ください. サーバ同期するような機能の中には,アップグレードされるまで機能しないものがあります.
+ %1$s の新しい版が出ています.現版で問題なくご使用になれますが,アップグレードするまで最新の機能をお使いになれません.
+
+
+ ようこそ
+ Ok
+ My Tracksについて
+
+
+ My Tracks 移動していません
+
+ My Tracks %1$s %2$.2f %3$s 時間 %4$s 速度/ペース %5$s %6$s
+
+
+ 計測単位についてのご注意
+ デフォルトの単位はメートルです.設定を変更しますか?
+
+
+ 誤り率: %1$d
+ S/N比: %1$d
+ Ec/Io比: %1$.1f dB
+ GSM 強度: %1$d
+ CDMA 強度: %1$d dBm
+ EVDO 強度: %1$d dBm
+
diff --git a/MyTracks/res/values/arrays.xml b/MyTracks/res/values/arrays.xml
index d1be00be5..78075af5f 100644
--- a/MyTracks/res/values/arrays.xml
+++ b/MyTracks/res/values/arrays.xml
@@ -370,5 +370,6 @@ limitations under the License.
- GPX
- KML
- CSV
+ - TCX
diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml
new file mode 100644
index 000000000..e71e9f5e5
--- /dev/null
+++ b/MyTracks/res/values/keys.xml
@@ -0,0 +1,45 @@
+
+
+
+
+ announcementFrequency
+ bluetoothDevice
+ bluetoothPairing
+ bluetoothSensor
+ defaultMapPublic
+ maxRecordingDistance
+ metricUnits
+ minRecordingDistance
+ minRecordingInterval
+ minRequiredAccuracy
+ modularStatsDisplay
+ pickExistingMap
+ recordingTrack
+ reportSpeed
+ selectedTrack
+ sendStatsAndPoints
+ sendToDocs
+ sendToMyMaps
+ sensorId
+ sensorType
+ shareUrlOnly
+ signalSamplingFrequency
+ splitFrequency
+ backupToSd
+ restoreFromSd
+ backupToCloud
+
\ No newline at end of file
diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml
index bc9a9181b..c0fcc2ee3 100644
--- a/MyTracks/res/values/strings.xml
+++ b/MyTracks/res/values/strings.xml
@@ -122,6 +122,7 @@ limitations under the License.
Save a GPX file
Save a KML file
Save a CSV file
+ Save a TCX file
Send to Google My Maps
Delete all tracks
@@ -135,6 +136,7 @@ limitations under the License.
A GPX file
A KML file
A CSV file
+ A TCX file
Clear map
@@ -205,6 +207,18 @@ limitations under the License.
Maximum time or distance after which a new split marker will be inserted
Pace
+ Only supported in Android 2.0 or above
+ Sensor Type
+ The type of sensor to connect to.
+ Sensor Id
+ The Id sent to sensors.
+ The Id must be an integer value.
+ Bluetooth sensor
+ The bluetooth sensor to connect to.
+ Modular Stats Display
+ The stats screen is split in various modes.
+ Display all stats on one screen
+
Backup
SD Card Backup
Backup now
@@ -310,6 +324,7 @@ limitations under the License.
minutes
second
seconds
+ ms
m
@@ -329,6 +344,12 @@ limitations under the License.
min/mi
per mile
+
+ W
+
+ rpm
+ bpm
+
Moving Time
Total Time
@@ -339,6 +360,10 @@ limitations under the License.
Statistics
Total Distance
Distance
+ Power
+ Cadence
+ Heart Rate
+ Max Heart Rate
-
Waiting...
@@ -356,7 +381,6 @@ limitations under the License.
Support:
- 1.0.14
mytracks@googlegroups.com
mytracks.appspot.com
Copyright 2009 Google Inc.
@@ -424,4 +448,29 @@ limitations under the License.
GSM Strength: %1$d
CDMA Strength: %1$d dBm
EVDO Strength: %1$d dBm
+
+
+ Bluetooth
+ Bluetooth options
+ Device pairing
+ Open Android\'s bluetooth settings to pair a device
+ bluetoothSensorsEnabled
+ Sensor Options
+
+
+ NONE
+ ANT
+ SRM
+ ATHLOSOFT
+
+
+ Connected to %s
+ Bluetooth sensor connecting ...
+ Bluetooth sensor not connected
+
+
+ Sensor Data Time
+ Power meter enabled
+ Heart rate monitor enabled
+
diff --git a/MyTracks/res/xml/preferences.xml b/MyTracks/res/xml/preferences.xml
index 419ccbd7c..8e37c0660 100644
--- a/MyTracks/res/xml/preferences.xml
+++ b/MyTracks/res/xml/preferences.xml
@@ -18,26 +18,26 @@ limitations under the License.
xmlns:android="http://schemas.android.com/apk/res/android">
-
+
-
+
-
+
-
+
-
+
-
+
= 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();
}
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksConstants.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksConstants.java
index 32350c145..78f3e05d6 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksConstants.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksConstants.java
@@ -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:
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java
index 4762c840e..8a5f255f1 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java
@@ -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();
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksList.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksList.java
index c2be23dce..f88421868 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksList.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksList.java
@@ -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");
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java
index c7b73f7d7..c60e9888e 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java
@@ -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();
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksOverlay.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksOverlay.java
index fabd7555f..84e1546bf 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksOverlay.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksOverlay.java
@@ -55,6 +55,7 @@ public class MyTracksOverlay extends Overlay {
private final Paint errorCirclePaint;
private final Context context;
private final ArrayList waypoints = new ArrayList();
+ private final ArrayList points = new ArrayList(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 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 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;
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksSettings.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksSettings.java
index 9e97487e7..ae0c3c1fc 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksSettings.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksSettings.java
@@ -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
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointDetails.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointDetails.java
index 33b911762..82604320b 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointDetails.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointDetails.java
@@ -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();
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointsList.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointsList.java
index 0e9d6040d..594c9fb98 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointsList.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointsList.java
@@ -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;
diff --git a/MyTracks/src/com/google/android/apps/mytracks/SendToGoogleDialog.java b/MyTracks/src/com/google/android/apps/mytracks/SendToGoogleDialog.java
index 8e7847cb0..3f6ef6da9 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/SendToGoogleDialog.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/SendToGoogleDialog.java
@@ -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();
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
index c16bb69fa..a0deb9c4a 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
@@ -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());
}
/**
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
index 163e29b03..448b820d1 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
@@ -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;
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java
index cfebe4539..a5a89564f 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java
@@ -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);
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/TcxTrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/TcxTrackWriter.java
new file mode 100644
index 000000000..7ad325f41
--- /dev/null
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/TcxTrackWriter.java
@@ -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("");
+ pw.print("");
+ pw.println();
+ }
+
+ @Override
+ public void writeBeginTrack(Location firstPoint) {
+ if (pw == null) {
+ return;
+ }
+ pw.println(" ");
+ pw.print(" ");
+ pw.print(" ");
+ pw.print(TIMESTAMP_FORMAT.format(track.getStatistics().getStartTime()));
+ pw.println("");
+ pw.println(" ");
+ pw.print(" ");
+ pw.print(track.getStatistics().getTotalTime() / 1000);
+ pw.println("");
+ pw.print(" ");
+ pw.print(track.getStatistics().getTotalDistance());
+ pw.println("");
+ // TODO max speed etc.
+ // Calories are a required element just put in 0.
+ pw.print("0");
+ pw.println("Active");
+ pw.println("Manual)");
+ }
+
+ @Override
+ public void writeOpenSegment() {
+ if (pw != null) {
+ pw.println(" ");
+ }
+ }
+
+ @Override
+ public void writeEndTrack(Location lastPoint) {
+ if (pw == null) {
+ return;
+ }
+ pw.println(" ");
+ pw.print(" ");
+ pw.print("");
+ pw.print(Build.MODEL);
+ pw.print("");
+ pw.println(")");
+ pw.println(" ");
+ pw.println(" ");
+ }
+
+ @Override
+ public void writeFooter() {
+ if (pw == null) {
+ return;
+ }
+ pw.print(" ");
+ pw.print("My Tracks by Google");
+ pw.println("");
+ pw.println("");
+ }
+
+ @Override
+ public void writeWaypoint(Waypoint waypoint) {
+ // TODO Write out the waypoints somewhere.
+ }
+}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriterFactory.java b/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriterFactory.java
index 98e7c177b..bc3c15ddd 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriterFactory.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriterFactory.java
@@ -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();
+ }
};
/**
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/MyTracksBackupAgent.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/MyTracksBackupAgent.java
index 2776bdc53..18c4e1a39 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/MyTracksBackupAgent.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/backup/MyTracksBackupAgent.java
@@ -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;
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java
new file mode 100644
index 000000000..5128ceca0
--- /dev/null
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java
@@ -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));
+ }
+ }
+}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java
index d0ec9a41e..ba0f0cf52 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java
@@ -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;
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
index fc952387d..65eebf418 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
@@ -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;
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
index 9724ba727..f0107e832 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
@@ -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();
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java b/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
index f232dbf51..bd721512a 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
@@ -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,
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java
index d5a8ed34b..c4c0b2317 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java
@@ -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();
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/TcxTrackWriterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/TcxTrackWriterTest.java
new file mode 100644
index 000000000..ec132e0db
--- /dev/null
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/TcxTrackWriterTest.java
@@ -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 segmentTags = getChildElements(lapTag, "Track", 2);
+ Element segment1Tag = segmentTags.get(0);
+ Element segment2Tag = segmentTags.get(1);
+ List seg1PointTags = getChildElements(segment1Tag, "Trackpoint", 2);
+ List 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 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"));
+ }
+}