Merge heads

This commit is contained in:
youtaol
2012-06-25 11:08:12 +08:00
parent b337da3719
commit 1c20addf6d
122 changed files with 854 additions and 1252 deletions
@@ -142,7 +142,7 @@ public class ChartView extends View {
series[SPEED_SERIES] = new ChartValueSeries(context,
0,
Integer.MAX_VALUE,
new int[] {1, 5, 10, 20, 50 },
new int[] {1, 5, 10, 20, 50, 100 },
R.string.description_speed_metric,
R.string.description_speed_imperial,
R.color.speed_fill,
@@ -789,7 +789,7 @@ public class ChartView extends View {
break;
}
}
if (index != -1) {
if (index != -1 && chartData.size() > 0) {
int dx = getX(maxX) - pointer.getIntrinsicWidth() / 2;
int dy = getY(series[index], chartData.get(chartData.size() - 1)[index + 1])
- pointer.getIntrinsicHeight();
@@ -139,8 +139,10 @@ public class TrackDetailActivity extends AbstractMyTracksActivity implements Del
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
trackDataHub = ((MyTracksApplication) getApplication()).getTrackDataHub();
trackDataHub.loadTrack(trackId);
mapViewContainer = getLayoutInflater().inflate(R.layout.map, null);
ApiAdapterFactory.getApiAdapter().disableHardwareAccelerated(mapViewContainer);
tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();
tabManager = new TabManager(this, tabHost, R.id.realtabcontent);
@@ -30,6 +30,7 @@ import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
* An activity that let's the user see and edit the user editable track meta
@@ -49,6 +50,7 @@ public class TrackEditActivity extends AbstractMyTracksActivity {
private Track track;
private EditText name;
private TextView activityTypeLabel;
private AutoCompleteTextView activityType;
private EditText description;
@@ -77,6 +79,8 @@ public class TrackEditActivity extends AbstractMyTracksActivity {
activityType = (AutoCompleteTextView) findViewById(R.id.track_edit_activity_type);
activityType.setText(track.getCategory());
activityTypeLabel = (TextView) findViewById(R.id.track_edit_activity_type_label);
setActivityTypeIcon(track.getIcon());
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
@@ -145,7 +149,7 @@ public class TrackEditActivity extends AbstractMyTracksActivity {
* @param iconValue the icon value
*/
private void setActivityTypeIcon(String iconValue) {
activityType.setCompoundDrawablesWithIntrinsicBounds(
activityTypeLabel.setCompoundDrawablesWithIntrinsicBounds(
TrackIconUtils.getIconDrawable(iconValue), 0, 0, 0);
}
}
@@ -21,11 +21,13 @@ import com.google.android.maps.mytracks.R;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.widget.Toast;
/**
* A DialogFragment to install Google Earth.
@@ -45,7 +47,13 @@ public class InstallEarthDialogFragment extends DialogFragment {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent().setData(Uri.parse(SaveActivity.GOOGLE_EARTH_MARKET_URL));
startActivity(intent);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(
getActivity(), R.string.track_detail_install_earth_error, Toast.LENGTH_LONG)
.show();
}
}
})
.create();
@@ -27,6 +27,7 @@ import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
import com.google.android.apps.mytracks.content.TrackDataListener;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.GeoRect;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.maps.GeoPoint;
@@ -120,6 +121,7 @@ public class MapFragment extends Fragment
});
messageTextView = (TextView) mapViewContainer.findViewById(R.id.map_message);
ApiAdapterFactory.getApiAdapter().invalidMenu(getActivity());
return mapViewContainer;
}
@@ -118,9 +118,9 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public void onProviderStateChange(ProviderState state) {
if (state == ProviderState.DISABLED || state == ProviderState.NO_FIX) {
if (isResumed() && (state == ProviderState.DISABLED || state == ProviderState.NO_FIX)) {
getActivity().runOnUiThread(new Runnable() {
@Override
@Override
public void run() {
lastLocation = null;
StatsUtils.setLocationValues(getActivity(), lastLocation, true);
@@ -131,7 +131,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public void onCurrentLocationChanged(final Location location) {
if (isRecording()) {
if (isResumed() && isRecording()) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -149,35 +149,39 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public void onSelectedTrackChanged(Track track, boolean isRecording) {
if (uiUpdateThread == null && isRecording) {
uiUpdateThread = new UiUpdateThread();
uiUpdateThread.start();
} else if (uiUpdateThread != null && !isRecording) {
uiUpdateThread.interrupt();
uiUpdateThread = null;
if (isResumed()) {
if (uiUpdateThread == null && isRecording) {
uiUpdateThread = new UiUpdateThread();
uiUpdateThread.start();
} else if (uiUpdateThread != null && !isRecording) {
uiUpdateThread.interrupt();
uiUpdateThread = null;
}
}
}
@Override
public void onTrackUpdated(final Track track) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (track == null || track.getTripStatistics() == null) {
lastLocation = null;
lastTripStatistics = null;
if (isResumed()) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (track == null || track.getTripStatistics() == null) {
lastLocation = null;
lastTripStatistics = null;
updateUi();
return;
}
lastTripStatistics = track.getTripStatistics();
startTime = track.getTripStatistics().getStartTime();
if (!isRecording()) {
lastLocation = null;
}
updateUi();
return;
}
lastTripStatistics = track.getTripStatistics();
startTime = track.getTripStatistics().getStartTime();
if (!isRecording()) {
lastLocation = null;
}
updateUi();
}
});
});
}
}
@Override
@@ -222,23 +226,27 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public boolean onUnitsChanged(final boolean metric) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateUi();
}
});
if (isResumed()) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateUi();
}
});
}
return true;
}
@Override
public boolean onReportSpeedChanged(final boolean speed) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateUi();
}
});
if (isResumed()) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateUi();
}
});
}
return true;
}
@@ -56,14 +56,20 @@ public class SendFusionTablesUtils {
Log.e(TAG, "Invalid track");
return null;
}
// TODO(jshih): Determine the correct bounding box and zoom level that
// will show the entire track.
TripStatistics stats = track.getTripStatistics();
double latE6 = stats.getBottom() + (stats.getTop() - stats.getBottom()) / 2;
double lonE6 = stats.getLeft() + (stats.getRight() - stats.getLeft()) / 2;
int z = 15;
double latE6;
double lonE6;
int z;
if (track.getNumberOfPoints() < 2) {
// Use Google's latitude and longitude
latE6 = 37.423 * 1.E6;
lonE6 = -122.084 * 1.E6;
z = 2;
} else {
TripStatistics stats = track.getTripStatistics();
latE6 = stats.getBottom() + (stats.getTop() - stats.getBottom()) / 2;
lonE6 = stats.getLeft() + (stats.getRight() - stats.getLeft()) / 2;
z = 15;
}
// We explicitly format with Locale.US because we need the latitude and
// longitude to be formatted in a locale-independent manner. Specifically,
// we need the decimal separator to be a period rather than a comma.
@@ -41,6 +41,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
@@ -177,7 +178,7 @@ public class AccountChooserActivity extends Activity {
}
@Override
public void onFailure() {
finish();
handleNoAccountPermission();
}
};
@@ -188,7 +189,7 @@ public class AccountChooserActivity extends Activity {
}
@Override
public void onFailure() {
finish();
handleNoAccountPermission();
}
};
@@ -199,7 +200,7 @@ public class AccountChooserActivity extends Activity {
}
@Override
public void onFailure() {
finish();
handleNoAccountPermission();
}
};
@@ -211,7 +212,7 @@ public class AccountChooserActivity extends Activity {
}
@Override
public void onFailure() {
finish();
handleNoAccountPermission();
}
};
@@ -283,4 +284,12 @@ public class AccountChooserActivity extends Activity {
startActivity(intent);
finish();
}
/**
* Handles when not able to get account permission.
*/
private void handleNoAccountPermission() {
Toast.makeText(this, R.string.send_google_no_account_permission, Toast.LENGTH_LONG).show();
finish();
}
}
@@ -79,6 +79,40 @@ public class AntSensorManager extends SensorManager {
private boolean requestedReset = false;
private AntInterface.ServiceListener serviceListener = new AntInterface.ServiceListener() {
@Override
public void onServiceConnected() {
setSensorState(Sensor.SensorState.CONNECTING);
serviceConnected = true;
try {
hasClaimedInterface = antInterface.hasClaimedInterface();
if (!hasClaimedInterface) {
hasClaimedInterface = antInterface.claimInterface();
}
if (!hasClaimedInterface) {
tryClaimAnt();
return;
}
if (!antInterface.isEnabled()) {
antInterface.enable();
}
requestReset();
enableDataMessage(true);
} catch (AntInterfaceException e) {
handleAntError();
}
}
@Override
public void onServiceDisconnected() {
serviceConnected = false;
if (hasClaimedInterface) {
enableDataMessage(false);
}
setSensorState(SensorState.DISCONNECTED);
}
};
/**
* Constructor.
*
@@ -112,29 +146,6 @@ public class AntSensorManager extends SensorManager {
context.registerReceiver(statusReceiver, statusIntentFilter);
if (!antInterface.initService(context, serviceListener)) {
AntInterface.goToMarket(context);
} else {
setSensorState(Sensor.SensorState.CONNECTING);
handleServiceConnected();
}
}
}
/**
* Handles service connected. Needs to be synchronized.
*/
private synchronized void handleServiceConnected() {
serviceConnected = antInterface.isServiceConnected();
if (serviceConnected) {
try {
hasClaimedInterface = antInterface.hasClaimedInterface();
if (hasClaimedInterface) {
enableDataMessage(true);
} else {
// Need to claim the ant interface if it is available
hasClaimedInterface = antInterface.claimInterface();
}
} catch (AntInterfaceException e) {
handleAntError();
}
}
}
@@ -162,6 +173,7 @@ public class AntSensorManager extends SensorManager {
antInterface.releaseService();
serviceConnected = false;
}
setSensorState(SensorState.DISCONNECTED);
}
@Override
@@ -172,7 +184,7 @@ public class AntSensorManager extends SensorManager {
/**
* Tries to claim the ant interface.
*/
public void tryClaimAnt() {
private void tryClaimAnt() {
try {
antInterface.requestForceClaimInterface(context.getString(R.string.my_tracks_app_name));
} catch (AntInterfaceException e) {
@@ -180,21 +192,6 @@ public class AntSensorManager extends SensorManager {
}
}
private AntInterface.ServiceListener serviceListener = new AntInterface.ServiceListener() {
@Override
public void onServiceConnected() {
handleServiceConnected();
}
@Override
public void onServiceDisconnected() {
serviceConnected = false;
if (hasClaimedInterface) {
enableDataMessage(false);
}
}
};
/**
* Configures ant radio.
*/
@@ -243,7 +240,6 @@ public class AntSensorManager extends SensorManager {
channelConfig[channel].setInitializing(false);
channelConfig[channel].setDeinitializing(true);
channelConfig[channel].setChannelState(ChannelStates.CLOSED);
setSensorState(SensorState.DISCONNECTED);
try {
antInterface.ANTCloseChannel(channel);
// Note, unassign channel after getting channel closed event
@@ -266,7 +262,7 @@ public class AntSensorManager extends SensorManager {
/**
* Requests reset.
*/
public void requestReset() {
private void requestReset() {
try {
requestedReset = true;
antInterface.ANTResetSystem();
@@ -316,6 +312,7 @@ public class AntSensorManager extends SensorManager {
if (wasClaimed) {
// Claimed by another application
enableDataMessage(false);
setSensorState(SensorState.DISCONNECTED);
}
}
} catch (AntInterfaceException e) {
@@ -557,7 +554,6 @@ public class AntSensorManager extends SensorManager {
for (int i = 0; i < CHANNELS; i++) {
closeChannel((byte) i);
}
setSensorState(SensorState.DISCONNECTED);
} catch (IllegalArgumentException e) {
// Can safely ignore
}
@@ -114,4 +114,14 @@ public class Api11Adapter extends Api10Adapter {
public <T> void addAllToArrayAdapter(ArrayAdapter<T> arrayAdapter, List<T> items) {
arrayAdapter.addAll(items);
}
@Override
public void invalidMenu(Activity activity) {
activity.invalidateOptionsMenu();
}
@Override
public void disableHardwareAccelerated(View view) {
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
@@ -32,6 +32,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.ListView;
@@ -146,6 +147,16 @@ public class Api7Adapter implements ApiAdapter {
}
}
@Override
public void invalidMenu(Activity activity) {
// Do nothing
}
@Override
public void disableHardwareAccelerated(View view) {
// Do nothing
}
@Override
public boolean handleSearchKey(MenuItem menuItem) {
// Return false and allow the framework to handle the search key.
@@ -26,6 +26,7 @@ import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
@@ -149,7 +150,7 @@ public interface ApiAdapter {
/**
* Configures the search widget.
*
* <p>
* Due to changes in API level 11.
*
* @param activity the activity
@@ -159,7 +160,7 @@ public interface ApiAdapter {
/**
* Handles the search menu selection. Returns true if handled.
*
* <p>
* Due to changes in API level 11.
*
* @param activity the activity
@@ -168,17 +169,33 @@ public interface ApiAdapter {
/**
* Adds all items to an array adapter.
*
* <p>
* Due to changes in API level 11.
*s
*
* @param arrayAdapter the array adapter
* @param items list of items
*/
public <T> void addAllToArrayAdapter(ArrayAdapter<T> arrayAdapter, List<T> items);
/**
* Handles the search key press. Returns true if handled.
* Invalidates the menu.
* <p>
* Due to changes in API level 11.
*/
public void invalidMenu(Activity activity);
/**
* Diables hardware-accelerated rendering for a view.
* <p>
* Due to chagnes in API level 11.
*
* @param view the view
*/
public void disableHardwareAccelerated(View view);
/**
* Handles the search key press. Returns true if handled.
* <p>
* Due to changes in API level 14.
*
* @param menu the search menu
@@ -70,6 +70,9 @@ public class StatsUtils {
R.string.stats_show_coordinate_key, PreferencesUtils.STATS_SHOW_COORDINATE_DEFAULT);
View coordinateLabelTableRow = activity.findViewById(R.id.stats_coordinate_label_table_row);
View coordinateValueTableRow = activity.findViewById(R.id.stats_coordinate_value_table_row);
if (coordinateLabelTableRow == null || coordinateValueTableRow == null) {
return;
}
coordinateLabelTableRow.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
coordinateValueTableRow.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
if (showCoordinate) {
@@ -149,6 +152,12 @@ public class StatsUtils {
View elevationValueTableRow1 = activity.findViewById(R.id.stats_elevation_value_table_row1);
View elevationLabelTableRow2 = activity.findViewById(R.id.stats_elevation_label_table_row2);
View elevationValueTableRow2 = activity.findViewById(R.id.stats_elevation_value_table_row2);
if (elevationLabelTableRow1 == null
|| elevationValueTableRow1 == null
|| elevationLabelTableRow2 == null
|| elevationValueTableRow2 == null) {
return;
}
elevationLabelTableRow1.setVisibility(showElevation ? View.VISIBLE : View.GONE);
elevationValueTableRow1.setVisibility(showElevation ? View.VISIBLE : View.GONE);
elevationLabelTableRow2.setVisibility(showElevation ? View.VISIBLE : View.GONE);
@@ -168,6 +177,9 @@ public class StatsUtils {
activity, R.string.stats_show_grade_key, PreferencesUtils.STATS_SHOW_GRADE_DEFAULT);
View gradeLabelTableRow = activity.findViewById(R.id.stats_grade_label_table_row);
View gradeValueTableRow = activity.findViewById(R.id.stats_grade_value_table_row);
if (gradeLabelTableRow == null || gradeValueTableRow == null) {
return;
}
gradeLabelTableRow.setVisibility(showGrade ? View.VISIBLE : View.GONE);
gradeValueTableRow.setVisibility(showGrade ? View.VISIBLE : View.GONE);
if (showGrade) {
@@ -190,6 +202,9 @@ public class StatsUtils {
private static void setTimeLabel(Activity activity, int id, int totalTimeId, int movingTimeId,
boolean totalTime) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
textView.setText(totalTime ? totalTimeId : movingTimeId);
}
@@ -205,6 +220,9 @@ public class StatsUtils {
private static void setSpeedLabel(
Activity activity, int id, int speedId, int paceId, boolean reportSpeed) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
textView.setText(reportSpeed ? speedId : paceId);
}
@@ -220,6 +238,9 @@ public class StatsUtils {
private static void setSpeedValue(
Activity activity, int id, double speed, boolean metricUnits, boolean reportSpeed) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
textView.setText(StringUtils.formatSpeed(activity, speed, metricUnits, reportSpeed));
}
@@ -234,6 +255,9 @@ public class StatsUtils {
private static void setDistanceValue(
Activity activity, int id, double distance, boolean metricUnits) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
textView.setText(StringUtils.formatDistance(activity, distance, metricUnits));
}
@@ -246,6 +270,9 @@ public class StatsUtils {
*/
private static void setTimeValue(Activity activity, int id, long time) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
String value = time == -1L ? activity.getString(R.string.value_unknown)
: StringUtils.formatElapsedTime(time);
textView.setText(value);
@@ -262,6 +289,9 @@ public class StatsUtils {
private static void setElevationValue(
Activity activity, int id, double elevation, boolean metricUnits) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
String value;
if (Double.isNaN(elevation) || Double.isInfinite(elevation)) {
value = activity.getString(R.string.value_unknown);
@@ -285,6 +315,9 @@ public class StatsUtils {
*/
private static void setGradeValue(Activity activity, int id, double grade) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
String value;
if (Double.isNaN(grade) || Double.isInfinite(grade)) {
value = activity.getString(R.string.value_unknown);
@@ -303,6 +336,9 @@ public class StatsUtils {
*/
private static void setCoordinateValue(Activity activity, int id, double coordinate) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
String value;
if (Double.isNaN(coordinate) || Double.isInfinite(coordinate)) {
value = activity.getString(R.string.value_unknown);
@@ -118,14 +118,14 @@ public class StringUtils {
return context.getString(R.string.value_unknown);
}
if (metricUnits) {
if (distance > 1000.0) {
if (distance > 500.0) {
distance *= UnitConversions.M_TO_KM;
return context.getString(R.string.value_float_kilometer, distance);
} else {
return context.getString(R.string.value_float_meter, distance);
}
} else {
if (distance * UnitConversions.M_TO_MI > 1) {
if (distance * UnitConversions.M_TO_MI > 0.5) {
distance *= UnitConversions.M_TO_MI;
return context.getString(R.string.value_float_mile, distance);
} else {