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