Merge to head

This commit is contained in:
Rodrigo Damazio
2012-01-05 22:23:56 -02:00
26 changed files with 346 additions and 341 deletions
+22 -28
View File
@@ -23,39 +23,33 @@ limitations under the License.
android:layout_width="fill_parent"
android:orientation="vertical"
android:padding="10dp">
<!-- Title -->
<TableLayout
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:padding="2dp"
android:shrinkColumns="0"
android:stretchColumns="1">
<TableRow>
<ImageView
android:layout_column="0"
android:orientation="horizontal">
<ImageView
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/arrow_icon"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="vertical">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scaleType="center"
android:src="@drawable/arrow_icon"/>
<LinearLayout
android:layout_column="1"
android:layout_width="fill_parent"
android:text="@string/my_tracks_app_name"
android:textSize="30sp"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="vertical">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/my_tracks_app_name"
android:textSize="30sp"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/about_copyright_notice"
android:textSize="15sp"/>
</LinearLayout>
</TableRow>
</TableLayout>
android:layout_width="fill_parent"
android:text="@string/about_copyright_notice"
android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>
<!-- Team -->
<TextView
+46 -81
View File
@@ -18,106 +18,71 @@ limitations under the License.
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical">
<LinearLayout
<TextView
android:background="@drawable/list_bar"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<TextView
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_width="fill_parent"
android:text="@string/send_google_title"
android:textColor="#fff"
android:textSize="20dip"/>
</LinearLayout>
android:layout_width="fill_parent"
android:paddingLeft="10dp"
android:text="@string/send_google_title"
android:textColor="@color/white"
android:textSize="20sp"/>
<ScrollView
android:layout_height="0dip"
android:layout_marginBottom="5dip"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip"
android:layout_height="0dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:layout_width="fill_parent">
<TableLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:stretchColumns="1">
<!-- Google My Maps -->
<TableRow>
<!-- Google Maps -->
<TableRow android:id="@+id/send_google_maps_row">
<ImageView
android:src="@drawable/mymaps_icon"
style="@style/SendGoogleImageView"/>
<CheckBox
android:id="@+id/send_google_my_maps"
android:text="@string/send_google_my_maps"
style="@style/SendGoogleCheckBox"/>
</TableRow>
<TableRow android:id="@+id/send_google_maps_option_row">
<RadioGroup
android:layout_column="1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/mymaps_icon"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_width="fill_parent"
android:orientation="vertical">
<CheckBox
android:checked="true"
android:id="@+id/send_google_my_maps"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/send_google_my_maps"
android:textSize="18dip"/>
<RadioGroup
android:id="@+id/send_google_my_maps_group"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<RadioButton
android:id="@+id/send_google_new_map"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/send_google_new_map"/>
<RadioButton
android:id="@+id/send_google_existing_map"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/send_google_existing_map"/>
</RadioGroup>
</LinearLayout>
android:layout_marginLeft="10dp"
android:layout_width="0dp">
<RadioButton
android:id="@+id/send_google_new_map"
android:text="@string/send_google_new_map"
style="@style/SendGoogleRadioButton"/>
<RadioButton
android:id="@+id/send_google_existing_map"
android:text="@string/send_google_existing_map"
style="@style/SendGoogleRadioButton"/>
</RadioGroup>
</TableRow>
<!-- Google Fusion Tables -->
<TableRow>
<TableRow android:id="@+id/send_google_fusion_tables_row">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/googledocs_icon"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_width="fill_parent"
android:orientation="vertical">
<CheckBox
android:checked="true"
android:id="@+id/send_google_fusion_tables"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/send_google_fusion_tables"
android:textSize="18dip"/>
</LinearLayout>
android:src="@drawable/googledocs_icon"
style="@style/SendGoogleImageView"/>
<CheckBox
android:id="@+id/send_google_fusion_tables"
android:text="@string/send_google_fusion_tables"
style="@style/SendGoogleCheckBox"/>
</TableRow>
<!-- Google Docs -->
<TableRow android:id="@+id/send_google_docs_table_row">
<TableRow android:id="@+id/send_google_docs_row">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/googledocs_icon"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_width="fill_parent"
android:orientation="vertical">
<CheckBox
android:checked="true"
android:id="@+id/send_google_docs"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/send_google_docs"
android:textSize="18dip"/>
</LinearLayout>
android:src="@drawable/googledocs_icon"
style="@style/SendGoogleImageView"/>
<CheckBox
android:id="@+id/send_google_docs"
android:text="@string/send_google_docs"
style="@style/SendGoogleCheckBox"/>
</TableRow>
</TableLayout>
</ScrollView>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+12 -10
View File
@@ -1129,7 +1129,6 @@ limitations under the License.
translation_description="When sending a track to Google Maps, the radio option to use an
existing map as opposed to create a new map.
Character limit: ~21 (1 line)
Screenshot: send_google_choose_service.png">
Use existing map
</string>
@@ -1151,7 +1150,6 @@ limitations under the License.
translation_description="When sending a track to Google Maps, the radio option to create a
new map as opposed to use an existing map.
Character limit: ~21 (1 line)
Screenshot: send_google_choose_service.png">
Create new map
</string>
@@ -2310,6 +2308,18 @@ limitations under the License.
Screenshot: track_list_share_options.png">
A %1$s file
</string>
<string name="track_list_share_fusion_table"
translation_description="In the context menu for a track, under the 'Share with friends...'
option, the menu option to save a track to Google Fusion Tables and share the Fusion Table
with friends. 'Fusion Table' in this context means a Google Fusion Table.">
Fusion Table
</string>
<string name="track_list_share_map"
translation_description="In the context menu for a track, under the 'Share with friends...'
option, the menu option to save a track to Google Maps and share the Map with friends. 'Map'
in this context means a Google Map.">
Map
</string>
<string name="track_list_share_track"
translation_description="In the context menu for a track, the menu option to share the track
with friends through other applications.
@@ -2317,14 +2327,6 @@ limitations under the License.
Screenshot: track_list_context_menu.png">
Share with friends...
</string>
<string name="track_list_share_url"
translation_description="In the context menu for a track, under the 'Share with friends...'
option, the menu option to save a track to Google Maps or Google Fusion Tables and share the
URL with friends.
Screenshot: track_list_share_options.png">
Map or Fusion Table URL
</string>
<string name="track_list_show_on_map"
translation_description="In the context menu for a track, the menu option to show the track on
the map.
+29 -6
View File
@@ -46,9 +46,9 @@ limitations under the License.
<style name="Button">
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_width">0dip</item>
<item name="android:layout_width">0dp</item>
<item name="android:maxLines">2</item>
<item name="android:textSize">14dip</item>
<item name="android:textSize">14sp</item>
</style>
<!-- Button layout -->
@@ -56,17 +56,18 @@ limitations under the License.
<item name="android:background">@drawable/list_bar</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:measureWithLargestChild">true</item>
<item name="android:orientation">horizontal</item>
<item name="android:paddingLeft">2dip</item>
<item name="android:paddingRight">2dip</item>
<item name="android:paddingTop">4dip</item>
<item name="android:paddingLeft">2dp</item>
<item name="android:paddingRight">2dp</item>
<item name="android:paddingTop">4dp</item>
</style>
<!-- Button spacer -->
<style name="ButtonSpacer">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">0.25</item>
<item name="android:layout_width">0dip</item>
<item name="android:layout_width">0dp</item>
<item name="android:orientation">horizontal</item>
<item name="android:visibility">gone</item>
</style>
@@ -106,6 +107,28 @@ limitations under the License.
<item name="android:layout_width">wrap_content</item>
</style>
<!-- Send Google CheckBox -->
<style name="SendGoogleCheckBox">
<item name="android:checked">true</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_marginLeft">10dp</item>
<item name="android:layout_width">0dp</item>
<item name="android:textSize">18sp</item>
</style>
<!-- Send Google ImageView -->
<style name="SendGoogleImageView">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
</style>
<!-- Send Google RadioButton -->
<style name="SendGoogleRadioButton">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:textSize">18sp</item>
</style>
<style name="SensorStateLabel">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">fill_parent</item>
@@ -805,7 +805,7 @@ public class ChartView extends View {
String s =
(mode == Mode.BY_DISTANCE)
? (shortFormat ? X_SHORT_FORMAT.format(x) : X_FORMAT.format(x))
: StringUtils.formatTime((long) x);
: StringUtils.formatElapsedTime((long) x);
c.drawText(s,
getX(x),
effectiveHeight + UNIT_BORDER + topBorder,
@@ -72,17 +72,18 @@ public abstract class Constants {
public static final int MENU_SEND_TO_GOOGLE = 102;
public static final int MENU_SHARE = 103;
public static final int MENU_SHOW = 104;
public static final int MENU_SHARE_LINK = 200;
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_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;
public static final int MENU_SHARE_MAP = 200;
public static final int MENU_SHARE_FUSION_TABLE = 201;
public static final int MENU_SHARE_GPX_FILE = 202;
public static final int MENU_SHARE_KML_FILE = 203;
public static final int MENU_SHARE_CSV_FILE = 204;
public static final int MENU_SHARE_TCX_FILE = 205;
public static final int MENU_WRITE_TO_SD_CARD = 206;
public static final int MENU_SAVE_GPX_FILE = 207;
public static final int MENU_SAVE_KML_FILE = 208;
public static final int MENU_SAVE_CSV_FILE = 209;
public static final int MENU_SAVE_TCX_FILE = 210;
public static final int MENU_CLEAR_MAP = 211;
/**
* The number of distance readings to smooth to get a stable signal.
@@ -26,6 +26,7 @@ import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.file.SaveActivity;
import com.google.android.apps.mytracks.io.sendtogoogle.SendActivity;
import com.google.android.apps.mytracks.io.sendtogoogle.SendType;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiFeatures;
@@ -370,8 +371,9 @@ public class MapActivity extends com.google.android.maps.MapActivity
R.string.track_list_send_google);
SubMenu share = menu.addSubMenu(0, Constants.MENU_SHARE, 0,
R.string.track_list_share_track);
share.add(0, Constants.MENU_SHARE_LINK, 0,
R.string.track_list_share_url);
share.add(0, Constants.MENU_SHARE_MAP, 0, R.string.track_list_share_map);
share.add(
0, Constants.MENU_SHARE_FUSION_TABLE, 0, R.string.track_list_share_fusion_table);
share.add(
0, Constants.MENU_SHARE_GPX_FILE, 0, String.format(shareFileFormat, fileTypes[0]));
share.add(
@@ -403,10 +405,13 @@ public class MapActivity extends com.google.android.maps.MapActivity
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case Constants.MENU_SEND_TO_GOOGLE:
SendActivity.sendToGoogle(this, dataHub.getSelectedTrackId(), false);
SendActivity.sendToGoogle(this, dataHub.getSelectedTrackId(), null);
return true;
case Constants.MENU_SHARE_LINK:
SendActivity.sendToGoogle(this, dataHub.getSelectedTrackId(), true);
case Constants.MENU_SHARE_MAP:
SendActivity.sendToGoogle(this, dataHub.getSelectedTrackId(), SendType.MYMAPS);
return true;
case Constants.MENU_SHARE_FUSION_TABLE:
SendActivity.sendToGoogle(this, dataHub.getSelectedTrackId(), SendType.FUSION_TABLES);
return true;
case Constants.MENU_SAVE_GPX_FILE:
case Constants.MENU_SAVE_KML_FILE:
@@ -23,6 +23,7 @@ import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection
import com.google.android.apps.mytracks.services.sensors.SensorManager;
import com.google.android.apps.mytracks.services.sensors.SensorManagerFactory;
import com.google.android.apps.mytracks.services.sensors.SensorUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import com.google.protobuf.InvalidProtocolBufferException;
@@ -32,8 +33,6 @@ import android.os.RemoteException;
import android.util.Log;
import android.widget.TextView;
import java.text.DateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
@@ -44,7 +43,6 @@ import java.util.TimerTask;
*/
public class SensorStateActivity extends Activity {
private static final DateFormat TIMESTAMP_FORMAT = DateFormat.getTimeInstance(DateFormat.SHORT);
private static final long REFRESH_PERIOD_MS = 250;
private final StatsUtilities utils;
@@ -263,7 +261,7 @@ public class SensorStateActivity extends Activity {
* @param sds sensor data set
*/
private String getLastSensorTime(Sensor.SensorDataSet sds) {
return TIMESTAMP_FORMAT.format(new Date(sds.getCreationTime()));
return StringUtils.formatTime(this, sds.getCreationTime());
}
/**
@@ -153,7 +153,7 @@ public class StatsUtilities {
}
public void setTime(int id, long l) {
setText(id, StringUtils.formatTime(l));
setText(id, StringUtils.formatElapsedTime(l));
}
public void setGrade(int id, double d) {
@@ -20,6 +20,7 @@ import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.io.file.SaveActivity;
import com.google.android.apps.mytracks.io.sendtogoogle.SendActivity;
import com.google.android.apps.mytracks.io.sendtogoogle.SendType;
import com.google.android.apps.mytracks.services.ServiceUtils;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.StringUtils;
@@ -95,8 +96,9 @@ public class TrackList extends ListActivity
R.string.track_list_send_google);
SubMenu share = menu.addSubMenu(0, Constants.MENU_SHARE, 0,
R.string.track_list_share_track);
share.add(0, Constants.MENU_SHARE_LINK, 0,
R.string.track_list_share_url);
share.add(0, Constants.MENU_SHARE_MAP, 0, R.string.track_list_share_map);
share.add(
0, Constants.MENU_SHARE_FUSION_TABLE, 0, R.string.track_list_share_fusion_table);
share.add(
0, Constants.MENU_SHARE_GPX_FILE, 0, String.format(shareFileFormat, fileTypes[0]));
share.add(
@@ -176,10 +178,13 @@ public class TrackList extends ListActivity
case Constants.MENU_WRITE_TO_SD_CARD:
return false;
case Constants.MENU_SEND_TO_GOOGLE:
SendActivity.sendToGoogle(this, trackId, false);
SendActivity.sendToGoogle(this, trackId, null);
return true;
case Constants.MENU_SHARE_LINK:
SendActivity.sendToGoogle(this, trackId, true);
case Constants.MENU_SHARE_MAP:
SendActivity.sendToGoogle(this, trackId, SendType.MYMAPS);
return true;
case Constants.MENU_SHARE_FUSION_TABLE:
SendActivity.sendToGoogle(this, trackId, SendType.FUSION_TABLES);
return true;
case Constants.MENU_SAVE_GPX_FILE:
case Constants.MENU_SAVE_KML_FILE:
@@ -310,7 +315,7 @@ public class TrackList extends ListActivity
TextView textView = (TextView) view;
if (columnIndex == startTimeIdx) {
long time = cursor.getLong(startTimeIdx);
textView.setText(StringUtils.formatDateTime(time));
textView.setText(StringUtils.formatDateTime(TrackList.this, time));
} else if (columnIndex == totalDistanceIdx) {
double length = cursor.getDouble(totalDistanceIdx);
String lengthUnit = null;
@@ -331,7 +336,7 @@ public class TrackList extends ListActivity
}
}
textView.setText(String.format("%s %.2f %s",
StringUtils.formatTime(cursor.getLong(totalTimeIdx)),
StringUtils.formatElapsedTime(cursor.getLong(totalTimeIdx)),
length,
lengthUnit));
} else {
@@ -269,7 +269,7 @@ public class WaypointsList extends ListActivity
if (time == 0) {
textView.setVisibility(View.GONE);
} else {
textView.setText(StringUtils.formatDateTime(time));
textView.setText(StringUtils.formatDateTime(WaypointsList.this, time));
textView.setVisibility(View.VISIBLE);
}
} else if (columnIndex == typeIdx) {
@@ -156,7 +156,7 @@ public class BackupActivityHelper {
// Make a user-visible version of the backup filenames
final String backupDateStrs[] = new String[backupDates.length];
for (int i = 0; i < backupDates.length; i++) {
backupDateStrs[i] = StringUtils.formatDateTime(backupDates[i].getTime());
backupDateStrs[i] = StringUtils.formatDateTime(activity, backupDates[i].getTime());
}
// Show a dialog for the user to pick which backup to restore
@@ -288,11 +288,9 @@ public class DocsHelper {
DocsTagBuilder tagBuilder = new DocsTagBuilder(metricUnits)
.append("name", track.getName())
.append("description", track.getDescription())
.append("date", StringUtils.formatDateTime(stats.getStartTime()))
.append("totaltime", StringUtils.formatTimeAlwaysShowingHours(
stats.getTotalTime()))
.append("movingtime", StringUtils.formatTimeAlwaysShowingHours(
stats.getMovingTime()))
.append("date", StringUtils.formatDateTime(context, stats.getStartTime()))
.append("totaltime", StringUtils.formatElapsedTime(stats.getTotalTime()))
.append("movingtime", StringUtils.formatElapsedTime(stats.getMovingTime()))
.appendLargeUnits("distance", stats.getTotalDistance() / 1000)
.append("distanceunit", distanceUnit)
.appendLargeUnits("averagespeed", stats.getAverageSpeed() * 3.6)
@@ -51,6 +51,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import java.util.ArrayList;
@@ -71,11 +72,11 @@ public class SendActivity extends Activity implements ProgressIndicator {
private static final String STATE_FUSION_SUCCESS = "fusionSuccess";
private static final String STATE_MAPS_SUCCESS = "mapsSuccess";
private static final String STATE_STATE = "state";
private static final String EXTRA_SHARE_LINK = "shareLink";
private static final String STATE_ACCOUNT_TYPE = "accountType";
private static final String STATE_ACCOUNT_NAME = "accountName";
private static final String STATE_TABLE_ID = "tableId";
private static final String STATE_MAP_ID = "mapId";
private static final String SEND_TYPE = "sendType";
/** States for the state machine that defines the upload process. */
private enum SendState {
@@ -120,7 +121,7 @@ public class SendActivity extends Activity implements ProgressIndicator {
private String lastAccountType;
// Send request information.
private boolean shareRequested = false;
private SendType sendType;
private long sendTrackId;
private boolean sendToMyMaps;
private boolean sendToMyMapsNewMap;
@@ -198,8 +199,7 @@ public class SendActivity extends Activity implements ProgressIndicator {
}
sendTrackId = ContentUris.parseId(data);
shareRequested = intent.getBooleanExtra(EXTRA_SHARE_LINK, false);
sendType = intent.getParcelableExtra(SEND_TYPE);
return true;
}
@@ -222,7 +222,7 @@ public class SendActivity extends Activity implements ProgressIndicator {
switch (id) {
case SEND_DIALOG:
SendDialog sendDialog = (SendDialog) dialog;
sendDialog.setDocsEnabled(!shareRequested);
sendDialog.setSendType(sendType);
return;
default:
return;
@@ -633,12 +633,13 @@ public class SendActivity extends Activity implements ProgressIndicator {
};
}
DialogInterface.OnClickListener onOkListener = (canShare && shareRequested)
DialogInterface.OnClickListener onOkListener = (canShare && sendType != null)
? doShareListener : finishListener;
DialogInterface.OnClickListener onShareListener = (canShare && !shareRequested)
DialogInterface.OnClickListener onShareListener = (canShare && sendType == null)
? doShareListener : null;
return ResultDialogFactory.makeDialog(this, results, onOkListener, onShareListener, finishOnCancelListener);
return ResultDialogFactory.makeDialog(
this, results, onOkListener, onShareListener, finishOnCancelListener);
}
private SendState onAllDone() {
@@ -905,13 +906,13 @@ public class SendActivity extends Activity implements ProgressIndicator {
progressDialog.setMessage("");
}
public static void sendToGoogle(Context ctx, long trackId, boolean shareLink) {
public static void sendToGoogle(Context ctx, long trackId, SendType sendType) {
Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId);
Intent intent = new Intent(ctx, SendActivity.class);
intent.setAction(Intent.ACTION_SEND);
intent.setDataAndType(uri, TracksColumns.CONTENT_ITEMTYPE);
intent.putExtra(SendActivity.EXTRA_SHARE_LINK, shareLink);
intent.putExtra(SEND_TYPE, (Parcelable) sendType);
ctx.startActivity(intent);
}
}
@@ -31,24 +31,33 @@ import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TableRow;
/**
* A dialog where the user can choose where to send the tracks to, i.e.
* to Google My Maps, Google Docs, etc.
* A dialog where the user can choose where to send a track to, i.e., Google
* Maps, Google Fusion Tables, and Google Docs.
*
* @author Leif Hendrik Wilden
*/
public class SendDialog extends Dialog {
private RadioButton newMapRadioButton;
private RadioButton existingMapRadioButton;
private CheckBox myMapsCheckBox;
private boolean mapsEnabled;
private boolean fusionTablesEnabled;
private boolean docsEnabled;
private TableRow mapsTableRow;
private TableRow fusionTablesTableRow;
private TableRow docsTableRow;
private CheckBox mapsCheckBox;
private CheckBox fusionTablesCheckBox;
private CheckBox docsCheckBox;
private TableRow docsTableRow;
private boolean docsEnabled;
private TableRow mapsOptionTableRow;
private RadioButton newMapRadioButton;
private RadioButton existingMapRadioButton;
private Button send;
private OnClickListener clickListener;
@@ -62,18 +71,29 @@ public class SendDialog extends Dialog {
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.mytracks_send_to_google);
final Button sendButton = (Button) findViewById(R.id.send_google_send_now);
mapsTableRow = (TableRow) findViewById(R.id.send_google_maps_row);
fusionTablesTableRow = (TableRow) findViewById(R.id.send_google_fusion_tables_row);
docsTableRow = (TableRow) findViewById(R.id.send_google_docs_row);
final RadioGroup myMapsGroup = (RadioGroup) findViewById(R.id.send_google_my_maps_group);
OnCheckedChangeListener checkBoxListener = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton button, boolean checked) {
updateDisplay();
}
};
mapsCheckBox = (CheckBox) findViewById(R.id.send_google_my_maps);
mapsCheckBox.setOnCheckedChangeListener(checkBoxListener);
fusionTablesCheckBox = (CheckBox) findViewById(R.id.send_google_fusion_tables);
fusionTablesCheckBox.setOnCheckedChangeListener(checkBoxListener);
docsCheckBox = (CheckBox) findViewById(R.id.send_google_docs);
docsCheckBox.setOnCheckedChangeListener(checkBoxListener);
mapsOptionTableRow = (TableRow) findViewById(R.id.send_google_maps_option_row);
newMapRadioButton = (RadioButton) findViewById(R.id.send_google_new_map);
existingMapRadioButton = (RadioButton) findViewById(R.id.send_google_existing_map);
myMapsCheckBox = (CheckBox) findViewById(R.id.send_google_my_maps);
fusionTablesCheckBox = (CheckBox) findViewById(R.id.send_google_fusion_tables);
docsCheckBox = (CheckBox) findViewById(R.id.send_google_docs);
docsTableRow = (TableRow) findViewById(R.id.send_google_docs_table_row);
Button cancel = (Button) findViewById(R.id.send_google_cancel);
cancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
@@ -84,7 +104,7 @@ public class SendDialog extends Dialog {
}
});
Button send = (Button) findViewById(R.id.send_google_send_now);
send = (Button) findViewById(R.id.send_google_send_now);
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (clickListener != null) {
@@ -93,34 +113,6 @@ public class SendDialog extends Dialog {
dismiss();
}
});
OnCheckedChangeListener checkBoxListener = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton button, boolean checked) {
sendButton.setEnabled(getSendToMyMaps() || getSendToFusionTables() || getSendToDocs());
myMapsGroup.setVisibility(getSendToMyMaps() ? View.VISIBLE : View.GONE);
}
};
myMapsCheckBox.setOnCheckedChangeListener(checkBoxListener);
fusionTablesCheckBox.setOnCheckedChangeListener(checkBoxListener);
docsCheckBox.setOnCheckedChangeListener(checkBoxListener);
SharedPreferences prefs = getContext().getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
if (prefs != null) {
boolean pickExistingMap = prefs.getBoolean(
getContext().getString(R.string.pick_existing_map_key), false);
newMapRadioButton.setChecked(!pickExistingMap);
existingMapRadioButton.setChecked(pickExistingMap);
myMapsCheckBox.setChecked(
prefs.getBoolean(getContext().getString(R.string.send_to_my_maps_key), true));
fusionTablesCheckBox.setChecked(
prefs.getBoolean(getContext().getString(R.string.send_to_fusion_tables_key), true));
docsCheckBox.setChecked(
prefs.getBoolean(getContext().getString(R.string.send_to_docs_key), true));
}
}
@Override
@@ -133,10 +125,11 @@ public class SendDialog extends Dialog {
if (editor != null) {
editor.putBoolean(
getContext().getString(R.string.pick_existing_map_key), !getCreateNewMap());
editor.putBoolean(getContext().getString(R.string.send_to_my_maps_key), getSendToMyMaps());
editor.putBoolean(
getContext().getString(R.string.send_to_fusion_tables_key), getSendToFusionTables());
if (docsEnabled) {
if (mapsEnabled && fusionTablesEnabled && docsEnabled) {
editor.putBoolean(
getContext().getString(R.string.send_to_my_maps_key), getSendToMyMaps());
editor.putBoolean(
getContext().getString(R.string.send_to_fusion_tables_key), getSendToFusionTables());
editor.putBoolean(getContext().getString(R.string.send_to_docs_key), getSendToDocs());
}
ApiFeatures.getInstance().getApiAdapter().applyPreferenceChanges(editor);
@@ -145,15 +138,69 @@ public class SendDialog extends Dialog {
}
/**
* To enable the Google Docs option.
*
* @param docsEnabled true to enable the Google Docs option
* Sets the sendType. If sendType is null, allows sending to all the Google
* services.
*
* @param sendType sendType
*/
public void setDocsEnabled(boolean docsEnabled) {
this.docsEnabled = docsEnabled;
public void setSendType(SendType sendType) {
updateState();
/*
* Note that sendType can be null, so cannot use a switch statement based on
* the sendType.
*/
if (sendType == SendType.MYMAPS) {
mapsEnabled = true;
fusionTablesEnabled = false;
docsEnabled = false;
mapsCheckBox.setChecked(true);
} else if (sendType == SendType.FUSION_TABLES) {
mapsEnabled = false;
fusionTablesEnabled = true;
docsEnabled = false;
fusionTablesCheckBox.setChecked(true);
} else {
mapsEnabled = true;
fusionTablesEnabled = true;
docsEnabled = true;
}
mapsTableRow.setVisibility(mapsEnabled ? View.VISIBLE : View.GONE);
fusionTablesTableRow.setVisibility(fusionTablesEnabled ? View.VISIBLE : View.GONE);
docsTableRow.setVisibility(docsEnabled ? View.VISIBLE : View.GONE);
updateDisplay();
}
/**
* Updates the UI state from the shared preferences.
*/
private void updateState() {
SharedPreferences prefs = getContext().getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
if (prefs != null) {
boolean pickExistingMap = prefs.getBoolean(
getContext().getString(R.string.pick_existing_map_key), false);
newMapRadioButton.setChecked(!pickExistingMap);
existingMapRadioButton.setChecked(pickExistingMap);
mapsCheckBox.setChecked(
prefs.getBoolean(getContext().getString(R.string.send_to_my_maps_key), true));
fusionTablesCheckBox.setChecked(
prefs.getBoolean(getContext().getString(R.string.send_to_fusion_tables_key), true));
docsCheckBox.setChecked(
prefs.getBoolean(getContext().getString(R.string.send_to_docs_key), true));
}
}
/**
* Updates the UI display based on the current state.
*/
private void updateDisplay() {
send.setEnabled(getSendToMyMaps() || getSendToFusionTables() || getSendToDocs());
mapsOptionTableRow.setVisibility(getSendToMyMaps() ? View.VISIBLE : View.GONE);
}
public void setOnClickListener(OnClickListener clickListener) {
this.clickListener = clickListener;
}
@@ -163,11 +210,11 @@ public class SendDialog extends Dialog {
}
public boolean getSendToMyMaps() {
return myMapsCheckBox.isChecked();
return mapsEnabled && mapsCheckBox.isChecked();
}
public boolean getSendToFusionTables() {
return fusionTablesCheckBox.isChecked();
return fusionTablesEnabled && fusionTablesCheckBox.isChecked();
}
public boolean getSendToDocs() {
@@ -17,12 +17,15 @@ package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.maps.mytracks.R;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Enumerates the services to which we can upload track data.
*
* @author Matthew Simmons
*/
public enum SendType {
public enum SendType implements Parcelable {
MYMAPS(R.string.send_google_my_maps,
R.string.send_google_my_maps_url),
FUSION_TABLES(R.string.send_google_fusion_tables,
@@ -47,4 +50,27 @@ public enum SendType {
public int getServiceUrl() {
return serviceUrl;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(ordinal());
}
public static final Creator<SendType> CREATOR = new Creator<SendType>() {
@Override
public SendType createFromParcel(Parcel source) {
return SendType.values()[source.readInt()];
}
@Override
public SendType[] newArray(int size) {
return new SendType[size];
}
};
}
@@ -44,7 +44,7 @@ class DefaultTrackNameFactory {
*/
String newTrackName(long trackId, long startTime) {
if (useTimestampTrackName()) {
return StringUtils.formatDateTime(startTime);
return StringUtils.formatDateTime(context, startTime);
} else {
return String.format(context.getString(R.string.track_name_format), trackId);
}
@@ -24,6 +24,7 @@ import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.format.DateUtils;
import java.text.DateFormat;
import java.text.NumberFormat;
@@ -46,35 +47,34 @@ public class StringUtils implements DescriptionGenerator {
private final Context context;
/**
* Formats the time based on user locale.
*
* @param time time
*/
public static String formatDateTime(long time) {
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
return formatter.format(new Date(time));
}
/**
* Formats a number of milliseconds as a string.
* Formats the date and time based on user's phone date/time preferences.
*
* @param time - A period of time in milliseconds.
* @return A string of the format M:SS, MM:SS or HH:MM:SS
* @param context the context
* @param time the time in milliseconds
*/
public static String formatTime(long time) {
return formatTimeInternal(time, false);
public static String formatDateTime(Context context, long time) {
DateFormat dateFormatter = android.text.format.DateFormat.getDateFormat(context);
return dateFormatter.format(new Date(time)) + " " + formatTime(context, time);
}
/**
* Formats a number of milliseconds as a string. To be used when we need the
* hours to be shown even when it is zero, e.g. exporting data to a
* spreadsheet.
* Formats the time based on user's phone date/time preferences.
*
* @param time - A period of time in milliseconds
* @return A string of the format HH:MM:SS even if time is less than 1 hour
* @param context the context
* @param time the time in milliseconds
*/
public static String formatTimeAlwaysShowingHours(long time) {
return formatTimeInternal(time, true);
public static String formatTime(Context context, long time) {
DateFormat timeFormatter = android.text.format.DateFormat.getTimeFormat(context);
return timeFormatter.format(new Date(time));
}
/**
* Formats the elapsed timed in the form "MM:SS" or "H:MM:SS".
*
* @param time the time in milliseconds
*/
public static String formatElapsedTime(long time) {
return DateUtils.formatElapsedTime(time / 1000);
}
private static final NumberFormat SINGLE_DECIMAL_PLACE_FORMAT = NumberFormat.getNumberInstance();
@@ -182,35 +182,6 @@ public class StringUtils implements DescriptionGenerator {
return time;
}
/**
* Formats a number of milliseconds as a string.
*
* @param time - A period of time in milliseconds
* @param alwaysShowHours - Whether to display 00 hours if time is less than 1
* hour
* @return A string of the format HH:MM:SS
*/
private static String formatTimeInternal(long time, boolean alwaysShowHours) {
int[] parts = getTimeParts(time);
StringBuilder builder = new StringBuilder();
if (parts[2] > 0 || alwaysShowHours) {
builder.append(parts[2]);
builder.append(':');
if (parts[1] <= 9) {
builder.append("0");
}
}
builder.append(parts[1]);
builder.append(':');
if (parts[0] <= 9) {
builder.append("0");
}
builder.append(parts[0]);
return builder.toString();
}
/**
* Gets the time as an array of parts.
*/
@@ -328,11 +299,11 @@ public class StringUtils implements DescriptionGenerator {
// Line 3
context.getString(R.string.stat_total_time),
StringUtils.formatTime(trackStats.getTotalTime()),
StringUtils.formatElapsedTime(trackStats.getTotalTime()),
// Line 4
context.getString(R.string.stat_moving_time),
StringUtils.formatTime(trackStats.getMovingTime()),
StringUtils.formatElapsedTime(trackStats.getMovingTime()),
// Line 5
averageSpeed, averageMovingSpeed, maxSpeed,
@@ -360,7 +331,7 @@ public class StringUtils implements DescriptionGenerator {
// Line 11
context.getString(R.string.send_google_recorded),
StringUtils.formatDateTime(trackStats.getStartTime()),
StringUtils.formatDateTime(context, trackStats.getStartTime()),
// Line 12
context.getString(R.string.track_detail_activity_type_hint), category,
@@ -470,9 +441,9 @@ public class StringUtils implements DescriptionGenerator {
distanceInKm, context.getString(R.string.unit_kilometer),
distanceInMiles, context.getString(R.string.unit_mile),
context.getString(R.string.stat_total_time),
StringUtils.formatTime(stats.getTotalTime()),
StringUtils.formatElapsedTime(stats.getTotalTime()),
context.getString(R.string.stat_moving_time),
StringUtils.formatTime(stats.getMovingTime()),
StringUtils.formatElapsedTime(stats.getMovingTime()),
context.getString(R.string.stat_average_speed),
averageSpeedInKmh, context.getString(R.string.unit_kilometer_per_hour),
averageSpeedInMph, context.getString(R.string.unit_mile_per_hour),
@@ -224,7 +224,7 @@ public class TrackWidgetProvider
StringUtils.formatSingleDecimalPlace(displayDistance) + " " + this.distanceLabel;
// convert ms to minutes
String time = StringUtils.formatTime(stats.getMovingTime());
String time = StringUtils.formatElapsedTime(stats.getMovingTime());
String speed = unknown;
if (!Double.isNaN(stats.getAverageMovingSpeed())) {
// Convert m/s to km/h
@@ -236,7 +236,7 @@ public class TrackWidgetProvider
speed = StringUtils.formatSingleDecimalPlace(displaySpeed) + " " + this.speedLabel;
} else {
long displayPace = (long) (3600000.0 / displaySpeed);
speed = StringUtils.formatTime(displayPace) + " " + paceLabel;
speed = StringUtils.formatElapsedTime(displayPace) + " " + paceLabel;
}
}
@@ -19,25 +19,20 @@ 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.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import com.google.android.testing.mocking.AndroidMock;
import com.google.android.testing.mocking.UsesMocks;
import android.content.Context;
import android.content.res.Resources;
import android.test.mock.MockContext;
import android.test.AndroidTestCase;
import android.test.mock.MockResources;
import java.io.IOException;
import junit.framework.TestCase;
/**
* Tests for {@link DocsHelper#addTrackRow}
*
* @author Matthew Simmons
*/
public class DocsHelper_AddTrackRowTest extends TestCase {
public class DocsHelper_AddTrackRowTest extends AndroidTestCase {
private static final long TIME = 1288721514000L;
private static class StringWritingDocsHelper extends DocsHelper {
@@ -61,20 +56,20 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
+ "xmlns:gsx='http://schemas.google.com/spreadsheets/2006/extended'>"
+ "<gsx:name><![CDATA[trackName]]></gsx:name>"
+ "<gsx:description><![CDATA[trackDescription]]></gsx:description>"
+ "<gsx:date><![CDATA[" + StringUtils.formatDateTime(TIME) + "]]></gsx:date>"
+ "<gsx:totaltime><![CDATA[0:00:05]]></gsx:totaltime>"
+ "<gsx:movingtime><![CDATA[0:00:04]]></gsx:movingtime>"
+ "<gsx:date><![CDATA[" + StringUtils.formatDateTime(getContext(), TIME) + "]]></gsx:date>"
+ "<gsx:totaltime><![CDATA[00:05]]></gsx:totaltime>"
+ "<gsx:movingtime><![CDATA[00:04]]></gsx:movingtime>"
+ "<gsx:distance><![CDATA[12.43]]></gsx:distance>"
+ "<gsx:distanceunit><![CDATA[mile]]></gsx:distanceunit>"
+ "<gsx:distanceunit><![CDATA[mi]]></gsx:distanceunit>"
+ "<gsx:averagespeed><![CDATA[8,947.75]]></gsx:averagespeed>"
+ "<gsx:averagemovingspeed><![CDATA[11,184.68]]>"
+ "</gsx:averagemovingspeed>"
+ "<gsx:maxspeed><![CDATA[3,355.40]]></gsx:maxspeed>"
+ "<gsx:speedunit><![CDATA[mph]]></gsx:speedunit>"
+ "<gsx:speedunit><![CDATA[mi/h]]></gsx:speedunit>"
+ "<gsx:elevationgain><![CDATA[19,685]]></gsx:elevationgain>"
+ "<gsx:minelevation><![CDATA[-1,640]]></gsx:minelevation>"
+ "<gsx:maxelevation><![CDATA[1,804]]></gsx:maxelevation>"
+ "<gsx:elevationunit><![CDATA[feet]]></gsx:elevationunit>"
+ "<gsx:elevationunit><![CDATA[ft]]></gsx:elevationunit>"
+ "<gsx:map>"
+ "<![CDATA[https://maps.google.com/maps/ms?msa=0&msid=trackMapId]]>"
+ "</gsx:map>"
@@ -97,9 +92,9 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
assertTrue(docsHelper.writtenData.contains(
"<gsx:distanceunit><![CDATA[km]]></gsx:distanceunit>"));
assertTrue(docsHelper.writtenData.contains(
"<gsx:speedunit><![CDATA[kph]]></gsx:speedunit>"));
"<gsx:speedunit><![CDATA[km/h]]></gsx:speedunit>"));
assertTrue(docsHelper.writtenData.contains(
"<gsx:elevationunit><![CDATA[meter]]></gsx:elevationunit>"));
"<gsx:elevationunit><![CDATA[m]]></gsx:elevationunit>"));
assertTrue(docsHelper.writtenData.contains(
"<gsx:distance><![CDATA[20.00]]></gsx:distance>"));
@@ -107,34 +102,7 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
/** Adds a row to the spreadsheet, using the provided helper. */
@UsesMocks({AuthManager.class, MockResources.class, Track.class})
private void addTrackRow(DocsHelper docsHelper, boolean useMetric)
throws IOException {
final Resources mockResources = AndroidMock.createMock(MockResources.class);
if (useMetric) {
AndroidMock.expect(mockResources.getString(R.string.unit_kilometer))
.andReturn("km");
AndroidMock.expect(mockResources.getString(R.string.unit_kilometer_per_hour))
.andReturn("kph");
AndroidMock.expect(mockResources.getString(R.string.unit_meter))
.andReturn("meter");
} else {
AndroidMock.expect(mockResources.getString(R.string.unit_mile))
.andReturn("mile");
AndroidMock.expect(mockResources.getString(R.string.unit_mile_per_hour))
.andReturn("mph");
AndroidMock.expect(mockResources.getString(R.string.unit_feet))
.andReturn("feet");
}
AndroidMock.replay(mockResources);
Context mockContext = new MockContext() {
@Override
public Resources getResources() {
return mockResources;
}
};
private void addTrackRow(DocsHelper docsHelper, boolean useMetric) throws IOException {
AuthManager mockAuthManager = AndroidMock.createMock(AuthManager.class);
AndroidMock.replay(mockAuthManager);
@@ -154,7 +122,7 @@ public class DocsHelper_AddTrackRowTest extends TestCase {
track.setMapId("trackMapId");
track.setStatistics(stats);
docsHelper.addTrackRow(mockContext, mockAuthManager, "ssid", "wsid",
docsHelper.addTrackRow(getContext(), mockAuthManager, "ssid", "wsid",
track, useMetric);
}
}
@@ -50,8 +50,9 @@ public class DefaultTrackNameFactoryTest extends AndroidTestCase {
public void testTimestampTrackName() {
DefaultTrackNameFactory factory =
new MockDefaultTrackNameFactory(getContext(), true);
assertEquals(StringUtils.formatDateTime(TIMESTAMP), factory.newTrackName(1, TIMESTAMP));
assertEquals(
StringUtils.formatDateTime(getContext(), TIMESTAMP), factory.newTrackName(1, TIMESTAMP));
}
public void testIncrementingTrackName() {