Bug fixes

This commit is contained in:
dkeen 2011-05-31 20:42:32 -07:00
parent b7a40aced2
commit 67e6f5347d
11 changed files with 94 additions and 52 deletions

View File

@ -1,6 +1,6 @@
<?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="3" package="com.dougkeen.bart" android:versionCode="4"
android:versionName="1.0"> android:versionName="1.0">
<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" />

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">Bart Catcher</string> <string name="app_name">BART Catcher</string>
<string name="favorite_routes">Favorite Routes</string> <string name="favorite_routes">Favorite Routes</string>
<string name="empty_favorites_list_message">Press the menu button and select \"Add route\" to add <string name="empty_favorites_list_message">Press the menu button and select \"Add route\" to add
a route</string> a route</string>
@ -22,4 +22,5 @@
<string name="yes">Yes</string> <string name="yes">Yes</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="view_on_bart_site">View details on BART site</string> <string name="view_on_bart_site">View details on BART site</string>
<string name="could_not_connect">Could not connect to BART services. Please try again later.</string>
</resources> </resources>

View File

@ -8,4 +8,6 @@ public class Constants {
public static final String FAVORITE_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/com.dougkeen.bart.favorite"; 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://" public static final Uri FAVORITE_CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/favorites"); + AUTHORITY + "/favorites");
public static final String TAG = "BartCatcher";
} }

View File

