Permalink
Browse files

Updated error handling.

  • Loading branch information...
1 parent 766caae commit 70a630ae1089d68c07d7f9c91bdb51f9e463bc40 @trajano committed Feb 11, 2012
View
@@ -15,6 +15,13 @@
<string name="last_updated">Last updated on: %s</string>
<string name="next_update">Next scheduled update on: %s</string>
<string name="pending">Pending</string>
+ <string name="error">Error</string>
<string name="problem_loading">There was a problem loading the data from the Internet.</string>
+ <string name="problem_loading_html_format"> <![CDATA[
+ <p>There was a problem loading the data from the Internet.</p>
+ <p><b>Exception message:</b><br />
+ %s.</p>]]>
+ </string>
+ <string name="problem_loading_format">here was a problem loading the data from the Internet. Exception message: %s.</string>
</resources>
@@ -17,6 +17,7 @@
import android.widget.TextView;
public class GasPricesActivity extends Activity {
+
/**
* Forced update progress dialog.
*/
@@ -55,6 +56,11 @@ public void onCreate(final Bundle savedInstanceState) {
}
preferences = new PreferenceAdaptor(this);
+ if (!preferences.isDataPresent() || preferences.isUpdateNeeded()) {
+ forcedUpdateDialog = ProgressDialog.show(this, "", getResources()
+ .getString(R.string.loading), true);
+ new UpdateTask(this).execute();
+ }
setContentView(R.layout.main);
GasPricesUpdateService.scheduleUpdate(this);
}
@@ -72,9 +78,7 @@ public boolean onOptionsItemSelected(final MenuItem item) {
if (R.id.UpdateMenuItem == item.getItemId()) {
forcedUpdateDialog = ProgressDialog.show(this, "", getResources()
.getString(R.string.loading), true);
- // TODO don't do this! create a new AsyncTask instead.
- final Intent intent = new Intent(this, GasPricesUpdateService.class);
- startService(intent);
+ new UpdateTask(this).execute();
return true;
} else if (R.id.ShowFeedData == item.getItemId()) {
final Intent intent = new Intent(this, GasPricesFeedActivity.class);
@@ -130,15 +134,15 @@ protected void onResume() {
* visible.
*/
private void updateView() {
- if (!preferences.isDataPresent() || preferences.isUpdateNeeded()) {
- forcedUpdateDialog = ProgressDialog.show(this, "", getResources()
- .getString(R.string.loading), true);
- // TODO don't do this! create a new AsyncTask instead.
- final Intent intent = new Intent(this, GasPricesUpdateService.class);
- startService(intent);
+ if (preferences.isError() && forcedUpdateDialog != null) {
+ forcedUpdateDialog.dismiss();
+ forcedUpdateDialog = null;
return;
}
+ if (!preferences.isDataPresent()) {
+ return;
+ }
final CityInfo cityInfo = preferences.getSelectedCityInfo();
{
@@ -78,10 +78,7 @@ public boolean onOptionsItemSelected(final MenuItem item) {
if (R.id.UpdateMenuItem == item.getItemId()) {
forcedUpdateDialog = ProgressDialog.show(this, "", getResources()
.getString(R.string.loading), true);
-
- // TODO don't do this! create a new AsyncTask instead.
- final Intent intent = new Intent(this, GasPricesUpdateService.class);
- startService(intent);
+ new UpdateTask(this).execute();
return true;
} else if (android.R.id.home == item.getItemId()) {
// app icon in action bar clicked; go home
@@ -1,13 +1,6 @@
package net.trajano.gasprices;
import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Scanner;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
import android.app.AlarmManager;
import android.app.IntentService;
@@ -68,41 +61,6 @@ public GasPricesUpdateService() {
super("GasPricesUpdateIntentService");
}
- /**
- * This will connect to the Internet to get the gas price data and return
- * the parsed {@link JSONObject}. This will return <code>null</code> if
- * there is an error parsing the data because there isn't anything that can
- * be done if there is a parse error, but the {@link IOException} is still
- * thrown for any communication errors.
- *
- * @return a parsed JSONObject.
- * @throws IOException
- * I/O error.
- */
- private JSONObject getGasPricesDataFromInternet() throws IOException {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(
- "http://www.tomorrowsgaspricetoday.com/mobile/json_mobile_data.php")
- .openConnection();
- try {
- // Read the JSON data, skip the first character since it
- // breaks the parsing.
- final String jsonData = new Scanner(urlConnection.getInputStream())
- .useDelimiter("\\A").next().substring(1);
-
- final Object value = new JSONTokener(jsonData).nextValue();
- if (value instanceof JSONObject) {
- return (JSONObject) value;
- } else {
- throw new IOException("Did not get a proper JSON object");
- }
- } catch (final JSONException e) {
- Log.e("GasPrices", e.getMessage());
- throw new IOException(e);
- } finally {
- urlConnection.disconnect();
- }
- }
-
/**
* <p>
* This is the only place in the application where an Internet request is
@@ -139,8 +97,9 @@ protected void onHandleIntent(final Intent intent) {
if (!backgroundEnabled) {
return;
}
- editor.setJsonData(getGasPricesDataFromInternet());
+ editor.setJsonData(GetDataUtil.getGasPricesDataFromInternet());
notificationManager.cancel(1);
+ editor.removeLastError();
} catch (final IOException e) {
Log.e("GasPrices", e.getMessage() + " and cry");
final Notification notification = new Notification.Builder(this)
@@ -0,0 +1,54 @@
+package net.trajano.gasprices;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Scanner;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+import android.util.Log;
+
+public final class GetDataUtil {
+ /**
+ * This will connect to the Internet to get the gas price data and return
+ * the parsed {@link JSONObject}. This will return <code>null</code> if
+ * there is an error parsing the data because there isn't anything that can
+ * be done if there is a parse error, but the {@link IOException} is still
+ * thrown for any communication errors.
+ *
+ * @return a parsed JSONObject.
+ * @throws IOException
+ * I/O error.
+ */
+ public static JSONObject getGasPricesDataFromInternet() throws IOException {
+ final HttpURLConnection urlConnection = (HttpURLConnection) new URL(
+ "http://www.tomorrowsgaspricetoday.com/mobile/json_mobile_data.php")
+ .openConnection();
+ try {
+ // Read the JSON data, skip the first character since it
+ // breaks the parsing.
+ final String jsonData = new Scanner(urlConnection.getInputStream())
+ .useDelimiter("\\A").next().substring(1);
+
+ final Object value = new JSONTokener(jsonData).nextValue();
+ if (value instanceof JSONObject) {
+ return (JSONObject) value;
+ } else {
+ throw new IOException("Did not get a proper JSON object");
+ }
+ } catch (final JSONException e) {
+ Log.e("GasPrices", e.getMessage());
+ throw new IOException(e);
+ } finally {
+ urlConnection.disconnect();
+ }
+ }
+
+ private GetDataUtil() {
+
+ }
+
+}
@@ -45,6 +45,10 @@
* JSON data key.
*/
static final String JSON_DATA_KEY = "json_data";
+ /**
+ * Last error key.
+ */
+ static final String LAST_ERROR_KEY = "last_error";
/**
* Last updated in seconds since epoch.
@@ -79,7 +83,7 @@
* @return
*/
public static boolean isKeyAffectGasPricesView(final String key) {
- return LAST_UPDATED_KEY.equals(key)
+ return LAST_UPDATED_KEY.equals(key) || LAST_ERROR_KEY.equals(key)
|| SELECTED_CITY_ID_KEY.equals("key");
}
@@ -209,6 +213,10 @@ public String getJsonDataString() {
return preferences.getString(JSON_DATA_KEY, null);
}
+ public String getLastError() {
+ return preferences.getString(LAST_ERROR_KEY, "");
+ }
+
/**
* This returns the {@link Date} represening the last updated timestamp.
*
@@ -303,6 +311,15 @@ public boolean isDataPresent() {
&& preferences.contains(JSON_DATA_KEY);
}
+ /**
+ * Checks if there is an error recorded.
+ *
+ * @return
+ */
+ public boolean isError() {
+ return preferences.contains(LAST_ERROR_KEY);
+ }
+
/**
* An updated is needed if the next update time occurs in the past.
*
@@ -143,6 +143,10 @@ public boolean commit() {
return editor.remove(key);
}
+ public void removeLastError() {
+ editor.remove(PreferenceAdaptor.LAST_ERROR_KEY);
+ }
+
/**
* This removes the selected city id for the widgets.
*
@@ -199,6 +203,20 @@ public void setJsonData(final JSONObject gasPrices) {
}
}
+ /**
+ * Sets the last error text.
+ *
+ * @param errorMessage
+ * error message. May be <code>null</code> to remove the message.
+ */
+ public void setLastError(final String errorMessage) {
+ if (errorMessage == null) {
+ editor.remove(PreferenceAdaptor.LAST_ERROR_KEY);
+ } else {
+ editor.putString(PreferenceAdaptor.LAST_ERROR_KEY, errorMessage);
+ }
+ }
+
/**
* Sets the last updated time preference. Internally it will convert it to a
* long before storing it in the shared preferences.
@@ -0,0 +1,72 @@
+package net.trajano.gasprices;
+
+import java.io.IOException;
+
+import org.json.JSONObject;
+
+import android.app.AlertDialog;
+import android.appwidget.AppWidgetManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class UpdateTask extends AsyncTask<Void, Void, Exception> {
+ private final Context context;
+
+ public UpdateTask(final Context context) {
+ this.context = context;
+ }
+
+ @Override
+ protected Exception doInBackground(final Void... params) {
+ final PreferenceAdaptor preferences = new PreferenceAdaptor(context);
+ final PreferenceAdaptorEditor editor = preferences.edit();
+
+ try {
+ final JSONObject data = GetDataUtil.getGasPricesDataFromInternet();
+ editor.setJsonData(data);
+ editor.setLastUpdatedToNow();
+ return null;
+ } catch (final IOException e) {
+ Log.e("GasPrices", e.getMessage() + " and cry");
+ editor.setLastError(e.getMessage());
+ return e;
+ } finally {
+ editor.apply();
+ }
+ }
+
+ @Override
+ protected void onPostExecute(final Exception result) {
+ if (result == null) {
+ final AppWidgetManager widgetManager = AppWidgetManager
+ .getInstance(context);
+ final ComponentName widgetComponent = new ComponentName(context,
+ GasPricesWidgetProvider.class);
+ final int[] widgetIds = widgetManager
+ .getAppWidgetIds(widgetComponent);
+ if (widgetIds.length > 0) {
+ final Intent update = new Intent();
+ update.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds);
+ update.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
+ context.sendBroadcast(update);
+ }
+ } else {
+ new AlertDialog.Builder(context)
+ .setTitle(R.string.error)
+ .setMessage(
+ context.getString(R.string.problem_loading_format,
+ result.getLocalizedMessage())).show();
+ }
+ }
+
+ @Override
+ protected void onPreExecute() {
+ final PreferenceAdaptor preferences = new PreferenceAdaptor(context);
+ final PreferenceAdaptorEditor editor = preferences.edit();
+ editor.removeLastError();
+ editor.apply();
+ }
+}

0 comments on commit 70a630a

Please sign in to comment.