Merging to head.

This commit is contained in:
Rodrigo Damazio
2011-03-11 23:14:52 -03:00
parent f7750f2a2c
commit 26af05cd01
29 changed files with 923 additions and 228 deletions
+2 -2
View File
@@ -18,7 +18,7 @@ limitations under the License.
package="com.google.android.maps.mytracks"
android:installLocation="auto"
android:versionCode="25"
android:versionName="1.1.2">
android:versionName="1.1.3rc1">
<application android:icon="@drawable/arrow_icon"
android:label="@string/app_name"
android:backupAgent="com.google.android.apps.mytracks.io.backup.MyTracksBackupAgent">
@@ -110,7 +110,7 @@ limitations under the License.
<!-- Permissions to initialize service -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Permissions for recording tracks and showing maps -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2011 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--
This layout is used as the content view for the send-to-Google result dialog.
It is used to summarize the results of uploading track data to one or more
services.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:paddingLeft="14dip"
android:paddingRight="14dip"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/status_track_upload_status"
style="?android:attr/textAppearanceLarge"/>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<!-- We don't want a divider, so we set its color to transparent. -->
<!-- We do this explicitly, rather than with a color resource, because -->
<!-- an apparent bug causes the divider to be wildly misrendered on -->
<!-- a Mini X10 running 2.1. -->
<ListView
android:id="@+id/send_to_google_result_list"
android:clickable="false"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:divider="#00000000"/>
</TableLayout>
<TextView
android:id="@+id/send_to_google_result_comment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/status_mymap_info"
android:visibility="gone"
style="?android:attr/textAppearanceSmall"/>
<TextView
android:id="@+id/send_to_google_result_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/error_please_try_again_later"
android:visibility="gone"
style="?android:attr/textAppearanceLarge"/>
</LinearLayout>
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2011 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--
This layout represents the result of sending track data to a single service.
It will be instantiated by a custom ListAdapter - once for each service to
which track data was uploaded.
-->
<TableRow
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/send_to_google_result_icon"
android:src="@drawable/success"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="top"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/send_to_google_result_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Google Docs"
style="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/send_to_google_result_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="http://google.com"
style="?android:attr/textAppearanceSmall"/>
</LinearLayout>
</TableRow>
+7
View File
@@ -287,4 +287,11 @@ limitations under the License.
<item>噴水</item>
<item>ウェイポイント</item>
</array>
<array name="sensor_type_options">
<item>なし</item>
<item>ANT+ センサー</item>
<item>SRM ANT+ ブリッジ</item>
<item>Zephyr Bluetooth</item>
</array>
</resources>
+61 -18
View File
@@ -35,6 +35,7 @@ limitations under the License.
<!-- Error messages -->
<string name="error_no_location_manager">この端末でロケーションマネージャを発見できませんでした.</string>
<string name="error_no_gps_location_provider">この端末でGPSロケーションプロバイダを発見できました.</string>
<string name="error_sending_to_mymap">Googleマイマップへのトラック送信でエラーが発生しました.しばらく待って試して下さい.</string>
<string name="error_sending_to_fusiontables">Google Fusion Tablesへのトラック送信でエラーが発生しました.しばらく待って試して下さい.</string>
<string name="error_sending_to_docs">Google Docsへのトラック送信でエラーが発生しました.しばらく待って試して下さい.</string>
<string name="error_unable_to_start_recording">記録作成開始できません.もう一度試して下さい.</string>
@@ -50,11 +51,13 @@ limitations under the License.
<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">新しいマイマップをmap.google.comに作成しました.</string>
<string name="status_new_fusiontable_has_been_created">新しいGoogle Fusion Tableをgoogle.com/fusiontablesに作成しました.</string>
<string name="status_tracks_have_been_uploaded">トラックをmaps.google.comに送信しました.</string>
<string name="status_tracks_have_been_uploaded_to_new_doc">トラックをdocs.google.comの新しいスプレッドシートに送信しました.</string>
<string name="status_tracks_have_been_uploaded_to_docs">トラックをdocs.google.comに送信しました.</string>
<string name="status_enable_gps">ここをタップして「位置情報とセキュリティの設定」を開いて「GPS機能を使用」にチェックして下さい.バックボタンで戻ってください.</string>
<string name="status_mymap_info">新しいトラックが表示されるまでに数分かかることがあります.</string>
<string name="status_enable_gps">ここをタップして「位置情報とセキュリティの設定」を開いて「GPS機能を使用」にチェックを入れて下さい.バックボタンで戻ってください.</string>
<string name="status_approximate_location">ご注意: 携帯電話中継局とWi-Fiネットワークから大まかな位置を特定します.</string>
<string name="status_no_location">現在位置決定ができません.位置取得源を増やし(位置情報とセキュリティの設定 をご覧ください)、空が見えるようにして下さい.もう一度試して下さい.</string>
<string name="status_waypoint_inserted">ウェイポイントマーカーを挿入しました.</string>
@@ -62,14 +65,17 @@ limitations under the License.
<!-- Progress dialog -->
<string name="progress_title">お待ちください...</string>
<string name="progress_message">トラックをGoogleに送信しました.</string>
<string name="progress_message">トラックをGoogleに送信しています.</string>
<string name="progress_message_reading_track">トラックを読んでいます...</string>
<string name="progress_message_preparing_track">トラックを準備しています...</string>
<string name="progress_message_authenticating_fusiontables">Google Fusion Tablesへの認証を行っています...</string>
<string name="progress_message_authenticating_mymaps">Googleマップへの認証を行っています...</string>
<string name="progress_message_authenticating_docs">Google 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="progress_message_sending_fusiontables">トラックをFusion Tablesに送信しています...</string>
<string name="progress_message_creating_fusiontable">新しいFusion Tablesを生成しています...</string>
<string name="progress_message_creating_fusiontable">新しいFusionテーブルを生成しています...</string>
<string name="import_progress_message">GPSトラックをインポートしています.若干時間がかかります.</string>
<string name="write_progress_message">SDカードにデータを書き込んでいます.若干時間がかかります.</string>
<string name="progress_message_updating_track">トラック統計情報を更新しています...</string>
@@ -84,6 +90,10 @@ limitations under the License.
<string name="new_map_description">Android用My Tracksで作成</string>
<string name="fusiontable_link">Android用&lt;a href=\'http://mytracks.appspot.com\'&gt;My Tracks&lt;/a&gt;で作成しました.</string>
<!-- Text and links when uploading to Google My Maps -->
<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>
@@ -113,10 +123,12 @@ limitations under the License.
<!-- TrackList -->
<string name="tracklist_show_track">表示</string>
<string name="tracklist_send_to_fusiontables">Google Fusion Tablesへ送信</string>
<string name="tracklist_send_to_new_fusiontable">新規Google Fusion Tableへ送信</string>
<string name="tracklist_send_to_docs">Google Docsへ送信</string>
<string name="tracklist_send_to_google">Googleへ送信...</string>
<string name="tracklist_send_to_mymaps">Googleマイマップに送信</string>
<string name="tracklist_send_to_new_mymap">新規Googleマイマップに送信</string>
<string name="tracklist_send_to_fusiontables">Google Fusion Tablesに送信</string>
<string name="tracklist_send_to_new_fusiontable">新規Google Fusion Tableに送信</string>
<string name="tracklist_send_to_docs">Google 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>
@@ -124,20 +136,33 @@ limitations under the License.
<string name="tracklist_save_as_kml">KMLファイルの保存</string>
<string name="tracklist_save_as_csv">CVSファイルの保存</string>
<string name="tracklist_save_as_tcx">TCXファイルの保存</string>
<string name="tracklist_btn_send_all_to_fusiontables">Google Fusion Tablesへの送信</string>
<string name="tracklist_btn_delete_all">全トラックの削除</string>
<string name="tracklist_btn_send_all_to_fusiontables">Google Fusion Tablesに送信</string>
<string name="tracklist_btn_send_all_to_mymaps">Googleマイマップに送信</string>
<string name="tracklist_btn_delete_all">全て削除</string>
<!-- Export All -->
<string name="tracklist_btn_export_all">全トラックの出力</string>
<string name="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_all_tracks">全トラック:</string>
<string name="tracklist_this_track">このトラック</string>
<string name="tracklist_share_track">共有...</string>
<string name="tracklist_share_link">マップへのリンク</string>
<string name="tracklist_share_gpx_file">GPXファイル</string>
<string name="tracklist_share_kml_file">KMLファイル</string>
<string name="tracklist_share_csv_file">CSVファイル</string>
<string name="tracklist_share_tcx_file">TCXファイル</string>
<string name="tracklist_clear_map">マップの消去</string>
<string name="tracklist_clear_map">マップのクリア</string>
<!-- Import All -->
<string name="tracklist_btn_import_all">全てインポート</string>
<string name="import_done">インポート終了</string>
<!-- Format:
$1 : Successful imports
$2 : Attempted imports
$3 : MyTracks gpx path
-->
<string name="import_done">%3$s からGPXファイル %2$d件のうち %1$d件をインポートしました</string>
<string name="import_empty">%s ではGPXファイルがありません.SDカードを読み込めないかディレクトリにGPXファイルが無いかも知れません.</string>
<string name="import_error">ファイル %s のインポートエラー</string>
<!-- Waypoints list -->
<string name="waypointslist_btn_delete_all">全てのマーカーの削除</string>
@@ -190,7 +215,7 @@ limitations under the License.
<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_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>
@@ -242,6 +267,23 @@ limitations under the License.
<!-- MyTracksSky -->
<string name="mytracks_sky">GPS衛星</string>
<!-- My Maps -->
<string name="select_map_message">アカウントからのマップ選択:</string>
<string name="create_new_map">新規マップ作成...</string>
<string name="map_list_title">Googleマイマップに送信</string>
<string name="maps_list_loading">マップをロード中...</string>
<string name="maps_list_failed">今回はマップをロードできませんでした!</string>
<string name="open_map">このマップを選択</string>
<string name="edit_map_details">マップ詳細編集</string>
<string name="share_track">トラック共有</string>
<string name="delete_map">アカウントからマップを削除</string>
<string name="map_title">マップタイトル:</string>
<string name="map_description">マップ説明:</string>
<string name="map_searchable_edit">このマップまたはコンテンツを検索結果に表示</string>
<string name="map_not_searchable_edit">このマップまたはコンテンツを検索結果に表示しない(直接URLで見られる可能性があります)</string>
<string name="map_searchable">このマップまたはコンテンツは検索結果に表示されます</string>
<string name="map_not_searchable">このマップもコンテンツも検索結果に表示されませんが、直接リンクで見られる可能性があります</string>
<!-- Sharing -->
<string name="share_map">マップ共有</string>
<string name="share_map_subject">マップを共有したいと思います</string>
@@ -332,7 +374,6 @@ limitations under the License.
<string name="cadence">ケイデンス</string>
<string name="heart_rate">心拍数</string>
<string name="max_heart_rate">最大心拍数</string>
<string name="unknown">-</string>
<string name="waiting">待機中...</string>
<!-- End User License Agreement -->
@@ -350,8 +391,10 @@ limitations under the License.
<!-- Send to Google -->
<string name="sendtogoogle_title">送信...</string>
<string name="sendtogoogle_google_fusiontables">Googleマイマップ</string>
<string name="sendtogoogle_google_mymaps">Googleマイマップ</string>
<string name="sendtogoogle_send_now">今すぐ送信</string>
<string name="sendtogoogle_create_new_map">新規マップ作成</string>
<string name="sendtogoogle_pick_existing_map">既存マップ選択</string>
<string name="sendtogoogle_send_stats">トラック統計情報送信</string>
<string name="sendtogoogle_send_stats_and_points">統計情報とポイント送信</string>
@@ -364,7 +407,7 @@ limitations under the License.
<string name="io_no_external_storage_found">外部ストレージを発見できませんでした.SDカードが刺さっているか、端末がコンピュータにマウントされていないか確認してください.</string>
<string name="io_write_failed">ファイルへの書き込みができません.</string>
<string name="io_read_failed">ファイルからの読み込みができません.</string>
<string name="io_create_dir_failed">SDカードにディレクトリを作成できません.</string>
<string name="io_create_dir_failed">SDカード上でディレクトリを作成できません.</string>
<string name="io_write_finished">SDカードへの書き込み終了.</string>
<string name="io_read_finished">SDカードからの読み込み終了.</string>
@@ -397,11 +440,11 @@ limitations under the License.
<string name="check_units_message">デフォルトの単位はメートルです.設定を変更しますか?</string>
<!-- Fake preference keys - never saved, but show options in the preferences screen -->
<!-- string name="method_bluetooth">Bluetooth</string --> <!-- duplicate -->
<string name="bluetooth_options">Bluetoothオプション</string>
<string name="bluetooth_pairing">ペアリング</string>
<string name="bluetooth_pairing_summary">ペアリングを行うには「Bluetooth設定」を開いて下さい</string>
<string name="sensor_bluetooth_options_key">bluetoothSensorsEnabled</string>
<string name="ant_options">ANTオプション</string>
<string name="sensor_options">センサーオプション</string>
<!-- Bluetooth Sensor -->
@@ -425,7 +468,7 @@ limitations under the License.
<!-- Manifest description (not seen inside the app) -->
<string name="notification_permission_label">トラック記録通知受信</string>
<string name="read_tracks_permission_label">トラック読み込み</string>
<string name="write_tracks_permission_label">トラック書き込み トラック記録の開始・終了</string>
<string name="write_tracks_permission_label">トラック書き込みとトラック記録の開始・終了</string>
<string name="notification_permission_description">トラック記録の開始・終了時に通知されます.</string>
<string name="read_tracks_permission_description">ポイントやウェイポイントといったトラックの読み込みを可能にします.</string>
<string name="write_tracks_permission_description">記録開始やウェイポイント追加といったトラック記録を可能にします.</string>
+5
View File
@@ -34,4 +34,9 @@ limitations under the License.
<string name="ant_sensor_type">ANT</string>
<string name="srm_ant_bridge_sensor_type">SRM_ANT_BRIDGE</string>
<string name="zephyr_sensor_type">ZEPHYR</string>
<!-- Send to Google URLs -->
<string name="sendtogoogle_google_fusiontables_url">google.com/fusiontables</string>
<string name="sendtogoogle_google_mymaps_url">maps.google.com</string>
<string name="sendtogoogle_google_docs_url">docs.google.com</string>
</resources>
+7 -6
View File
@@ -35,9 +35,10 @@ limitations under the License.
<!-- Error messages -->
<string name="error_no_location_manager">No location manager was found on this device!</string>
<string name="error_no_gps_location_provider">No GPS location provider was found on this device.</string>
<string name="error_sending_to_mymap">There was an error while sending your track to Google My Map. Please try again later.</string>
<string name="error_sending_to_fusiontables">There was an error while sending your track to Google Fusion Tables. Please try again later.</string>
<string name="error_sending_to_docs">There was an error while sending your track to Google Docs. Please try again later.</string>
<string name="error_sending_to_mymap">There was an error while sending your track to Google My Map.</string>
<string name="error_sending_to_fusiontables">There was an error while sending your track to Google Fusion Tables.</string>
<string name="error_sending_to_docs">There was an error while sending your track to Google Docs.</string>
<string name="error_please_try_again_later">Please try again later.</string>
<string name="error_unable_to_start_recording">Unable to start recording. Try again.</string>
<string name="error_unable_to_stop_recording">Unable to stop recording. Try again.</string>
<string name="error_unable_to_read_file">Unable to read from file.</string>
@@ -56,12 +57,13 @@ limitations under the License.
<string name="status_tracks_have_been_uploaded">Your track has been sent to maps.google.com.</string>
<string name="status_tracks_have_been_uploaded_to_new_doc">Your track has been sent to a new spreadsheet at docs.google.com.</string>
<string name="status_tracks_have_been_uploaded_to_docs">Your track has been sent to docs.google.com.</string>
<string name="status_mymap_info">It may sometimes take a few minutes before new tracks appear.</string>
<string name="status_mymap_info">It may take a few minutes before new tracks appear.</string>
<string name="status_enable_gps">Please tap here to go to Security and Location Settings and check \'enable GPS satellites\'. Press back button to return.</string>
<string name="status_approximate_location">Note: An approximate location as determined from cell towers and WIFI networks is shown.</string>
<string name="status_no_location">A location can currently not be determined. Enable more location sources (see Security and Location Settings) and make sure the sky is visible. Try again later.</string>
<string name="status_waypoint_inserted">A way point marker was inserted.</string>
<string name="status_statistics_inserted">A statistics marker was inserted.</string>
<string name="status_track_upload_status">Upload status:</string>
<!-- Progress dialog -->
<string name="progress_title">Please wait...</string>
@@ -276,7 +278,7 @@ limitations under the License.
<string name="maps_list_failed">Your maps could not be loaded at this time!</string>
<string name="open_map">Select this Map</string>
<string name="edit_map_details">Edit Map Details</string>
<string name="share_track">Share Track with Friends</string>
<string name="share_track">Share Track</string>
<string name="delete_map">Delete Map from your Account</string>
<string name="map_title">Map Title:</string>
<string name="map_description">Map Description:</string>
@@ -295,7 +297,6 @@ limitations under the License.
<string name="send_track_body_format">I think you might be interested in this track.
To view this track use Google Earth or other mapping software.</string>
<string name="share_track">Share track with friends</string>
<!-- Visibility -->
<string name="public_map">Public</string>
@@ -1,12 +1,12 @@
/*
* 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
@@ -15,20 +15,20 @@
*/
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.io.sendtogoogle.SendDialog;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager.BadTokenException;
/**
* A class to handle all dialog related events for My Tracks.
*
*
* @author Sandor Dornbush
*/
public class DialogManager {
@@ -37,14 +37,12 @@ public class DialogManager {
public static final int DIALOG_IMPORT_PROGRESS = 2;
public static final int DIALOG_PROGRESS = 3;
public static final int DIALOG_SEND_TO_GOOGLE = 4;
public static final int DIALOG_SEND_TO_GOOGLE_RESULT = 5;
public static final int DIALOG_WRITE_PROGRESS = 6;
public static final int DIALOG_WRITE_PROGRESS = 5;
private ProgressDialog progressDialog;
private ProgressDialog importProgressDialog;
private ProgressDialog writeProgressDialog;
private SendToGoogleDialog sendToGoogleDialog;
private AlertDialog sendToGoogleResultDialog;
private SendDialog sendToGoogleDialog;
private ChartSettingsDialog chartSettingsDialog;
private MyTracks activity;
@@ -52,7 +50,7 @@ public class DialogManager {
public DialogManager(MyTracks activity) {
this.activity = activity;
}
protected Dialog onCreateDialog(int id, Bundle args) {
switch (id) {
case DIALOG_CHART_SETTINGS:
@@ -77,26 +75,8 @@ public class DialogManager {
progressDialog.setProgress(10);
return progressDialog;
case DIALOG_SEND_TO_GOOGLE:
sendToGoogleDialog = new SendToGoogleDialog(activity);
sendToGoogleDialog = new SendDialog(activity);
return sendToGoogleDialog;
case DIALOG_SEND_TO_GOOGLE_RESULT:
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("Title");
builder.setMessage("Message");
builder.setPositiveButton(activity.getString(R.string.ok), null);
builder.setNeutralButton(activity.getString(R.string.share_track),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SendToGoogleDialog sendToGoogleDialog = getSendToGoogleDialog();
final boolean sentToMyMaps = sendToGoogleDialog.getSendToMyMaps();
final boolean sentToFusionTables = sendToGoogleDialog.getSendToFusionTables();
activity.shareLinkToMap(sentToMyMaps, sentToFusionTables);
dialog.dismiss();
}
});
sendToGoogleResultDialog = builder.create();
return sendToGoogleResultDialog;
case DIALOG_WRITE_PROGRESS:
writeProgressDialog = new ProgressDialog(activity);
writeProgressDialog.setIcon(android.R.drawable.ic_dialog_info);
@@ -115,24 +95,6 @@ public class DialogManager {
case DIALOG_SEND_TO_GOOGLE:
activity.resetSendToGoogleStatus();
break;
case DIALOG_SEND_TO_GOOGLE_RESULT:
boolean success = activity.getSendToGoogleSuccess();
sendToGoogleResultDialog.setTitle(
success ? R.string.success : R.string.error);
sendToGoogleResultDialog.setIcon(success
? android.R.drawable.ic_dialog_info
: android.R.drawable.ic_dialog_alert);
sendToGoogleResultDialog.setMessage(activity.getSendToGoogleResultMessage());
boolean canShare =
activity.getSendToFusionTablesTableId() != null &&
activity.getSendToMyMapsMapId() != null;
View share =
sendToGoogleResultDialog.findViewById(android.R.id.button3);
if (share != null) {
share.setVisibility(canShare ? View.VISIBLE : View.GONE);
}
break;
case DIALOG_CHART_SETTINGS:
Log.d(MyTracksConstants.TAG, "MyTracks.onPrepare chart dialog");
chartSettingsDialog.setup(activity.getChartActivity());
@@ -151,7 +113,7 @@ public class DialogManager {
}
});
}
public void setProgressValue(final int percent) {
activity.runOnUiThread(new Runnable() {
public void run() {
@@ -167,7 +129,7 @@ public class DialogManager {
/**
* @return the sendToGoogleDialog
*/
public SendToGoogleDialog getSendToGoogleDialog() {
public SendDialog getSendToGoogleDialog() {
return sendToGoogleDialog;
}
@@ -196,9 +158,9 @@ public class DialogManager {
}
/**
* Just like showDialog, but will catch a BadTokenException that sometimes
* (very rarely) gets thrown. This might happen if the user hits the "back"
* button immediately after sending tracks to google.
* Just like showDialog, but will catch a {@link BadTokenException} that
* sometimes (very rarely) gets thrown. This might happen if the user hits
* the "back" button immediately after sending tracks to google.
*
* @param id the dialog id
*/
@@ -218,6 +180,24 @@ public class DialogManager {
});
}
/**
* The equivalent of {@link #showDialogSafely(int)}, but for a specific
* dialog instance.
*/
public static void showDialogSafely(Activity activity, final Dialog dialog) {
activity.runOnUiThread(new Runnable() {
public void run() {
try {
dialog.show();
} catch (BadTokenException e) {
Log.w(MyTracksConstants.TAG, "Could not display dialog", e);
} catch (IllegalStateException e) {
Log.w(MyTracksConstants.TAG, "Could not display dialog", e);
}
}
});
}
/**
* Dismisses the progress dialog if it is showing. Executed on the UI thread.
*/
@@ -36,6 +36,10 @@ import com.google.android.apps.mytracks.io.TrackWriter;
import com.google.android.apps.mytracks.io.TrackWriterFactory;
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.mymaps.MapsService;
import com.google.android.apps.mytracks.io.sendtogoogle.ResultDialogFactory;
import com.google.android.apps.mytracks.io.sendtogoogle.SendDialog;
import com.google.android.apps.mytracks.io.sendtogoogle.SendResult;
import com.google.android.apps.mytracks.io.sendtogoogle.SendType;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.services.TrackRecordingService;
@@ -77,7 +81,9 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
@@ -139,9 +145,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
private ITrackRecordingService trackRecordingService;
/**
* Does the user want to share the current track.
*/
/**
* Does the user want to share the current track.
*/
private boolean shareRequested = false;
/**
@@ -909,11 +915,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
* Initiates the process to send tracks to google.
* This is called once the user has selected sending options via the
* SendToGoogleDialog.
*
*
* TODO: Change this whole flow to an actual state machine.
*/
public void sendToGoogle() {
SendToGoogleDialog sendToGoogleDialog =
SendDialog sendToGoogleDialog =
dialogManager.getSendToGoogleDialog();
if (sendToGoogleDialog == null) {
return;
@@ -934,7 +940,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
}
private void sendToGoogleMapsOrPickMap(SendToGoogleDialog sendToGoogleDialog) {
private void sendToGoogleMapsOrPickMap(SendDialog sendToGoogleDialog) {
if (!sendToGoogleDialog.getCreateNewMap()) {
// Ask the user to choose a map to upload into
Intent listIntent = new Intent(this, MyMapsList.class);
@@ -989,7 +995,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
private void onSendToGoogleMapsDone() {
SendToGoogleDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
SendDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
if (sendToGoogleDialog.getSendToFusionTables()) {
authenticateToFusionTables(null);
} else if (sendToGoogleDialog.getSendToDocs()) {
@@ -1029,7 +1035,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
Log.w(MyTracksConstants.TAG, "Updating table id failed.", e);
}
}
onSendToFusionTablesDone();
}
};
@@ -1044,7 +1050,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
private void onSendToFusionTablesDone() {
SendToGoogleDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
SendDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
if (sendToGoogleDialog.getSendToDocs()) {
authenticateToGoogleDocs();
} else {
@@ -1076,7 +1082,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
Log.d(MyTracksConstants.TAG, "Sending to Docs....");
setProgressValue(50);
setProgressMessage(R.string.progress_message_sending_docs);
final SendToDocs sender = new SendToDocs(this,
final SendToDocs sender = new SendToDocs(this,
authMap.get(SendToDocs.GDATA_SERVICE_NAME_TRIX),
authMap.get(SendToDocs.GDATA_SERVICE_NAME_DOCLIST), trackId);
sendToTrackId = trackId;
@@ -1099,30 +1105,53 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
private void onSendToGoogleDone() {
SendToGoogleDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
SendDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
final boolean sentToMyMaps = sendToGoogleDialog.getSendToMyMaps();
final boolean sentToFusionTables = sendToGoogleDialog.getSendToFusionTables();
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
runOnUiThread(new Runnable() {
public void run() {
if (shareRequested) {
Toast.makeText(MyTracks.this, getSendToGoogleResultMessage(), Toast.LENGTH_LONG)
.show();
if (shareLinkToMap(sentToMyMaps, sentToFusionTables)) {
return;
}
// We've finished sending the track to the user-selected services. Now
// we tell them the results of the upload, and optionally share the track.
// There are a few different paths through this code:
//
// 1. The user pre-requested a share (shareRequested == true). We're going
// to display the result dialog *without* the share button (the share
// listener will be null). The OK button listener will initiate the
// share.
//
// 2. The user did not pre-request a share, and the set of services to
// which we succeeded in uploading the track are compatible with
// sharing. We'll display a share button (the share listener will be
// non-null), and will share the link if the user clicks it.
//
// 3. The user did not pre-request a share, and the set of services to
// which we succeeded in uploading the track are incompatible with
// sharing. We won't display a share button.
final boolean canShare = getSendToFusionTablesTableId() != null
|| getSendToMyMapsMapId() != null;
DialogInterface.OnClickListener doShareListener = null;
if (canShare) {
doShareListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
shareLinkToMap(sentToMyMaps, sentToFusionTables);
}
};
}
// If anything failed or sharing was not requested, show the dialog
dialogManager.showDialogSafely(
DialogManager.DIALOG_SEND_TO_GOOGLE_RESULT);
}
});
DialogInterface.OnClickListener onOkListener = (canShare && shareRequested)
? doShareListener : null;
DialogInterface.OnClickListener onShareListener = (canShare && !shareRequested)
? doShareListener : null;
AlertDialog sendToGoogleResultDialog = ResultDialogFactory.makeDialog(this,
makeSendToGoogleResults(sendToGoogleDialog), onOkListener, onShareListener);
DialogManager.showDialogSafely(this, sendToGoogleResultDialog);
}
boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) {
private boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) {
String url = null;
if (sentToMyMaps && sendToMyMapsSuccess) {
// Prefer a link to My Maps
@@ -1145,27 +1174,24 @@ public class MyTracks extends TabActivity implements OnTouchListener,
return SendToFusionTables.getMapVisualizationUrl(track);
}
String getSendToGoogleResultMessage() {
StringBuilder message = new StringBuilder();
SendToGoogleDialog sendToGoogleDialog =
dialogManager.getSendToGoogleDialog();
if (sendToGoogleDialog.getSendToMyMaps()) {
message.append(sendToMyMapsMessage);
/**
* Creates a list of {@link SendResult} instances based on the set of
* services selected in {@link SendDialog} and the results as known to
* this class.
*/
private List<SendResult> makeSendToGoogleResults(SendDialog dialog) {
List<SendResult> results = new ArrayList<SendResult>();
if (dialog.getSendToMyMaps()) {
results.add(new SendResult(SendType.MYMAPS, sendToMyMapsSuccess));
}
if (sendToGoogleDialog.getSendToFusionTables()) {
message.append(sendToFusionTablesMessage);
if (dialog.getSendToFusionTables()) {
results.add(new SendResult(SendType.FUSION_TABLES, sendToFusionTablesSuccess));
}
if (sendToGoogleDialog.getSendToDocs()) {
if (message.length() > 0) {
message.append(' ');
}
message.append(sendToDocsMessage);
if (dialog.getSendToDocs()) {
results.add(new SendResult(SendType.DOCS, sendToDocsSuccess));
}
if (sendToMyMapsSuccess && sendToFusionTablesSuccess && sendToDocsSuccess) {
message.append(' ');
message.append(getString(R.string.status_mymap_info));
}
return message.toString();
return results;
}
void clearSelectedTrack() {
@@ -1293,7 +1319,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
public boolean getSendToGoogleSuccess() {
return sendToFusionTablesSuccess && sendToDocsSuccess;
return sendToMyMapsSuccess && sendToFusionTablesSuccess && sendToDocsSuccess;
}
// @VisibleForTesting
@@ -1305,12 +1331,12 @@ public class MyTracks extends TabActivity implements OnTouchListener,
SharedPreferences getSharedPreferences() {
return sharedPreferences;
}
// @VisibleForTesting
static void clearInstance() {
instance = null;
}
// @VisibleForTesting
ITrackRecordingService getTrackRecordingService() {
return trackRecordingService;
@@ -232,10 +232,14 @@ public class MyTracksSettings extends PreferenceActivity {
// Update the ANT+ sensors.
// TODO: Only enable on phones that have ANT+.
findPreference(getString(R.string.ant_heart_rate_sensor_id_key))
.setEnabled(getString(R.string.ant_sensor_type).equals(sensorType));
findPreference(getString(R.string.ant_srm_bridge_sensor_id_key))
.setEnabled(getString(R.string.srm_ant_bridge_sensor_type).equals(sensorType));
Preference antHrm = findPreference(getString(R.string.ant_heart_rate_sensor_id_key));
Preference antSrm = findPreference(getString(R.string.ant_srm_bridge_sensor_id_key));
if (antHrm != null && antSrm != null) {
antHrm
.setEnabled(getString(R.string.ant_sensor_type).equals(sensorType));
antSrm
.setEnabled(getString(R.string.srm_ant_bridge_sensor_type).equals(sensorType));
}
}
/**
@@ -172,7 +172,7 @@ public class SendToFusionTables implements Runnable {
private void doUpload() {
((GoogleHeaders) transport.defaultHeaders).setGoogleLogin(auth.getAuthToken());
int statusMessageId = R.string.error_sending_to_fusiontables;
boolean success = true;
boolean success = false;
try {
progressIndicator.setProgressValue(PROGRESS_INITIALIZATION);
progressIndicator.setProgressMessage(R.string.progress_message_reading_track);
@@ -204,10 +204,11 @@ public class SendToFusionTables implements Runnable {
}
statusMessageId = R.string.status_new_fusiontable_has_been_created;
success = true;
Log.d(MyTracksConstants.TAG, "SendToFusionTables: Done: " + success);
progressIndicator.setProgressValue(PROGRESS_COMPLETE);
} finally {
} finally {
final boolean finalSuccess = success;
final int finalStatusMessageId = statusMessageId;
context.runOnUiThread(new Runnable() {
@@ -0,0 +1,106 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.view.View;
import android.widget.ListView;
import java.util.List;
/**
* Creates the dialog used to display the results of sending track data to
* Google. The dialog lists the services to which data was uploaded, along
* with an indicator of success/failure. If possible, a button is displayed
* offering to share the uploaded track.
*
* Implementation note: This class is a factory, rather than a {@link Dialog}
* subclass, because alert dialogs have to be created with
* {@link AlertDialog.Builder}. Attempts to subclass {@link AlertDialog}
* directly have been unsuccessful, as {@link AlertDialog.Builder} uses a
* private subclass to implement most of the interesting behavior.
*
* @author Matthew Simmons
*/
public class ResultDialogFactory {
private ResultDialogFactory() {}
/**
* Create a send-to-Google result dialog. The caller is responsible for
* showing it.
*
* @param activity the activity associated with the dialog
* @param results the results to be displayed in the dialog
* @param onOkClickListener the listener to invoke if the OK button is
* clicked
* @param onShareClickListener the listener to invoke if the Share button is
* clicked. If no share listener is provided, the Share button will not
* be displayed.
* @return the created dialog
*/
public static AlertDialog makeDialog(Activity activity, List<SendResult> results,
DialogInterface.OnClickListener onOkClickListener,
DialogInterface.OnClickListener onShareClickListener) {
boolean success = true;
for (SendResult result : results) {
if (!result.isSuccess()) {
success = false;
break;
}
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
.setView(makeDialogContent(activity, results, success));
if (success) {
builder.setTitle(R.string.success);
builder.setIcon(android.R.drawable.ic_dialog_info);
} else {
builder.setTitle(R.string.error);
builder.setIcon(android.R.drawable.ic_dialog_alert);
}
builder.setPositiveButton(activity.getString(R.string.ok), onOkClickListener);
if (onShareClickListener != null) {
builder.setNeutralButton(activity.getString(R.string.share_track),
onShareClickListener);
}
return builder.create();
}
private static View makeDialogContent(Activity activity, List<SendResult> results,
boolean success) {
ResultListAdapter resultListAdapter = new ResultListAdapter(activity,
R.layout.send_to_google_result_list_item, results);
View content = activity.getLayoutInflater().inflate(R.layout.send_to_google_result, null);
ListView resultList = (ListView) content.findViewById(R.id.send_to_google_result_list);
resultList.setAdapter(resultListAdapter);
content.findViewById(R.id.send_to_google_result_comment)
.setVisibility(success ? View.VISIBLE : View.GONE);
content.findViewById(R.id.send_to_google_result_error)
.setVisibility(success ? View.GONE : View.VISIBLE);
return content;
}
}
@@ -0,0 +1,85 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
import java.util.List;
/**
* This class implements the {@link ListAdapter} used by the send-to-Google
* result dialog created by {@link ResultDialogFactory}. It generates views
* for each entry in an array of {@link SendResult} instances.
* @author Matthew Simmons
*/
class ResultListAdapter extends ArrayAdapter<SendResult> {
public ResultListAdapter(Context context, int textViewResourceId, List<SendResult> results) {
super(context, textViewResourceId, results);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater
= (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.send_to_google_result_list_item, null);
}
SendResult result = getItem(position);
setImage(view, result.isSuccess() ? R.drawable.success : R.drawable.failure);
setName(view, result.getType().getServiceName());
setUrl(view, result.getType().getServiceUrl());
return view;
}
@Override
public boolean areAllItemsEnabled() {
// We don't want the displayed items to be clickable
return false;
}
// The following protected methods exist to be overridden for testing
// purposes. Doing so insulates the test class from the details of the
// layout.
protected void setImage(View content, int drawableId) {
ImageView imageView = (ImageView) content.findViewById(R.id.send_to_google_result_icon);
imageView.setImageDrawable(getContext().getResources().getDrawable(drawableId));
}
protected void setName(View content, int nameId) {
setTextViewText(content, R.id.send_to_google_result_name, nameId);
}
protected void setUrl(View content, int urlId) {
setTextViewText(content, R.id.send_to_google_result_url, urlId);
}
private void setTextViewText(View content, int viewId, int textId) {
TextView textView = (TextView) content.findViewById(viewId);
textView.setText(getContext().getString(textId));
}
};
@@ -1,20 +1,23 @@
/*
* Copyright 2008 Google Inc.
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks;
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.apps.mytracks.DialogManager;
import com.google.android.apps.mytracks.MyTracks;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.maps.mytracks.R;
import android.app.Dialog;
@@ -37,7 +40,7 @@ import android.widget.RadioGroup;
*
* @author Leif Hendrik Wilden
*/
public class SendToGoogleDialog extends Dialog {
public class SendDialog extends Dialog {
private RadioGroup groupMyMaps;
private RadioButton createNewMapRadioButton;
@@ -49,7 +52,7 @@ public class SendToGoogleDialog extends Dialog {
private RadioButton sendStatsAndPointsRadioButton;
private Button sendButton;
public SendToGoogleDialog(Context context) {
public SendDialog(Context context) {
super(context);
}
@@ -81,8 +84,6 @@ public class SendToGoogleDialog extends Dialog {
sendToFusionTablesCheckBox.isChecked() ||
sendToDocsCheckBox.isChecked());
groupMyMaps.setVisibility(sendToMyMapsCheckBox.isChecked() ? View.VISIBLE : View.INVISIBLE);
//groupDocs.setVisibility(
// sendToDocsCheckBox.isChecked() ? View.VISIBLE : View.INVISIBLE);
}
};
@@ -0,0 +1,46 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
/**
* This class represents the the result of the uploading of track data to a
* single service.
*
* @author Matthew Simmons
*/
public class SendResult {
private final SendType type;
private final boolean success;
/**
* @param type the service to which track data was uploaded
* @param success true if the uploading succeeded
*/
public SendResult(SendType type, boolean success) {
this.type = type;
this.success = success;
}
/** Returns the service to which the track data was uploaded */
public SendType getType() {
return type;
}
/** Returns true if the uploading succeeded */
public boolean isSuccess() {
return success;
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.maps.mytracks.R;
/**
* Enumerates the services to which we can upload track data.
*
* @author Matthew Simmons
*/
public enum SendType {
MYMAPS(R.string.sendtogoogle_google_mymaps,
R.string.sendtogoogle_google_mymaps_url),
FUSION_TABLES(R.string.sendtogoogle_google_fusiontables,
R.string.sendtogoogle_google_fusiontables_url),
DOCS(R.string.sendtogoogle_google_docs,
R.string.sendtogoogle_google_docs_url);
private int serviceName;
private int serviceUrl;
private SendType(int serviceName, int serviceUrl) {
this.serviceName = serviceName;
this.serviceUrl = serviceUrl;
}
/** Returns the resource ID for the printable (short) name of the service */
public int getServiceName() {
return serviceName;
}
/** Returns the resource ID for the service's URL */
public int getServiceUrl() {
return serviceUrl;
}
}
@@ -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
@@ -128,6 +128,25 @@ public class StatusAnnouncerTask implements PeriodicTask {
*/
@Override
public void run(TrackRecordingService service) {
if (service == null) {
Log.e(MyTracksConstants.TAG, "StatusAnnouncer TrackRecordingService not initialized");
return;
}
runWithStatistics(service.getTripStatistics());
}
/**
* This method exists as a convenience for testing code, allowing said code
* to avoid needing to instantiate an entire {@link TrackRecordingService}
* just to test the announcer.
*/
protected void runWithStatistics(TripStatistics statistics) {
if (statistics == null) {
Log.e(MyTracksConstants.TAG, "StatusAnnouncer stats not initialized.");
return;
}
if (!ready || tts == null) {
Log.e(MyTracksConstants.TAG, "StatusAnnouncer Tts not ready.");
return;
@@ -139,12 +158,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
return;
}
if (service == null || service.getTripStatistics() == null) {
Log.e(MyTracksConstants.TAG, "StatusAnnouncer stats not initialized.");
return;
}
String announcement = getAnnouncement(service.getTripStatistics());
String announcement = getAnnouncement(statistics);
Log.d(MyTracksConstants.TAG, "Announcement: " + announcement);
speakAnnouncment(announcement);
}
@@ -165,7 +179,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
boolean metricUnits = true;
boolean reportSpeed = true;
if (preferences != null) {
metricUnits =
metricUnits =
preferences.getBoolean(context.getString(R.string.metric_units_key),
true);
reportSpeed =
@@ -902,7 +902,7 @@ public class TrackRecordingService extends Service implements LocationListener {
// Make it an impossible location.
Location l = new Location("");
l.setLatitude(100);
l.setLongitude(200);
l.setLongitude(180);
wpt.setLocation(l);
} else {
// A null location is ok, and expected on track start.
@@ -1,12 +1,12 @@
/*
* 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
@@ -15,7 +15,8 @@
*/
package com.google.android.apps.mytracks;
import android.app.AlertDialog;
import com.google.android.apps.mytracks.io.sendtogoogle.SendDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.test.ActivityInstrumentationTestCase2;
@@ -66,15 +67,7 @@ public class DialogManagerTest
Dialog d =
getActivity().onCreateDialog(DialogManager.DIALOG_SEND_TO_GOOGLE, null);
assertNotNull(d);
assertTrue(d instanceof SendToGoogleDialog);
}
public void test_onCreateSendToGoogleResult() {
Dialog d =
getActivity().onCreateDialog(
DialogManager.DIALOG_SEND_TO_GOOGLE_RESULT, null);
assertNotNull(d);
assertTrue(d instanceof AlertDialog);
assertTrue(d instanceof SendDialog);
}
public void test_onCreateWriteProgress() {
@@ -18,31 +18,31 @@ package com.google.android.apps.mytracks.io.docs;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.io.AuthManager;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.maps.mytracks.R;
import com.google.android.testing.mocking.AndroidMock;
import com.google.android.testing.mocking.UsesMocks;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.content.res.Resources;
import android.test.mock.MockContext;
import android.test.mock.MockResources;
import junit.framework.TestCase;
import java.io.IOException;
import junit.framework.TestCase;
/**
* Tests for {@link DocsHelper#addTrackRow}
*
*
* @author Matthew Simmons
*/
public class DocsHelper_AddTrackRowTest extends TestCase {
private static final long TIME = 1288721514000L;
private static class StringWritingDocsHelper extends DocsHelper {
String writtenSheetUri = null;
String writtenData = null;
@Override
protected void writeRowData(AuthManager trixAuth, String worksheetUri,
String postText) {
@@ -54,7 +54,7 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
public void testAddTrackRow_imperial() throws Exception {
StringWritingDocsHelper docsHelper = new StringWritingDocsHelper();
addTrackRow(docsHelper, false);
String expectedData =
"<entry xmlns='http://www.w3.org/2005/Atom' "
+ "xmlns:gsx='http://schemas.google.com/spreadsheets/2006/extended'>"
@@ -81,11 +81,11 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
+ "</entry>";
assertEquals(
"http://spreadsheets.google.com/feeds/list/ssid/wsid/private/full",
"http://spreadsheets.google.com/feeds/list/ssid/wsid/private/full",
docsHelper.writtenSheetUri);
assertEquals(expectedData, docsHelper.writtenData);
}
public void testAddTrackRow_metric() throws Exception {
StringWritingDocsHelper docsHelper = new StringWritingDocsHelper();
addTrackRow(docsHelper, true);
@@ -100,18 +100,17 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
"<gsx:speedunit><![CDATA[kph]]></gsx:speedunit>"));
assertTrue(docsHelper.writtenData.contains(
"<gsx:elevationunit><![CDATA[meter]]></gsx:elevationunit>"));
assertTrue(docsHelper.writtenData.contains(
"<gsx:distance><![CDATA[20.00]]></gsx:distance>"));
}
@UsesMocks({AuthManager.class, MockContext.class, MockResources.class,
Track.class})
/** Adds a row to the spreadsheet, using the provided helper. */
private void addTrackRow(DocsHelper docsHelper, boolean useMetric)
@UsesMocks({AuthManager.class, MockResources.class, Track.class})
private void addTrackRow(DocsHelper docsHelper, boolean useMetric)
throws IOException {
Resources mockResources = AndroidMock.createMock(MockResources.class);
final Resources mockResources = AndroidMock.createMock(MockResources.class);
if (useMetric) {
AndroidMock.expect(mockResources.getString(R.string.kilometer))
.andReturn("km");
@@ -128,15 +127,17 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
.andReturn("feet");
}
AndroidMock.replay(mockResources);
Context mockContext = AndroidMock.createMock(MockContext.class);
AndroidMock.expect(mockContext.getResources())
.andReturn(mockResources).anyTimes();
AndroidMock.replay(mockContext);
Context mockContext = new MockContext() {
@Override
public Resources getResources() {
return mockResources;
}
};
AuthManager mockAuthManager = AndroidMock.createMock(AuthManager.class);
AndroidMock.replay(mockAuthManager);
TripStatistics stats = new TripStatistics();
stats.setStartTime(TIME);
stats.setTotalTime(5000);
@@ -146,14 +147,14 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
stats.setTotalElevationGain(6000);
stats.setMinElevation(-500);
stats.setMaxElevation(550);
Track track = new Track();
track.setName("trackName");
track.setDescription("trackDescription");
track.setMapId("trackMapId");
track.setStatistics(stats);
docsHelper.addTrackRow(mockContext, mockAuthManager, "ssid", "wsid",
docsHelper.addTrackRow(mockContext, mockAuthManager, "ssid", "wsid",
track, useMetric);
}
}
@@ -0,0 +1,121 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.apps.mytracks.MyTracks;
import com.google.android.maps.mytracks.R;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
/**
* Tests {@link ResultDialogFactory}.
*
* @author Matthew Simmons
*/
public class ResultDialogFactoryTest extends ActivityInstrumentationTestCase2<MyTracks> {
public ResultDialogFactoryTest() {
super(MyTracks.class);
}
private List<SendResult> makeResults(SendResult... results) {
List<SendResult> resultsList = new ArrayList<SendResult>();
for (SendResult result : results) {
resultsList.add(result);
}
return resultsList;
}
private DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
};
public void testSuccess_noShare() {
List<SendResult> results = makeResults(new SendResult(SendType.MYMAPS, true),
new SendResult(SendType.DOCS, true));
AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results, clickListener, null);
dialog.show();
ListView listView = (ListView) dialog.findViewById(R.id.send_to_google_result_list);
ListAdapter listAdapter = listView.getAdapter();
assertEquals(2, listAdapter.getCount());
assertEquals(SendType.MYMAPS, ((SendResult) listAdapter.getItem(0)).getType());
assertEquals(SendType.DOCS, ((SendResult) listAdapter.getItem(1)).getType());
// Checking the return code of Dialog#getButton doesn't appear to be
// sufficient, as a Button will be returned even if it doesn't appear in
// the rendered dialog.
assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_POSITIVE).getVisibility());
assertEquals(View.GONE, dialog.getButton(AlertDialog.BUTTON_NEUTRAL).getVisibility());
assertEquals(View.VISIBLE,
dialog.findViewById(R.id.send_to_google_result_comment).getVisibility());
assertEquals(View.GONE,
dialog.findViewById(R.id.send_to_google_result_error).getVisibility());
// TODO: Test correct listener invocation. Neither TouchUtils#clickView
// nor Button#performClick appear to cause listener invocation. This
// might be Android bug
// http://code.google.com/p/android/issues/detail?id=6564
}
public void testSuccess_share() {
List<SendResult> results = makeResults(new SendResult(SendType.MYMAPS, true),
new SendResult(SendType.DOCS, true));
AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results,
clickListener, clickListener);
dialog.show();
assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_POSITIVE).getVisibility());
assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_NEUTRAL).getVisibility());
}
public void testFailure_noShare() {
List<SendResult> results = makeResults(new SendResult(SendType.MYMAPS, true),
new SendResult(SendType.DOCS, false));
AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results, clickListener, null);
dialog.show();
assertEquals(View.GONE,
dialog.findViewById(R.id.send_to_google_result_comment).getVisibility());
assertEquals(View.VISIBLE,
dialog.findViewById(R.id.send_to_google_result_error).getVisibility());
}
public void testFailure_share() {
List<SendResult> results = makeResults(new SendResult(SendType.MYMAPS, true),
new SendResult(SendType.DOCS, false));
AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results,
clickListener, clickListener);
dialog.show();
assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_POSITIVE).getVisibility());
assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_NEUTRAL).getVisibility());
}
}
@@ -0,0 +1,116 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.test.AndroidTestCase;
import android.view.LayoutInflater;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* Tests {@link ResultListAdapter}.
*
* @author Matthew Simmons
*/
public class ResultListAdapterTest extends AndroidTestCase {
private static class TestResultListAdapter extends ResultListAdapter {
public View contentView;
public int drawableId;
public int nameId;
public int urlId;
public TestResultListAdapter(Context context, List<SendResult> results) {
super(context, 0, results);
}
@Override
protected void setImage(View content, int drawableId) {
saveContentView(content);
this.drawableId = drawableId;
}
@Override
protected void setName(View content, int nameId) {
saveContentView(content);
this.nameId = nameId;
}
@Override
protected void setUrl(View content, int urlId) {
saveContentView(content);
this.urlId = urlId;
}
private void saveContentView(View contentView) {
if (this.contentView == null) {
this.contentView = contentView;
} else {
AndroidTestCase.assertEquals(this.contentView, contentView);
}
}
}
private final SendType sendType = SendType.MYMAPS;
private View inflateContentView(int viewId) {
LayoutInflater layoutInflater
= (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return layoutInflater.inflate(viewId, null);
}
private List<SendResult> makeResult(SendType type, boolean success) {
List<SendResult> results = new ArrayList<SendResult>();
results.add(new SendResult(type, success));
return results;
}
public void testSuccess_createsNewView() {
TestResultListAdapter adapter = new TestResultListAdapter(getContext(),
makeResult(sendType, true));
adapter.getView(0, null, null);
assertEquals(R.drawable.success, adapter.drawableId);
assertEquals(sendType.getServiceName(), adapter.nameId);
assertEquals(sendType.getServiceUrl(), adapter.urlId);
}
public void testSuccess_reusesView() {
View contentView = inflateContentView(R.layout.send_to_google_result_list_item);
TestResultListAdapter adapter = new TestResultListAdapter(getContext(),
makeResult(sendType, true));
adapter.getView(0, contentView, null);
assertEquals(contentView, adapter.contentView);
assertEquals(R.drawable.success, adapter.drawableId);
assertEquals(sendType.getServiceName(), adapter.nameId);
assertEquals(sendType.getServiceUrl(), adapter.urlId);
}
public void testFailure() {
TestResultListAdapter adapter = new TestResultListAdapter(getContext(),
makeResult(sendType, false));
adapter.getView(0, null, null);
assertEquals(R.drawable.failure, adapter.drawableId);
assertEquals(sendType.getServiceName(), adapter.nameId);
assertEquals(sendType.getServiceUrl(), adapter.urlId);
}
}
@@ -1,12 +1,12 @@
/*
* 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
@@ -255,7 +255,6 @@ public class StatusAnnouncerTaskTest extends AndroidTestCase {
@UsesMocks({
StatusAnnouncerTask.class,
StringUtils.class,
TrackRecordingService.class,
})
@Override
protected void setUp() throws Exception {
@@ -390,9 +389,6 @@ public class StatusAnnouncerTaskTest extends AndroidTestCase {
public void testRun() throws Exception {
// Expect service data calls
TripStatistics stats = new TripStatistics();
TrackRecordingService service =
AndroidMock.createMock(TrackRecordingService.class);
expect(service.getTripStatistics()).andStubReturn(stats);
// Expect announcement building call
expect(mockTask.getAnnouncement(same(stats))).andStubReturn(ANNOUNCEMENT);
@@ -407,75 +403,63 @@ public class StatusAnnouncerTaskTest extends AndroidTestCase {
.andReturn(TextToSpeech.SUCCESS);
// Run the announcement
AndroidMock.replay(tts, stringUtils, service);
task.run(service);
AndroidMock.verify(mockTask, tts, stringUtils, service);
AndroidMock.replay(tts, stringUtils);
task.runWithStatistics(stats);
AndroidMock.verify(mockTask, tts, stringUtils);
}
public void testRun_notReady() throws Exception {
TrackRecordingService service =
AndroidMock.createMock(TrackRecordingService.class);
// Put task in "not ready" state
startTask(TextToSpeech.ERROR);
// Run the announcement
AndroidMock.replay(tts, stringUtils, service);
task.run(service);
AndroidMock.verify(mockTask, tts, stringUtils, service);
AndroidMock.replay(tts, stringUtils);
task.runWithStatistics(null);
AndroidMock.verify(mockTask, tts, stringUtils);
}
public void testRun_duringCall() throws Exception {
TrackRecordingService service =
AndroidMock.createMock(TrackRecordingService.class);
startTask(TextToSpeech.SUCCESS);
expect(tts.isSpeaking()).andStubReturn(false);
// Run the announcement
AndroidMock.replay(tts, stringUtils, service);
AndroidMock.replay(tts, stringUtils);
PhoneStateListener phoneListener = phoneListenerCapture.getValue();
phoneListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK, null);
task.run(service);
AndroidMock.verify(mockTask, tts, stringUtils, service);
task.runWithStatistics(null);
AndroidMock.verify(mockTask, tts, stringUtils);
}
public void testRun_ringWhileSpeaking() throws Exception {
TrackRecordingService service =
AndroidMock.createMock(TrackRecordingService.class);
startTask(TextToSpeech.SUCCESS);
expect(tts.isSpeaking()).andStubReturn(true);
expect(tts.stop()).andReturn(TextToSpeech.SUCCESS);
AndroidMock.replay(tts, stringUtils, service);
AndroidMock.replay(tts, stringUtils);
// Update the state to ringing - this should stop the current announcement.
PhoneStateListener phoneListener = phoneListenerCapture.getValue();
phoneListener.onCallStateChanged(TelephonyManager.CALL_STATE_RINGING, null);
// Run the announcement - this should do nothing.
task.run(service);
task.runWithStatistics(null);
AndroidMock.verify(mockTask, tts, stringUtils, service);
AndroidMock.verify(mockTask, tts, stringUtils);
}
public void testRun_whileRinging() throws Exception {
TrackRecordingService service =
AndroidMock.createMock(TrackRecordingService.class);
startTask(TextToSpeech.SUCCESS);
expect(tts.isSpeaking()).andStubReturn(false);
// Run the announcement
AndroidMock.replay(tts, stringUtils, service);
AndroidMock.replay(tts, stringUtils);
PhoneStateListener phoneListener = phoneListenerCapture.getValue();
phoneListener.onCallStateChanged(TelephonyManager.CALL_STATE_RINGING, null);
task.run(service);
AndroidMock.verify(mockTask, tts, stringUtils, service);
task.runWithStatistics(null);
AndroidMock.verify(mockTask, tts, stringUtils);
}
public void testRun_noService() throws Exception {
@@ -489,16 +473,13 @@ public class StatusAnnouncerTaskTest extends AndroidTestCase {
public void testRun_noStats() throws Exception {
// Expect service data calls
TrackRecordingService service =
AndroidMock.createMock(TrackRecordingService.class);
expect(service.getTripStatistics()).andStubReturn(null);
startTask(TextToSpeech.SUCCESS);
// Run the announcement
AndroidMock.replay(tts, stringUtils, service);
task.run(service);
AndroidMock.verify(mockTask, tts, stringUtils, service);
AndroidMock.replay(tts, stringUtils);
task.runWithStatistics(null);
AndroidMock.verify(mockTask, tts, stringUtils);
}
private void startTask(int state) {