1 package de.example.exampletdd.fragment.overview;
 
   3 import java.io.FileNotFoundException;
 
   4 import java.io.IOException;
 
   5 import java.net.MalformedURLException;
 
   6 import java.net.URISyntaxException;
 
   8 import java.text.DecimalFormat;
 
   9 import java.text.NumberFormat;
 
  10 import java.text.SimpleDateFormat;
 
  11 import java.util.ArrayList;
 
  12 import java.util.Calendar;
 
  13 import java.util.Date;
 
  14 import java.util.List;
 
  15 import java.util.Locale;
 
  17 import org.apache.http.client.ClientProtocolException;
 
  19 import android.app.DialogFragment;
 
  20 import android.app.ListFragment;
 
  21 import android.content.ComponentName;
 
  22 import android.content.Intent;
 
  23 import android.content.SharedPreferences;
 
  24 import android.graphics.Bitmap;
 
  25 import android.graphics.BitmapFactory;
 
  26 import android.net.http.AndroidHttpClient;
 
  27 import android.os.AsyncTask;
 
  28 import android.os.Bundle;
 
  29 import android.os.Parcelable;
 
  30 import android.preference.PreferenceManager;
 
  31 import android.util.Log;
 
  32 import android.view.View;
 
  33 import android.widget.ListView;
 
  35 import com.fasterxml.jackson.core.JsonParseException;
 
  37 import de.example.exampletdd.R;
 
  38 import de.example.exampletdd.activityinterface.GetWeather;
 
  39 import de.example.exampletdd.fragment.ErrorDialogFragment;
 
  40 import de.example.exampletdd.fragment.ProgressDialogFragment;
 
  41 import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment;
 
  42 import de.example.exampletdd.httpclient.CustomHTTPClient;
 
  43 import de.example.exampletdd.model.GeocodingData;
 
  44 import de.example.exampletdd.model.forecastweather.ForecastWeatherData;
 
  45 import de.example.exampletdd.parser.IJPOSWeatherParser;
 
  46 import de.example.exampletdd.parser.JPOSWeatherParser;
 
  47 import de.example.exampletdd.service.WeatherServiceParser;
 
  48 import de.example.exampletdd.service.WeatherServicePersistenceFile;
 
  50 public class WeatherInformationOverviewFragment extends ListFragment implements GetWeather {
 
  51     private boolean mIsFahrenheit;
 
  52     private String mDayForecast;
 
  53     private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
 
  54     private Parcelable mListState;
 
  57     public void onCreate(final Bundle savedInstanceState) {
 
  58         super.onCreate(savedInstanceState);
 
  60         final SharedPreferences sharedPreferences = PreferenceManager
 
  61                 .getDefaultSharedPreferences(this.getActivity());
 
  62         final String keyPreference = this.getResources().getString(
 
  63                 R.string.weather_preferences_day_forecast_key);
 
  64         this.mDayForecast = sharedPreferences.getString(keyPreference, "");
 
  66         this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
 
  67         this.mWeatherServicePersistenceFile.removeForecastWeatherData();
 
  71     public void onActivityCreated(final Bundle savedInstanceState) {
 
  72         super.onActivityCreated(savedInstanceState);
 
  74         final ListView listWeatherView = this.getListView();
 
  75         listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
 
  77         if (savedInstanceState != null) {
 
  79             final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState
 
  80                     .getSerializable("ForecastWeatherData");
 
  82             if (forecastWeatherData != null) {
 
  84                     this.mWeatherServicePersistenceFile
 
  85                     .storeForecastWeatherData(forecastWeatherData);
 
  86                 } catch (final IOException e) {
 
  87                     final DialogFragment newFragment = ErrorDialogFragment
 
  88                             .newInstance(R.string.error_dialog_generic_error);
 
  89                     newFragment.show(this.getFragmentManager(), "errorDialog");
 
  93             this.mListState = savedInstanceState.getParcelable("ListState");
 
  96         this.setHasOptionsMenu(false);
 
  98         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(
 
  99                 this.getActivity(), R.layout.weather_main_entry_list);
 
 102         this.setEmptyText("Press download to receive weather information");
 
 104         this.setListAdapter(adapter);
 
 105         this.setListShown(true);
 
 106         this.setListShownNoAnimation(true);
 
 110     public void onListItemClick(final ListView l, final View v, final int position, final long id) {
 
 111         final WeatherInformationSpecificDataFragment fragment = (WeatherInformationSpecificDataFragment) this.getFragmentManager()
 
 112                 .findFragmentById(R.id.weather_specific_data__fragment);
 
 113         if (fragment == null) {
 
 115             final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO").
 
 116                     setComponent(new ComponentName("de.example.exampletdd",
 
 117                             "de.example.exampletdd.WeatherInformationSpecificDataActivity"));
 
 118             intent.putExtra("CHOSEN_DAY", (int) id);
 
 119             WeatherInformationOverviewFragment.this.getActivity().startActivity(intent);
 
 122             fragment.getWeatherByDay((int) id);
 
 127     public void onSaveInstanceState(final Bundle savedInstanceState) {
 
 130         final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
 
 131                 .getForecastWeatherData();
 
 133         if (forecastWeatherData != null) {
 
 134             savedInstanceState.putSerializable("ForecastWeatherData", forecastWeatherData);
 
 137         this.mListState = this.getListView().onSaveInstanceState();
 
 138         savedInstanceState.putParcelable("ListState", this.mListState);
 
 140         super.onSaveInstanceState(savedInstanceState);
 
 144     public void getRemoteWeatherInformation() {
 
 146         final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
 
 148         if (geocodingData != null) {
 
 149             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
 
 150             final WeatherServiceParser weatherService = new WeatherServiceParser(
 
 152             final AndroidHttpClient httpClient = AndroidHttpClient
 
 153                     .newInstance("Android Weather Information Agent");
 
 154             final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(
 
 157             final ForecastWeatherTask weatherTask = new ForecastWeatherTask(HTTPweatherClient,
 
 161             weatherTask.execute(geocodingData);
 
 166     public void getWeatherByDay(final int chosenDay) {
 
 170     public void updateForecastWeatherData(final ForecastWeatherData forecastWeatherData) {
 
 171         final List<WeatherOverviewEntry> entries = new ArrayList<WeatherOverviewEntry>();
 
 172         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(this.getActivity(),
 
 173                 R.layout.weather_main_entry_list);
 
 176         final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.getDefault());
 
 177         tempFormatter.applyPattern("#####.##");
 
 178         final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.getDefault());
 
 179         final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d",
 
 180                 Locale.getDefault());
 
 181         final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
 
 182         final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
 
 185         final Calendar calendar = Calendar.getInstance();
 
 186         for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData
 
 191             if ((forecast.getWeather().size() > 0) &&
 
 192                     (forecast.getWeather().get(0).getIcon() != null) &&
 
 193                     (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) {
 
 194                 final String icon = forecast.getWeather().get(0).getIcon();
 
 195                 picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
 
 196                         .getResourceDrawable());
 
 198                 picture = BitmapFactory.decodeResource(this.getResources(),
 
 199                         R.drawable.weather_severe_alert);
 
 202             final Long forecastUNIXDate = (Long) forecast.getDt();
 
 203             calendar.setTimeInMillis(forecastUNIXDate * 1000L);
 
 204             final Date dayTime = calendar.getTime();
 
 205             final String dayTextName = dayNameFormatter.format(dayTime);
 
 206             final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime);
 
 208             Double maxTemp = null;
 
 209             if (forecast.getTemp().getMax() != null) {
 
 210                 maxTemp = (Double) forecast.getTemp().getMax();
 
 211                 maxTemp = maxTemp - tempUnits;
 
 214             Double minTemp = null;
 
 215             if (forecast.getTemp().getMin() != null) {
 
 216                 minTemp = (Double) forecast.getTemp().getMin();
 
 217                 minTemp = minTemp - tempUnits;
 
 220             if ((maxTemp != null) && (minTemp != null)) {
 
 221                 entries.add(new WeatherOverviewEntry(dayTextName, monthAndDayNumberText,
 
 222                         tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol,
 
 227         this.setListAdapter(null);
 
 228         adapter.addAll(entries);
 
 229         this.setListAdapter(adapter);
 
 233     public void onResume() {
 
 236         final SharedPreferences sharedPreferences = PreferenceManager
 
 237                 .getDefaultSharedPreferences(this.getActivity());
 
 239         // 1. Update units of measurement.
 
 240         String keyPreference = this.getResources().getString(
 
 241                 R.string.weather_preferences_units_key);
 
 242         final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
 
 243         final String celsius = this.getResources().getString(
 
 244                 R.string.weather_preferences_units_celsius);
 
 245         if (unitsPreferenceValue.equals(celsius)) {
 
 246             this.mIsFahrenheit = false;
 
 248             this.mIsFahrenheit = true;
 
 251         // 2. Update number day forecast.
 
 252         keyPreference = this.getResources().getString(
 
 253                 R.string.weather_preferences_day_forecast_key);
 
 254         this.mDayForecast = sharedPreferences.getString(keyPreference, "");
 
 257         // 3. Update forecast weather data on display.
 
 258         final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
 
 259                 .getForecastWeatherData();
 
 260         if ((this.mListState != null) && (forecastWeatherData != null)) {
 
 261             this.updateForecastWeatherData(forecastWeatherData);
 
 262             this.getListView().onRestoreInstanceState(this.mListState);
 
 263         } else if (forecastWeatherData != null) {
 
 264             this.updateForecastWeatherData(forecastWeatherData);
 
 269     public class ForecastWeatherTask extends AsyncTask<Object, Void, ForecastWeatherData> {
 
 270         private static final String TAG = "ForecastWeatherTask";
 
 271         private final CustomHTTPClient weatherHTTPClient;
 
 272         private final WeatherServiceParser weatherService;
 
 273         private final DialogFragment newFragment;
 
 275         public ForecastWeatherTask(final CustomHTTPClient weatherHTTPClient,
 
 276                 final WeatherServiceParser weatherService) {
 
 277             this.weatherHTTPClient = weatherHTTPClient;
 
 278             this.weatherService = weatherService;
 
 279             this.newFragment = ProgressDialogFragment.newInstance(
 
 280                     R.string.progress_dialog_get_remote_data,
 
 281                     WeatherInformationOverviewFragment.this
 
 282                     .getString(R.string.progress_dialog_generic_message));
 
 286         protected void onPreExecute() {
 
 287             this.newFragment.show(WeatherInformationOverviewFragment.this.getActivity()
 
 288                     .getFragmentManager(), "progressDialog");
 
 292         protected ForecastWeatherData doInBackground(final Object... params) {
 
 293             ForecastWeatherData forecastWeatherData = null;
 
 296                 forecastWeatherData = this.doInBackgroundThrowable(params);
 
 297             } catch (final ClientProtocolException e) {
 
 298                 Log.e(TAG, "doInBackground exception: ", e);
 
 299             } catch (final MalformedURLException e) {
 
 300                 Log.e(TAG, "doInBackground exception: ", e);
 
 301             } catch (final URISyntaxException e) {
 
 302                 Log.e(TAG, "doInBackground exception: ", e);
 
 303             } catch (final JsonParseException e) {
 
 304                 Log.e(TAG, "doInBackground exception: ", e);
 
 305             } catch (final IOException e) {
 
 306                 // logger infrastructure swallows UnknownHostException :/
 
 307                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
 
 309                 this.weatherHTTPClient.close();
 
 312             return forecastWeatherData;
 
 316         protected void onPostExecute(final ForecastWeatherData weatherData) {
 
 317             this.weatherHTTPClient.close();
 
 319             this.newFragment.dismiss();
 
 321             if (weatherData != null) {
 
 323                     this.onPostExecuteThrowable(weatherData);
 
 324                 } catch (final IOException e) {
 
 325                     Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
 
 326                     final DialogFragment newFragment = ErrorDialogFragment
 
 327                             .newInstance(R.string.error_dialog_generic_error);
 
 328                     newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
 
 331                 final DialogFragment newFragment = ErrorDialogFragment
 
 332                         .newInstance(R.string.error_dialog_generic_error);
 
 333                 newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
 
 338         protected void onCancelled(final ForecastWeatherData weatherData) {
 
 339             this.weatherHTTPClient.close();
 
 341             final DialogFragment newFragment = ErrorDialogFragment
 
 342                     .newInstance(R.string.error_dialog_connection_tiemout);
 
 343             newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
 
 346         private ForecastWeatherData doInBackgroundThrowable(final Object... params)
 
 347                 throws ClientProtocolException, MalformedURLException,
 
 348                 URISyntaxException, JsonParseException, IOException {
 
 351             final GeocodingData geocodingData = (GeocodingData) params[0];
 
 354             final String APIVersion = WeatherInformationOverviewFragment.this.getResources()
 
 355                     .getString(R.string.api_version);
 
 357             final String urlAPI = WeatherInformationOverviewFragment.this.getResources()
 
 358                     .getString(R.string.uri_api_weather_forecast);
 
 359             final String url = this.weatherService.createURIAPIForecastWeather(urlAPI, APIVersion,
 
 360                     geocodingData.getLatitude(), geocodingData.getLongitude(), WeatherInformationOverviewFragment.this.mDayForecast);
 
 361             final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
 
 362             final ForecastWeatherData forecastWeatherData = this.weatherService
 
 363                     .retrieveForecastWeatherDataFromJPOS(jsonData);
 
 365             return forecastWeatherData;
 
 368         private void onPostExecuteThrowable(final ForecastWeatherData forecastWeatherData)
 
 369                 throws FileNotFoundException, IOException {
 
 370             WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile
 
 371             .storeForecastWeatherData(forecastWeatherData);
 
 373             WeatherInformationOverviewFragment.this.updateForecastWeatherData(forecastWeatherData);