Merge from main.

This commit is contained in:
Jimmy Shih
2012-02-06 09:44:01 -08:00
8 changed files with 205 additions and 102 deletions
+26 -35
View File
@@ -15,69 +15,60 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="2dip"
android:paddingBottom="2dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="vertical">
android:orientation="vertical"
android:paddingBottom="2dip"
android:paddingTop="2dip">
<LinearLayout
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView android:id="@+id/trackdetails_item_icon"
android:layout_width="wrap_content"
android:orientation="horizontal">
<ImageView android:id="@+id/track_list_item_icon"
android:contentDescription="@string/track_list_icon_description"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingLeft="4dip"
android:paddingRight="2dip"
android:paddingTop="5dip"
android:src="@drawable/track"/>
<LinearLayout
android:orientation="horizontal"
android:src="@drawable/track" />
<TextView android:id="@+id/track_list_item_name"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:layout_width="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView android:id="@+id/track_list_item_category"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/trackdetails_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:singleLine="true"
android:text="Track name"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView android:id="@+id/trackdetails_item_category"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:singleLine = "true"
android:text="Activity type"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
android:singleLine = "true"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
<TextView android:id="@+id/trackdetails_item_time"
<TextView android:id="@+id/track_list_item_time"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:singleLine="true"
android:textColor="#fff"
android:text="Start time"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<TextView android:id="@+id/trackdetails_item_stats"
<TextView android:id="@+id/track_list_item_stats"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:singleLine="true"
android:textColor="#0f0"
android:text="Distance and total time"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<TextView android:id="@+id/trackdetails_item_description"
<TextView android:id="@+id/track_list_item_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft = "6dip"
android:singleLine = "false"
android:text="Description"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
+2 -4
View File
@@ -32,7 +32,8 @@ limitations under the License.
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:src="@drawable/ylw_pushpin"/>
android:src="@drawable/ylw_pushpin"
android:contentDescription="@string/marker_list_icon_description"/>
<LinearLayout
android:orientation="vertical"
@@ -45,7 +46,6 @@ limitations under the License.
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:singleLine = "true"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView android:id="@+id/waypointslist_item_time"
@@ -54,7 +54,6 @@ limitations under the License.
android:layout_marginLeft = "6dip"
android:singleLine = "true"
android:textColor = "#fff"
android:text="date and time"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<TextView android:id="@+id/waypointslist_item_category"
@@ -63,7 +62,6 @@ limitations under the License.
android:layout_marginLeft = "6dip"
android:singleLine = "true"
android:textColor="#0f0"
android:text="category"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2012 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apl/res/com.google.android.apps.mytracks"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView android:id="@android:id/list"
android:layout_height="fill_parent"
android:layout_width="fill_parent" />
<TextView android:id="@android:id/empty"
android:gravity="center"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:text="@string/search_no_results"
android:textColor="@android:color/white"
android:textSize="20dip"
android:textStyle="bold"
android:visibility="gone" />
</LinearLayout>
+21 -1
View File
@@ -815,6 +815,10 @@ limitations under the License.
Screenshot: marker_list_context_menu.png">
Edit
</string>
<string name="marker_list_icon_description"
translation_description="In the Markers page, the accessibility description for the marker icon.">
Marker
</string>
<string name="marker_list_insert_statistics"
translation_description="In the Markers page, the button on the bottom to insert a statistics
marker.
@@ -1101,7 +1105,12 @@ limitations under the License.
translation_description="The hint shown on the search box until the user types a search query.
See suggestion at http://developer.android.com/guide/topics/search/search-dialog.html about
keeping this consistent with other Android apps.">
Search My Tracks tracks and waypoints
Search My Tracks
</string>
<string name="search_no_results"
translation_description="Message shown instead of a list of results to indicate there were no
search results.">
No tracks or waypoints matched your search.
</string>
<string name="search_voice_prompt"
translation_description="Prompt shown when the user activates voice search, asking him to speak
@@ -2326,6 +2335,17 @@ limitations under the License.
Screenshot: track_list_show_on_map.png">
Show on map
</string>
<string name="track_list_icon_description"
translation_description="In the 'Tracks' page, the accessibility description for the track icon.">
Track
</string>
<string name="track_list_track_name"
translation_description="In the 'Search Result' page, the text field indicating the track that a
waypoint belongs to.
%1$s: track name. E.g., 'Grand Canyon trail'">
In track \'%1$s\'.
</string>
<string name="track_name_format"
translation_description="When creating a new track, the string format to name the track.
@@ -17,6 +17,7 @@ package com.google.android.apps.mytracks;
import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.SearchEngine;
import com.google.android.apps.mytracks.content.SearchEngine.ScoredResult;
import com.google.android.apps.mytracks.content.SearchEngine.SearchQuery;
@@ -25,12 +26,16 @@ import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
@@ -55,26 +60,51 @@ import java.util.SortedSet;
*/
public class SearchActivity extends ListActivity {
private static final String ICON_FIELD = "icon";
private static final String NAME_FIELD = "name";
private static final String DESCRIPTION_FIELD = "description";
private static final String CATEGORY_FIELD = "category";
private static final String TIME_FIELD = "time";
private static final String STATS_FIELD = "stats";
private static final String TRACK_ID_FIELD = "trackId";
private static final String WAYPOINT_ID_FIELD = "waypointId";
private static final String EXTRA_CURRENT_TRACK_ID = "trackId";
private static final boolean LOG_SCORES = true;
private MyTracksProviderUtils providerUtils;
private SearchEngine engine;
private LocationManager locationManager;
private SharedPreferences preferences;
private SearchRecentSuggestions suggestions;
private boolean metricUnits;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
engine = new SearchEngine(this);
providerUtils = MyTracksProviderUtils.Factory.get(this);
engine = new SearchEngine(providerUtils);
suggestions = SearchEngineProvider.newHelper(this);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
preferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
setContentView(R.layout.search_list);
handleIntent(getIntent());
}
@Override
protected void onResume() {
super.onResume();
metricUnits =
preferences.getBoolean(getString(R.string.metric_units_key), true);
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
@@ -146,23 +176,41 @@ public class SearchActivity extends ListActivity {
}
private void prepareWaypointForDisplay(Waypoint waypoint, Map<String, Object> resultMap) {
resultMap.put("icon", waypoint.getType() == Waypoint.TYPE_STATISTICS ? R.drawable.ylw_pushpin
: R.drawable.blue_pushpin);
resultMap.put("name", waypoint.getName());
resultMap.put("description", waypoint.getDescription());
resultMap.put("category", waypoint.getCategory());
resultMap.put("time", String.format("%tc", waypoint.getLocation().getTime()));
resultMap.put("trackId", waypoint.getTrackId());
resultMap.put("waypointId", waypoint.getId());
// Look up the owner track.
// TODO: It may be more appropriate to do this as a join in the retrieval phase of the search.
String trackName = null;
long trackId = waypoint.getTrackId();
if (trackId > 0) {
Track track = providerUtils.getTrack(trackId);
if (track != null) {
trackName = track.getName();
}
}
resultMap.put(ICON_FIELD, waypoint.getType() == Waypoint.TYPE_STATISTICS
? R.drawable.ylw_pushpin : R.drawable.blue_pushpin);
resultMap.put(NAME_FIELD, waypoint.getName());
resultMap.put(DESCRIPTION_FIELD, waypoint.getDescription());
resultMap.put(CATEGORY_FIELD, waypoint.getCategory());
// In the same place as we show time for tracks, show the track name for waypoints.
resultMap.put(TIME_FIELD, getString(R.string.track_list_track_name, trackName));
resultMap.put(STATS_FIELD, StringUtils.formatDateTime(this, waypoint.getLocation().getTime()));
resultMap.put(TRACK_ID_FIELD, waypoint.getTrackId());
resultMap.put(WAYPOINT_ID_FIELD, waypoint.getId());
}
private void prepareTrackForDisplay(Track track, Map<String, Object> resultMap) {
resultMap.put("icon", R.drawable.track);
resultMap.put("name", track.getName());
resultMap.put("description", track.getDescription());
resultMap.put("category", track.getCategory());
resultMap.put("time", String.format("%tc", track.getStatistics().getStartTime()));
resultMap.put("trackId", track.getId());
TripStatistics stats = track.getStatistics();
resultMap.put(ICON_FIELD, R.drawable.track);
resultMap.put(NAME_FIELD, track.getName());
resultMap.put(DESCRIPTION_FIELD, track.getDescription());
resultMap.put(CATEGORY_FIELD, track.getCategory());
resultMap.put(TIME_FIELD, StringUtils.formatDateTime(this, stats.getStartTime()));
resultMap.put(STATS_FIELD,
StringUtils.formatTimeDistance(this, stats.getTotalDistance(), stats.getTotalTime(),
metricUnits));
resultMap.put(TRACK_ID_FIELD, track.getId());
}
/**
@@ -176,18 +224,20 @@ public class SearchActivity extends ListActivity {
// TODO: Custom view for search results.
R.layout.mytracks_list_item,
new String[] {
"icon",
"name",
"description",
"category",
"time"
ICON_FIELD,
NAME_FIELD,
DESCRIPTION_FIELD,
CATEGORY_FIELD,
TIME_FIELD,
STATS_FIELD,
},
new int[] {
R.id.trackdetails_item_icon,
R.id.trackdetails_item_name,
R.id.trackdetails_item_description,
R.id.trackdetails_item_category,
R.id.trackdetails_item_time
R.id.track_list_item_icon,
R.id.track_list_item_name,
R.id.track_list_item_description,
R.id.track_list_item_category,
R.id.track_list_item_time,
R.id.track_list_item_stats,
});
setListAdapter(adapter);
@@ -203,12 +253,12 @@ public class SearchActivity extends ListActivity {
private Intent createViewDataIntent(Map<String, Object> clickedData) {
Intent intent = new Intent(Intent.ACTION_VIEW);
if (clickedData.containsKey("waypointId")) {
long waypointId = (Long) clickedData.get("waypointId");
if (clickedData.containsKey(WAYPOINT_ID_FIELD)) {
long waypointId = (Long) clickedData.get(WAYPOINT_ID_FIELD);
Uri uri = ContentUris.withAppendedId(WaypointsColumns.CONTENT_URI, waypointId);
intent.setDataAndType(uri, WaypointsColumns.CONTENT_ITEMTYPE);
} else {
long trackId = (Long) clickedData.get("trackId");
long trackId = (Long) clickedData.get(TRACK_ID_FIELD);
Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId);
intent.setDataAndType(uri, TracksColumns.CONTENT_ITEMTYPE);
}
@@ -24,7 +24,6 @@ import com.google.android.apps.mytracks.io.sendtogoogle.UploadServiceChooserActi
import com.google.android.apps.mytracks.services.ServiceUtils;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
import android.app.ListActivity;
@@ -311,9 +310,9 @@ public class TrackList extends ListActivity
new String[] { TracksColumns.NAME, TracksColumns.STARTTIME,
TracksColumns.TOTALDISTANCE, TracksColumns.DESCRIPTION,
TracksColumns.CATEGORY },
new int[] { R.id.trackdetails_item_name, R.id.trackdetails_item_time,
R.id.trackdetails_item_stats, R.id.trackdetails_item_description,
R.id.trackdetails_item_category });
new int[] { R.id.track_list_item_name, R.id.track_list_item_time,
R.id.track_list_item_stats, R.id.track_list_item_description,
R.id.track_list_item_category });
final int startTimeIdx =
tracksCursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
@@ -330,28 +329,10 @@ public class TrackList extends ListActivity
long time = cursor.getLong(startTimeIdx);
textView.setText(StringUtils.formatDateTime(TrackList.this, time));
} else if (columnIndex == totalDistanceIdx) {
double length = cursor.getDouble(totalDistanceIdx);
String lengthUnit = null;
if (metricUnits) {
if (length > 1000.0) {
length /= 1000.0;
lengthUnit = getString(R.string.unit_kilometer);
} else {
lengthUnit = getString(R.string.unit_meter);
}
} else {
if (length > UnitConversions.MI_TO_M) {
length /= UnitConversions.MI_TO_M;
lengthUnit = getString(R.string.unit_mile);
} else {
length *= UnitConversions.M_TO_FT;
lengthUnit = getString(R.string.unit_feet);
}
}
textView.setText(String.format("%s %.2f %s",
StringUtils.formatElapsedTime(cursor.getLong(totalTimeIdx)),
length,
lengthUnit));
double totalDistance = cursor.getDouble(totalDistanceIdx);
long totalTime = cursor.getLong(totalTimeIdx);
String totalDistanceStr = StringUtils.formatTimeDistance(TrackList.this, totalDistance, totalTime, metricUnits);
textView.setText(totalDistanceStr);
} else {
textView.setText(cursor.getString(columnIndex));
if (textView.getText().length() < 1) {
@@ -362,6 +343,7 @@ public class TrackList extends ListActivity
}
return true;
}
});
setListAdapter(adapter);
}
@@ -18,7 +18,6 @@ package com.google.android.apps.mytracks.content;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.LocationUtils;
import android.content.Context;
import android.database.Cursor;
import android.location.Location;
@@ -149,10 +148,6 @@ public class SearchEngine {
private final MyTracksProviderUtils providerUtils;
public SearchEngine(Context ctx) {
providerUtils = MyTracksProviderUtils.Factory.get(ctx);
}
public SearchEngine(MyTracksProviderUtils providerUtils) {
this.providerUtils = providerUtils;
}
@@ -77,8 +77,41 @@ public class StringUtils implements DescriptionGenerator {
return DateUtils.formatElapsedTime(time / 1000);
}
/**
* Formats the elapsed time and total distance.
*
* @param context the current context
* @param totalDistance the total distance in meters
* @param totalTime the total time in milliseconds
* @param metric whether to use metric units
* @return the formatted string
*/
public static String formatTimeDistance(Context context, double totalDistance, long totalTime, boolean metric) {
String distanceUnit;
if (metric) {
if (totalDistance > 2000.0) {
totalDistance /= 1000.0;
distanceUnit = context.getString(R.string.unit_kilometer);
} else {
distanceUnit = context.getString(R.string.unit_meter);
}
} else {
if (totalDistance > 2 * UnitConversions.MI_TO_M) {
totalDistance /= UnitConversions.MI_TO_M;
distanceUnit = context.getString(R.string.unit_mile);
} else {
totalDistance *= UnitConversions.M_TO_FT;
distanceUnit = context.getString(R.string.unit_feet);
}
}
return String.format("%s %.2f %s",
formatElapsedTime(totalTime),
totalDistance,
distanceUnit);
}
private static final NumberFormat SINGLE_DECIMAL_PLACE_FORMAT = NumberFormat.getNumberInstance();
static {
SINGLE_DECIMAL_PLACE_FORMAT.setMaximumFractionDigits(1);
SINGLE_DECIMAL_PLACE_FORMAT.setMinimumFractionDigits(1);
@@ -342,7 +375,7 @@ public class StringUtils implements DescriptionGenerator {
/**
* Returns the 'Created by My Tracks on Android' string.
*
*
* @param context the context
* @param addLink true to add a link to the My Tracks web site
*/
@@ -355,7 +388,7 @@ public class StringUtils implements DescriptionGenerator {
return String.format(format, "", "");
}
}
private String getSpeedString(double speed, int speedLabel, int paceLabel,
boolean displaySpeed) {
double speedInKph = speed * 3.6;