Added quick route functionality

This commit is contained in:
dkeen@dkeen-laptop 2012-07-16 08:06:31 -07:00
parent e79dc2ba46
commit bb63de996e
12 changed files with 253 additions and 102 deletions

View File

@ -53,6 +53,18 @@
<data android:mimeType="vnd.android.cursor.dir/com.dougkeen.bart.favorite" />
</intent-filter>
</activity>
<activity
android:name="QuickRouteActivity"
android:label="@string/quick_departure_lookup"
android:theme="@android:style/Theme.Dialog" >
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/com.dougkeen.bart.arbitraryroute" />
</intent-filter>
</activity>
<activity
android:name="ViewDeparturesActivity"
android:label="@string/departures" >
@ -62,6 +74,7 @@
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/com.dougkeen.bart.favorite" />
<data android:mimeType="vnd.android.cursor.item/com.dougkeen.bart.arbitraryroute" />
</intent-filter>
</activity>
<activity

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:paddingLeft="5dp" android:paddingRight="5dp">
<TextView android:id="@+id/origin_label" android:text="@string/origin"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textSize="15dp" android:layout_below="@+id/form_header"
android:layout_alignLeft="@+id/form_header"></TextView>
<Spinner android:id="@+id/origin_spinner" android:layout_below="@id/origin_label"
android:layout_height="wrap_content" android:layout_width="fill_parent" />
<TextView android:id="@+id/destination_label" android:text="@string/destination"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textSize="15dp" android:layout_below="@+id/origin_spinner"
android:layout_alignLeft="@+id/origin_spinner"></TextView>
<Spinner android:id="@+id/destination_spinner"
android:layout_below="@id/destination_label" android:layout_height="wrap_content"
android:layout_width="fill_parent" />
<CheckBox android:id="@+id/return_checkbox"
android:layout_below="@id/destination_spinner" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:text="@string/also_add_return_route" />
<LinearLayout android:layout_height="wrap_content"
android:layout_width="fill_parent" android:layout_below="@id/return_checkbox"
style="@style/ButtonBar" android:id="@+id/buttonBar"
android:orientation="horizontal">
<Button android:text="@string/save" android:layout_weight="1"
android:layout_height="wrap_content" android:id="@+id/saveButton"
android:layout_width="fill_parent"></Button>
<Button android:text="@string/cancel" android:layout_weight="1"
android:layout_height="wrap_content" android:id="@+id/cancelButton"
android:layout_width="fill_parent"></Button>
</LinearLayout>
</RelativeLayout>

View File

@ -15,4 +15,19 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<FrameLayout
style="ButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" >
<Button
android:id="@+id/quickLookupButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/quick_departure_lookup" />
</FrameLayout>
</LinearLayout>

72
res/layout/route_form.xml Normal file
View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="5dp"
android:paddingRight="5dp" >
<TextView
android:id="@+id/origin_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="@string/origin"
android:textSize="15dp" >
</TextView>
<Spinner
android:id="@+id/origin_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/origin_label" />
<TextView
android:id="@+id/destination_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/origin_spinner"
android:layout_below="@+id/origin_spinner"
android:text="@string/destination"
android:textSize="15dp" >
</TextView>
<Spinner
android:id="@+id/destination_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/destination_label" />
<CheckBox
android:id="@+id/return_checkbox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/destination_spinner"
android:text="@string/also_add_return_route"
android:visibility="gone" />
<LinearLayout
android:id="@+id/buttonBar"
style="@style/ButtonBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/return_checkbox"
android:orientation="horizontal" >
<Button
android:id="@+id/okButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/ok" >
</Button>
<Button
android:id="@+id/cancelButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel" >
</Button>
</LinearLayout>
</RelativeLayout>

View File

@ -30,4 +30,6 @@
<string name="view_system_map">View system map</string>
<string name="system_map">System map</string>
<string name="departures">Departures</string>
<string name="ok">OK</string>
<string name="quick_departure_lookup">Quick departure lookup</string>
</resources>

View File

@ -126,4 +126,8 @@
<item name="android:layout_marginBottom">5dp</item>
</style>
<style name="bottomButton">
<item name="android:background">#222</item>
</style>
</resources>

View File