@ -8,6 +8,8 @@ import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
import com.dougkeen.bart.data.Arrival; import com.dougkeen.bart.data.Arrival;
import com.dougkeen.bart.data.RealTimeArrivals; import com.dougkeen.bart.data.RealTimeArrivals;
@ -20,7 +22,7 @@ public class EtdContentHandler extends DefaultHandler {
private final static List<String> TAGS = Arrays.asList("date", "time", private final static List<String> TAGS = Arrays.asList("date", "time",
"abbreviation", "minutes", "platform", "direction", "length", "abbreviation", "minutes", "platform", "direction", "length",
"hexcolor", "bikeflag"); "color", "hexcolor", "bikeflag");
private RealTimeArrivals realTimeArrivals; private RealTimeArrivals realTimeArrivals;
@ -76,6 +78,13 @@ public class EtdContentHandler extends DefaultHandler {
currentArrival.setDirection(currentValue); currentArrival.setDirection(currentValue);
} else if (localName.equals("length")) { } else if (localName.equals("length")) {
currentArrival.setTrainLength(Integer.parseInt(currentValue)); currentArrival.setTrainLength(Integer.parseInt(currentValue));
} else if (localName.equals("color")) {
try {
currentArrival.setLine(Line.valueOf(currentValue));
} catch (IllegalArgumentException e) {
Log.w("BartApp", "There is no line called '" + currentValue
+ "'");
}
} else if (localName.equals("hexcolor")) { } else if (localName.equals("hexcolor")) {
currentArrival.setDestinationColor("#ff" currentArrival.setDestinationColor("#ff"
+ currentValue.substring(1)); + currentValue.substring(1));

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.util.List; import java.util.List;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@ -16,6 +17,7 @@ import android.util.Xml;
public abstract class GetRealTimeArrivalsTask extends public abstract class GetRealTimeArrivalsTask extends
AsyncTask<GetRealTimeArrivalsTask.Params, Integer, RealTimeArrivals> { AsyncTask<GetRealTimeArrivalsTask.Params, Integer, RealTimeArrivals> {
private static final int CONNECTION_TIMEOUT_MILLIS = 10000;
private final static String API_KEY = "5LD9-IAYI-TRAT-MHHW"; private final static String API_KEY = "5LD9-IAYI-TRAT-MHHW";
private final static String API_URL = "http://api.bart.gov/api/etd.aspx?cmd=etd&key=" private final static String API_URL = "http://api.bart.gov/api/etd.aspx?cmd=etd&key="
+ API_KEY + "&orig=%1$s&dir=%2$s"; + API_KEY + "&orig=%1$s&dir=%2$s";
@ -32,30 +34,28 @@ public abstract class GetRealTimeArrivalsTask extends
mRoutes = params.origin.getRoutesForDestination(params.destination); mRoutes = params.origin.getRoutesForDestination(params.destination);
URL sourceUrl;
try {
sourceUrl = new URL(String.format(API_URL,
params.origin.abbreviation, mRoutes.get(0).getDirection()));
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
if (!isCancelled()) { if (!isCancelled()) {
return getArrivalsFromNetwork(params, sourceUrl, 0); return getArrivalsFromNetwork(params, 0);
} else { } else {
return null; return null;
} }
} }
private RealTimeArrivals getArrivalsFromNetwork(Params params, private RealTimeArrivals getArrivalsFromNetwork(Params params,
URL sourceUrl, int attemptNumber) { int attemptNumber) {
try { try {
URL sourceUrl = new URL(String.format(API_URL,
params.origin.abbreviation, mRoutes.get(0).getDirection()));
EtdContentHandler handler = new EtdContentHandler(params.origin, EtdContentHandler handler = new EtdContentHandler(params.origin,
params.destination, mRoutes); params.destination, mRoutes);
if (isCancelled()) { if (isCancelled()) {
return null; return null;
} }
Xml.parse(sourceUrl.openStream(), Xml.findEncodingByName("UTF-8"), URLConnection connection = sourceUrl.openConnection();
connection.setConnectTimeout(CONNECTION_TIMEOUT_MILLIS);
Xml.parse(connection.getInputStream(),
Xml.findEncodingByName("UTF-8"),
handler); handler);
final RealTimeArrivals realTimeArrivals = handler final RealTimeArrivals realTimeArrivals = handler
.getRealTimeArrivals(); .getRealTimeArrivals();
@ -71,8 +71,7 @@ public abstract class GetRealTimeArrivalsTask extends
} catch (InterruptedException interrupt) { } catch (InterruptedException interrupt) {
// Ignore... just go on to next attempt // Ignore... just go on to next attempt
} }
return getArrivalsFromNetwork(params, sourceUrl, return getArrivalsFromNetwork(params, attemptNumber + 1);
attemptNumber++);
} else { } else {
mIOException = e; mIOException = e;
return null; return null;

View File

@ -25,7 +25,7 @@ public enum Line {
Station.POWL, Station.MONT, Station.EMBR, Station.WOAK, Station.POWL, Station.MONT, Station.EMBR, Station.WOAK,
Station._12TH, Station._19TH, Station.MCAR, Station.ROCK, Station._12TH, Station._19TH, Station.MCAR, Station.ROCK,
Station.ORIN, Station.LAFY, Station.WCRK, Station.PHIL, Station.ORIN, Station.LAFY, Station.WCRK, Station.PHIL,
Station.CONC, Station.NCON), Station.CONC, Station.NCON, Station.PITT),
BLUE(true, Station.DALY, Station.BALB, Station.GLEN, Station._24TH, BLUE(true, Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
Station._16TH, Station.CIVC, Station.POWL, Station.MONT, Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
Station.EMBR, Station.WOAK, Station.LAKE, Station.FTVL, Station.EMBR, Station.WOAK, Station.LAKE, Station.FTVL,
@ -36,13 +36,12 @@ public enum Line {
Station.EMBR, Station.WOAK, Station.LAKE, Station.FTVL, Station.EMBR, Station.WOAK, Station.LAKE, Station.FTVL,
Station.COLS, Station.SANL, Station.BAYF, Station.HAYW, Station.COLS, Station.SANL, Station.BAYF, Station.HAYW,
Station.SHAY, Station.UCTY, Station.FRMT), Station.SHAY, Station.UCTY, Station.FRMT),
YELLOW_ORANGE_TRANSFER(YELLOW, ORANGE, Station.MLBR, Station.SFIA, YELLOW_ORANGE_SCHEDULED_TRANSFER(YELLOW, ORANGE, Station.MLBR,
Station.SBRN, Station.SSAN, Station.COLM, Station.DALY, Station.SFIA, Station.SBRN, Station.SSAN, Station.COLM,
Station.BALB, Station.GLEN, Station._24TH, Station._16TH, Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
Station.CIVC, Station.POWL, Station.MONT, Station.EMBR, Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
Station.WOAK, Station._12TH, Station._19TH, Station.EMBR, Station.WOAK, Station.ASHB, Station.DBRK,
Station.MCAR, Station.ASHB, Station.DBRK, Station.NBRK, Station.NBRK, Station.PLZA, Station.DELN, Station.RICH);
Station.PLZA, Station.DELN, Station.RICH);
public final List<Station> stations; public final List<Station> stations;
@ -93,16 +92,4 @@ public enum Line {
return destinations; return destinations;
} }
public boolean trainDestinationIsApplicable(Station station) {
if (transferLine1 != null && transferLine1.stations.contains(station)) {
return true;
} else if (transferLine2 != null
&& transferLine2.stations.contains(station)) {
return true;
} else {
return stations.contains(station);
}
}
} }

View File

@ -74,4 +74,25 @@ public class Route {
builder.append("]"); builder.append("]");
return builder.toString(); return builder.toString();
} }
public boolean trainDestinationIsApplicable(Station lineDestination,
Line viaLine) {
Line routeLine = getLine();
if (routeLine.transferLine1 != null
&& viaLine.equals(routeLine.transferLine1)) {
return true;
} else if (routeLine.transferLine2 != null
&& viaLine.equals(routeLine.transferLine2)) {
return true;
} else {
int originIndex = viaLine.stations.indexOf(origin);
int routeDestinationIndex = viaLine.stations.indexOf(destination);
int lineDestinationIndex = viaLine.stations
.indexOf(lineDestination);
return routeDestinationIndex >= 0
&& ((originIndex <= routeDestinationIndex && routeDestinationIndex <= lineDestinationIndex)
|| (originIndex >= routeDestinationIndex && routeDestinationIndex >= lineDestinationIndex));
}
}
} }

