8168e2379c38ff982ddacc72f9db25f937e63a28
[JavaForFun] /
1 package de.example.exampletdd.fragment.overview;
2
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5 import java.net.MalformedURLException;
6 import java.net.URISyntaxException;
7 import java.net.URL;
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;
16
17 import org.apache.http.client.ClientProtocolException;
18
19 import android.app.DialogFragment;
20 import android.content.SharedPreferences;
21 import android.graphics.Bitmap;
22 import android.graphics.BitmapFactory;
23 import android.net.http.AndroidHttpClient;
24 import android.os.AsyncTask;
25 import android.os.Bundle;
26 import android.os.Parcelable;
27 import android.preference.PreferenceManager;
28 import android.support.v4.app.ListFragment;
29 import android.util.Log;
30 import android.view.View;
31 import android.widget.ListView;
32
33 import com.fasterxml.jackson.core.JsonParseException;
34
35 import de.example.exampletdd.R;
36 import de.example.exampletdd.activityinterface.GetWeather;
37 import de.example.exampletdd.fragment.ProgressDialogFragment;
38 import de.example.exampletdd.httpclient.CustomHTTPClient;
39 import de.example.exampletdd.model.GeocodingData;
40 import de.example.exampletdd.model.forecastweather.ForecastWeatherData;
41 import de.example.exampletdd.parser.IJPOSWeatherParser;
42 import de.example.exampletdd.parser.JPOSWeatherParser;
43 import de.example.exampletdd.service.WeatherServiceParser;
44 import de.example.exampletdd.service.WeatherServicePersistenceFile;
45
46 public class WeatherInformationOverviewFragment extends ListFragment implements GetWeather {
47     private boolean mIsFahrenheit;
48     private String mDayForecast;
49     private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
50     private Parcelable mListState;
51
52     @Override
53     public void onCreate(final Bundle savedInstanceState) {
54         super.onCreate(savedInstanceState);
55
56         final SharedPreferences sharedPreferences = PreferenceManager
57                 .getDefaultSharedPreferences(this.getActivity());
58         final String keyPreference = this.getResources().getString(
59                 R.string.weather_preferences_day_forecast_key);
60         this.mDayForecast = sharedPreferences.getString(keyPreference, "");
61
62         this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
63         this.mWeatherServicePersistenceFile.removeForecastWeatherData();
64     }
65
66     @Override
67     public void onActivityCreated(final Bundle savedInstanceState) {
68         super.onActivityCreated(savedInstanceState);
69
70         final ListView listWeatherView = this.getListView();
71         listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
72
73         if (savedInstanceState != null) {
74             // Restore state
75             final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState
76                     .getSerializable("ForecastWeatherData");
77
78             if (forecastWeatherData != null) {
79                 try {
80                     this.mWeatherServicePersistenceFile
81                     .storeForecastWeatherData(forecastWeatherData);
82                 } catch (final IOException e) {
83                     //                    final DialogFragment newFragment = ErrorDialogFragment
84                     //                            .newInstance(R.string.error_dialog_generic_error);
85                     //                    newFragment.show(this.getFragmentManager(), "errorDialog");
86                 }
87             }
88
89             this.mListState = savedInstanceState.getParcelable("ListState");
90         }
91
92         this.setHasOptionsMenu(false);
93
94         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(
95                 this.getActivity(), R.layout.weather_main_entry_list);
96
97
98         this.setEmptyText("Press download to receive weather information");
99
100         this.setListAdapter(adapter);
101         this.setListShown(true);
102         this.setListShownNoAnimation(true);
103     }
104
105     @Override
106     public void onListItemClick(final ListView l, final View v, final int position, final long id) {
107         //        final WeatherInformationSpecificDataFragment fragment = (WeatherInformationSpecificDataFragment) this.getFragmentManager()
108         //                .findFragmentById(R.id.weather_specific_data__fragment);
109         //        if (fragment == null) {
110         //            // handset layout
111         //            final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO").
112         //                    setComponent(new ComponentName("de.example.exampletdd",
113         //                            "de.example.exampletdd.WeatherInformationSpecificDataActivity"));
114         //            intent.putExtra("CHOSEN_DAY", (int) id);
115         //            WeatherInformationOverviewFragment.this.getActivity().startActivity(intent);
116         //        } else {
117         //            // tablet layout
118         //            fragment.getWeatherByDay((int) id);
119         //        }
120     }
121
122     @Override
123     public void onSaveInstanceState(final Bundle savedInstanceState) {
124
125         // Save state
126         final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
127                 .getForecastWeatherData();
128
129         if (forecastWeatherData != null) {
130             savedInstanceState.putSerializable("ForecastWeatherData", forecastWeatherData);
131         }
132
133         this.mListState = this.getListView().onSaveInstanceState();
134         savedInstanceState.putParcelable("ListState", this.mListState);
135
136         super.onSaveInstanceState(savedInstanceState);
137     }
138
139     @Override
140     public void getRemoteWeatherInformation() {
141
142         final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
143
144         if (geocodingData != null) {
145             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
146             final WeatherServiceParser weatherService = new WeatherServiceParser(
147                     JPOSWeatherParser);
148             final AndroidHttpClient httpClient = AndroidHttpClient
149                     .newInstance("Android Weather Information Agent");
150             final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(
151                     httpClient);
152
153             final ForecastWeatherTask weatherTask = new ForecastWeatherTask(HTTPweatherClient,
154                     weatherService);
155
156
157             weatherTask.execute(geocodingData);
158         }
159     }
160
161     @Override
162     public void getWeatherByDay(final int chosenDay) {
163         // Nothing to do.
164     }
165
166     public void updateForecastWeatherData(final ForecastWeatherData forecastWeatherData) {
167         final List<WeatherOverviewEntry> entries = new ArrayList<WeatherOverviewEntry>();
168         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(this.getActivity(),
169                 R.layout.weather_main_entry_list);
170
171
172         final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
173         tempFormatter.applyPattern("#####.##");
174         final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.US);
175         final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d", Locale.US);
176         final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
177         final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
178
179
180         final Calendar calendar = Calendar.getInstance();
181         for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData
182                 .getList()) {
183
184             Bitmap picture;
185
186             if ((forecast.getWeather().size() > 0) &&
187                     (forecast.getWeather().get(0).getIcon() != null) &&
188                     (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) {
189                 final String icon = forecast.getWeather().get(0).getIcon();
190                 picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
191                         .getResourceDrawable());
192             } else {
193                 picture = BitmapFactory.decodeResource(this.getResources(),
194                         R.drawable.weather_severe_alert);
195             }
196
197             final Long forecastUNIXDate = (Long) forecast.getDt();
198             calendar.setTimeInMillis(forecastUNIXDate * 1000L);
199             final Date dayTime = calendar.getTime();
200             final String dayTextName = dayNameFormatter.format(dayTime);
201             final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime);
202
203             Double maxTemp = null;
204             if (forecast.getTemp().getMax() != null) {
205                 maxTemp = (Double) forecast.getTemp().getMax();
206                 maxTemp = maxTemp - tempUnits;
207             }
208
209             Double minTemp = null;
210             if (forecast.getTemp().getMin() != null) {
211                 minTemp = (Double) forecast.getTemp().getMin();
212                 minTemp = minTemp - tempUnits;
213             }
214
215             if ((maxTemp != null) && (minTemp != null)) {
216                 entries.add(new WeatherOverviewEntry(dayTextName, monthAndDayNumberText,
217                         tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol,
218                         picture));
219             }
220         }
221
222         this.setListAdapter(null);
223         adapter.addAll(entries);
224         this.setListAdapter(adapter);
225     }
226
227     @Override
228     public void onResume() {
229         super.onResume();
230
231         final SharedPreferences sharedPreferences = PreferenceManager
232                 .getDefaultSharedPreferences(this.getActivity());
233
234         // 1. Update units of measurement.
235         String keyPreference = this.getResources().getString(
236                 R.string.weather_preferences_units_key);
237         final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
238         final String celsius = this.getResources().getString(
239                 R.string.weather_preferences_units_celsius);
240         if (unitsPreferenceValue.equals(celsius)) {
241             this.mIsFahrenheit = false;
242         } else {
243             this.mIsFahrenheit = true;
244         }
245
246         // 2. Update number day forecast.
247         keyPreference = this.getResources().getString(
248                 R.string.weather_preferences_day_forecast_key);
249         this.mDayForecast = sharedPreferences.getString(keyPreference, "");
250
251
252         // 3. Update forecast weather data on display.
253         final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
254                 .getForecastWeatherData();
255         if ((this.mListState != null) && (forecastWeatherData != null)) {
256             this.updateForecastWeatherData(forecastWeatherData);
257             this.getListView().onRestoreInstanceState(this.mListState);
258         } else if (forecastWeatherData != null) {
259             this.updateForecastWeatherData(forecastWeatherData);
260         }
261
262     }
263
264     public class ForecastWeatherTask extends AsyncTask<Object, Void, ForecastWeatherData> {
265         private static final String TAG = "ForecastWeatherTask";
266         private final CustomHTTPClient weatherHTTPClient;
267         private final WeatherServiceParser weatherService;
268         private final DialogFragment newFragment;
269
270         public ForecastWeatherTask(final CustomHTTPClient weatherHTTPClient,
271                 final WeatherServiceParser weatherService) {
272             this.weatherHTTPClient = weatherHTTPClient;
273             this.weatherService = weatherService;
274             this.newFragment = ProgressDialogFragment.newInstance(
275                     R.string.progress_dialog_get_remote_data,
276                     WeatherInformationOverviewFragment.this
277                     .getString(R.string.progress_dialog_generic_message));
278         }
279
280         @Override
281         protected void onPreExecute() {
282             this.newFragment.show(WeatherInformationOverviewFragment.this.getActivity()
283                     .getFragmentManager(), "progressDialog");
284         }
285
286         @Override
287         protected ForecastWeatherData doInBackground(final Object... params) {
288             ForecastWeatherData forecastWeatherData = null;
289
290             try {
291                 forecastWeatherData = this.doInBackgroundThrowable(params);
292             } catch (final ClientProtocolException e) {
293                 Log.e(TAG, "doInBackground exception: ", e);
294             } catch (final MalformedURLException e) {
295                 Log.e(TAG, "doInBackground exception: ", e);
296             } catch (final URISyntaxException e) {
297                 Log.e(TAG, "doInBackground exception: ", e);
298             } catch (final JsonParseException e) {
299                 Log.e(TAG, "doInBackground exception: ", e);
300             } catch (final IOException e) {
301                 // logger infrastructure swallows UnknownHostException :/
302                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
303             } finally {
304                 this.weatherHTTPClient.close();
305             }
306
307             return forecastWeatherData;
308         }
309
310         @Override
311         protected void onPostExecute(final ForecastWeatherData weatherData) {
312             this.weatherHTTPClient.close();
313
314             this.newFragment.dismiss();
315
316             if (weatherData != null) {
317                 try {
318                     this.onPostExecuteThrowable(weatherData);
319                 } catch (final IOException e) {
320                     Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
321                     //                    final DialogFragment newFragment = ErrorDialogFragment
322                     //                            .newInstance(R.string.error_dialog_generic_error);
323                     //                    newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
324                 }
325             } else {
326                 //                final DialogFragment newFragment = ErrorDialogFragment
327                 //                        .newInstance(R.string.error_dialog_generic_error);
328                 //                newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
329             }
330         }
331
332         @Override
333         protected void onCancelled(final ForecastWeatherData weatherData) {
334             this.weatherHTTPClient.close();
335
336             //            final DialogFragment newFragment = ErrorDialogFragment
337             //                    .newInstance(R.string.error_dialog_connection_tiemout);
338             //            newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
339         }
340
341         private ForecastWeatherData doInBackgroundThrowable(final Object... params)
342                 throws ClientProtocolException, MalformedURLException,
343                 URISyntaxException, JsonParseException, IOException {
344
345             // 1. Coordinates
346             final GeocodingData geocodingData = (GeocodingData) params[0];
347
348
349             final String APIVersion = WeatherInformationOverviewFragment.this.getResources()
350                     .getString(R.string.api_version);
351             // 2. Forecast
352             final String urlAPI = WeatherInformationOverviewFragment.this.getResources()
353                     .getString(R.string.uri_api_weather_forecast);
354             final String url = this.weatherService.createURIAPIForecastWeather(urlAPI, APIVersion,
355                     geocodingData.getLatitude(), geocodingData.getLongitude(), WeatherInformationOverviewFragment.this.mDayForecast);
356             final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
357             final ForecastWeatherData forecastWeatherData = this.weatherService
358                     .retrieveForecastWeatherDataFromJPOS(jsonData);
359
360             return forecastWeatherData;
361         }
362
363         private void onPostExecuteThrowable(final ForecastWeatherData forecastWeatherData)
364                 throws FileNotFoundException, IOException {
365             WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile
366             .storeForecastWeatherData(forecastWeatherData);
367
368             WeatherInformationOverviewFragment.this.updateForecastWeatherData(forecastWeatherData);
369         }
370     }
371 }