@ -0,0 +1,78 @@
package com.dougkeen.bart;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.Toast;
import com.dougkeen.bart.model.Station;
public abstract class AbstractRouteSelectionActivity extends Activity {
public AbstractRouteSelectionActivity() {
super();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.route_form);
SpinnerAdapter originSpinnerAdapter = new ArrayAdapter<Station>(this,
R.layout.simple_spinner_item, Station.getStationList());
((Spinner) findViewById(R.id.origin_spinner))
.setAdapter(originSpinnerAdapter);
SpinnerAdapter destinationSpinnerAdapter = new ArrayAdapter<Station>(
this, R.layout.simple_spinner_item, Station.getStationList());
((Spinner) findViewById(R.id.destination_spinner))
.setAdapter(destinationSpinnerAdapter);
Button okButton = (Button) findViewById(R.id.okButton);
okButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Station origin = (Station) ((Spinner) findViewById(R.id.origin_spinner))
.getSelectedItem();
Station destination = (Station) ((Spinner) findViewById(R.id.destination_spinner))
.getSelectedItem();
if (origin == null) {
Toast.makeText(v.getContext(),
com.dougkeen.bart.R.string.error_null_origin,
Toast.LENGTH_LONG);
return;
}
if (destination == null) {
Toast.makeText(v.getContext(),
com.dougkeen.bart.R.string.error_null_destination,
Toast.LENGTH_LONG);
return;
}
if (origin.equals(destination)) {
Toast.makeText(
v.getContext(),
com.dougkeen.bart.R.string.error_matching_origin_and_destination,
Toast.LENGTH_LONG);
return;
}
onOkButtonClick(origin, destination);
}
});
Button cancelButton = (Button) findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
setResult(RESULT_CANCELED);
finish();
}
});
}
abstract protected void onOkButtonClick(Station origin, Station destination);
}

View File

