Now includes offline system map

This commit is contained in:
dkeen@dkeen-laptop 2011-11-05 11:51:20 -07:00
parent fd4a7b2cef
commit d732f0854a
10 changed files with 108 additions and 94 deletions

View File

@ -4,5 +4,6 @@
<classpathentry kind="src" path="gen"/> <classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/> <classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath> </classpath>

View File

@ -1,50 +1,74 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dougkeen.bart" android:versionCode="6" package="com.dougkeen.bart"
android:versionName="1.0.1"> android:versionCode="7"
android:versionName="1.0.2" >
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-sdk android:minSdkVersion="7" /> <uses-sdk android:minSdkVersion="7" />
<application android:icon="@drawable/icon" android:label="@string/app_name" <application
android:debuggable="true"> android:debuggable="true"
<activity android:name="RoutesListActivity" android:icon="@drawable/icon"
android:label="@string/app_name"> android:label="@string/app_name" >
<intent-filter> <activity
android:label="@string/app_name"
android:name="RoutesListActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter >
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" /> <action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/com.dougkeen.bart.favorite" /> <data android:mimeType="vnd.android.cursor.dir/com.dougkeen.bart.favorite" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter >
<action android:name="android.intent.action.GET_CONTENT" /> <action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" /> <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.favorite" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="AddRouteActivity" android:label="@string/app_name"> <activity
<intent-filter> android:label="@string/app_name"
android:name="AddRouteActivity" >
<intent-filter >
<action android:name="android.intent.action.INSERT" /> <action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/com.dougkeen.bart.favorite" /> <data android:mimeType="vnd.android.cursor.dir/com.dougkeen.bart.favorite" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="ViewDeparturesActivity" <activity
android:label="@string/app_name"> android:label="@string/app_name"
<intent-filter> android:name="ViewDeparturesActivity" >
<intent-filter >
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <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.favorite" />
</intent-filter> </intent-filter>
</activity> </activity>
<provider android:name=".data.BartContentProvider" <activity
android:authorities="com.dougkeen.bart.dataprovider" android:label="Don\'t Miss The Bart data provider" /> android:label="@string/app_name"
android:name="ViewMapActivity" >
</activity>
<provider
android:authorities="com.dougkeen.bart.dataprovider"
android:label="Don\&apos;t Miss The Bart data provider"
android:name=".data.BartContentProvider" />
</application> </application>
</manifest> </manifest>

View File

@ -1,11 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-7

BIN
res/drawable/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 KiB

View File

@ -13,7 +13,7 @@
<string name="error_null_destination">You must select a destination station</string> <string name="error_null_destination">You must select a destination station</string>
<string name="error_null_origin">You must select an origin station</string> <string name="error_null_origin">You must select an origin station</string>
<string name="departure_wait_message">Please wait while real time departure data is <string name="departure_wait_message">Please wait while real time departure data is
loaded...</string> loaded</string>
<string name="no_data_message">No departure data is currently available for this <string name="no_data_message">No departure data is currently available for this
route. Note that this route may require a non-standard transfer due to route. Note that this route may require a non-standard transfer due to
a temporary change in service. Check for service advisories posted at a temporary change in service. Check for service advisories posted at

View File

