- use a dialog to insert markers with an option to open full insert screen

- remember the last chosen marker type
- auto increment the default marker name
- fix IME option when toggling between marker type
- add more spacing between items in the editor
- rename WaypointType to WAYPOINT and STATISTICS
- rename to ListItemUtils
- remove unused appwidget_text color
This commit is contained in:
Jimmy Shih
2012-04-27 09:48:01 -07:00
parent 2ec090354b
commit 1a23ba673c
26 changed files with 478 additions and 207 deletions
+46
View File
@@ -0,0 +1,46 @@
<?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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/ScrollView" >
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:padding="8dp" >
<RadioGroup
android:id="@+id/marker_add_type"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content" >
<RadioButton
android:id="@+id/marker_add_statistics"
android:text="@string/marker_statistics"
style="@style/TextMedium" />
<RadioButton
android:id="@+id/marker_add_waypoint"
android:text="@string/marker_waypoint"
style="@style/TextMedium" />
</RadioGroup>
<Button
android:id="@+id/marker_add_more_options"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/generic_more_options" />
</RelativeLayout>
</ScrollView>
+2 -2
View File
@@ -30,10 +30,10 @@ limitations under the License.
android:layout_width="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/marker_detail_marker_type"
android:id="@+id/marker_detail_waypoint_marker_type"
style="@style/TextLarge" />
<TextView
android:id="@+id/marker_detail_description"
android:id="@+id/marker_detail_waypoint_description"
style="@style/TextLarge" />
</LinearLayout>
<TableLayout
+31 -17
View File
@@ -30,48 +30,62 @@ limitations under the License.
android:layout_width="fill_parent"
android:orientation="vertical" >
<TextView
android:text="@string/marker_edit_type"
style="@style/TextMedium" />
android:text="@string/marker_type"
style="@style/EditLabel" />
<RadioGroup
android:id="@+id/marker_edit_type"
android:layout_height="wrap_content"
android:layout_width="wrap_content" >
<RadioButton
android:id="@+id/marker_edit_type_statistics"
android:text="@string/marker_edit_type_statistics"
android:id="@+id/marker_edit_statistics"
android:text="@string/marker_statistics"
style="@style/TextMedium" />
<RadioButton
android:id="@+id/marker_edit_type_waypoint"
android:text="@string/marker_edit_type_waypoint"
android:id="@+id/marker_edit_waypoint"
android:text="@string/marker_waypoint"
style="@style/TextMedium" />
</RadioGroup>
</LinearLayout>
<TextView
android:text="@string/generic_name"
style="@style/TextMedium" />
<EditText
android:hint="@string/generic_name"
android:id="@+id/marker_edit_name"
style="@style/EditName" />
style="@style/EditLabel" />
<LinearLayout
android:id="@+id/marker_edit_statistics_section"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="vertical" >
<EditText
android:drawableLeft="@drawable/yellow_pushpin"
android:hint="@string/generic_name"
android:id="@+id/marker_edit_statistics_name"
android:imeOptions="actionDone"
style="@style/EditName" />
</LinearLayout>
<LinearLayout
android:id="@+id/marker_edit_waypoint_section"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="vertical" >
<EditText
android:drawableLeft="@drawable/blue_pushpin"
android:hint="@string/generic_name"
android:id="@+id/marker_edit_waypoint_name"
android:imeOptions="actionNext"
style="@style/EditName" />
<TextView
android:text="@string/marker_edit_marker_type"
style="@style/TextMedium" />
android:text="@string/marker_edit_waypoint_marker_type"
style="@style/EditLabel.WithPaddingTop" />
<AutoCompleteTextView
android:hint="@string/marker_edit_marker_type_hint"
android:id="@+id/marker_edit_marker_type"
android:hint="@string/marker_edit_waypoint_marker_type_hint"
android:id="@+id/marker_edit_waypoint_marker_type"
android:imeOptions="actionNext"
style="@style/EditCategory" />
<TextView
android:text="@string/generic_description"
style="@style/TextMedium" />
style="@style/EditLabel.WithPaddingTop" />
<EditText
android:hint="@string/generic_description"
android:id="@+id/marker_edit_description"
android:id="@+id/marker_edit_waypoint_description"
android:imeOptions="actionDone"
style="@style/EditDescription" />
</LinearLayout>
+3 -3
View File
@@ -26,7 +26,7 @@ limitations under the License.
android:padding="8dp" >
<TextView
android:text="@string/generic_name"
style="@style/TextMedium" />
style="@style/EditLabel" />
<EditText
android:drawableLeft="@drawable/track"
android:hint="@string/generic_name"
@@ -35,7 +35,7 @@ limitations under the License.
style="@style/EditName" />
<TextView
android:text="@string/track_edit_activity_type"
style="@style/TextMedium" />
style="@style/EditLabel.WithPaddingTop" />
<AutoCompleteTextView
android:hint="@string/track_edit_activity_type_hint"
android:id="@+id/track_edit_activity_type"
@@ -43,7 +43,7 @@ limitations under the License.
style="@style/EditCategory" />
<TextView
android:text="@string/generic_description"
style="@style/TextMedium" />
style="@style/EditLabel.WithPaddingTop" />
<EditText
android:hint="@string/generic_description"
android:id="@+id/track_edit_description"
-1
View File
@@ -46,7 +46,6 @@ limitations under the License.
<color name="power_fill">#40401465</color>
<!-- AppWidget colors -->
<color name="appwidget_text">#EDEDED</color>
<color name="appwidget_hr">#99999999</color>
<!-- Colors for dynamic track drawing -->
+1
View File
@@ -35,6 +35,7 @@ limitations under the License.
<string name="min_recording_interval_key">minRecordingInterval</string>
<string name="min_required_accuracy_key">minRequiredAccuracy</string>
<string name="pick_existing_map_key">pickExistingMap</string>
<string name="pick_statistics_marker_key">pickStatisticsMarker</string>
<string name="preferred_account_key">preferredAccount</string>
<string name="recording_track_id_key">recordingTrackId</string>
<string name="report_speed_key">reportSpeed</string>
+59 -45
View File
@@ -654,6 +654,10 @@ limitations under the License.
</string>
<!-- Generic Strings -->
<string name="generic_add"
translation_description="The text on a button to say add.">
Add
</string>
<string name="generic_cancel"
translation_description="The text on a button to say cancel.">
Cancel
@@ -670,6 +674,10 @@ limitations under the License.
translation_description="The title on an alert dialog indicating error.">
Error
</string>
<string name="generic_more_options"
translation_description="The text on a button to say more options.">
More options
</string>
<string name="generic_name"
translation_description="The text label for entering a name.">
Name
@@ -951,67 +959,47 @@ limitations under the License.
</string>
<!-- Marker -->
<string name="marker_add_error"
translation_description="When adding a marker, the message indicating error.">
Unable to insert a marker. Try again.
</string>
<string name="marker_add_success"
translation_description="When adding a marker, the message indicating success.">
A marker was inserted.
</string>
<string name="marker_delete_one_marker_confirm_message"
translation_description="When deleting a marker, the confirmation dialog message informing the
user that the marker will be permanently deleted from the phone.">
The marker will be permanently deleted from the phone.
</string>
<string name="marker_detail_description"
translation_description="In the marker detail page, the label for the description.
<string name="marker_detail_name"
translation_description="In the marker detail page, the label for the marker name.
%1$s marker name. E.g., 'Waypoint 1'.">
Name: %1$s
</string>
<string name="marker_detail_waypoint_description"
translation_description="In the marker detail page, the label for the waypoint description.
%1$s marker description. E.g., 'At the top'.">
Description: %1$s
</string>
<string name="marker_detail_marker_type"
translation_description="In the marker detail page, the label for the marker type.
<string name="marker_detail_waypoint_marker_type"
translation_description="In the marker detail page, the label for the waypoint marker type.
%1$s marker type. E.g., 'building'.">
Marker type: %1$s
</string>
<string name="marker_detail_name"
translation_description="In the marker detail page, the label for the marker name.
%1$s marker name. E.g., 'Waypoint1'.">
Name: %1$s
</string>
<string name="marker_edit_add"
translation_description="The label on the button to add a marker.">
Add
</string>
<string name="marker_edit_add_error"
translation_description="When adding a marker, the message indicating error.">
Unable to insert a marker. Try again.
</string>
<string name="marker_edit_add_success"
translation_description="When adding a marker, the message indicating success.">
A marker was inserted.
</string>
<string name="marker_edit_add_title"
translation_description="The title of the page to add a new marker.">
New Marker
</string>
<string name="marker_edit_marker_type"
translation_description="The label for the text field to edit the marker type, including some
exmaples.">
<string name="marker_edit_waypoint_marker_type"
translation_description="In the marker edit page, the label for the waypoint marker type,
including some exmaples.">
Marker type (e.g. building, pothole...)
</string>
<string name="marker_edit_marker_type_hint"
translation_description="The hint in the 'Marker type' text field when it is empty.">
<string name="marker_edit_waypoint_marker_type_hint"
translation_description="In the marker edit page, the hint in the waypoint marker type text
field when it is empty.">
Marker type
</string>
<string name="marker_edit_type"
translation_description="When adding a marker, the label to select a type, statistics or
waypoint.">
Type
</string>
<string name="marker_edit_type_statistics"
translation_description="The label to add a statistics marker.">
Statistics
</string>
<string name="marker_edit_type_waypoint"
translation_description="The label to add a waypoint marker.">
Waypoint
</string>
</string>
<string name="marker_label_end"
translation_description="When inserting a marker to indicate the end of a track, the marker's
name. E.g., 'track_name (End)'.
@@ -1030,7 +1018,33 @@ limitations under the License.
translation_description="The message when the marker list is empty.">
You don\'t have any markers.
</string>
<string name="marker_statistics"
translation_description="The label to add a statistics marker.">
Statistics
</string>
<string name="marker_statistics_name_format"
translation_description="When adding a statistics marker, the string format for the default
name.
%1$d: number. E.g., '1'.">
Statistics %1$d
</string>
<string name="marker_type"
translation_description="When adding a marker, the label to select a type, statistics or
waypoint.">
Type
</string>
<string name="marker_waypoint"
translation_description="The label to add a waypoint marker.">
Waypoint
</string>
<string name="marker_waypoint_name_format"
translation_description="When adding a waypoint marker, the string format for the default name.
%1$d: number. E.g., '1'.">
Waypoint %1$d
</string>
<!-- Menu Items -->
<string name="menu_aggregated_statistics"
translation_description="In the menu, to go to the aggregated statistics page.">
+6
View File
@@ -45,6 +45,12 @@ limitations under the License.
<item name="android:selectAllOnFocus">true</item>
<item name="android:singleLine">false</item>
</style>
<!-- The style for the edit label -->
<style name="EditLabel" parent="@style/TextMedium" />
<!-- The style for the edit lable with padding top -->
<style name="EditLabel.WithPaddingTop">
<item name="android:paddingTop">16dp</item>
</style>
<!-- The style for the edit name -->
<style name="EditName" parent="@style/TextMedium.WithIcon">
<item name="android:inputType">textAutoCorrect|textCapWords</item>
@@ -73,11 +73,12 @@ public class MarkerDetailActivity extends AbstractMyTracksActivity {
waypointSection.setVisibility(View.VISIBLE);
statisticsSection.setVisibility(View.GONE);
TextView markerType = (TextView) findViewById(R.id.marker_detail_marker_type);
markerType.setText(getString(R.string.marker_detail_marker_type, waypoint.getCategory()));
TextView description = (TextView) findViewById(R.id.marker_detail_description);
description.setText(getString(R.string.marker_detail_description, waypoint.getDescription()));
TextView markerType = (TextView) findViewById(R.id.marker_detail_waypoint_marker_type);
markerType.setText(getString(
R.string.marker_detail_waypoint_marker_type, waypoint.getCategory()));
TextView description = (TextView) findViewById(R.id.marker_detail_waypoint_description);
description.setText(getString(
R.string.marker_detail_waypoint_description, waypoint.getDescription()));
} else {
waypointSection.setVisibility(View.GONE);
statisticsSection.setVisibility(View.VISIBLE);
@@ -20,23 +20,20 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.content.WaypointCreationRequest.WaypointType;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;
/**
* An activity to add/edit a marker.
@@ -47,19 +44,25 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
private static final String TAG = MarkerEditActivity.class.getSimpleName();
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_MARKER_ID = "marker_id";
public static final String EXTRA_STATISTICS_MARKER = "statistics_marker";
private long trackId;
private long markerId;
private boolean statisticsMarker;
private TrackRecordingServiceConnection trackRecordingServiceConnection;
private Waypoint waypoint;
// UI elements
private View typeSection;
private RadioGroup type;
private EditText name;
private View statisticsSection;
private EditText statisticsName;
private View waypointSection;
private AutoCompleteTextView markerType;
private EditText description;
private EditText waypointName;
private AutoCompleteTextView waypointMarkerType;
private EditText waypointDescription;
private Button done;
@Override
@@ -67,30 +70,48 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
super.onCreate(bundle);
setContentView(R.layout.marker_edit);
trackId = getIntent().getLongExtra(EXTRA_TRACK_ID, -1L);
markerId = getIntent().getLongExtra(EXTRA_MARKER_ID, -1L);
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
statisticsMarker = getIntent().getBooleanExtra(EXTRA_STATISTICS_MARKER, true);
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
// Setup UI elements
typeSection = findViewById(R.id.marker_edit_type_section);
type = (RadioGroup) findViewById(R.id.marker_edit_type);
type.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
boolean statistics = checkedId == R.id.marker_edit_type_statistics;
name.setText(
statistics ? R.string.marker_edit_type_statistics : R.string.marker_edit_type_waypoint);
// Call selectAll so that all EditText have selectAllOnFocus style.
name.selectAll();
updateUiByMarkerType(statistics);
boolean statistics = checkedId == R.id.marker_edit_statistics;
statisticsSection.setVisibility(statistics ? View.VISIBLE : View.GONE);
waypointSection.setVisibility(statistics ? View.GONE : View.VISIBLE);
int nextMarkerNumber = trackId == -1L ? -1
: MyTracksProviderUtils.Factory.get(MarkerEditActivity.this)
.getNextMarkerNumber(trackId, statistics);
if (statistics) {
String name = nextMarkerNumber == -1 ? getString(R.string.marker_type_statistics)
: getString(R.string.marker_statistics_name_format, nextMarkerNumber);
statisticsName.setText(name);
statisticsName.selectAll();
} else {
String name = nextMarkerNumber == -1 ? getString(R.string.marker_type_waypoint)
: getString(R.string.marker_waypoint_name_format, nextMarkerNumber);
waypointName.setText(name);
waypointName.selectAll();
waypointMarkerType.setText("");
waypointDescription.setText("");
}
}
});
name = (EditText) findViewById(R.id.marker_edit_name);
statisticsSection = findViewById(R.id.marker_edit_statistics_section);
statisticsName = (EditText) findViewById(R.id.marker_edit_statistics_name);
waypointSection = findViewById(R.id.marker_edit_waypoint_section);
markerType = (AutoCompleteTextView) findViewById(R.id.marker_edit_marker_type);
waypointName = (EditText) findViewById(R.id.marker_edit_waypoint_name);
waypointMarkerType = (AutoCompleteTextView) findViewById(R.id.marker_edit_waypoint_marker_type);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.waypoint_types, android.R.layout.simple_dropdown_item_1line);
markerType.setAdapter(adapter);
description = (EditText) findViewById(R.id.marker_edit_description);
waypointMarkerType.setAdapter(adapter);
waypointDescription = (EditText) findViewById(R.id.marker_edit_waypoint_description);
Button cancel = (Button) findViewById(R.id.marker_edit_cancel);
cancel.setOnClickListener(new OnClickListener() {
@@ -109,9 +130,9 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
private void updateUiByMarkerId() {
final boolean newMarker = markerId == -1L;
setTitle(newMarker ? R.string.marker_edit_add_title : R.string.menu_edit);
setTitle(newMarker ? R.string.menu_insert_marker : R.string.menu_edit);
typeSection.setVisibility(newMarker ? View.VISIBLE : View.GONE);
done.setText(newMarker ? R.string.marker_edit_add : R.string.generic_save);
done.setText(newMarker ? R.string.generic_add : R.string.generic_save);
done.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -125,7 +146,7 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
});
if (newMarker) {
type.check(R.id.marker_edit_type_statistics);
type.check(statisticsMarker ? R.id.marker_edit_statistics : R.id.marker_edit_waypoint);
} else {
waypoint = MyTracksProviderUtils.Factory.get(this).getWaypoint(markerId);
if (waypoint == null) {
@@ -133,29 +154,19 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
finish();
return;
}
name.setText(waypoint.getName());
boolean statistics = waypoint.getType() == Waypoint.TYPE_STATISTICS;
updateUiByMarkerType(statistics);
if (!statistics) {
markerType.setText(waypoint.getCategory());
description.setText(waypoint.getDescription());
}
statisticsSection.setVisibility(statistics ? View.VISIBLE : View.GONE);
waypointSection.setVisibility(statistics ? View.GONE : View.VISIBLE);
if (statistics) {
statisticsName.setText(waypoint.getName());
} else {
waypointName.setText(waypoint.getName());
waypointMarkerType.setText(waypoint.getCategory());
waypointDescription.setText(waypoint.getDescription());
}
}
}
/**
* Updates the UI by marker type.
*
* @param statistics true for a statistics marker
*/
private void updateUiByMarkerType(boolean statistics) {
name.setCompoundDrawablesWithIntrinsicBounds(
statistics ? R.drawable.yellow_pushpin : R.drawable.blue_pushpin, 0, 0, 0);
name.setImeOptions(statistics ? EditorInfo.IME_ACTION_DONE : EditorInfo.IME_ACTION_NEXT);
waypointSection.setVisibility(statistics ? View.GONE : View.VISIBLE);
}
@Override
protected void onResume() {
super.onResume();
@@ -172,41 +183,33 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
* Adds a marker.
*/
private void addMarker() {
boolean statistics = type.getCheckedRadioButtonId() == R.id.marker_edit_type_statistics;
WaypointType waypointType = statistics ? WaypointType.STATISTICS : WaypointType.MARKER;
String markerCategory = statistics ? null : markerType.getText().toString();
String markerDescription = statistics ? null : description.getText().toString();
String markerIconUrl = getString(
statistics ? R.string.marker_statistics_icon_url : R.string.marker_waypoint_icon_url);
boolean statistics = type.getCheckedRadioButtonId() == R.id.marker_edit_statistics;
PreferencesUtils.setBoolean(this, R.string.pick_statistics_marker_key, statistics);
WaypointType waypointType = statistics ? WaypointType.STATISTICS : WaypointType.WAYPOINT;
String markerName = statistics ? statisticsName.getText().toString()
: waypointName.getText().toString();
String markerCategory = statistics ? null : waypointMarkerType.getText().toString();
String markerDescription = statistics ? null : waypointDescription.getText().toString();
String markerIconUrl = getString(statistics ? R.string.marker_statistics_icon_url
: R.string.marker_waypoint_icon_url);
WaypointCreationRequest waypointCreationRequest = new WaypointCreationRequest(
waypointType, name.getText().toString(), markerCategory, markerDescription, markerIconUrl);
ITrackRecordingService trackRecordingService =
trackRecordingServiceConnection.getServiceIfBound();
if (trackRecordingService == null) {
Log.d(TAG, "Unable to add marker, no track recording service");
} else {
try {
if (trackRecordingService.insertWaypoint(waypointCreationRequest) != -1L) {
Toast.makeText(this, R.string.marker_edit_add_success, Toast.LENGTH_SHORT).show();
return;
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to add marker", e);
} catch (IllegalStateException e) {
Log.e(TAG, "Unable to add marker.", e);
}
}
Toast.makeText(this, R.string.marker_edit_add_error, Toast.LENGTH_LONG).show();
waypointType, markerName, markerCategory, markerDescription, markerIconUrl);
TrackRecordingServiceConnectionUtils.addMarker(
this, trackRecordingServiceConnection, waypointCreationRequest);
}
/**
* Saves a marker.
*/
private void saveMarker() {
waypoint.setName(name.getText().toString());
if (waypoint.getType() == Waypoint.TYPE_WAYPOINT) {
waypoint.setCategory(markerType.getText().toString());
waypoint.setDescription(description.getText().toString());
boolean statistics = waypoint.getType() == Waypoint.TYPE_STATISTICS;
if (statistics) {
waypoint.setName(statisticsName.getText().toString());
} else {
waypoint.setName(waypointName.getText().toString());
waypoint.setCategory(waypointMarkerType.getText().toString());
waypoint.setDescription(waypointDescription.getText().toString());
}
MyTracksProviderUtils.Factory.get(this).updateWaypoint(waypoint);
}
@@ -20,9 +20,10 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.fragments.DeleteOneMarkerDialogFragment;
import com.google.android.apps.mytracks.fragments.MarkerAddDialogFragment;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtil;
import com.google.android.apps.mytracks.util.ListItemUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
@@ -143,7 +144,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity {
String startTime = time == 0
? null : StringUtils.formatDateTime(MarkerListActivity.this, time);
String description = statistics ? null : cursor.getString(descriptionIndex);
ListItemUtil.setListItem(view, name, iconId, category, null, null, startTime, description);
ListItemUtils.setListItem(view, name, iconId, category, null, null, startTime, description);
}
};
listView.setAdapter(resourceCursorAdapter);
@@ -195,8 +196,8 @@ public class MarkerListActivity extends AbstractMyTracksActivity {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.marker_list_insert_marker:
Intent intent = IntentUtils.newIntent(this, MarkerEditActivity.class);
startActivity(intent);
MarkerAddDialogFragment.newInstance(trackId)
.show(getSupportFragmentManager(), MarkerAddDialogFragment.MARKER_ADD_DIALOG_TAG);
return true;
case R.id.marker_list_search:
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this);
@@ -28,7 +28,7 @@ import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtil;
import com.google.android.apps.mytracks.util.ListItemUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
@@ -165,7 +165,7 @@ public class SearchListActivity extends AbstractMyTracksActivity {
String totalDistance = (String) resultMap.get(TOTAL_DISTANCE_FIELD);
String startTime = (String) resultMap.get(START_TIME_FIELD);
String description = (String) resultMap.get(DESCRIPTION_FIELD);
ListItemUtil.setListItem(view,
ListItemUtils.setListItem(view,
name,
iconId,
category,
@@ -25,12 +25,12 @@ import com.google.android.apps.mytracks.fragments.ChartSettingsDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment;
import com.google.android.apps.mytracks.fragments.InstallEarthDialogFragment;
import com.google.android.apps.mytracks.fragments.MapFragment;
import com.google.android.apps.mytracks.fragments.MarkerAddDialogFragment;
import com.google.android.apps.mytracks.fragments.StatsFragment;
import com.google.android.apps.mytracks.io.file.SaveActivity;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
import com.google.android.apps.mytracks.io.sendtogoogle.UploadServiceChooserActivity;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.AnalyticsUtils;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
@@ -47,7 +47,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -55,7 +54,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.Toast;
import java.util.List;
@@ -271,8 +269,8 @@ public class TrackDetailActivity extends AbstractMyTracksActivity {
TrackRecordingServiceConnectionUtils.stop(this, trackRecordingServiceConnection);
return true;
case R.id.track_detail_insert_marker:
intent = IntentUtils.newIntent(this, MarkerEditActivity.class);
startActivity(intent);
MarkerAddDialogFragment.newInstance(trackId)
.show(getSupportFragmentManager(), MarkerAddDialogFragment.MARKER_ADD_DIALOG_TAG);
return true;
case R.id.track_detail_play:
if (isEarthInstalled()) {
@@ -379,25 +377,8 @@ public class TrackDetailActivity extends AbstractMyTracksActivity {
public boolean onTrackballEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (TrackRecordingServiceConnectionUtils.isRecording(this, trackRecordingServiceConnection)) {
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
.getServiceIfBound();
if (trackRecordingService == null) {
Log.e(TAG, "The track recording service is null");
return true;
}
boolean success = false;
try {
long waypointId = trackRecordingService.insertWaypoint(
WaypointCreationRequest.DEFAULT_STATISTICS);
if (waypointId != -1L) {
success = true;
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to insert waypoint", e);
}
Toast.makeText(this,
success ? R.string.marker_edit_add_success : R.string.marker_edit_add_error,
success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show();
TrackRecordingServiceConnectionUtils.addMarker(
this, trackRecordingServiceConnection, WaypointCreationRequest.DEFAULT_STATISTICS);
return true;
}
}
@@ -28,7 +28,7 @@ import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.EulaUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtil;
import com.google.android.apps.mytracks.util.ListItemUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
@@ -223,7 +223,7 @@ public class TrackListActivity extends FragmentActivity {
startTime = null;
}
String description = cursor.getString(descriptionIndex);
ListItemUtil.setListItem(view,
ListItemUtils.setListItem(view,
name,
iconId,
category,
@@ -0,0 +1,122 @@
/*
* 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.fragments;
import com.google.android.apps.mytracks.MarkerEditActivity;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
/**
* A DialogFragment to add a marker.
*
* @author Jimmy Shih
*/
public class MarkerAddDialogFragment extends DialogFragment {
public static final String MARKER_ADD_DIALOG_TAG = "markerAddDialog";
private static final String KEY_TRACK_ID = "trackId";
private TrackRecordingServiceConnection trackRecordingServiceConnection;
private RadioGroup radioGroup;
private Button moreOptions;
/**
* Creates a new instance of {@link MarkerAddDialogFragment}.
*
* @param trackId the track id
*/
public static MarkerAddDialogFragment newInstance(long trackId) {
Bundle bundle = new Bundle();
bundle.putLong(KEY_TRACK_ID, trackId);
MarkerAddDialogFragment markerAddDialogFragment = new MarkerAddDialogFragment();
markerAddDialogFragment.setArguments(bundle);
return markerAddDialogFragment;
}
@Override
public void onCreate(Bundle arg0) {
super.onCreate(arg0);
trackRecordingServiceConnection = new TrackRecordingServiceConnection(getActivity(), null);
}
@Override
public void onResume() {
super.onResume();
TrackRecordingServiceConnectionUtils.resume(getActivity(), trackRecordingServiceConnection);
}
@Override
public void onDestroy() {
super.onDestroy();
trackRecordingServiceConnection.unbind();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.marker_add, null);
radioGroup = (RadioGroup) view.findViewById(R.id.marker_add_type);
moreOptions = (Button) view.findViewById(R.id.marker_add_more_options);
moreOptions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean statisticsMarker = radioGroup.getCheckedRadioButtonId()
== R.id.marker_add_statistics;
Intent intent = IntentUtils.newIntent(getActivity(), MarkerEditActivity.class);
intent.putExtra(MarkerEditActivity.EXTRA_TRACK_ID, getArguments().getLong(KEY_TRACK_ID));
intent.putExtra(MarkerEditActivity.EXTRA_STATISTICS_MARKER, statisticsMarker);
startActivity(intent);
dismiss();
}
});
boolean pickStatisticsMarker = PreferencesUtils.getBoolean(
getActivity(), R.string.pick_statistics_marker_key, true);
radioGroup.check(pickStatisticsMarker ? R.id.marker_add_statistics : R.id.marker_add_waypoint);
return new AlertDialog.Builder(getActivity())
.setNegativeButton(R.string.generic_cancel, null)
.setPositiveButton(R.string.generic_add, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean statisticsMarker = radioGroup.getCheckedRadioButtonId()
== R.id.marker_add_statistics;
PreferencesUtils.setBoolean(
getActivity(), R.string.pick_statistics_marker_key, statisticsMarker);
TrackRecordingServiceConnectionUtils.addMarker(getActivity(),
trackRecordingServiceConnection,
statisticsMarker ? WaypointCreationRequest.DEFAULT_STATISTICS
: WaypointCreationRequest.DEFAULT_WAYPOINT);
}
})
.setTitle(R.string.menu_insert_marker)
.setView(view)
.create();
}
}
@@ -102,7 +102,7 @@ public class CsvTrackWriter implements TrackFormatWriter {
@Override
public void writeBeginWaypoints() {
writeCommaSeparatedLine(context.getString(R.string.generic_name),
context.getString(R.string.marker_edit_marker_type_hint),
context.getString(R.string.marker_edit_waypoint_marker_type_hint),
context.getString(R.string.generic_description),
context.getString(R.string.description_location_latitude),
context.getString(R.string.description_location_longitude),
@@ -933,12 +933,12 @@ public class TrackRecordingService extends Service {
"Unable to insert waypoint marker while not recording!");
}
if (request == null) {
request = WaypointCreationRequest.DEFAULT_MARKER;
request = WaypointCreationRequest.DEFAULT_WAYPOINT;
}
Waypoint wpt = new Waypoint();
switch (request.getType()) {
case MARKER:
buildMarker(wpt, request);
case WAYPOINT:
buildWaypointMarker(wpt, request);
break;
case STATISTICS:
buildStatisticsMarker(wpt, request);
@@ -963,18 +963,22 @@ public class TrackRecordingService extends Service {
return Long.parseLong(uri.getLastPathSegment());
}
private void buildMarker(Waypoint wpt, WaypointCreationRequest request) {
private void buildWaypointMarker(Waypoint wpt, WaypointCreationRequest request) {
wpt.setType(Waypoint.TYPE_WAYPOINT);
if (request.getIconUrl() == null) {
wpt.setIcon(getString(R.string.marker_waypoint_icon_url));
} else {
wpt.setIcon(request.getIconUrl());
}
if (request.getName() == null) {
wpt.setName(getString(R.string.marker_edit_type_waypoint));
String name;
if (request.getName() != null) {
name = request.getName();
} else {
wpt.setName(request.getName());
int nextMarkerNumber = providerUtils.getNextMarkerNumber(recordingTrackId, false);
name = nextMarkerNumber == -1 ? getString(R.string.marker_type_waypoint)
: getString(R.string.marker_waypoint_name_format, nextMarkerNumber);
}
wpt.setName(name);
if (request.getCategory() != null) {
wpt.setCategory(request.getCategory());
}
@@ -1003,8 +1007,15 @@ public class TrackRecordingService extends Service {
// Set the rest of the waypoint data
waypoint.setType(Waypoint.TYPE_STATISTICS);
waypoint.setName(request.getName() != null ? request.getName()
: getString(R.string.marker_edit_type_statistics));
String name;
if (request.getName() != null) {
name = request.getName();
} else {
int nextMarkerNumber = providerUtils.getNextMarkerNumber(recordingTrackId, true);
name = nextMarkerNumber == -1 ? getString(R.string.marker_type_statistics)
: getString(R.string.marker_statistics_name_format, nextMarkerNumber);
}
waypoint.setName(name);
waypoint.setStatistics(waypointStatsBuilder.getStatistics());
waypoint.setDescription(descriptionGenerator.generateWaypointDescription(waypoint));
waypoint.setIcon(getString(R.string.marker_statistics_icon_url));
@@ -26,9 +26,9 @@ import android.widget.TextView;
*
* @author Jimmy Shih
*/
public class ListItemUtil {
public class ListItemUtils {
private ListItemUtil() {}
private ListItemUtils() {}
/**
* Sets a list item.
@@ -197,7 +197,7 @@ public class PreferencesUtils {
* @param keyId the key id
* @param defaultValue the default value
*/
private static boolean getBoolean(Context context, int keyId, boolean defaultValue) {
public static boolean getBoolean(Context context, int keyId, boolean defaultValue) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getBoolean(getKey(context, keyId), defaultValue);
@@ -210,7 +210,7 @@ public class PreferencesUtils {
* @param keyId the key id
* @param value the value
*/
private static void setBoolean(Context context, int keyId, boolean value) {
public static void setBoolean(Context context, int keyId, boolean value) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();
@@ -17,9 +17,11 @@
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.TrackEditActivity;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.maps.mytracks.R;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
@@ -28,6 +30,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
import java.util.List;
@@ -122,7 +125,7 @@ public class TrackRecordingServiceConnectionUtils {
/**
* Resumes the track recording service connection.
*
*
* @param context the context
* @param trackRecordingServiceConnection the track recording service
* connection
@@ -134,4 +137,29 @@ public class TrackRecordingServiceConnectionUtils {
PreferencesUtils.setRecordingTrackId(context, -1L);
}
}
/**
* Adds a marker.
*/
public static void addMarker(Context context,
TrackRecordingServiceConnection trackRecordingServiceConnection,
WaypointCreationRequest waypointCreationRequest) {
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
.getServiceIfBound();
if (trackRecordingService == null) {
Log.d(TAG, "Unable to add marker, no track recording service");
} else {
try {
if (trackRecordingService.insertWaypoint(waypointCreationRequest) != -1L) {
Toast.makeText(context, R.string.marker_add_success, Toast.LENGTH_SHORT).show();
return;
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to add marker", e);
} catch (IllegalStateException e) {
Log.e(TAG, "Unable to add marker.", e);
}
}
Toast.makeText(context, R.string.marker_add_error, Toast.LENGTH_LONG).show();
}
}
@@ -129,6 +129,15 @@ public interface MyTracksProviderUtils {
*/
long getLastWaypointId(long trackId);
/**
* Gets the next marker number.
*
* @param trackId the track id
* @param statistics true for statistics marker, false for waypoint marker
* @return the next number or -1 if unable to get the value
*/
int getNextMarkerNumber(long trackId, boolean statistics);
/**
* Finds the last recorded track from the track provider.
*
@@ -794,6 +794,37 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
return -1;
}
@Override
public int getNextMarkerNumber(long trackId, boolean statistics) {
if (trackId == -1L) {
return -1;
}
String[] projection = { "_id" };
String selection = WaypointsColumns.TRACKID + "=? AND " + WaypointsColumns.TYPE + "=?";
String[] selectionArgs = new String[] { String.valueOf(trackId),
String.valueOf(statistics ? Waypoint.TYPE_STATISTICS : Waypoint.TYPE_WAYPOINT) };
Cursor cursor = null;
try {
cursor = contentResolver.query(
WaypointsColumns.CONTENT_URI, projection, selection, selectionArgs, null);
if (cursor != null) {
int count = cursor.getCount();
/*
* For statistics markers, the first marker is for the track statistics,
* thus just return the count as the next user visible number.
*/
return statistics ? count : count + 1;
}
} catch (RuntimeException e) {
Log.w(TAG, "Caught unexpected exception.", e);
} finally {
if (cursor != null) {
cursor.close();
}
}
return -1;
}
@Override
public Track getLastTrack() {
Cursor cursor = null;
@@ -26,7 +26,7 @@ import android.os.Parcelable;
public class WaypointCreationRequest implements Parcelable {
public static enum WaypointType {
MARKER,
WAYPOINT,
STATISTICS;
}
@@ -36,8 +36,8 @@ public class WaypointCreationRequest implements Parcelable {
private String description;
private String iconUrl;
public final static WaypointCreationRequest DEFAULT_MARKER =
new WaypointCreationRequest(WaypointType.MARKER);
public final static WaypointCreationRequest DEFAULT_WAYPOINT =
new WaypointCreationRequest(WaypointType.WAYPOINT);
public final static WaypointCreationRequest DEFAULT_STATISTICS =
new WaypointCreationRequest(WaypointType.STATISTICS);
@@ -29,7 +29,7 @@ import android.test.AndroidTestCase;
public class WaypointCreationRequestTest extends AndroidTestCase {
public void testTypeParceling() {
WaypointCreationRequest original = WaypointCreationRequest.DEFAULT_MARKER;
WaypointCreationRequest original = WaypointCreationRequest.DEFAULT_WAYPOINT;
Parcel p = Parcel.obtain();
original.writeToParcel(p, 0);
p.setDataPosition(0);
@@ -42,7 +42,7 @@ public class WaypointCreationRequestTest extends AndroidTestCase {
public void testAllAttributesParceling() {
WaypointCreationRequest original =
new WaypointCreationRequest(WaypointType.MARKER, "name", "category", "description", "img.png");
new WaypointCreationRequest(WaypointType.WAYPOINT, "name", "category", "description", "img.png");
Parcel p = Parcel.obtain();
original.writeToParcel(p, 0);
p.setDataPosition(0);
@@ -31,9 +31,16 @@ public class CsvTrackWriterTest extends TrackFormatWriterTest {
String expectedTrackHeader = getExpectedLine(
"Name", "Activity type", "Description");
String expectedTrack = getExpectedLine(TRACK_NAME, TRACK_CATEGORY, TRACK_DESCRIPTION);
String expectedMarkerHeader = getExpectedLine("Marker name", "Marker type",
"Marker description", "Latitude (deg)", "Longitude (deg)", "Altitude (m)", "Bearing (deg)",
"Accuracy (m)", "Speed (m/s)", "Time");
String expectedMarkerHeader = getExpectedLine("Name",
"Marker type",
"Description",
"Latitude (deg)",
"Longitude (deg)",
"Altitude (m)",
"Bearing (deg)",
"Accuracy (m)",
"Speed (m/s)",
"Time");
String expectedMarker1 = getExpectedLine(WAYPOINT1_NAME, WAYPOINT1_CATEGORY,
WAYPOINT1_DESCRIPTION, "1.0", "-1.0", "10.0", "100.0", "1,000", "10,000",
"1970-01-01T00:01:40.000Z");
@@ -491,11 +491,9 @@ public class TrackRecordingServiceTest extends ServiceTestCase<TestRecordingServ
assertEquals(1, service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS));
assertEquals(2, service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS));
Waypoint wpt = providerUtils.getWaypoint(1);
assertEquals(getContext().getString(R.string.marker_statistics_icon_url),
wpt.getIcon());
assertEquals(getContext().getString(R.string.marker_edit_type_statistics),
wpt.getName());
Waypoint wpt = providerUtils.getWaypoint(2);
assertEquals(getContext().getString(R.string.marker_statistics_icon_url), wpt.getIcon());
assertEquals(getContext().getString(R.string.marker_statistics_name_format, 1), wpt.getName());
assertEquals(Waypoint.TYPE_STATISTICS, wpt.getType());
assertEquals(123L, wpt.getTrackId());
assertEquals(0.0, wpt.getLength());
@@ -512,7 +510,7 @@ public class TrackRecordingServiceTest extends ServiceTestCase<TestRecordingServ
assertFalse(service.isRecording());
try {
service.insertWaypoint(WaypointCreationRequest.DEFAULT_MARKER);
service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT);
fail("Expecting IllegalStateException");
} catch (IllegalStateException e) {
// Expected.
@@ -526,12 +524,11 @@ public class TrackRecordingServiceTest extends ServiceTestCase<TestRecordingServ
ITrackRecordingService service = bindAndGetService(createStartIntent());
assertTrue(service.isRecording());
assertEquals(1, service.insertWaypoint(WaypointCreationRequest.DEFAULT_MARKER));
assertEquals(1, service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT));
Waypoint wpt = providerUtils.getWaypoint(1);
assertEquals(getContext().getString(R.string.marker_waypoint_icon_url),
wpt.getIcon());
assertEquals(getContext().getString(R.string.marker_edit_type_waypoint),
wpt.getName());
assertEquals(getContext().getString(R.string.marker_waypoint_name_format, 1), wpt.getName());
assertEquals(Waypoint.TYPE_WAYPOINT, wpt.getType());
assertEquals(123L, wpt.getTrackId());
assertEquals(0.0, wpt.getLength());
@@ -727,7 +724,7 @@ public class TrackRecordingServiceTest extends ServiceTestCase<TestRecordingServ
if (i % 10 == 0) {
service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
} else if (i % 7 == 0) {
service.insertWaypoint(WaypointCreationRequest.DEFAULT_MARKER);
service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT);
}
}