@ -1,83 +1,25 @@
package com.dougkeen.bart;
import com.dougkeen.bart.data.RoutesColumns;
import com.dougkeen.bart.model.Constants;
import com.dougkeen.bart.model.Station;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.Toast;
public class AddRouteActivity extends Activity {
import com.dougkeen.bart.data.RoutesColumns;
import com.dougkeen.bart.model.Constants;
import com.dougkeen.bart.model.Station;
public class AddRouteActivity extends AbstractRouteSelectionActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_favorite);
SpinnerAdapter originSpinnerAdapter = new ArrayAdapter<Station>(this,
R.layout.simple_spinner_item, Station.getStationList());
((Spinner) findViewById(R.id.origin_spinner))
.setAdapter(originSpinnerAdapter);
SpinnerAdapter destinationSpinnerAdapter = new ArrayAdapter<Station>(
this, R.layout.simple_spinner_item, Station.getStationList());
((Spinner) findViewById(R.id.destination_spinner))
.setAdapter(destinationSpinnerAdapter);
Button saveButton = (Button) findViewById(R.id.saveButton);
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onSaveButtonClick();
}
});
Button cancelButton = (Button) findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
setResult(RESULT_CANCELED);
finish();
}
});
findViewById(R.id.return_checkbox).setVisibility(View.VISIBLE);
}
protected void onSaveButtonClick() {
Station origin = (Station) ((Spinner) findViewById(R.id.origin_spinner))
.getSelectedItem();
Station destination = (Station) ((Spinner) findViewById(R.id.destination_spinner))
.getSelectedItem();
if (origin == null) {
Toast.makeText(this, com.dougkeen.bart.R.string.error_null_origin,
Toast.LENGTH_LONG);
return;
}
if (destination == null) {
Toast.makeText(this,
com.dougkeen.bart.R.string.error_null_destination,
Toast.LENGTH_LONG);
return;
}
if (origin.equals(destination)) {
Toast.makeText(
this,
com.dougkeen.bart.R.string.error_matching_origin_and_destination,
Toast.LENGTH_LONG);
return;
}
@Override
protected void onOkButtonClick(Station origin, Station destination) {
ContentValues values = new ContentValues();
values.put(RoutesColumns.FROM_STATION.string, origin.abbreviation);
values.put(RoutesColumns.TO_STATION.string, destination.abbreviation);
@ -97,5 +39,4 @@ public class AddRouteActivity extends Activity {
setResult(RESULT_OK, (new Intent()).setAction(newUri.toString()));
finish();
}
}

View File

@ -0,0 +1,17 @@
package com.dougkeen.bart;
import android.content.Intent;
import com.dougkeen.bart.model.Constants;
import com.dougkeen.bart.model.Station;
public class QuickRouteActivity extends AbstractRouteSelectionActivity {
@Override
protected void onOkButtonClick(Station origin, Station destination) {
startActivity(new Intent(Intent.ACTION_VIEW,
Constants.ARBITRARY_ROUTE_CONTENT_URI_ROOT.buildUpon()
.appendPath(origin.abbreviation)
.appendPath(destination.abbreviation).build()));
}
}

View File

@ -21,6 +21,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.SimpleCursorAdapter.ViewBinder;
@ -88,6 +89,15 @@ public class RoutesListActivity extends ActionBarListActivity {
setListAdapter(adapter);
registerForContextMenu(getListView());
((Button) findViewById(R.id.quickLookupButton))
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(Intent.ACTION_PICK,
Constants.ARBITRARY_ROUTE_CONTENT_URI_ROOT));
}
});
}
private void refreshFares() {

View File

@ -9,6 +9,8 @@ import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MatrixCursor.RowBuilder;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
@ -22,6 +24,8 @@ public class BartContentProvider extends ContentProvider {
private static final int FAVORITES = 1;
private static final int FAVORITE_ID = 2;
private static final int ARBITRARY_ROUTE = 3;
private static final int ARBITRARY_ROUTE_UNDEFINED = 4;
/**
* The default sort order for events
@ -33,6 +37,9 @@ public class BartContentProvider extends ContentProvider {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(Constants.AUTHORITY, "favorites", FAVORITES);
sUriMatcher.addURI(Constants.AUTHORITY, "favorites/#", FAVORITE_ID);
sUriMatcher.addURI(Constants.AUTHORITY, "route/*/*", ARBITRARY_ROUTE);
sUriMatcher.addURI(Constants.AUTHORITY, "route",
ARBITRARY_ROUTE_UNDEFINED);
sFavoritesProjectionMap = new HashMap<String, String>();
sFavoritesProjectionMap.put(RoutesColumns._ID.string,
@ -45,7 +52,8 @@ public class BartContentProvider extends ContentProvider {
RoutesColumns.FARE.string);
sFavoritesProjectionMap.put(RoutesColumns.FARE_LAST_UPDATED.string,
RoutesColumns.FARE_LAST_UPDATED.string);
sFavoritesProjectionMap.put(RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string,
sFavoritesProjectionMap.put(
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string,
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string);
sFavoritesProjectionMap.put(RoutesColumns.AVERAGE_TRIP_LENGTH.string,
RoutesColumns.AVERAGE_TRIP_LENGTH.string);
@ -66,6 +74,10 @@ public class BartContentProvider extends ContentProvider {
return Constants.FAVORITE_CONTENT_TYPE;
} else if (match == FAVORITE_ID) {
return Constants.FAVORITE_CONTENT_ITEM_TYPE;
} else if (match == ARBITRARY_ROUTE) {
return Constants.ARBITRARY_ROUTE_TYPE;
} else if (match == ARBITRARY_ROUTE_UNDEFINED) {
return Constants.ARBITRARY_ROUTE_UNDEFINED_TYPE;
} else {
throw new IllegalArgumentException("Unknown URI " + uri);
}
@ -82,14 +94,29 @@ public class BartContentProvider extends ContentProvider {
int match = sUriMatcher.match(uri);
if (match == FAVORITES) {
qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
qb.setProjectionMap(sFavoritesProjectionMap);
if (match == ARBITRARY_ROUTE) {
MatrixCursor returnCursor = new MatrixCursor(projection);
RowBuilder newRow = returnCursor.newRow();
for (String column : projection) {
if (column.equals(RoutesColumns.FROM_STATION.string)) {
newRow.add(uri.getPathSegments().get(1));
} else if (column.equals(RoutesColumns.TO_STATION.string)) {
newRow.add(uri.getPathSegments().get(2));
} else {
newRow.add(null);
}
}
return returnCursor;
} else if (match == FAVORITE_ID) {
qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
qb.setProjectionMap(sFavoritesProjectionMap);
qb.appendWhere(RoutesColumns._ID + " = "
+ uri.getPathSegments().get(1));
} else if (match == FAVORITES) {
qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
qb.setProjectionMap(sFavoritesProjectionMap);
} else {
throw new IllegalArgumentException("Unknown URI " + uri);
}

View File

@ -5,9 +5,13 @@ import android.net.Uri;
public class Constants {
public static final String AUTHORITY = "com.dougkeen.bart.dataprovider";
public static final String FAVORITE_CONTENT_TYPE = "vnd.android.cursor.dir/com.dougkeen.bart.favorite";
public static final String ARBITRARY_ROUTE_UNDEFINED_TYPE = "vnd.android.cursor.dir/com.dougkeen.bart.arbitraryroute";
public static final String ARBITRARY_ROUTE_TYPE = "vnd.android.cursor.item/com.dougkeen.bart.arbitraryroute";
public static final String FAVORITE_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/com.dougkeen.bart.favorite";
public static final Uri FAVORITE_CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/favorites");
public static final Uri ARBITRARY_ROUTE_CONTENT_URI_ROOT = Uri
.parse("content://" + AUTHORITY + "/route");
public static final String MAP_URL = "http://m.bart.gov/images/global/system-map29.gif";
public static final String TAG = "BartRunner";