@ -36,7 +36,6 @@ public class AddRouteActivity extends Activity {
Button saveButton = (Button) findViewById(R.id.saveButton); Button saveButton = (Button) findViewById(R.id.saveButton);
saveButton.setOnClickListener(new View.OnClickListener() { saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { public void onClick(View v) {
onSaveButtonClick(); onSaveButtonClick();
} }
@ -45,7 +44,6 @@ public class AddRouteActivity extends Activity {
Button cancelButton = (Button) findViewById(R.id.cancelButton); Button cancelButton = (Button) findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(new View.OnClickListener() { cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { public void onClick(View v) {
setResult(RESULT_CANCELED); setResult(RESULT_CANCELED);
finish(); finish();

View File

@ -42,20 +42,16 @@ public class RoutesListActivity extends ListActivity {
setContentView(R.layout.main); setContentView(R.layout.main);
mQuery = managedQuery(Constants.FAVORITE_CONTENT_URI, new String[] { mQuery = managedQuery(Constants.FAVORITE_CONTENT_URI, new String[] {
RoutesColumns._ID.string, RoutesColumns._ID.string, RoutesColumns.FROM_STATION.string,
RoutesColumns.FROM_STATION.string,
RoutesColumns.TO_STATION.string }, null, null, RoutesColumns.TO_STATION.string }, null, null,
RoutesColumns._ID.string); RoutesColumns._ID.string);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.favorite_listing, R.layout.favorite_listing, mQuery, new String[] {
mQuery, RoutesColumns.FROM_STATION.string,
new String[] { RoutesColumns.FROM_STATION.string, RoutesColumns.TO_STATION.string }, new int[] {
RoutesColumns.TO_STATION.string }, R.id.originText, R.id.destinationText });
new int[] { R.id.originText,
R.id.destinationText });
adapter.setViewBinder(new ViewBinder() { adapter.setViewBinder(new ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, public boolean setViewValue(View view, Cursor cursor,
int columnIndex) { int columnIndex) {
((TextView) view).setText(Station.getByAbbreviation(cursor ((TextView) view).setText(Station.getByAbbreviation(cursor
@ -93,9 +89,7 @@ public class RoutesListActivity extends ListActivity {
Constants.FAVORITE_CONTENT_URI)); Constants.FAVORITE_CONTENT_URI));
return true; return true;
} else if (itemId == R.id.view_system_map_button) { } else if (itemId == R.id.view_system_map_button) {
startActivity(new Intent( startActivity(new Intent(this, ViewMapActivity.class));
Intent.ACTION_VIEW,
Uri.parse(Constants.MAP_URL)));
return true; return true;
} else { } else {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@ -132,8 +126,7 @@ public class RoutesListActivity extends ListActivity {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo(); .getMenuInfo();
mCurrentlySelectedUri = ContentUris.withAppendedId( mCurrentlySelectedUri = ContentUris.withAppendedId(
Constants.FAVORITE_CONTENT_URI, Constants.FAVORITE_CONTENT_URI, info.id);
info.id);
if (item.getItemId() == R.id.view) { if (item.getItemId() == R.id.view) {
startActivity(new Intent(Intent.ACTION_VIEW, mCurrentlySelectedUri)); startActivity(new Intent(Intent.ACTION_VIEW, mCurrentlySelectedUri));
@ -154,7 +147,6 @@ public class RoutesListActivity extends ListActivity {
builder.setMessage("Are you sure you want to delete this route?"); builder.setMessage("Are you sure you want to delete this route?");
builder.setPositiveButton(R.string.yes, builder.setPositiveButton(R.string.yes,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
getContentResolver().delete(mCurrentlySelectedUri, getContentResolver().delete(mCurrentlySelectedUri,
null, null); null, null);
@ -165,7 +157,6 @@ public class RoutesListActivity extends ListActivity {
}); });
builder.setNegativeButton(R.string.cancel, builder.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mCurrentlySelectedUri = null; mCurrentlySelectedUri = null;
mCurrentlySelectedRouteName = null; mCurrentlySelectedRouteName = null;

View File

@ -44,7 +44,6 @@ public class ViewDeparturesActivity extends ListActivity {
private boolean mIsAutoUpdating = false; private boolean mIsAutoUpdating = false;
private final Runnable AUTO_UPDATE_RUNNABLE = new Runnable() { private final Runnable AUTO_UPDATE_RUNNABLE = new Runnable() {
@Override
public void run() { public void run() {
runAutoUpdate(); runAutoUpdate();
} }
@ -135,8 +134,7 @@ public class ViewDeparturesActivity extends ListActivity {
} }
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager mWakeLock = powerManager
.newWakeLock( .newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,
PowerManager.SCREEN_DIM_WAKE_LOCK,
"ViewDeparturesActivity"); "ViewDeparturesActivity");
mWakeLock.acquire(); mWakeLock.acquire();
if (mDeparturesAdapter != null && !mDeparturesAdapter.isEmpty()) { if (mDeparturesAdapter != null && !mDeparturesAdapter.isEmpty()) {
@ -152,8 +150,8 @@ public class ViewDeparturesActivity extends ListActivity {
if (!hasWindowFocus()) if (!hasWindowFocus())
return; return;
if (mGetDeparturesTask != null if (mGetDeparturesTask != null
&& mGetDeparturesTask.getStatus() && mGetDeparturesTask.getStatus().equals(
.equals(AsyncTask.Status.RUNNING)) { AsyncTask.Status.RUNNING)) {
// Don't overlap fetches // Don't overlap fetches
return; return;
} }
@ -172,8 +170,7 @@ public class ViewDeparturesActivity extends ListActivity {
mDataFetchIsPending = false; mDataFetchIsPending = false;
Log.w(Constants.TAG, e.getMessage(), e); Log.w(Constants.TAG, e.getMessage(), e);
Toast.makeText(ViewDeparturesActivity.this, Toast.makeText(ViewDeparturesActivity.this,
R.string.could_not_connect, R.string.could_not_connect, Toast.LENGTH_LONG).show();
Toast.LENGTH_LONG).show();
((TextView) findViewById(android.R.id.empty)) ((TextView) findViewById(android.R.id.empty))
.setText(R.string.could_not_connect); .setText(R.string.could_not_connect);
// Try again in 60s // Try again in 60s
@ -182,8 +179,7 @@ public class ViewDeparturesActivity extends ListActivity {
}; };
Log.i(Constants.TAG, "Fetching data from server"); Log.i(Constants.TAG, "Fetching data from server");
mGetDeparturesTask.execute(new GetRealTimeDeparturesTask.Params( mGetDeparturesTask.execute(new GetRealTimeDeparturesTask.Params(
mOrigin, mOrigin, mDestination));
mDestination));
} }
protected void processLatestDepartures(RealTimeDepartures result) { protected void processLatestDepartures(RealTimeDepartures result) {
@ -241,8 +237,7 @@ public class ViewDeparturesActivity extends ListActivity {
mDeparturesAdapter.notifyDataSetChanged(); mDeparturesAdapter.notifyDataSetChanged();
if (hasWindowFocus() && firstDeparture != null) { if (hasWindowFocus() && firstDeparture != null) {
if (needsBetterAccuracy if (needsBetterAccuracy || firstDeparture.hasDeparted()) {
|| firstDeparture.hasDeparted()) {
// Get more data in 20s // Get more data in 20s
scheduleDataFetch(20000); scheduleDataFetch(20000);
} else { } else {
@ -277,7 +272,6 @@ public class ViewDeparturesActivity extends ListActivity {
private void scheduleDataFetch(int millisUntilExecute) { private void scheduleDataFetch(int millisUntilExecute) {
if (!mDataFetchIsPending) { if (!mDataFetchIsPending) {
mListTitleView.postDelayed(new Runnable() { mListTitleView.postDelayed(new Runnable() {
@Override
public void run() { public void run() {
fetchLatestDepartures(); fetchLatestDepartures();
} }
@ -314,15 +308,14 @@ public class ViewDeparturesActivity extends ListActivity {
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse("http://m.bart.gov/schedules/qp_results.aspx?type=departure&date=today&time=" Uri.parse("http://m.bart.gov/schedules/qp_results.aspx?type=departure&date=today&time="
+ DateFormat.format("h:mmaa", + DateFormat.format("h:mmaa",
System.currentTimeMillis()) + "&orig=" System.currentTimeMillis())
+ "&orig="
+ mOrigin.abbreviation + mOrigin.abbreviation
+ "&dest=" + "&dest="
+ mDestination.abbreviation))); + mDestination.abbreviation)));
return true; return true;
} else if (itemId == R.id.view_system_map_button) { } else if (itemId == R.id.view_system_map_button) {
startActivity(new Intent( startActivity(new Intent(this, ViewMapActivity.class));
Intent.ACTION_VIEW,
Uri.parse(Constants.MAP_URL)));
return true; return true;
} else { } else {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);

View File

@ -0,0 +1,21 @@
package com.dougkeen.bart;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class ViewMapActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webview = new WebView(this);
setContentView(webview);
webview.getSettings().setBuiltInZoomControls(true);
webview.getSettings().setSupportZoom(true);
webview.loadUrl("file:///android_res/drawable/map.png");
}
}

View File

@ -195,7 +195,6 @@ public class Departure implements Parcelable, Comparable<Departure> {
} }
} }
@Override
public int compareTo(Departure another) { public int compareTo(Departure another) {
return (this.getMinutes() > another.getMinutes()) ? 1 : ( return (this.getMinutes() > another.getMinutes()) ? 1 : (
(this.getMinutes() == another.getMinutes()) ? 0 : -1); (this.getMinutes() == another.getMinutes()) ? 0 : -1);
@ -270,12 +269,10 @@ public class Departure implements Parcelable, Comparable<Departure> {
return builder.toString(); return builder.toString();
} }
@Override
public int describeContents() { public int describeContents() {
return 0; return 0;
} }
@Override
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeString(destination.abbreviation); dest.writeString(destination.abbreviation);
dest.writeString(destinationColor); dest.writeString(destinationColor);