9d4a579341cd419b1f5eae384c626b24395b8d1a
[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.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.preference.PreferenceManager;
30 import android.util.Log;
31 import android.view.View;
32 import android.widget.ListView;
33
34 import com.fasterxml.jackson.core.JsonParseException;
35
36 import de.example.exampletdd.R;
37 import de.example.exampletdd.activityinterface.GetWeather;
38 import de.example.exampletdd.fragment.ErrorDialogFragment;
39 import de.example.exampletdd.fragment.ProgressDialogFragment;
40 import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment;
41 import de.example.exampletdd.httpclient.CustomHTTPClient;
42 import de.example.exampletdd.model.GeocodingData;
43 import de.example.exampletdd.model.forecastweather.ForecastWeatherData;
44 import de.example.exampletdd.parser.IJPOSWeatherParser;
45 import de.example.exampletdd.parser.JPOSWeatherParser;
46 import de.example.exampletdd.service.WeatherServiceParser;
47 import de.example.exampletdd.service.WeatherServicePersistenceFile;
48
49 public class WeatherInformationOverviewFragment extends ListFragment implements GetWeather {
50     private boolean mIsFahrenheit;
51     private String mDayForecast;
52     private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
53
54     @Override
55     public void onCreate(final Bundle savedInstanceState) {
56         super.onCreate(savedInstanceState);
57
58         final SharedPreferences sharedPreferences = PreferenceManager
59                 .getDefaultSharedPreferences(this.getActivity());
60         final String keyPreference = this.getResources().getString(
61                 R.string.weather_preferences_day_forecast_key);
62         this.mDayForecast = sharedPreferences.getString(keyPreference, "");
63
64         this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
65         this.mWeatherServicePersistenceFile.removeForecastWeatherData();
66     }
67
68     @Override
69     public void onActivityCreated(final Bundle savedInstanceState) {
70         super.onActivityCreated(savedInstanceState);
71
72         final ListView listWeatherView = this.getListView();
73         listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
74
75         if (savedInstanceState != null) {
76             // Restore state
77             final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState
78                     .getSerializable("ForecastWeatherData");
79
80             if (forecastWeatherData != null) {
81                 try {
82                     this.mWeatherServicePersistenceFile
83                     .storeForecastWeatherData(forecastWeatherData);
84                 } catch (final IOException e) {
85                     final DialogFragment newFragment = ErrorDialogFragment
86                             .newInstance(R.string.error_dialog_generic_error);
87                     newFragment.show(this.getFragmentManager(), "errorDialog");
88                 }
89             }
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         super.onSaveInstanceState(savedInstanceState);
134     }
135
136     @Override
137     public void getRemoteWeatherInformation() {
138
139         final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
140
141         if (geocodingData != null) {
142             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
143             final WeatherServiceParser weatherService = new WeatherServiceParser(
144                     JPOSWeatherParser);
145             final AndroidHttpClient httpClient = AndroidHttpClient
146                     .newInstance("Android Weather Information Agent");
147             final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(
148                     httpClient);
149
150             final ForecastWeatherTask weatherTask = new ForecastWeatherTask(HTTPweatherClient,
151                     weatherService);
152
153
154             weatherTask.execute(geocodingData);
155         }
156     }
157
158     @Override
159     public void getWeatherByDay(final int chosenDay) {
160         // Nothing to do.
161     }
162
163     public void updateForecastWeatherData(final ForecastWeatherData forecastWeatherData) {
164         final List<WeatherOverviewEntry> entries = new ArrayList<WeatherOverviewEntry>();
165         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(this.getActivity(),
166                 R.layout.weather_main_entry_list);
167
168
169         final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.getDefault());
170         tempFormatter.applyPattern("#####.##");
171         final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.getDefault());
172         final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d",
173                 Locale.getDefault());
174         final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
175         final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
176
177
178         final Calendar calendar = Calendar.getInstance();
179         for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData
180                 .getList()) {
181
182             Bitmap picture;
183
184             if ((forecast.getWeather().size() > 0) &&
185                     (forecast.getWeather().get(0).getIcon() != null) &&
186                     (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) {
187                 final String icon = forecast.getWeather().get(0).getIcon();
188                 picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
189                         .getResourceDrawable());
190             } else {
191                 picture = BitmapFactory.decodeResource(this.getResources(),
192                         R.drawable.weather_severe_alert);
193             }
194
195             final Long forecastUNIXDate = (Long) forecast.getDt();
196             calendar.setTimeInMillis(forecastUNIXDate * 1000L);
197             final Date dayTime = calendar.getTime();
198             final String dayTextName = dayNameFormatter.format(dayTime);
199             final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime);
200
201             Double maxTemp = null;
202             if (forecast.getTemp().getMax() != null) {
203                 maxTemp = (Double) forecast.getTemp().getMax();
204                 maxTemp = maxTemp - tempUnits;
205             }
206
207             Double minTemp = null;
208             if (forecast.getTemp().getMin() != null) {
209                 minTemp = (Double) forecast.getTemp().getMin();
210                 minTemp = minTemp - tempUnits;
211             }
212
213             if ((maxTemp != null) && (minTemp != null)) {
214                 entries.add(new WeatherOverviewEntry(dayTextName, monthAndDayNumberText,
215                         tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol,
216                         picture));
217             }
218         }
219
220         this.setListAdapter(null);
221         adapter.addAll(entries);
222         this.setListAdapter(adapter);
223     }
224
225     @Override
226     public void onResume() {
227         super.onResume();
228
229         final SharedPreferences sharedPreferences = PreferenceManager
230                 .getDefaultSharedPreferences(this.getActivity());
231
232         // 1. Update units of measurement.
233         String keyPreference = this.getResources().getString(
234                 R.string.weather_preferences_units_key);
235         final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
236         final String celsius = this.getResources().getString(
237                 R.string.weather_preferences_units_celsius);
238         if (unitsPreferenceValue.equals(celsius)) {
239             this.mIsFahrenheit = false;
240         } else {
241             this.mIsFahrenheit = true;
242         }
243
244         // 2. Update number day forecast.
245         keyPreference = this.getResources().getString(
246                 R.string.weather_preferences_day_forecast_key);
247         this.mDayForecast = sharedPreferences.getString(keyPreference, "");
248
249
250         // 3. Update forecast weather data on display.
251         final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
252                 .getForecastWeatherData();
253         if (forecastWeatherData != null) {
254             this.updateForecastWeatherData(forecastWeatherData);
255         }
256
257     }
258
259     public class ForecastWeatherTask extends AsyncTask<Object, Void, ForecastWeatherData> {
260         private static final String TAG = "ForecastWeatherTask";
261         private final CustomHTTPClient weatherHTTPClient;
262         private final WeatherServiceParser weatherService;
263         private final DialogFragment newFragment;
264
265         public ForecastWeatherTask(final CustomHTTPClient weatherHTTPClient,
266                 final WeatherServiceParser weatherService) {
267             this.weatherHTTPClient = weatherHTTPClient;
268             this.weatherService = weatherService;
269             this.newFragment = ProgressDialogFragment.newInstance(
270                     R.string.progress_dialog_get_remote_data,
271                     WeatherInformationOverviewFragment.this
272                     .getString(R.string.progress_dialog_generic_message));
273         }
274
275         @Override
276         protected void onPreExecute() {
277             this.newFragment.show(WeatherInformationOverviewFragment.this.getActivity()
278                     .getFragmentManager(), "progressDialog");
279         }
280
281         @Override
282         protected ForecastWeatherData doInBackground(final Object... params) {
283             ForecastWeatherData forecastWeatherData = null;
284
285             try {
286                 forecastWeatherData = this.doInBackgroundThrowable(params);
287             } catch (final ClientProtocolException e) {
288                 Log.e(TAG, "doInBackground exception: ", e);
289             } catch (final MalformedURLException e) {
290                 Log.e(TAG, "doInBackground exception: ", e);
291             } catch (final URISyntaxException e) {
292                 Log.e(TAG, "doInBackground exception: ", e);
293             } catch (final JsonParseException e) {
294                 Log.e(TAG, "doInBackground exception: ", e);
295             } catch (final IOException e) {
296                 // logger infrastructure swallows UnknownHostException :/
297                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
298             } finally {
299                 this.weatherHTTPClient.close();
300             }
301
302             return forecastWeatherData;
303         }
304
305         @Override
306         protected void onPostExecute(final ForecastWeatherData weatherData) {
307             this.weatherHTTPClient.close();
308
309             this.newFragment.dismiss();
310
311             if (weatherData != null) {
312                 try {
313                     this.onPostExecuteThrowable(weatherData);
314                 } catch (final IOException e) {
315                     Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
316                     final DialogFragment newFragment = ErrorDialogFragment
317                             .newInstance(R.string.error_dialog_generic_error);
318                     newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
319                 }
320             } else {
321                 final DialogFragment newFragment = ErrorDialogFragment
322                         .newInstance(R.string.error_dialog_generic_error);
323                 newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
324             }
325         }
326
327         @Override
328         protected void onCancelled(final ForecastWeatherData weatherData) {
329             this.weatherHTTPClient.close();
330
331             final DialogFragment newFragment = ErrorDialogFragment
332                     .newInstance(R.string.error_dialog_connection_tiemout);
333             newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
334         }
335
336         private ForecastWeatherData doInBackgroundThrowable(final Object... params)
337                 throws ClientProtocolException, MalformedURLException,
338                 URISyntaxException, JsonParseException, IOException {
339             // final SharedPreferences sharedPreferences = PreferenceManager
340             // .getDefaultSharedPreferences(WeatherInformationOverviewFragment.this
341             // .getActivity());
342             //
343             // final String keyPreference =
344             // WeatherInformationOverviewFragment.this
345             // .getActivity().getString(
346             // R.string.weather_preferences_language_key);
347             // final String languagePreferenceValue =
348             // sharedPreferences.getString(keyPreference, "");
349
350             // 1. Coordinates
351             final GeocodingData geocodingData = (GeocodingData) params[0];
352
353
354             final String APIVersion = WeatherInformationOverviewFragment.this.getResources()
355                     .getString(R.string.api_version);
356             // 2. Forecast
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);
364
365             return forecastWeatherData;
366         }
367
368         private void onPostExecuteThrowable(final ForecastWeatherData forecastWeatherData)
369                 throws FileNotFoundException, IOException {
370             WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile
371             .storeForecastWeatherData(forecastWeatherData);
372
373             WeatherInformationOverviewFragment.this.updateForecastWeatherData(forecastWeatherData);
374         }
375     }
376 }