sync from main

This commit is contained in:
Jimmy Shih
2012-04-05 17:06:43 -07:00
parent 32e8044b0b
commit 5082936ad1
8 changed files with 228 additions and 85 deletions
+3 -15
View File
@@ -46,27 +46,15 @@ limitations under the License.
android:orientation="horizontal" > android:orientation="horizontal" >
<TextView <TextView
android:id="@+id/track_list_item_time" android:id="@+id/track_list_item_time"
android:layout_height="wrap_content" style="@style/TrackListItemStatsTextView" />
android:layout_width="wrap_content"
android:singleLine="true"
android:textColor="@color/green"
style="@android:style/TextAppearance.DeviceDefault.Small" />
<TextView <TextView
android:id="@+id/track_list_item_distance" android:id="@+id/track_list_item_distance"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_width="wrap_content" style="@style/TrackListItemStatsTextView" />
android:singleLine="true"
android:textColor="@color/green"
style="@android:style/TextAppearance.DeviceDefault.Small" />
<TextView <TextView
android:id="@+id/track_list_item_start" android:id="@+id/track_list_item_start"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_width="wrap_content" style="@style/TrackListItemStatsTextView" />
android:singleLine="true"
android:textColor="@color/green"
style="@android:style/TextAppearance.DeviceDefault.Small" />
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/track_list_item_description" android:id="@+id/track_list_item_description"
+2 -2
View File
@@ -2315,8 +2315,8 @@ limitations under the License.
<string name="track_detail_install_earth_message" <string name="track_detail_install_earth_message"
translation_description="When playing a track, the message informing the user that he needs translation_description="When playing a track, the message informing the user that he needs
Google Earth to play the track and asking him if he wants to install Google Earth from the Google Earth to play the track and asking him if he wants to install Google Earth from the
Android Market."> Play Store.">
You need Google Earth to play the track. Do you want to install from the Market? You need Google Earth to play the track. Do you want to install from the Play Store?
</string> </string>
<string name="track_detail_map_tab" <string name="track_detail_map_tab"
translation_description="In the track detail page, the title of the tab showing the map."> translation_description="In the track detail page, the title of the tab showing the map.">
+9 -1
View File
@@ -125,7 +125,15 @@ limitations under the License.
<item name="android:textColor">@color/stat_label_text</item> <item name="android:textColor">@color/stat_label_text</item>
</style> </style>
<!-- Welcome page TextView --> <!-- The TextView showing the stats in the track list item -->
<style name="TrackListItemStatsTextView" parents="@android:style/TextAppearance.DeviceDefault.Small">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">@color/green</item>
</style>
<!-- Welcome page TextView -->
<style name="WelcomeTextView"> <style name="WelcomeTextView">
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">fill_parent</item> <item name="android:layout_width">fill_parent</item>
@@ -88,14 +88,14 @@ public class TrackDetailActivity extends FragmentActivity {
private TabManager tabManager; private TabManager tabManager;
private long trackId; private long trackId;
private MenuItem stopRecording; private MenuItem stopRecordingMenuItem;
private MenuItem insertMarker; private MenuItem insertMarkerMenuItem;
private MenuItem play; private MenuItem playMenuItem;
private MenuItem share; private MenuItem shareMenuItem;
private MenuItem sendGoogle; private MenuItem sendGoogleMenuItem;
private MenuItem save; private MenuItem saveMenuItem;
private MenuItem edit; private MenuItem editMenuItem;
private MenuItem delete; private MenuItem deleteMenuItem;
private View mapViewContainer; private View mapViewContainer;
@@ -107,10 +107,8 @@ public class TrackDetailActivity extends FragmentActivity {
new OnSharedPreferenceChangeListener() { new OnSharedPreferenceChangeListener() {
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (key == null) { // Note that key can be null
return; if (getString(R.string.recording_track_key).equals(key)) {
}
if (key.equals(getString(R.string.recording_track_key))) {
updateMenu(); updateMenu();
} }
} }
@@ -242,7 +240,7 @@ public class TrackDetailActivity extends FragmentActivity {
R.string.track_detail_delete_confirm_message, new DialogInterface.OnClickListener() { R.string.track_detail_delete_confirm_message, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
MyTracksProviderUtils.Factory.get(TrackDetailActivity.this).deleteTrack(trackId); deleteCurrentTrack();
startTrackListActivity(); startTrackListActivity();
} }
}); });
@@ -317,14 +315,14 @@ public class TrackDetailActivity extends FragmentActivity {
menu.findItem(R.id.track_detail_share_tcx) menu.findItem(R.id.track_detail_share_tcx)
.setTitle(getString(R.string.menu_share_file, fileTypes[3])); .setTitle(getString(R.string.menu_share_file, fileTypes[3]));
stopRecording = menu.findItem(R.id.track_detail_stop_recording); stopRecordingMenuItem = menu.findItem(R.id.track_detail_stop_recording);
insertMarker = menu.findItem(R.id.track_detail_insert_marker); insertMarkerMenuItem = menu.findItem(R.id.track_detail_insert_marker);
play = menu.findItem(R.id.track_detail_play); playMenuItem = menu.findItem(R.id.track_detail_play);
share = menu.findItem(R.id.track_detail_share); shareMenuItem = menu.findItem(R.id.track_detail_share);
sendGoogle = menu.findItem(R.id.track_detail_send_google); sendGoogleMenuItem = menu.findItem(R.id.track_detail_send_google);
save = menu.findItem(R.id.track_detail_save); saveMenuItem = menu.findItem(R.id.track_detail_save);
edit = menu.findItem(R.id.track_detail_edit); editMenuItem = menu.findItem(R.id.track_detail_edit);
delete = menu.findItem(R.id.track_detail_delete); deleteMenuItem = menu.findItem(R.id.track_detail_delete);
updateMenu(); updateMenu();
return true; return true;
@@ -359,7 +357,7 @@ public class TrackDetailActivity extends FragmentActivity {
stopRecording(); stopRecording();
return true; return true;
case R.id.track_detail_insert_marker: case R.id.track_detail_insert_marker:
// TODO: // TODO: Add insert marker when updating WaypointList to ICS
return true; return true;
case R.id.track_detail_play: case R.id.track_detail_play:
if (isEarthInstalled()) { if (isEarthInstalled()) {
@@ -518,37 +516,44 @@ public class TrackDetailActivity extends FragmentActivity {
} }
/** /**
* s Updates the menu items. * Updates the menu items.
* *
* @param isRecording true if recording * @param isRecording true if recording
*/ */
private void updateMenuItems(boolean isRecording) { private void updateMenuItems(boolean isRecording) {
if (stopRecording != null) { if (stopRecordingMenuItem != null) {
stopRecording.setVisible(isRecording); stopRecordingMenuItem.setVisible(isRecording);
} }
if (insertMarker != null) { if (insertMarkerMenuItem != null) {
insertMarker.setVisible(isRecording); insertMarkerMenuItem.setVisible(isRecording);
} }
if (play != null) { if (playMenuItem != null) {
play.setVisible(!isRecording); playMenuItem.setVisible(!isRecording);
} }
if (share != null) { if (shareMenuItem != null) {
share.setVisible(!isRecording); shareMenuItem.setVisible(!isRecording);
} }
if (sendGoogle != null) { if (sendGoogleMenuItem != null) {
sendGoogle.setVisible(!isRecording); sendGoogleMenuItem.setVisible(!isRecording);
} }
if (save != null) { if (saveMenuItem != null) {
save.setVisible(!isRecording); saveMenuItem.setVisible(!isRecording);
} }
if (edit != null) { if (editMenuItem != null) {
edit.setVisible(!isRecording); editMenuItem.setVisible(!isRecording);
} }
if (delete != null) { if (deleteMenuItem != null) {
delete.setVisible(!isRecording); deleteMenuItem.setVisible(!isRecording);
} }
} }
/**
* Deletes the current track.
*/
private void deleteCurrentTrack() {
MyTracksProviderUtils.Factory.get(TrackDetailActivity.this).deleteTrack(trackId);
}
/** /**
* Starts the {@link TrackListActivity}. * Starts the {@link TrackListActivity}.
*/ */
@@ -86,24 +86,25 @@ public class TrackListActivity extends FragmentActivity {
private final Runnable bindChangedCallback = new Runnable() { private final Runnable bindChangedCallback = new Runnable() {
@Override @Override
public void run() { public void run() {
if (startNewRecording) { if (!startNewRecording) {
ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound(); return;
if (service != null) { }
try {
recordingTrackId = service.startNewTrack(); ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound();
startNewRecording = false; if (service == null) {
Toast.makeText( Log.d(TAG, "service not available to start a new recording");
TrackListActivity.this, R.string.track_list_record_success, Toast.LENGTH_SHORT) return;
.show(); }
Log.d(TAG, "Started a new recording"); try {
} catch (Exception e) { recordingTrackId = service.startNewTrack();
Toast.makeText( startNewRecording = false;
TrackListActivity.this, R.string.track_list_record_error, Toast.LENGTH_LONG).show(); Toast.makeText(
Log.d(TAG, "Unable to start a new recording.", e); TrackListActivity.this, R.string.track_list_record_success, Toast.LENGTH_SHORT).show();
} Log.d(TAG, "Started a new recording");
} else { } catch (Exception e) {
Log.d(TAG, "service not available to start a new recording"); Toast.makeText(TrackListActivity.this, R.string.track_list_record_error, Toast.LENGTH_LONG)
} .show();
Log.e(TAG, "Unable to start a new recording.", e);
} }
} }
}; };
@@ -116,13 +117,11 @@ public class TrackListActivity extends FragmentActivity {
new OnSharedPreferenceChangeListener() { new OnSharedPreferenceChangeListener() {
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (key == null) { // Note that key can be null
return; if (getString(R.string.metric_units_key).equals(key)) {
}
if (key.equals(getString(R.string.metric_units_key))) {
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true); metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
} }
if (key.equals(getString(R.string.recording_track_key))) { if (getString(R.string.recording_track_key).equals(key)) {
recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L); recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L);
if (isRecording()) { if (isRecording()) {
trackRecordingServiceConnection.startAndBind(); trackRecordingServiceConnection.startAndBind();
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.LocationUtils; import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.common.annotations.VisibleForTesting;
import android.location.Location; import android.location.Location;
import android.util.Log; import android.util.Log;
@@ -109,11 +110,12 @@ public class SendToGoogleUtils {
* @param segment the track segment * @param segment the track segment
* @param splitTracks an array of track segments * @param splitTracks an array of track segments
*/ */
private static void prepareTrackSegment(Track segment, ArrayList<Track> splitTracks) { @VisibleForTesting
static boolean prepareTrackSegment(Track segment, ArrayList<Track> splitTracks) {
// Make sure the segment has at least 2 points // Make sure the segment has at least 2 points
if (segment.getLocations().size() < 2) { if (segment.getLocations().size() < 2) {
Log.d(TAG, "segment has less than 2 points"); Log.d(TAG, "segment has less than 2 points");
return; return false;
} }
// For a new segment, sets it stop time // For a new segment, sets it stop time
@@ -128,5 +130,6 @@ public class SendToGoogleUtils {
LocationUtils.decimate(segment, 2.0); LocationUtils.decimate(segment, 2.0);
splitTracks.add(segment); splitTracks.add(segment);
return true;
} }
} }
@@ -31,9 +31,9 @@ import android.location.Location;
public class TrackStubUtils { public class TrackStubUtils {
static final String LOCATION_PROVIDER = "gps"; static final String LOCATION_PROVIDER = "gps";
static final double INITIAL_LATITUDE = 22; public static final double INITIAL_LATITUDE = 22;
static final double INITIAL_LONGITUDE = 22; public static final double INITIAL_LONGITUDE = 22;
static final double INITIAL_ALTITUDE = 22; public static final double INITIAL_ALTITUDE = 22;
static final float INITIAL_ACCURACY = 5; static final float INITIAL_ACCURACY = 5;
static final float INITIAL_SPEED = 10; static final float INITIAL_SPEED = 10;
static final float INITIAL_BEARING = 3.0f; static final float INITIAL_BEARING = 3.0f;
@@ -0,0 +1,140 @@
/*
* 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.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
/**
* Tests the {@link SendToGoogleUtils}.
*
* @author Youtao Liu
*/
import com.google.android.apps.mytracks.TrackStubUtils;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.Track;
import android.location.Location;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
public class SendToGoogleUtilsTest extends TestCase {
private final static long TRACK_ID = 1L;
private final static String TRACK_CATEGORY = "trackCategory";
private final static String TRACK_NAME = "trackName";
private final static double DIFFERENCE = 0.02;
private final static double INVALID_LATITUDE = 91;
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
* when there is only one location in a segment.
*/
public void testPrepareTrackSegment_onlyOneLocation() {
Track trackStub = TrackStubUtils.createTrack(1);
assertFalse(SendToGoogleUtils.prepareTrackSegment(trackStub, null));
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, ArrayList)} when there
* is no stop time.
*/
public void testPrepareTrackSegment_noStopTime() {
Track trackStub = TrackStubUtils.createTrack(2);
assertEquals(-1L, trackStub.getStatistics().getStopTime());
ArrayList<Track> tracksArray = new ArrayList<Track>();
assertTrue(SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray));
assertEquals(trackStub, tracksArray.get(0));
// The stop time should be the time of last location
assertEquals(trackStub.getLocations().get(1).getTime(), trackStub.getStatistics().getStopTime());
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
* when there is stop time.
*/
public void testPrepareTrackSegment_hasStopTime() {
Track trackStub = TrackStubUtils.createTrack(2);
// Gives a margin to make sure the this time will be not same with the last
// location in the track.
long stopTime = System.currentTimeMillis() + 1000;
trackStub.getStatistics().setStopTime(stopTime);
ArrayList<Track> tracksArray = new ArrayList<Track>();
SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray);
assertEquals(trackStub, tracksArray.get(0));
assertEquals(stopTime, trackStub.getStatistics().getStopTime());
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareLocations(Track, java.util.List)} .
*/
public void testPrepareLocations() {
Track trackStub = TrackStubUtils.createTrack(2);
trackStub.setId(TRACK_ID);
trackStub.setName(TRACK_NAME);
trackStub.setCategory(TRACK_CATEGORY);
List<Location> locationsArray = new ArrayList<Location>();
// Adds 100 location to List.
for (int i = 0; i < 100; i++) {
// Use this variable as a flag to make all points in the track can be kept
// after run the LocationUtils#decimate(Track, double) with
// Ramer–Douglas–Peucker algorithm.
double latitude = TrackStubUtils.INITIAL_LATITUDE;
if (i % 2 == 0) {
latitude -= DIFFERENCE * (i % 10);
}
// Inserts 9 points which have wrong latitude, so would have 10 segments.
if (i % 10 == 0 && i > 0) {
MyTracksLocation location = TrackStubUtils.createMyTracksLocation();
location.setLatitude(INVALID_LATITUDE);
locationsArray.add(location);
} else {
locationsArray.add(TrackStubUtils.createMyTracksLocation(latitude,
TrackStubUtils.INITIAL_LONGITUDE + DIFFERENCE * (i % 10),
TrackStubUtils.INITIAL_ALTITUDE + DIFFERENCE * (i % 10)));
}
}
ArrayList<Track> result = SendToGoogleUtils.prepareLocations(trackStub, locationsArray);
assertEquals(10, result.size());
// Checks all segments.
for (int i = 0; i < 10; i++) {
Track segmentOne = result.get(i);
assertEquals(TRACK_ID, segmentOne.getId());
assertEquals(TRACK_NAME, segmentOne.getName());
assertEquals(TRACK_CATEGORY, segmentOne.getCategory());
}
// Checks all locations in the first segment.
for (int j = 0; j < 9; j++) {
double latitude = TrackStubUtils.INITIAL_LATITUDE;
if (j % 2 == 0) {
latitude -= DIFFERENCE * (j % 10);
}
Location oneLocation = result.get(0).getLocations().get(j);
assertEquals(TrackStubUtils.createMyTracksLocation().getAltitude() + DIFFERENCE * (j % 10),
oneLocation.getAltitude());
assertEquals(latitude, oneLocation.getLatitude());
assertEquals(TrackStubUtils.createMyTracksLocation().getLongitude() + DIFFERENCE * (j % 10),
oneLocation.getLongitude());
}
}
}