b122d8f4430ffaf265ebe4d460dd5fb9cac355b4
[JavaForFun] /
1 package de.example.exampletdd.fragment.current;
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.SharedPreferences;
22 import android.graphics.Bitmap;
23 import android.graphics.BitmapFactory;
24 import android.net.http.AndroidHttpClient;
25 import android.os.AsyncTask;
26 import android.os.Bundle;
27 import android.preference.PreferenceManager;
28 import android.util.Log;
29 import android.widget.ImageView;
30 import android.widget.ListView;
31
32 import com.fasterxml.jackson.core.JsonParseException;
33
34 import de.example.exampletdd.R;
35 import de.example.exampletdd.fragment.ErrorDialogFragment;
36 import de.example.exampletdd.fragment.ProgressDialogFragment;
37 import de.example.exampletdd.fragment.specific.WeatherSpecificDataAdapter;
38 import de.example.exampletdd.fragment.specific.WeatherSpecificDataEntry;
39 import de.example.exampletdd.httpclient.CustomHTTPClient;
40 import de.example.exampletdd.model.GeocodingData;
41 import de.example.exampletdd.model.currentweather.CurrentWeatherData;
42 import de.example.exampletdd.parser.IJPOSWeatherParser;
43 import de.example.exampletdd.parser.JPOSWeatherParser;
44 import de.example.exampletdd.service.WeatherServiceParser;
45 import de.example.exampletdd.service.WeatherServicePersistenceFile;
46
47 public class WeatherInformationCurrentDataFragment extends ListFragment {
48     private boolean mIsFahrenheit;
49     private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
50
51     @Override
52     public void onCreate(final Bundle savedInstanceState) {
53         super.onCreate(savedInstanceState);
54
55         // final SharedPreferences sharedPreferences = PreferenceManager
56         // .getDefaultSharedPreferences(this.getActivity());
57         // final String keyPreference = this.getResources().getString(
58         // R.string.weather_preferences_language_key);
59         // this.mLanguage = sharedPreferences.getString(
60         // keyPreference, "");
61
62         this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
63         this.mWeatherServicePersistenceFile.removeCurrentWeatherData();
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 CurrentWeatherData currentWeatherData = (CurrentWeatherData) savedInstanceState
76                     .getSerializable("CurrentWeatherData");
77
78             if (currentWeatherData != null) {
79                 try {
80                     this.mWeatherServicePersistenceFile.storeCurrentWeatherData(currentWeatherData);
81                 } catch (final IOException e) {
82                     final DialogFragment newFragment = ErrorDialogFragment
83                             .newInstance(R.string.error_dialog_generic_error);
84                     newFragment.show(this.getFragmentManager(), "errorDialog");
85                 }
86             }
87         }
88
89         this.setHasOptionsMenu(false);
90
91         final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter(
92                 this.getActivity(), R.layout.weather_data_entry_list);
93
94
95         this.setEmptyText("No data available");
96
97         this.setListAdapter(adapter);
98         this.setListShown(true);
99         this.setListShownNoAnimation(true);
100
101     }
102
103     @Override
104     public void onResume() {
105         super.onResume();
106
107         final SharedPreferences sharedPreferences = PreferenceManager
108                 .getDefaultSharedPreferences(this.getActivity());
109
110         // 1. Update units of measurement.
111         final String keyPreference = this.getResources().getString(
112                 R.string.weather_preferences_units_key);
113         final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
114         final String celsius = this.getResources().getString(
115                 R.string.weather_preferences_units_celsius);
116         if (unitsPreferenceValue.equals(celsius)) {
117             this.mIsFahrenheit = false;
118         } else {
119             this.mIsFahrenheit = true;
120         }
121
122         // 2. Try to restore old information
123         final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
124                 .getCurrentWeatherData();
125         if (currentWeatherData != null) {
126             this.updateCurrentWeatherData(currentWeatherData);
127         } else {
128             // 2.1 Empty list by default
129             final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter(
130                     this.getActivity(), R.layout.weather_data_entry_list);
131             this.setListAdapter(adapter);
132
133             // 2.2. Try to update weather data on display with remote
134             // information.
135             this.getRemoteCurrentWeatherInformation();
136         }
137
138
139
140         // 3. If language changed, try to retrieve new data for new language
141         // (new strings with the chosen language)
142         // keyPreference = this.getResources().getString(
143         // R.string.weather_preferences_language_key);
144         // final String languagePreferenceValue = sharedPreferences.getString(
145         // keyPreference, "");
146         // if (!languagePreferenceValue.equals(this.mLanguage)) {
147         // this.mLanguage = languagePreferenceValue;
148         // this.getWeather();
149         // }
150     }
151
152     @Override
153     public void onSaveInstanceState(final Bundle savedInstanceState) {
154
155         // Save state
156         final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
157                 .getCurrentWeatherData();
158
159         if (currentWeatherData != null) {
160             savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData);
161         }
162
163         super.onSaveInstanceState(savedInstanceState);
164     }
165
166
167     public void updateCurrentWeatherData(final CurrentWeatherData currentWeatherData) {
168         final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale
169                 .getDefault());
170         tempFormatter.applyPattern("#####.#####");
171         final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z",
172                 Locale.getDefault());
173
174         final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
175
176         final List<WeatherSpecificDataEntry> entries = this.createEmptyEntriesList();
177
178         final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter(
179                 this.getActivity(), R.layout.weather_data_entry_list);
180
181         if (currentWeatherData.getWeather().size() > 0) {
182             entries.set(0,
183                     new WeatherSpecificDataEntry(this.getString(R.string.text_field_description),
184                             currentWeatherData.getWeather().get(0).getDescription()));
185         }
186
187         if (currentWeatherData.getMain().getTemp() != null) {
188             double conversion = (Double) currentWeatherData.getMain().getTemp();
189             conversion = conversion - tempUnits;
190             entries.set(1, new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem),
191                     tempFormatter.format(conversion)));
192         }
193
194         if (currentWeatherData.getMain().getTemp_max() != null) {
195             double conversion = (Double) currentWeatherData.getMain().getTemp_max();
196             conversion = conversion - tempUnits;
197             entries.set(2, new WeatherSpecificDataEntry(
198                     this.getString(R.string.text_field_tem_max), tempFormatter.format(conversion)));
199         }
200
201         if (currentWeatherData.getMain().getTemp_max() != null) {
202             double conversion = (Double) currentWeatherData.getMain().getTemp_min();
203             conversion = conversion - tempUnits;
204             entries.set(3, new WeatherSpecificDataEntry(
205                     this.getString(R.string.text_field_tem_min), tempFormatter.format(conversion)));
206         }
207
208         if (currentWeatherData.getSys().getSunrise() != null) {
209             final long unixTime = (Long) currentWeatherData.getSys().getSunrise();
210             final Date unixDate = new Date(unixTime * 1000L);
211             final String dateFormatUnix = dateFormat.format(unixDate);
212             entries.set(4,
213                     new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_rise),
214                             dateFormatUnix));
215         }
216
217         if (currentWeatherData.getSys().getSunset() != null) {
218             final long unixTime = (Long) currentWeatherData.getSys().getSunset();
219             final Date unixDate = new Date(unixTime * 1000L);
220             final String dateFormatUnix = dateFormat.format(unixDate);
221             entries.set(5, new WeatherSpecificDataEntry(
222                     this.getString(R.string.text_field_sun_set), dateFormatUnix));
223         }
224
225         if (currentWeatherData.getClouds().getAll() != null) {
226             final double cloudiness = (Double) currentWeatherData.getClouds().getAll();
227             entries.set(6,
228                     new WeatherSpecificDataEntry(this.getString(R.string.text_field_cloudiness),
229                             tempFormatter.format(cloudiness)));
230         }
231
232         if (currentWeatherData.getIconData() != null) {
233             final Bitmap icon = BitmapFactory.decodeByteArray(currentWeatherData.getIconData(), 0,
234                     currentWeatherData.getIconData().length);
235             final ImageView imageIcon = (ImageView) this.getActivity().findViewById(
236                     R.id.weather_picture);
237             imageIcon.setImageBitmap(icon);
238         }
239
240         adapter.addAll(entries);
241         this.setListAdapter(adapter);
242     }
243
244     public class CurrentWeatherTask extends AsyncTask<Object, Void, CurrentWeatherData> {
245         private static final String TAG = "WeatherTask";
246         private final CustomHTTPClient weatherHTTPClient;
247         private final WeatherServiceParser weatherService;
248         private final DialogFragment newFragment;
249
250         public CurrentWeatherTask(final CustomHTTPClient weatherHTTPClient,
251                 final WeatherServiceParser weatherService) {
252             this.weatherHTTPClient = weatherHTTPClient;
253             this.weatherService = weatherService;
254             this.newFragment = ProgressDialogFragment.newInstance(
255                     R.string.progress_dialog_get_remote_data,
256                     WeatherInformationCurrentDataFragment.this
257                     .getString(R.string.progress_dialog_generic_message));
258         }
259
260         @Override
261         protected void onPreExecute() {
262             this.newFragment.show(WeatherInformationCurrentDataFragment.this.getActivity()
263                     .getFragmentManager(), "progressDialog");
264         }
265
266         @Override
267         protected CurrentWeatherData doInBackground(final Object... params) {
268             CurrentWeatherData currentWeatherData = null;
269
270             try {
271                 currentWeatherData = this.doInBackgroundThrowable(params);
272             } catch (final ClientProtocolException e) {
273                 Log.e(TAG, "doInBackground exception: ", e);
274             } catch (final MalformedURLException e) {
275                 Log.e(TAG, "doInBackground exception: ", e);
276             } catch (final URISyntaxException e) {
277                 Log.e(TAG, "doInBackground exception: ", e);
278             } catch (final JsonParseException e) {
279                 Log.e(TAG, "doInBackground exception: ", e);
280             } catch (final IOException e) {
281                 // logger infrastructure swallows UnknownHostException :/
282                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
283             } finally {
284                 this.weatherHTTPClient.close();
285             }
286
287             return currentWeatherData;
288         }
289
290         @Override
291         protected void onPostExecute(final CurrentWeatherData currentWeatherData) {
292             this.weatherHTTPClient.close();
293
294             this.newFragment.dismiss();
295
296             if (currentWeatherData != null) {
297                 try {
298                     this.onPostExecuteThrowable(currentWeatherData);
299                 } catch (final IOException e) {
300                     Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
301                     final DialogFragment newFragment = ErrorDialogFragment
302                             .newInstance(R.string.error_dialog_generic_error);
303                     newFragment.show(
304                             WeatherInformationCurrentDataFragment.this.getFragmentManager(),
305                             "errorDialog");
306                 }
307             } else {
308                 final DialogFragment newFragment = ErrorDialogFragment
309                         .newInstance(R.string.error_dialog_generic_error);
310                 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
311                         "errorDialog");
312             }
313         }
314
315         @Override
316         protected void onCancelled(final CurrentWeatherData currentWeatherData) {
317             this.weatherHTTPClient.close();
318
319             final DialogFragment newFragment = ErrorDialogFragment
320                     .newInstance(R.string.error_dialog_connection_tiemout);
321             newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
322                     "errorDialog");
323         }
324
325         private CurrentWeatherData doInBackgroundThrowable(final Object... params)
326                 throws ClientProtocolException, MalformedURLException, URISyntaxException,
327                 JsonParseException, IOException {
328             // final SharedPreferences sharedPreferences = PreferenceManager
329             // .getDefaultSharedPreferences(WeatherInformationCurrentDataFragment.this
330             // .getActivity());
331             //
332             // final String keyPreference =
333             // WeatherInformationCurrentDataFragment.this
334             // .getActivity().getString(
335             // R.string.weather_preferences_language_key);
336             // final String languagePreferenceValue =
337             // sharedPreferences.getString(keyPreference, "");
338
339             // 1. Coordinates
340             final GeocodingData geocodingData = (GeocodingData) params[0];
341
342             final String APIVersion = WeatherInformationCurrentDataFragment.this.getResources()
343                     .getString(R.string.api_version);
344
345             // 2. Today
346             final String urlAPI = WeatherInformationCurrentDataFragment.this.getResources()
347                     .getString(R.string.uri_api_weather_today);
348             final String url = this.weatherService.createURIAPITodayWeather(urlAPI, APIVersion,
349                     geocodingData.getLatitude(), geocodingData.getLongitude());
350             final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
351             final CurrentWeatherData currentWeatherData = this.weatherService
352                     .retrieveCurrentWeatherDataFromJPOS(jsonData);
353             final Calendar now = Calendar.getInstance();
354             currentWeatherData.setDate(now.getTime());
355
356
357             return currentWeatherData;
358         }
359
360         private void onPostExecuteThrowable(final CurrentWeatherData currentWeatherData)
361                 throws FileNotFoundException, IOException {
362
363             WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile
364             .storeCurrentWeatherData(currentWeatherData);
365
366             WeatherInformationCurrentDataFragment.this.updateCurrentWeatherData(currentWeatherData);
367         }
368     }
369
370     private void getRemoteCurrentWeatherInformation() {
371
372         final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
373
374         if (geocodingData != null) {
375             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
376             final WeatherServiceParser weatherService = new WeatherServiceParser(JPOSWeatherParser);
377             final AndroidHttpClient httpClient = AndroidHttpClient
378                     .newInstance("Android Weather Information Agent");
379             final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(httpClient);
380
381             final CurrentWeatherTask weatherTask = new CurrentWeatherTask(HTTPweatherClient,
382                     weatherService);
383
384             weatherTask.execute(geocodingData);
385         }
386     }
387
388     private List<WeatherSpecificDataEntry> createEmptyEntriesList() {
389         final List<WeatherSpecificDataEntry> entries = new ArrayList<WeatherSpecificDataEntry>();
390         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_description),
391                 null));
392         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem), null));
393         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem_max), null));
394         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem_min), null));
395         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_rise), null));
396         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_set), null));
397         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_cloudiness),
398                 null));
399         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_rain_time),
400                 null));
401         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_rain_amount),
402                 null));
403         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_wind_speed),
404                 null));
405         entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_humidity), null));
406
407         return entries;
408     }
409 }