Now using commons-httpclient
This commit is contained in:
parent
114dd4c6f4
commit
b9c5bdf148
@ -3,5 +3,6 @@
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
BIN
libs/commons-io-2.0.1.jar
Normal file
BIN
libs/commons-io-2.0.1.jar
Normal file
Binary file not shown.
@ -1,20 +1,34 @@
|
||||
package com.dougkeen.bart;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.conn.params.ConnManagerParams;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.params.HttpConnectionParams;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.dougkeen.bart.data.RealTimeDepartures;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Xml;
|
||||
|
||||
public abstract class GetRealTimeDeparturesTask extends
|
||||
public abstract class GetRealTimeDeparturesTask
|
||||
extends
|
||||
AsyncTask<GetRealTimeDeparturesTask.Params, Integer, RealTimeDepartures> {
|
||||
|
||||
private static final int CONNECTION_TIMEOUT_MILLIS = 10000;
|
||||
@ -23,7 +37,7 @@ public abstract class GetRealTimeDeparturesTask extends
|
||||
+ API_KEY + "&orig=%1$s&dir=%2$s";
|
||||
private final static int MAX_ATTEMPTS = 3;
|
||||
|
||||
private IOException mIOException;
|
||||
private Exception mException;
|
||||
|
||||
private List<Route> mRoutes;
|
||||
|
||||
@ -43,8 +57,9 @@ public abstract class GetRealTimeDeparturesTask extends
|
||||
|
||||
private RealTimeDepartures getDeparturesFromNetwork(Params params,
|
||||
int attemptNumber) {
|
||||
String xml = null;
|
||||
try {
|
||||
URL sourceUrl = new URL(String.format(API_URL,
|
||||
HttpUriRequest request = new HttpGet(String.format(API_URL,
|
||||
params.origin.abbreviation, mRoutes.get(0).getDirection()));
|
||||
|
||||
EtdContentHandler handler = new EtdContentHandler(params.origin,
|
||||
@ -52,11 +67,23 @@ public abstract class GetRealTimeDeparturesTask extends
|
||||
if (isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
URLConnection connection = sourceUrl.openConnection();
|
||||
connection.setConnectTimeout(CONNECTION_TIMEOUT_MILLIS);
|
||||
Xml.parse(connection.getInputStream(),
|
||||
Xml.findEncodingByName("UTF-8"),
|
||||
handler);
|
||||
|
||||
HttpResponse response = executeWithRecovery(request);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
||||
throw new IOException("Server returned "
|
||||
+ response.getStatusLine().toString());
|
||||
}
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
IOUtils.copy(response.getEntity().getContent(), writer, "UTF-8");
|
||||
|
||||
xml = writer.toString();
|
||||
if (xml.length() == 0) {
|
||||
throw new IOException("Server returned blank xml document");
|
||||
}
|
||||
|
||||
Xml.parse(xml, handler);
|
||||
final RealTimeDepartures realTimeDepartures = handler
|
||||
.getRealTimeDepartures();
|
||||
return realTimeDepartures;
|
||||
@ -67,20 +94,45 @@ public abstract class GetRealTimeDeparturesTask extends
|
||||
} catch (IOException e) {
|
||||
if (attemptNumber < MAX_ATTEMPTS - 1) {
|
||||
try {
|
||||
Log.w(Constants.TAG,
|
||||
"Attempt to contact server failed... retrying in 5s",
|
||||
e);
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException interrupt) {
|
||||
// Ignore... just go on to next attempt
|
||||
}
|
||||
return getDeparturesFromNetwork(params, attemptNumber + 1);
|
||||
} else {
|
||||
mIOException = e;
|
||||
mException = new Exception("Could not contact BART system", e);
|
||||
return null;
|
||||
}
|
||||
} catch (SAXException e) {
|
||||
throw new RuntimeException(e);
|
||||
mException = new Exception(
|
||||
"Could not understand response from BART system: " + xml, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpResponse executeWithRecovery(final HttpUriRequest request)
|
||||
throws IOException, ClientProtocolException {
|
||||
try {
|
||||
return getHttpClient().execute(request);
|
||||
} catch (IllegalStateException e) {
|
||||
// try again... this is a rare error
|
||||
return getHttpClient().execute(request);
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpClient getHttpClient() {
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
final HttpParams params = client.getParams();
|
||||
HttpConnectionParams.setConnectionTimeout(params,
|
||||
CONNECTION_TIMEOUT_MILLIS);
|
||||
HttpConnectionParams.setSoTimeout(params, CONNECTION_TIMEOUT_MILLIS);
|
||||
ConnManagerParams.setTimeout(params, CONNECTION_TIMEOUT_MILLIS);
|
||||
return client;
|
||||
}
|
||||
|
||||
public static class Params {
|
||||
public Params(Station origin, Station destination) {
|
||||
super();
|
||||
@ -105,11 +157,11 @@ public abstract class GetRealTimeDeparturesTask extends
|
||||
if (result != null) {
|
||||
onResult(result);
|
||||
} else {
|
||||
onNetworkError(mIOException);
|
||||
onError(mException);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void onResult(RealTimeDepartures result);
|
||||
|
||||
public abstract void onNetworkError(IOException e);
|
||||
public abstract void onError(Exception exception);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.dougkeen.bart;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.ListActivity;
|
||||
@ -53,7 +52,7 @@ public class ViewDeparturesActivity extends ListActivity {
|
||||
|
||||
private PowerManager.WakeLock mWakeLock;
|
||||
|
||||
private boolean mFetchDeparturesOnNextFocus;
|
||||
private boolean mDataFetchIsPending;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -96,14 +95,13 @@ public class ViewDeparturesActivity extends ListActivity {
|
||||
}
|
||||
}
|
||||
setListAdapter(mDeparturesAdapter);
|
||||
|
||||
mFetchDeparturesOnNextFocus = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (mGetDeparturesTask != null) {
|
||||
mGetDeparturesTask.cancel(true);
|
||||
mDataFetchIsPending = false;
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
@ -122,9 +120,8 @@ public class ViewDeparturesActivity extends ListActivity {
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus) {
|
||||
if (mFetchDeparturesOnNextFocus) {
|
||||
if (!mDataFetchIsPending) {
|
||||
fetchLatestDepartures();
|
||||
mFetchDeparturesOnNextFocus = false;
|
||||
}
|
||||
PowerManager powerManaer = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = powerManaer
|
||||
@ -154,20 +151,21 @@ public class ViewDeparturesActivity extends ListActivity {
|
||||
mGetDeparturesTask = new GetRealTimeDeparturesTask() {
|
||||
@Override
|
||||
public void onResult(RealTimeDepartures result) {
|
||||
mDataFetchIsPending = false;
|
||||
Log.i(Constants.TAG, "Processing data from server");
|
||||
processLatestDepartures(result);
|
||||
Log.i(Constants.TAG, "Done processing data from server");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkError(IOException e) {
|
||||
Log.w(Constants.TAG, e.getMessage());
|
||||
public void onError(Exception e) {
|
||||
mDataFetchIsPending = false;
|
||||
Log.w(Constants.TAG, e.getMessage(), e);
|
||||
Toast.makeText(ViewDeparturesActivity.this,
|
||||
R.string.could_not_connect,
|
||||
Toast.LENGTH_LONG).show();
|
||||
((TextView) findViewById(android.R.id.empty))
|
||||
.setText(R.string.could_not_connect);
|
||||
|
||||
}
|
||||
};
|
||||
Log.i(Constants.TAG, "Fetching data from server");
|
||||
@ -234,13 +232,7 @@ public class ViewDeparturesActivity extends ListActivity {
|
||||
if (needsBetterAccuracy
|
||||
|| firstDeparture.hasDeparted()) {
|
||||
// Get more data in 20s
|
||||
mListTitleView.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fetchLatestDepartures();
|
||||
}
|
||||
}, 20000);
|
||||
Log.i(Constants.TAG, "Scheduled another data fetch in 20s");
|
||||
scheduleDataFetch(20000);
|
||||
} else {
|
||||
// Get more 90 seconds before next train arrives, right when
|
||||
// next train arrives, or 3 minutes, whichever is sooner
|
||||
@ -255,15 +247,12 @@ public class ViewDeparturesActivity extends ListActivity {
|
||||
} else if (intervalUntilNextDeparture > alternativeInterval) {
|
||||
interval = alternativeInterval;
|
||||
}
|
||||
mListTitleView.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fetchLatestDepartures();
|
||||
}
|
||||
}, interval);
|
||||
Log.i(Constants.TAG, "Scheduled another data fetch in "
|
||||
+ interval / 1000
|
||||
+ "s");
|
||||
|
||||
if (interval < 0) {
|
||||
interval = 20000;
|
||||
}
|
||||
|
||||
scheduleDataFetch(interval);
|
||||
}
|
||||
if (!mIsAutoUpdating) {
|
||||
mIsAutoUpdating = true;
|
||||
@ -273,6 +262,20 @@ public class ViewDeparturesActivity extends ListActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleDataFetch(int millisUntilExecute) {
|
||||
if (!mDataFetchIsPending) {
|
||||
mListTitleView.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fetchLatestDepartures();
|
||||
}
|
||||
}, millisUntilExecute);
|
||||
mDataFetchIsPending = true;
|
||||
Log.i(Constants.TAG, "Scheduled another data fetch in "
|
||||
+ millisUntilExecute / 1000 + "s");
|
||||
}
|
||||
}
|
||||
|
||||
private void runAutoUpdate() {
|
||||
if (mIsAutoUpdating && mDeparturesAdapter != null) {
|
||||
mDeparturesAdapter.notifyDataSetChanged();
|
||||
@ -303,7 +306,6 @@ public class ViewDeparturesActivity extends ListActivity {
|
||||
+ mOrigin.abbreviation
|
||||
+ "&dest="
|
||||
+ mDestination.abbreviation)));
|
||||
mFetchDeparturesOnNextFocus = true;
|
||||
return true;
|
||||
} else {
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
@ -166,7 +166,7 @@ public class Departure implements Parcelable, Comparable<Departure> {
|
||||
}
|
||||
|
||||
public boolean hasDeparted() {
|
||||
return getMinutes() == 0 || getMeanSecondsLeft() < 0;
|
||||
return getMeanSecondsLeft() < 0;
|
||||
}
|
||||
|
||||
public void calculateEstimates(long originalEstimateTime) {
|
||||
|
Loading…
Reference in New Issue
Block a user