Changed arrivals to departures.
Added handling for WHITE and SPCL --HG-- rename : res/layout/arrival_listing.xml => res/layout/departure_listing.xml rename : src/com/dougkeen/bart/ArrivalArrayAdapter.java => src/com/dougkeen/bart/DepartureArrayAdapter.java rename : src/com/dougkeen/bart/GetRealTimeArrivalsTask.java => src/com/dougkeen/bart/GetRealTimeDeparturesTask.java rename : src/com/dougkeen/bart/ViewArrivalsActivity.java => src/com/dougkeen/bart/ViewDeparturesActivity.java rename : src/com/dougkeen/bart/data/Arrival.java => src/com/dougkeen/bart/data/Departure.java rename : src/com/dougkeen/bart/data/RealTimeArrivals.java => src/com/dougkeen/bart/data/RealTimeDepartures.java
This commit is contained in:
parent
67e6f5347d
commit
ca8f07b30a
@ -35,7 +35,7 @@
|
|||||||
<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=".ViewArrivalsActivity"
|
<activity android:name="ViewDeparturesActivity"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
@ -8,20 +8,20 @@
|
|||||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||||
android:layout_toRightOf="@id/destinationColorBar"
|
android:layout_toRightOf="@id/destinationColorBar"
|
||||||
android:layout_alignParentTop="true">
|
android:layout_alignParentTop="true">
|
||||||
<TextView android:id="@+id/destinationText" style="@style/ArrivalDestinationText"
|
<TextView android:id="@+id/destinationText" style="@style/DepartureDestinationText"
|
||||||
android:layout_weight="1" android:singleLine="true"
|
android:layout_weight="1" android:singleLine="true"
|
||||||
android:ellipsize="marquee" />
|
android:ellipsize="marquee" />
|
||||||
<ImageView android:id="@+id/bikeIcon" android:src="@drawable/bike"
|
<ImageView android:id="@+id/bikeIcon" android:src="@drawable/bike"
|
||||||
style="@style/BikeIcon" />
|
style="@style/BikeIcon" />
|
||||||
<TextView android:id="@+id/countdown" style="@style/ArrivalCountdownText"
|
<TextView android:id="@+id/countdown" style="@style/DepartureCountdownText"
|
||||||
android:gravity="right" />
|
android:gravity="right" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<ImageView android:id="@+id/xferIcon" android:src="@drawable/xfer"
|
<ImageView android:id="@+id/xferIcon" android:src="@drawable/xfer"
|
||||||
android:layout_below="@id/topRow" android:layout_alignParentRight="true"
|
android:layout_below="@id/topRow" android:layout_alignParentRight="true"
|
||||||
style="@style/XferIcon" />
|
style="@style/XferIcon" />
|
||||||
<TextView android:id="@+id/trainLengthText" style="@style/ArrivalTrainLengthText"
|
<TextView android:id="@+id/trainLengthText" style="@style/DepartureTrainLengthText"
|
||||||
android:layout_toRightOf="@id/destinationColorBar"
|
android:layout_toRightOf="@id/destinationColorBar"
|
||||||
android:layout_below="@id/topRow" />
|
android:layout_below="@id/topRow" />
|
||||||
<TextView android:layout_alignParentRight="true" android:id="@+id/uncertainty"
|
<TextView android:layout_alignParentRight="true" android:id="@+id/uncertainty"
|
||||||
android:layout_below="@id/topRow" style="@style/ArrivalUncertaintyText" />
|
android:layout_below="@id/topRow" style="@style/DepartureUncertaintyText" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:title="@string/view_arrivals" android:id="@+id/view"></item>
|
<item android:title="@string/view_departures" android:id="@+id/view"></item>
|
||||||
<item android:title="@string/delete" android:id="@+id/delete"></item>
|
<item android:title="@string/delete" android:id="@+id/delete"></item>
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -2,7 +2,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>
|
||||||
<string name="add_route">Add a route</string>
|
<string name="add_route">Add a route</string>
|
||||||
<string name="origin">Origin</string>
|
<string name="origin">Origin</string>
|
||||||
@ -12,15 +13,17 @@
|
|||||||
different</string>
|
different</string>
|
||||||
<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="arrival_wait_message">Please wait while real time arrival 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 arrival data is currently available for this
|
<string name="no_data_message">No departure data is currently available for this
|
||||||
route</string>
|
route. Note that there may be service advisories posted at
|
||||||
|
http://m.bart.gov/schedules/advisories/</string>
|
||||||
<string name="view">View</string>
|
<string name="view">View</string>
|
||||||
<string name="view_arrivals">View arrivals</string>
|
<string name="view_departures">View departures</string>
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
<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>
|
<string name="could_not_connect">Could not connect to BART services. Please try
|
||||||
|
again later.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<item name="android:singleLine">true</item>
|
<item name="android:singleLine">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ArrivalDestinationText">
|
<style name="DepartureDestinationText">
|
||||||
<item name="android:layout_width">wrap_content</item>
|
<item name="android:layout_width">wrap_content</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
<item name="android:textSize">22dp</item>
|
<item name="android:textSize">22dp</item>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<item name="android:layout_marginLeft">3dp</item>
|
<item name="android:layout_marginLeft">3dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ArrivalTrainLengthText">
|
<style name="DepartureTrainLengthText">
|
||||||
<item name="android:layout_width">wrap_content</item>
|
<item name="android:layout_width">wrap_content</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
<item name="android:textSize">18dp</item>
|
<item name="android:textSize">18dp</item>
|
||||||
@ -35,14 +35,14 @@
|
|||||||
<item name="android:layout_marginLeft">3dp</item>
|
<item name="android:layout_marginLeft">3dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ArrivalCountdownText">
|
<style name="DepartureCountdownText">
|
||||||
<item name="android:layout_width">wrap_content</item>
|
<item name="android:layout_width">wrap_content</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
<item name="android:textSize">20dp</item>
|
<item name="android:textSize">20dp</item>
|
||||||
<item name="android:singleLine">true</item>
|
<item name="android:singleLine">true</item>
|
||||||
<item name="android:width">90dp</item>
|
<item name="android:width">90dp</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="ArrivalUncertaintyText">
|
<style name="DepartureUncertaintyText">
|
||||||
<item name="android:layout_width">wrap_content</item>
|
<item name="android:layout_width">wrap_content</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
<item name="android:textSize">16dp</item>
|
<item name="android:textSize">16dp</item>
|
||||||
|
@ -13,36 +13,36 @@ import android.widget.ImageView;
|
|||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.dougkeen.bart.data.Arrival;
|
import com.dougkeen.bart.data.Departure;
|
||||||
|
|
||||||
public class ArrivalArrayAdapter extends ArrayAdapter<Arrival> {
|
public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
||||||
|
|
||||||
public ArrivalArrayAdapter(Context context, int textViewResourceId,
|
public DepartureArrayAdapter(Context context, int textViewResourceId,
|
||||||
Arrival[] objects) {
|
Departure[] objects) {
|
||||||
super(context, textViewResourceId, objects);
|
super(context, textViewResourceId, objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrivalArrayAdapter(Context context, int resource,
|
public DepartureArrayAdapter(Context context, int resource,
|
||||||
int textViewResourceId, Arrival[] objects) {
|
int textViewResourceId, Departure[] objects) {
|
||||||
super(context, resource, textViewResourceId, objects);
|
super(context, resource, textViewResourceId, objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrivalArrayAdapter(Context context, int resource,
|
public DepartureArrayAdapter(Context context, int resource,
|
||||||
int textViewResourceId, List<Arrival> objects) {
|
int textViewResourceId, List<Departure> objects) {
|
||||||
super(context, resource, textViewResourceId, objects);
|
super(context, resource, textViewResourceId, objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrivalArrayAdapter(Context context, int resource,
|
public DepartureArrayAdapter(Context context, int resource,
|
||||||
int textViewResourceId) {
|
int textViewResourceId) {
|
||||||
super(context, resource, textViewResourceId);
|
super(context, resource, textViewResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrivalArrayAdapter(Context context, int textViewResourceId,
|
public DepartureArrayAdapter(Context context, int textViewResourceId,
|
||||||
List<Arrival> objects) {
|
List<Departure> objects) {
|
||||||
super(context, textViewResourceId, objects);
|
super(context, textViewResourceId, objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrivalArrayAdapter(Context context, int textViewResourceId) {
|
public DepartureArrayAdapter(Context context, int textViewResourceId) {
|
||||||
super(context, textViewResourceId);
|
super(context, textViewResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,30 +53,30 @@ public class ArrivalArrayAdapter extends ArrayAdapter<Arrival> {
|
|||||||
view = convertView;
|
view = convertView;
|
||||||
} else {
|
} else {
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||||
view = inflater.inflate(R.layout.arrival_listing, parent, false);
|
view = inflater.inflate(R.layout.departure_listing, parent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Arrival arrival = getItem(position);
|
Departure departure = getItem(position);
|
||||||
((TextView) view.findViewById(R.id.destinationText)).setText(arrival
|
((TextView) view.findViewById(R.id.destinationText)).setText(departure
|
||||||
.getDestination().toString());
|
.getDestination().toString());
|
||||||
((TextView) view.findViewById(R.id.trainLengthText)).setText(arrival
|
((TextView) view.findViewById(R.id.trainLengthText)).setText(departure
|
||||||
.getTrainLengthText());
|
.getTrainLengthText());
|
||||||
ImageView colorBar = (ImageView) view
|
ImageView colorBar = (ImageView) view
|
||||||
.findViewById(R.id.destinationColorBar);
|
.findViewById(R.id.destinationColorBar);
|
||||||
((GradientDrawable) colorBar.getDrawable()).setColor(Color
|
((GradientDrawable) colorBar.getDrawable()).setColor(Color
|
||||||
.parseColor(arrival.getDestinationColor()));
|
.parseColor(departure.getDestinationColor()));
|
||||||
((TextView) view.findViewById(R.id.countdown)).setText(arrival
|
((TextView) view.findViewById(R.id.countdown)).setText(departure
|
||||||
.getCountdownText());
|
.getCountdownText());
|
||||||
((TextView) view.findViewById(R.id.uncertainty)).setText(arrival
|
((TextView) view.findViewById(R.id.uncertainty)).setText(departure
|
||||||
.getUncertaintyText());
|
.getUncertaintyText());
|
||||||
if (arrival.isBikeAllowed()) {
|
if (departure.isBikeAllowed()) {
|
||||||
((ImageView) view.findViewById(R.id.bikeIcon))
|
((ImageView) view.findViewById(R.id.bikeIcon))
|
||||||
.setVisibility(View.VISIBLE);
|
.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
((ImageView) view.findViewById(R.id.bikeIcon))
|
((ImageView) view.findViewById(R.id.bikeIcon))
|
||||||
.setVisibility(View.INVISIBLE);
|
.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
if (arrival.getRequiresTransfer()) {
|
if (departure.getRequiresTransfer()) {
|
||||||
((ImageView) view.findViewById(R.id.xferIcon))
|
((ImageView) view.findViewById(R.id.xferIcon))
|
||||||
.setVisibility(View.VISIBLE);
|
.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
@ -10,32 +10,34 @@ import org.xml.sax.helpers.DefaultHandler;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.dougkeen.bart.data.Arrival;
|
import com.dougkeen.bart.data.Departure;
|
||||||
import com.dougkeen.bart.data.RealTimeArrivals;
|
import com.dougkeen.bart.data.RealTimeDepartures;
|
||||||
|
|
||||||
public class EtdContentHandler extends DefaultHandler {
|
public class EtdContentHandler extends DefaultHandler {
|
||||||
public EtdContentHandler(Station origin, Station destination,
|
public EtdContentHandler(Station origin, Station destination,
|
||||||
List<Route> routes) {
|
List<Route> routes) {
|
||||||
super();
|
super();
|
||||||
realTimeArrivals = new RealTimeArrivals(origin, destination, routes);
|
realTimeDepartures = new RealTimeDepartures(origin, destination, routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
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",
|
||||||
"color", "hexcolor", "bikeflag");
|
"color", "hexcolor", "bikeflag");
|
||||||
|
|
||||||
private RealTimeArrivals realTimeArrivals;
|
private RealTimeDepartures realTimeDepartures;
|
||||||
|
|
||||||
public RealTimeArrivals getRealTimeArrivals() {
|
public RealTimeDepartures getRealTimeDepartures() {
|
||||||
return realTimeArrivals;
|
return realTimeDepartures;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String date;
|
private String date;
|
||||||
private String currentDestination;
|
private String currentDestination;
|
||||||
private String currentValue;
|
private String currentValue;
|
||||||
private Arrival currentArrival;
|
private Departure currentDeparture;
|
||||||
private boolean isParsingTag;
|
private boolean isParsingTag;
|
||||||
|
|
||||||
|
private boolean getDestinationFromLine;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void characters(char[] ch, int start, int length)
|
public void characters(char[] ch, int start, int length)
|
||||||
throws SAXException {
|
throws SAXException {
|
||||||
@ -51,11 +53,15 @@ public class EtdContentHandler extends DefaultHandler {
|
|||||||
isParsingTag = true;
|
isParsingTag = true;
|
||||||
}
|
}
|
||||||
if (localName.equals("estimate")) {
|
if (localName.equals("estimate")) {
|
||||||
currentArrival = new Arrival();
|
currentDeparture = new Departure();
|
||||||
currentArrival.setDestination(Station
|
if (currentDestination.equalsIgnoreCase("SPCL")) {
|
||||||
|
getDestinationFromLine = true;
|
||||||
|
} else {
|
||||||
|
currentDeparture.setDestination(Station
|
||||||
.getByAbbreviation(currentDestination));
|
.getByAbbreviation(currentDestination));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endElement(String uri, String localName, String qName)
|
public void endElement(String uri, String localName, String qName)
|
||||||
@ -63,40 +69,60 @@ public class EtdContentHandler extends DefaultHandler {
|
|||||||
if (localName.equals("date")) {
|
if (localName.equals("date")) {
|
||||||
date = currentValue;
|
date = currentValue;
|
||||||
} else if (localName.equals("time")) {
|
} else if (localName.equals("time")) {
|
||||||
realTimeArrivals.setTime(Date.parse(date + " " + currentValue));
|
realTimeDepartures.setTime(Date.parse(date + " " + currentValue));
|
||||||
} else if (localName.equals("abbreviation")) {
|
} else if (localName.equals("abbreviation")) {
|
||||||
currentDestination = currentValue;
|
currentDestination = currentValue;
|
||||||
} else if (localName.equals("minutes")) {
|
} else if (localName.equals("minutes")) {
|
||||||
if (currentValue.equalsIgnoreCase("arrived")) {
|
if (currentValue.equalsIgnoreCase("arrived")) {
|
||||||
currentArrival.setMinutes(0);
|
currentDeparture.setMinutes(0);
|
||||||
} else {
|
} else {
|
||||||
currentArrival.setMinutes(Integer.parseInt(currentValue));
|
currentDeparture.setMinutes(Integer.parseInt(currentValue));
|
||||||
}
|
}
|
||||||
} else if (localName.equals("platform")) {
|
} else if (localName.equals("platform")) {
|
||||||
currentArrival.setPlatform(currentValue);
|
currentDeparture.setPlatform(currentValue);
|
||||||
} else if (localName.equals("direction")) {
|
} else if (localName.equals("direction")) {
|
||||||
currentArrival.setDirection(currentValue);
|
currentDeparture.setDirection(currentValue);
|
||||||
} else if (localName.equals("length")) {
|
} else if (localName.equals("length")) {
|
||||||
currentArrival.setTrainLength(Integer.parseInt(currentValue));
|
currentDeparture.setTrainLength(Integer.parseInt(currentValue));
|
||||||
} else if (localName.equals("color")) {
|
} else if (localName.equals("color")) {
|
||||||
try {
|
try {
|
||||||
currentArrival.setLine(Line.valueOf(currentValue));
|
if (getDestinationFromLine) {
|
||||||
|
final Line line = Line.valueOf(currentValue);
|
||||||
|
currentDeparture.setLine(line);
|
||||||
|
currentDeparture.setDestination(line
|
||||||
|
.getUsualTerminusForDirectionAndOrigin(
|
||||||
|
currentDeparture.getDirection(),
|
||||||
|
realTimeDepartures.getOrigin()));
|
||||||
|
} else if (currentValue.equalsIgnoreCase("WHITE")) {
|
||||||
|
for (Line line : Line.values()) {
|
||||||
|
if (line.stations.indexOf(currentDeparture
|
||||||
|
.getDestination()) >= 0
|
||||||
|
&& line.stations.indexOf(realTimeDepartures
|
||||||
|
.getDestination()) >= 0) {
|
||||||
|
currentDeparture.setLine(line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentDeparture.setLine(Line.valueOf(currentValue));
|
||||||
|
}
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
Log.w("BartApp", "There is no line called '" + currentValue
|
Log.w(Constants.TAG, "There is no line called '" + currentValue
|
||||||
+ "'");
|
+ "'");
|
||||||
}
|
}
|
||||||
} else if (localName.equals("hexcolor")) {
|
} else if (localName.equals("hexcolor")) {
|
||||||
currentArrival.setDestinationColor("#ff"
|
currentDeparture.setDestinationColor("#ff"
|
||||||
+ currentValue.substring(1));
|
+ currentValue.substring(1));
|
||||||
} else if (localName.equals("bikeflag")) {
|
} else if (localName.equals("bikeflag")) {
|
||||||
currentArrival.setBikeAllowed(currentValue.equalsIgnoreCase("1"));
|
currentDeparture.setBikeAllowed(currentValue.equalsIgnoreCase("1"));
|
||||||
} else if (localName.equals("estimate")) {
|
} else if (localName.equals("estimate")) {
|
||||||
realTimeArrivals.addArrival(currentArrival);
|
realTimeDepartures.addDeparture(currentDeparture);
|
||||||
currentArrival = null;
|
currentDeparture = null;
|
||||||
|
getDestinationFromLine = false;
|
||||||
} else if (localName.equals("etd")) {
|
} else if (localName.equals("etd")) {
|
||||||
currentDestination = null;
|
currentDestination = null;
|
||||||
} else if (localName.equals("station")) {
|
} else if (localName.equals("station")) {
|
||||||
realTimeArrivals.sortArrivals();
|
realTimeDepartures.sortDepartures();
|
||||||
}
|
}
|
||||||
isParsingTag = false;
|
isParsingTag = false;
|
||||||
currentValue = null;
|
currentValue = null;
|
||||||
|
@ -9,13 +9,13 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import com.dougkeen.bart.data.RealTimeArrivals;
|
import com.dougkeen.bart.data.RealTimeDepartures;
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
public abstract class GetRealTimeArrivalsTask extends
|
public abstract class GetRealTimeDeparturesTask extends
|
||||||
AsyncTask<GetRealTimeArrivalsTask.Params, Integer, RealTimeArrivals> {
|
AsyncTask<GetRealTimeDeparturesTask.Params, Integer, RealTimeDepartures> {
|
||||||
|
|
||||||
private static final int CONNECTION_TIMEOUT_MILLIS = 10000;
|
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";
|
||||||
@ -28,20 +28,20 @@ public abstract class GetRealTimeArrivalsTask extends
|
|||||||
private List<Route> mRoutes;
|
private List<Route> mRoutes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RealTimeArrivals doInBackground(Params... paramsArray) {
|
protected RealTimeDepartures doInBackground(Params... paramsArray) {
|
||||||
// Always expect one param
|
// Always expect one param
|
||||||
Params params = paramsArray[0];
|
Params params = paramsArray[0];
|
||||||
|
|
||||||
mRoutes = params.origin.getRoutesForDestination(params.destination);
|
mRoutes = params.origin.getRoutesForDestination(params.destination);
|
||||||
|
|
||||||
if (!isCancelled()) {
|
if (!isCancelled()) {
|
||||||
return getArrivalsFromNetwork(params, 0);
|
return getDeparturesFromNetwork(params, 0);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RealTimeArrivals getArrivalsFromNetwork(Params params,
|
private RealTimeDepartures getDeparturesFromNetwork(Params params,
|
||||||
int attemptNumber) {
|
int attemptNumber) {
|
||||||
try {
|
try {
|
||||||
URL sourceUrl = new URL(String.format(API_URL,
|
URL sourceUrl = new URL(String.format(API_URL,
|
||||||
@ -57,9 +57,9 @@ public abstract class GetRealTimeArrivalsTask extends
|
|||||||
Xml.parse(connection.getInputStream(),
|
Xml.parse(connection.getInputStream(),
|
||||||
Xml.findEncodingByName("UTF-8"),
|
Xml.findEncodingByName("UTF-8"),
|
||||||
handler);
|
handler);
|
||||||
final RealTimeArrivals realTimeArrivals = handler
|
final RealTimeDepartures realTimeDepartures = handler
|
||||||
.getRealTimeArrivals();
|
.getRealTimeDepartures();
|
||||||
return realTimeArrivals;
|
return realTimeDepartures;
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
@ -71,7 +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, attemptNumber + 1);
|
return getDeparturesFromNetwork(params, attemptNumber + 1);
|
||||||
} else {
|
} else {
|
||||||
mIOException = e;
|
mIOException = e;
|
||||||
return null;
|
return null;
|
||||||
@ -101,7 +101,7 @@ public abstract class GetRealTimeArrivalsTask extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(RealTimeArrivals result) {
|
protected void onPostExecute(RealTimeDepartures result) {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
onResult(result);
|
onResult(result);
|
||||||
} else {
|
} else {
|
||||||
@ -109,7 +109,7 @@ public abstract class GetRealTimeArrivalsTask extends
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onResult(RealTimeArrivals result);
|
public abstract void onResult(RealTimeDepartures result);
|
||||||
|
|
||||||
public abstract void onNetworkError(IOException e);
|
public abstract void onNetworkError(IOException e);
|
||||||
}
|
}
|
@ -92,4 +92,22 @@ public enum Line {
|
|||||||
|
|
||||||
return destinations;
|
return destinations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Station getUsualTerminusForDirectionAndOrigin(String direction,
|
||||||
|
Station origin) {
|
||||||
|
boolean isNorth = false;
|
||||||
|
if (direction.toLowerCase().startsWith("s") && directionMayInvert
|
||||||
|
&& origin.invertDirection) {
|
||||||
|
isNorth = true;
|
||||||
|
} else if (direction.toLowerCase().startsWith("n")
|
||||||
|
&& !(directionMayInvert && origin.invertDirection)) {
|
||||||
|
isNorth = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNorth) {
|
||||||
|
return stations.get(stations.size() - 1);
|
||||||
|
} else {
|
||||||
|
return stations.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,8 @@ public enum Station {
|
|||||||
UCTY("ucty", "Union City", true, "bayf"),
|
UCTY("ucty", "Union City", true, "bayf"),
|
||||||
WCRK("wcrk", "Walnut Creek", false, "mcar"),
|
WCRK("wcrk", "Walnut Creek", false, "mcar"),
|
||||||
WDUB("wdub", "West Dublin/Pleasanton", false, "bayf"),
|
WDUB("wdub", "West Dublin/Pleasanton", false, "bayf"),
|
||||||
WOAK("woak", "West Oakland", false);
|
WOAK("woak", "West Oakland", false),
|
||||||
|
SPCL("spcl", "Special", false);
|
||||||
|
|
||||||
public final String abbreviation;
|
public final String abbreviation;
|
||||||
public final String name;
|
public final String name;
|
||||||
|
@ -13,6 +13,7 @@ import android.os.Bundle;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
|
import android.text.util.Linkify;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@ -21,12 +22,12 @@ import android.widget.ArrayAdapter;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.dougkeen.bart.GetRealTimeArrivalsTask.Params;
|
import com.dougkeen.bart.GetRealTimeDeparturesTask.Params;
|
||||||
import com.dougkeen.bart.data.Arrival;
|
import com.dougkeen.bart.data.Departure;
|
||||||
import com.dougkeen.bart.data.RealTimeArrivals;
|
import com.dougkeen.bart.data.RealTimeDepartures;
|
||||||
import com.dougkeen.bart.data.RoutesColumns;
|
import com.dougkeen.bart.data.RoutesColumns;
|
||||||
|
|
||||||
public class ViewArrivalsActivity extends ListActivity {
|
public class ViewDeparturesActivity extends ListActivity {
|
||||||
|
|
||||||
private static final int UNCERTAINTY_THRESHOLD = 17;
|
private static final int UNCERTAINTY_THRESHOLD = 17;
|
||||||
|
|
||||||
@ -35,11 +36,11 @@ public class ViewArrivalsActivity extends ListActivity {
|
|||||||
private Station mOrigin;
|
private Station mOrigin;
|
||||||
private Station mDestination;
|
private Station mDestination;
|
||||||
|
|
||||||
private ArrayAdapter<Arrival> mArrivalsAdapter;
|
private ArrayAdapter<Departure> mDeparturesAdapter;
|
||||||
|
|
||||||
private TextView mListTitleView;
|
private TextView mListTitleView;
|
||||||
|
|
||||||
private AsyncTask<Params, Integer, RealTimeArrivals> mGetArrivalsTask;
|
private AsyncTask<Params, Integer, RealTimeDepartures> mGetDeparturesTask;
|
||||||
|
|
||||||
private boolean mIsAutoUpdating = false;
|
private boolean mIsAutoUpdating = false;
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ public class ViewArrivalsActivity extends ListActivity {
|
|||||||
|
|
||||||
private PowerManager.WakeLock mWakeLock;
|
private PowerManager.WakeLock mWakeLock;
|
||||||
|
|
||||||
private boolean mFetchArrivalsOnNextFocus;
|
private boolean mFetchDeparturesOnNextFocus;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -77,31 +78,32 @@ public class ViewArrivalsActivity extends ListActivity {
|
|||||||
mOrigin = Station.getByAbbreviation(cursor.getString(0));
|
mOrigin = Station.getByAbbreviation(cursor.getString(0));
|
||||||
mDestination = Station.getByAbbreviation(cursor.getString(1));
|
mDestination = Station.getByAbbreviation(cursor.getString(1));
|
||||||
|
|
||||||
String header = mOrigin.name + " to " + mDestination.name;
|
String header = "Departures:\n" + mOrigin.name + " to "
|
||||||
|
+ mDestination.name;
|
||||||
|
|
||||||
mListTitleView = (TextView) findViewById(R.id.listTitle);
|
mListTitleView = (TextView) findViewById(R.id.listTitle);
|
||||||
mListTitleView.setText(header);
|
mListTitleView.setText(header);
|
||||||
((TextView) findViewById(android.R.id.empty))
|
((TextView) findViewById(android.R.id.empty))
|
||||||
.setText(R.string.arrival_wait_message);
|
.setText(R.string.departure_wait_message);
|
||||||
|
|
||||||
mArrivalsAdapter = new ArrivalArrayAdapter(this,
|
mDeparturesAdapter = new DepartureArrayAdapter(this,
|
||||||
R.layout.arrival_listing);
|
R.layout.departure_listing);
|
||||||
if (savedInstanceState != null
|
if (savedInstanceState != null
|
||||||
&& savedInstanceState.containsKey("arrivals")) {
|
&& savedInstanceState.containsKey("departures")) {
|
||||||
for (Parcelable arrival : savedInstanceState
|
for (Parcelable departure : savedInstanceState
|
||||||
.getParcelableArray("arrivals")) {
|
.getParcelableArray("departures")) {
|
||||||
mArrivalsAdapter.add((Arrival) arrival);
|
mDeparturesAdapter.add((Departure) departure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setListAdapter(mArrivalsAdapter);
|
setListAdapter(mDeparturesAdapter);
|
||||||
|
|
||||||
mFetchArrivalsOnNextFocus = true;
|
mFetchDeparturesOnNextFocus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
if (mGetArrivalsTask != null) {
|
if (mGetDeparturesTask != null) {
|
||||||
mGetArrivalsTask.cancel(true);
|
mGetDeparturesTask.cancel(true);
|
||||||
}
|
}
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
@ -109,26 +111,28 @@ public class ViewArrivalsActivity extends ListActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
Arrival[] arrivals = new Arrival[mArrivalsAdapter.getCount()];
|
Departure[] departures = new Departure[mDeparturesAdapter.getCount()];
|
||||||
for (int i = mArrivalsAdapter.getCount() - 1; i >= 0; i--) {
|
for (int i = mDeparturesAdapter.getCount() - 1; i >= 0; i--) {
|
||||||
arrivals[i] = mArrivalsAdapter.getItem(i);
|
departures[i] = mDeparturesAdapter.getItem(i);
|
||||||
}
|
}
|
||||||
outState.putParcelableArray("arrivals", arrivals);
|
outState.putParcelableArray("departures", departures);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWindowFocusChanged(boolean hasFocus) {
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
super.onWindowFocusChanged(hasFocus);
|
super.onWindowFocusChanged(hasFocus);
|
||||||
if (hasFocus) {
|
if (hasFocus) {
|
||||||
if (mFetchArrivalsOnNextFocus) {
|
if (mFetchDeparturesOnNextFocus) {
|
||||||
fetchLatestArrivals();
|
fetchLatestDepartures();
|
||||||
mFetchArrivalsOnNextFocus = false;
|
mFetchDeparturesOnNextFocus = false;
|
||||||
}
|
}
|
||||||
PowerManager powerManaer = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
PowerManager powerManaer = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||||
mWakeLock = powerManaer.newWakeLock(
|
mWakeLock = powerManaer
|
||||||
PowerManager.SCREEN_DIM_WAKE_LOCK, "ViewArrivalsActivity");
|
.newWakeLock(
|
||||||
|
PowerManager.SCREEN_DIM_WAKE_LOCK,
|
||||||
|
"ViewDeparturesActivity");
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
if (mArrivalsAdapter != null && !mArrivalsAdapter.isEmpty()) {
|
if (mDeparturesAdapter != null && !mDeparturesAdapter.isEmpty()) {
|
||||||
mIsAutoUpdating = true;
|
mIsAutoUpdating = true;
|
||||||
}
|
}
|
||||||
runAutoUpdate();
|
runAutoUpdate();
|
||||||
@ -137,28 +141,28 @@ public class ViewArrivalsActivity extends ListActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchLatestArrivals() {
|
private void fetchLatestDepartures() {
|
||||||
if (!hasWindowFocus())
|
if (!hasWindowFocus())
|
||||||
return;
|
return;
|
||||||
if (mGetArrivalsTask != null
|
if (mGetDeparturesTask != null
|
||||||
&& mGetArrivalsTask.getStatus()
|
&& mGetDeparturesTask.getStatus()
|
||||||
.equals(AsyncTask.Status.RUNNING)) {
|
.equals(AsyncTask.Status.RUNNING)) {
|
||||||
// Don't overlap fetches
|
// Don't overlap fetches
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mGetArrivalsTask = new GetRealTimeArrivalsTask() {
|
mGetDeparturesTask = new GetRealTimeDeparturesTask() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(RealTimeArrivals result) {
|
public void onResult(RealTimeDepartures result) {
|
||||||
Log.i(Constants.TAG, "Processing data from server");
|
Log.i(Constants.TAG, "Processing data from server");
|
||||||
processLatestArrivals(result);
|
processLatestDepartures(result);
|
||||||
Log.i(Constants.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) {
|
||||||
Log.w(Constants.TAG, e.getMessage());
|
Log.w(Constants.TAG, e.getMessage());
|
||||||
Toast.makeText(ViewArrivalsActivity.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))
|
||||||
@ -167,80 +171,96 @@ public class ViewArrivalsActivity extends ListActivity {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
Log.i(Constants.TAG, "Fetching data from server");
|
Log.i(Constants.TAG, "Fetching data from server");
|
||||||
mGetArrivalsTask.execute(new GetRealTimeArrivalsTask.Params(mOrigin,
|
mGetDeparturesTask.execute(new GetRealTimeDeparturesTask.Params(
|
||||||
|
mOrigin,
|
||||||
mDestination));
|
mDestination));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processLatestArrivals(RealTimeArrivals result) {
|
protected void processLatestDepartures(RealTimeDepartures result) {
|
||||||
if (result.getArrivals().isEmpty()) {
|
if (result.getDepartures().isEmpty()) {
|
||||||
((TextView) findViewById(android.R.id.empty))
|
final TextView textView = (TextView) findViewById(android.R.id.empty);
|
||||||
.setText(R.string.no_data_message);
|
textView.setText(R.string.no_data_message);
|
||||||
|
Linkify.addLinks(textView, Linkify.WEB_URLS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean needsBetterAccuracy = false;
|
boolean needsBetterAccuracy = false;
|
||||||
Arrival firstArrival = null;
|
Departure firstDeparture = null;
|
||||||
final List<Arrival> arrivals = result.getArrivals();
|
final List<Departure> departures = result.getDepartures();
|
||||||
if (mArrivalsAdapter.getCount() > 0) {
|
if (mDeparturesAdapter.getCount() > 0) {
|
||||||
int adapterIndex = -1;
|
int adapterIndex = -1;
|
||||||
for (Arrival arrival : arrivals) {
|
for (Departure departure : departures) {
|
||||||
adapterIndex++;
|
adapterIndex++;
|
||||||
Arrival existingArrival = null;
|
Departure existingDeparture = null;
|
||||||
if (adapterIndex < mArrivalsAdapter.getCount()) {
|
if (adapterIndex < mDeparturesAdapter.getCount()) {
|
||||||
existingArrival = mArrivalsAdapter.getItem(adapterIndex);
|
existingDeparture = mDeparturesAdapter
|
||||||
|
.getItem(adapterIndex);
|
||||||
}
|
}
|
||||||
while (existingArrival != null
|
while (existingDeparture != null
|
||||||
&& !arrival.equals(existingArrival)) {
|
&& !departure.equals(existingDeparture)) {
|
||||||
mArrivalsAdapter.remove(existingArrival);
|
mDeparturesAdapter.remove(existingDeparture);
|
||||||
if (adapterIndex < mArrivalsAdapter.getCount()) {
|
if (adapterIndex < mDeparturesAdapter.getCount()) {
|
||||||
existingArrival = mArrivalsAdapter
|
existingDeparture = mDeparturesAdapter
|
||||||
.getItem(adapterIndex);
|
.getItem(adapterIndex);
|
||||||
} else {
|
} else {
|
||||||
existingArrival = null;
|
existingDeparture = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (existingArrival != null) {
|
if (existingDeparture != null) {
|
||||||
existingArrival.mergeEstimate(arrival);
|
existingDeparture.mergeEstimate(departure);
|
||||||
} else {
|
} else {
|
||||||
mArrivalsAdapter.add(arrival);
|
mDeparturesAdapter.add(departure);
|
||||||
existingArrival = arrival;
|
existingDeparture = departure;
|
||||||
}
|
}
|
||||||
if (firstArrival == null) {
|
if (firstDeparture == null) {
|
||||||
firstArrival = existingArrival;
|
firstDeparture = existingDeparture;
|
||||||
}
|
}
|
||||||
if (existingArrival.getUncertaintySeconds() > UNCERTAINTY_THRESHOLD) {
|
if (existingDeparture.getUncertaintySeconds() > UNCERTAINTY_THRESHOLD) {
|
||||||
needsBetterAccuracy = true;
|
needsBetterAccuracy = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (Arrival arrival : arrivals) {
|
for (Departure departure : departures) {
|
||||||
if (firstArrival == null) {
|
if (firstDeparture == null) {
|
||||||
firstArrival = arrival;
|
firstDeparture = departure;
|
||||||
}
|
}
|
||||||
mArrivalsAdapter.add(arrival);
|
mDeparturesAdapter.add(departure);
|
||||||
}
|
}
|
||||||
needsBetterAccuracy = true;
|
needsBetterAccuracy = true;
|
||||||
}
|
}
|
||||||
mArrivalsAdapter.notifyDataSetChanged();
|
mDeparturesAdapter.notifyDataSetChanged();
|
||||||
|
|
||||||
if (hasWindowFocus() && firstArrival != null) {
|
if (hasWindowFocus() && firstDeparture != null) {
|
||||||
if (needsBetterAccuracy
|
if (needsBetterAccuracy
|
||||||
|| firstArrival.hasArrived()) {
|
|| firstDeparture.hasDeparted()) {
|
||||||
// Get more data in 20s
|
// Get more data in 20s
|
||||||
mListTitleView.postDelayed(new Runnable() {
|
mListTitleView.postDelayed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
fetchLatestArrivals();
|
fetchLatestDepartures();
|
||||||
}
|
}
|
||||||
}, 20000);
|
}, 20000);
|
||||||
Log.i(Constants.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 90 seconds before next train arrives, right when
|
||||||
final int interval = firstArrival.getMinSecondsLeft() * 1000;
|
// next train arrives, or 3 minutes, whichever is sooner
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
final long nextDepartureMillis = firstDeparture
|
||||||
|
.getMinSecondsLeft() * 1000L;
|
||||||
|
final int intervalUntilNextDeparture = (int) (nextDepartureMillis - now);
|
||||||
|
final int alternativeInterval = 3 * 60 * 1000;
|
||||||
|
|
||||||
|
int interval = intervalUntilNextDeparture;
|
||||||
|
if (intervalUntilNextDeparture > 95000
|
||||||
|
&& intervalUntilNextDeparture < alternativeInterval) {
|
||||||
|
interval = interval - 90 * 1000;
|
||||||
|
} else if (intervalUntilNextDeparture > alternativeInterval) {
|
||||||
|
interval = alternativeInterval;
|
||||||
|
}
|
||||||
mListTitleView.postDelayed(new Runnable() {
|
mListTitleView.postDelayed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
fetchLatestArrivals();
|
fetchLatestDepartures();
|
||||||
}
|
}
|
||||||
}, interval);
|
}, interval);
|
||||||
Log.i(Constants.TAG, "Scheduled another data fetch in "
|
Log.i(Constants.TAG, "Scheduled another data fetch in "
|
||||||
@ -256,8 +276,8 @@ public class ViewArrivalsActivity extends ListActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void runAutoUpdate() {
|
private void runAutoUpdate() {
|
||||||
if (mIsAutoUpdating && mArrivalsAdapter != null) {
|
if (mIsAutoUpdating && mDeparturesAdapter != null) {
|
||||||
mArrivalsAdapter.notifyDataSetChanged();
|
mDeparturesAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
if (hasWindowFocus()) {
|
if (hasWindowFocus()) {
|
||||||
mListTitleView.postDelayed(AUTO_UPDATE_RUNNABLE, 1000);
|
mListTitleView.postDelayed(AUTO_UPDATE_RUNNABLE, 1000);
|
||||||
@ -285,7 +305,7 @@ public class ViewArrivalsActivity extends ListActivity {
|
|||||||
+ mOrigin.abbreviation
|
+ mOrigin.abbreviation
|
||||||
+ "&dest="
|
+ "&dest="
|
||||||
+ mDestination.abbreviation)));
|
+ mDestination.abbreviation)));
|
||||||
mFetchArrivalsOnNextFocus = true;
|
mFetchDeparturesOnNextFocus = true;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
@ -6,12 +6,14 @@ import android.os.Parcelable;
|
|||||||
import com.dougkeen.bart.Line;
|
import com.dougkeen.bart.Line;
|
||||||
import com.dougkeen.bart.Station;
|
import com.dougkeen.bart.Station;
|
||||||
|
|
||||||
public class Arrival implements Parcelable, Comparable<Arrival> {
|
public class Departure implements Parcelable, Comparable<Departure> {
|
||||||
public Arrival() {
|
private static final int MINIMUM_MERGE_OVERLAP_MILLIS = 10000;
|
||||||
|
|
||||||
|
public Departure() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Arrival(String destinationAbbr, String destinationColor,
|
public Departure(String destinationAbbr, String destinationColor,
|
||||||
String platform, String direction, boolean bikeAllowed,
|
String platform, String direction, boolean bikeAllowed,
|
||||||
int trainLength, int minutes) {
|
int trainLength, int minutes) {
|
||||||
super();
|
super();
|
||||||
@ -24,7 +26,7 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
|
|||||||
this.minutes = minutes;
|
this.minutes = minutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Arrival(Parcel in) {
|
public Departure(Parcel in) {
|
||||||
readFromParcel(in);
|
readFromParcel(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,20 +165,30 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
|
|||||||
.currentTimeMillis()) / 1000);
|
.currentTimeMillis()) / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasArrived() {
|
public boolean hasDeparted() {
|
||||||
return getMinutes() == 0 || getMeanSecondsLeft() < 0;
|
return getMinutes() == 0 || getMeanSecondsLeft() < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void calculateEstimates(long originalEstimateTime) {
|
public void calculateEstimates(long originalEstimateTime) {
|
||||||
setMinEstimate(originalEstimateTime + (getMinutes() * 60 * 1000));
|
setMinEstimate(originalEstimateTime + (getMinutes() * 60 * 1000)
|
||||||
setMaxEstimate(getMinEstimate() + (59 * 1000));
|
- (30000));
|
||||||
|
setMaxEstimate(getMinEstimate() + 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mergeEstimate(Departure departure) {
|
||||||
|
if ((getMaxEstimate() - departure.getMinEstimate()) < MINIMUM_MERGE_OVERLAP_MILLIS
|
||||||
|
|| departure.getMaxEstimate() - getMinEstimate() < MINIMUM_MERGE_OVERLAP_MILLIS) {
|
||||||
|
// The estimate must have changed... just use the latest incoming
|
||||||
|
// values
|
||||||
|
setMinEstimate(departure.getMinEstimate());
|
||||||
|
setMaxEstimate(departure.getMaxEstimate());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mergeEstimate(Arrival arrival) {
|
|
||||||
final long newMin = Math
|
final long newMin = Math
|
||||||
.max(getMinEstimate(), arrival.getMinEstimate());
|
.max(getMinEstimate(), departure.getMinEstimate());
|
||||||
final long newMax = Math
|
final long newMax = Math
|
||||||
.min(getMaxEstimate(), arrival.getMaxEstimate());
|
.min(getMaxEstimate(), departure.getMaxEstimate());
|
||||||
if (newMax > newMin) { // We can never have 0 or negative uncertainty
|
if (newMax > newMin) { // We can never have 0 or negative uncertainty
|
||||||
setMinEstimate(newMin);
|
setMinEstimate(newMin);
|
||||||
setMaxEstimate(newMax);
|
setMaxEstimate(newMax);
|
||||||
@ -184,7 +196,7 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Arrival 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);
|
||||||
}
|
}
|
||||||
@ -197,7 +209,7 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
|
|||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
Arrival other = (Arrival) obj;
|
Departure other = (Departure) obj;
|
||||||
if (bikeAllowed != other.bikeAllowed)
|
if (bikeAllowed != other.bikeAllowed)
|
||||||
return false;
|
return false;
|
||||||
if (destination != other.destination)
|
if (destination != other.destination)
|
||||||
@ -227,8 +239,8 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
|
|||||||
public String getCountdownText() {
|
public String getCountdownText() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
int secondsLeft = getMeanSecondsLeft();
|
int secondsLeft = getMeanSecondsLeft();
|
||||||
if (hasArrived()) {
|
if (hasDeparted()) {
|
||||||
builder.append("Arrived");
|
builder.append("Departed");
|
||||||
} else {
|
} else {
|
||||||
builder.append(secondsLeft / 60);
|
builder.append(secondsLeft / 60);
|
||||||
builder.append("m, ");
|
builder.append("m, ");
|
||||||
@ -239,7 +251,7 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getUncertaintyText() {
|
public String getUncertaintyText() {
|
||||||
if (hasArrived()) {
|
if (hasDeparted()) {
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
return "(±" + getUncertaintySeconds() + "s)";
|
return "(±" + getUncertaintySeconds() + "s)";
|
||||||
@ -290,13 +302,13 @@ public class Arrival implements Parcelable, Comparable<Arrival> {
|
|||||||
maxEstimate = in.readLong();
|
maxEstimate = in.readLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Parcelable.Creator<Arrival> CREATOR = new Parcelable.Creator<Arrival>() {
|
public static final Parcelable.Creator<Departure> CREATOR = new Parcelable.Creator<Departure>() {
|
||||||
public Arrival createFromParcel(Parcel in) {
|
public Departure createFromParcel(Parcel in) {
|
||||||
return new Arrival(in);
|
return new Departure(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Arrival[] newArray(int size) {
|
public Departure[] newArray(int size) {
|
||||||
return new Arrival[size];
|
return new Departure[size];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -7,8 +7,8 @@ import java.util.List;
|
|||||||
import com.dougkeen.bart.Route;
|
import com.dougkeen.bart.Route;
|
||||||
import com.dougkeen.bart.Station;
|
import com.dougkeen.bart.Station;
|
||||||
|
|
||||||
public class RealTimeArrivals {
|
public class RealTimeDepartures {
|
||||||
public RealTimeArrivals(Station origin, Station destination,
|
public RealTimeDepartures(Station origin, Station destination,
|
||||||
List<Route> routes) {
|
List<Route> routes) {
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.destination = destination;
|
this.destination = destination;
|
||||||
@ -19,7 +19,7 @@ public class RealTimeArrivals {
|
|||||||
private Station destination;
|
private Station destination;
|
||||||
private long time;
|
private long time;
|
||||||
|
|
||||||
private List<Arrival> arrivals;
|
private List<Departure> departures;
|
||||||
|
|
||||||
private List<Route> routes;
|
private List<Route> routes;
|
||||||
|
|
||||||
@ -47,32 +47,35 @@ public class RealTimeArrivals {
|
|||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Arrival> getArrivals() {
|
public List<Departure> getDepartures() {
|
||||||
if (arrivals == null) {
|
if (departures == null) {
|
||||||
arrivals = new ArrayList<Arrival>();
|
departures = new ArrayList<Departure>();
|
||||||
}
|
}
|
||||||
return arrivals;
|
return departures;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setArrivals(List<Arrival> arrivals) {
|
public void setDepartures(List<Departure> departures) {
|
||||||
this.arrivals = arrivals;
|
this.departures = departures;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addArrival(Arrival arrival) {
|
public void addDeparture(Departure departure) {
|
||||||
Station destination = Station.getByAbbreviation(arrival
|
Station destination = Station.getByAbbreviation(departure
|
||||||
.getDestinationAbbreviation());
|
.getDestinationAbbreviation());
|
||||||
|
if (departure.getLine() == null)
|
||||||
|
return;
|
||||||
for (Route route : routes) {
|
for (Route route : routes) {
|
||||||
if (route.trainDestinationIsApplicable(destination, arrival.getLine())) {
|
if (route.trainDestinationIsApplicable(destination,
|
||||||
arrival.setRequiresTransfer(route.hasTransfer());
|
departure.getLine())) {
|
||||||
getArrivals().add(arrival);
|
departure.setRequiresTransfer(route.hasTransfer());
|
||||||
arrival.calculateEstimates(time);
|
getDepartures().add(departure);
|
||||||
|
departure.calculateEstimates(time);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sortArrivals() {
|
public void sortDepartures() {
|
||||||
Collections.sort(getArrivals());
|
Collections.sort(getDepartures());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Route> getRoutes() {
|
public List<Route> getRoutes() {
|
||||||
@ -86,14 +89,14 @@ public class RealTimeArrivals {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("RealTimeArrivals [origin=");
|
builder.append("RealTimeDepartures [origin=");
|
||||||
builder.append(origin);
|
builder.append(origin);
|
||||||
builder.append(", destination=");
|
builder.append(", destination=");
|
||||||
builder.append(destination);
|
builder.append(destination);
|
||||||
builder.append(", time=");
|
builder.append(", time=");
|
||||||
builder.append(time);
|
builder.append(time);
|
||||||
builder.append(", arrivals=");
|
builder.append(", departures=");
|
||||||
builder.append(arrivals);
|
builder.append(departures);
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user