View File

@ -154,10 +154,14 @@ public enum Station {
.addAll(getOutboundTransferStation() .addAll(getOutboundTransferStation()
.getRoutesForDestination(dest, .getRoutesForDestination(dest,
getOutboundTransferStation())); getOutboundTransferStation()));
} else { } else if (dest.getInboundTransferStation() != null) {
returnList.addAll(getRoutesForDestination(dest final List<Route> routesForDestination = getRoutesForDestination(
.getInboundTransferStation(), dest dest.getInboundTransferStation(),
.getInboundTransferStation())); dest.getInboundTransferStation());
if (routesForDestination != null
&& !routesForDestination.isEmpty()) {
returnList.addAll(routesForDestination);
}
} }
} }
return returnList; return returnList;

View File

@ -14,7 +14,6 @@ import android.os.Parcelable;
import android.os.PowerManager; import android.os.PowerManager;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.util.Log; import android.util.Log;
import android.util.TimeFormatException;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
@ -24,13 +23,11 @@ import android.widget.Toast;
import com.dougkeen.bart.GetRealTimeArrivalsTask.Params; import com.dougkeen.bart.GetRealTimeArrivalsTask.Params;
import com.dougkeen.bart.data.Arrival; import com.dougkeen.bart.data.Arrival;
import com.dougkeen.bart.data.RoutesColumns;
import com.dougkeen.bart.data.RealTimeArrivals; import com.dougkeen.bart.data.RealTimeArrivals;
import com.dougkeen.bart.data.RoutesColumns;
public class ViewArrivalsActivity extends ListActivity { public class ViewArrivalsActivity extends ListActivity {
private static final String TAG = "BartCatcher";
private static final int UNCERTAINTY_THRESHOLD = 17; private static final int UNCERTAINTY_THRESHOLD = 17;
private Uri mUri; private Uri mUri;
@ -143,22 +140,33 @@ public class ViewArrivalsActivity extends ListActivity {
private void fetchLatestArrivals() { private void fetchLatestArrivals() {
if (!hasWindowFocus()) if (!hasWindowFocus())
return; return;
if (mGetArrivalsTask != null
&& mGetArrivalsTask.getStatus()
.equals(AsyncTask.Status.RUNNING)) {
// Don't overlap fetches
return;
}
mGetArrivalsTask = new GetRealTimeArrivalsTask() { mGetArrivalsTask = new GetRealTimeArrivalsTask() {
@Override @Override
public void onResult(RealTimeArrivals result) { public void onResult(RealTimeArrivals result) {
Log.i(TAG, "Processing data from server"); Log.i(Constants.TAG, "Processing data from server");
processLatestArrivals(result); processLatestArrivals(result);
Log.i(TAG, "Done processing data from server"); Log.i(Constants.TAG, "Done processing data from server");
} }
@Override @Override
public void onNetworkError(IOException e) { public void onNetworkError(IOException e) {
Toast.makeText(ViewArrivalsActivity.this, e.getMessage(), Log.w(Constants.TAG, e.getMessage());
Toast.LENGTH_SHORT).show(); Toast.makeText(ViewArrivalsActivity.this,
R.string.could_not_connect,
Toast.LENGTH_LONG).show();
((TextView) findViewById(android.R.id.empty))
.setText(R.string.could_not_connect);
} }
}; };
Log.i(TAG, "Fetching data from server"); Log.i(Constants.TAG, "Fetching data from server");
mGetArrivalsTask.execute(new GetRealTimeArrivalsTask.Params(mOrigin, mGetArrivalsTask.execute(new GetRealTimeArrivalsTask.Params(mOrigin,
mDestination)); mDestination));
} }
@ -225,7 +233,7 @@ public class ViewArrivalsActivity extends ListActivity {
fetchLatestArrivals(); fetchLatestArrivals();
} }
}, 20000); }, 20000);
Log.i(TAG, "Scheduled another data fetch in 20s"); Log.i(Constants.TAG, "Scheduled another data fetch in 20s");
} else { } else {
// Get more when next train arrives // Get more when next train arrives
final int interval = firstArrival.getMinSecondsLeft() * 1000; final int interval = firstArrival.getMinSecondsLeft() * 1000;
@ -235,7 +243,8 @@ public class ViewArrivalsActivity extends ListActivity {
fetchLatestArrivals(); fetchLatestArrivals();
} }
}, interval); }, interval);
Log.i(TAG, "Scheduled another data fetch in " + interval / 1000 Log.i(Constants.TAG, "Scheduled another data fetch in "
+ interval / 1000
+ "s"); + "s");
} }
if (!mIsAutoUpdating) { if (!mIsAutoUpdating) {

View File

@ -3,6 +3,7 @@ package com.dougkeen.bart.data;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import com.dougkeen.bart.Line;
import com.dougkeen.bart.Station; import com.dougkeen.bart.Station;
public class Arrival implements Parcelable, Comparable<Arrival> { public class Arrival implements Parcelable, Comparable<Arrival> {
@ -28,6 +29,7 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
} }
private Station destination; private Station destination;
private Line line;
private String destinationColor; private String destinationColor;
private String platform; private String platform;
private String direction; private String direction;
@ -60,6 +62,14 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
return null; return null;
} }
public Line getLine() {
return line;
}
public void setLine(Line line) {
this.line = line;
}
public String getDestinationColor() { public String getDestinationColor() {
return destinationColor; return destinationColor;
} }

View File

@ -62,7 +62,7 @@ public class RealTimeArrivals {
Station destination = Station.getByAbbreviation(arrival Station destination = Station.getByAbbreviation(arrival
.getDestinationAbbreviation()); .getDestinationAbbreviation());
for (Route route : routes) { for (Route route : routes) {
if (route.getLine().trainDestinationIsApplicable(destination)) { if (route.trainDestinationIsApplicable(destination, arrival.getLine())) {
arrival.setRequiresTransfer(route.hasTransfer()); arrival.setRequiresTransfer(route.hasTransfer());
getArrivals().add(arrival); getArrivals().add(arrival);
arrival.calculateEstimates(time); arrival.calculateEstimates(time);