7c63d530ae2bbd447c39d33b9ac0236dfa98ec3a
[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.Calendar;
12 import java.util.Date;
13 import java.util.Locale;
14
15 import org.apache.http.client.ClientProtocolException;
16
17 import android.app.DialogFragment;
18 import android.app.ListFragment;
19 import android.content.SharedPreferences;
20 import android.graphics.Bitmap;
21 import android.graphics.BitmapFactory;
22 import android.net.http.AndroidHttpClient;
23 import android.os.AsyncTask;
24 import android.os.Bundle;
25 import android.preference.PreferenceManager;
26 import android.util.Log;
27 import android.widget.ListView;
28
29 import com.fasterxml.jackson.core.JsonParseException;
30
31 import de.example.exampletdd.R;
32 import de.example.exampletdd.fragment.ErrorDialogFragment;
33 import de.example.exampletdd.fragment.ProgressDialogFragment;
34 import de.example.exampletdd.fragment.overview.IconsList;
35 import de.example.exampletdd.httpclient.CustomHTTPClient;
36 import de.example.exampletdd.model.GeocodingData;
37 import de.example.exampletdd.model.currentweather.CurrentWeatherData;
38 import de.example.exampletdd.parser.IJPOSWeatherParser;
39 import de.example.exampletdd.parser.JPOSWeatherParser;
40 import de.example.exampletdd.service.WeatherServiceParser;
41 import de.example.exampletdd.service.WeatherServicePersistenceFile;
42
43 public class WeatherInformationCurrentDataFragment extends ListFragment {
44     private boolean mIsFahrenheit;
45     private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
46
47     @Override
48     public void onCreate(final Bundle savedInstanceState) {
49         super.onCreate(savedInstanceState);
50
51         this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
52         this.mWeatherServicePersistenceFile.removeCurrentWeatherData();
53     }
54
55     @Override
56     public void onActivityCreated(final Bundle savedInstanceState) {
57         super.onActivityCreated(savedInstanceState);
58
59         final ListView listWeatherView = this.getListView();
60         listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
61
62         if (savedInstanceState != null) {
63             // Restore state
64             final CurrentWeatherData currentWeatherData = (CurrentWeatherData) savedInstanceState
65                     .getSerializable("CurrentWeatherData");
66
67             if (currentWeatherData != null) {
68                 try {
69                     this.mWeatherServicePersistenceFile.storeCurrentWeatherData(currentWeatherData);
70                 } catch (final IOException e) {
71                     final DialogFragment newFragment = ErrorDialogFragment
72                             .newInstance(R.string.error_dialog_generic_error);
73                     newFragment.show(this.getFragmentManager(), "errorDialog");
74                 }
75             }
76         }
77
78         this.setHasOptionsMenu(false);
79
80         this.setEmptyText("No data available");
81
82         this.setListShownNoAnimation(false);
83     }
84
85     @Override
86     public void onResume() {
87         super.onResume();
88
89         final SharedPreferences sharedPreferences = PreferenceManager
90                 .getDefaultSharedPreferences(this.getActivity());
91
92         // 1. Update units of measurement.
93         final String keyPreference = this.getResources().getString(
94                 R.string.weather_preferences_units_key);
95         final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
96         final String celsius = this.getResources().getString(
97                 R.string.weather_preferences_units_celsius);
98         if (unitsPreferenceValue.equals(celsius)) {
99             this.mIsFahrenheit = false;
100         } else {
101             this.mIsFahrenheit = true;
102         }
103
104         // 2. Try to restore old information
105         final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
106                 .getCurrentWeatherData();
107         if (currentWeatherData != null) {
108             this.updateCurrentWeatherData(currentWeatherData);
109         } else {
110             // 3. Try to update weather data on display with remote
111             this.getRemoteCurrentWeatherInformation();
112         }
113     }
114
115     @Override
116     public void onSaveInstanceState(final Bundle savedInstanceState) {
117
118         // Save state
119         final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
120                 .getCurrentWeatherData();
121
122         if (currentWeatherData != null) {
123             savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData);
124         }
125
126         super.onSaveInstanceState(savedInstanceState);
127     }
128
129
130     public void updateCurrentWeatherData(final CurrentWeatherData currentWeatherData) {
131         final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale
132                 .getDefault());
133         tempFormatter.applyPattern("#####.#####");
134         final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z",
135                 Locale.getDefault());
136
137         final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
138         final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
139
140         final int[] layouts = new int[3];
141         layouts[0] = R.layout.weather_current_data_entry_first;
142         layouts[1] = R.layout.weather_current_data_entry_second;
143         layouts[2] = R.layout.weather_current_data_entry_fifth;
144         final WeatherCurrentDataAdapter adapter = new WeatherCurrentDataAdapter(this.getActivity(),
145                 layouts);
146
147
148         String tempMax = "";
149         if (currentWeatherData.getMain().getTemp_max() != null) {
150             double conversion = (Double) currentWeatherData.getMain().getTemp_max();
151             conversion = conversion - tempUnits;
152             tempMax = tempFormatter.format(conversion) + symbol;
153         }
154         String tempMin = "";
155         if (currentWeatherData.getMain().getTemp_min() != null) {
156             double conversion = (Double) currentWeatherData.getMain().getTemp_min();
157             conversion = conversion - tempUnits;
158             tempMin = tempFormatter.format(conversion) + symbol;
159         }
160         Bitmap picture;
161         if ((currentWeatherData.getWeather().size() > 0)
162                 && (currentWeatherData.getWeather().get(0).getIcon() != null)
163                 && (IconsList.getIcon(currentWeatherData.getWeather().get(0).getIcon()) != null)) {
164             final String icon = currentWeatherData.getWeather().get(0).getIcon();
165             picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
166                     .getResourceDrawable());
167         } else {
168             picture = BitmapFactory.decodeResource(this.getResources(),
169                     R.drawable.weather_severe_alert);
170         }
171         final WeatherCurrentDataEntryFirst entryFirst = new WeatherCurrentDataEntryFirst(tempMax,
172                 tempMin, picture);
173         adapter.add(entryFirst);
174
175         String description = "no description available";
176         if (currentWeatherData.getWeather().size() > 0) {
177             description = currentWeatherData.getWeather().get(0).getDescription();
178         }
179         final WeatherCurrentDataEntrySecond entrySecond = new WeatherCurrentDataEntrySecond(
180                 description);
181         adapter.add(entrySecond);
182
183         String humidityValue = "";
184         if ((currentWeatherData.getMain() != null)
185                 && (currentWeatherData.getMain().getHumidity() != null)) {
186             final double conversion = (Double) currentWeatherData.getMain().getHumidity();
187             humidityValue = tempFormatter.format(conversion);
188         }
189         String pressureValue = "";
190         if ((currentWeatherData.getMain() != null)
191                 && (currentWeatherData.getMain().getPressure() != null)) {
192             final double conversion = (Double) currentWeatherData.getMain().getPressure();
193             pressureValue = tempFormatter.format(conversion);
194         }
195         String windValue = "";
196         if ((currentWeatherData.getWind() != null)
197                 && (currentWeatherData.getWind().getSpeed() != null)) {
198             final double conversion = (Double) currentWeatherData.getWind().getSpeed();
199             windValue = tempFormatter.format(conversion);
200         }
201         String rainValue = "";
202         if ((currentWeatherData.getRain() != null)
203                 && (currentWeatherData.getRain().get3h() != null)) {
204             final double conversion = (Double) currentWeatherData.getRain().get3h();
205             rainValue = tempFormatter.format(conversion);
206         }
207         String cloudsValue = "";
208         if ((currentWeatherData.getClouds() != null)
209                 && (currentWeatherData.getClouds().getAll() != null)) {
210             final double conversion = (Double) currentWeatherData.getClouds().getAll();
211             cloudsValue = tempFormatter.format(conversion);
212         }
213         String snowValue = "";
214         if ((currentWeatherData.getSnow() != null)
215                 && (currentWeatherData.getSnow().get3h() != null)) {
216             final double conversion = (Double) currentWeatherData.getSnow().get3h();
217             snowValue = tempFormatter.format(conversion);
218         }
219         String feelsLike = "";
220         if (currentWeatherData.getMain().getTemp() != null) {
221             double conversion = (Double) currentWeatherData.getMain().getTemp();
222             conversion = conversion - tempUnits;
223             feelsLike = tempFormatter.format(conversion);
224         }
225         String sunRiseTime = "";
226         if (currentWeatherData.getSys().getSunrise() != null) {
227             final long unixTime = (Long) currentWeatherData.getSys().getSunrise();
228             final Date unixDate = new Date(unixTime * 1000L);
229             sunRiseTime = dateFormat.format(unixDate);
230         }
231         String sunSetTime = "";
232         if (currentWeatherData.getSys().getSunset() != null) {
233             final long unixTime = (Long) currentWeatherData.getSys().getSunset();
234             final Date unixDate = new Date(unixTime * 1000L);
235             sunSetTime = dateFormat.format(unixDate);
236         }
237         final WeatherCurrentDataEntryFifth entryFifth = new WeatherCurrentDataEntryFifth(
238                 sunRiseTime, sunSetTime, humidityValue, pressureValue, windValue, rainValue,
239                 feelsLike, symbol, snowValue, cloudsValue);
240         adapter.add(entryFifth);
241
242
243         this.setListAdapter(adapter);
244     }
245
246     public class CurrentWeatherTask extends AsyncTask<Object, Void, CurrentWeatherData> {
247         private static final String TAG = "WeatherTask";
248         private final CustomHTTPClient weatherHTTPClient;
249         private final WeatherServiceParser weatherService;
250         private final DialogFragment newFragment;
251
252         public CurrentWeatherTask(final CustomHTTPClient weatherHTTPClient,
253                 final WeatherServiceParser weatherService) {
254             this.weatherHTTPClient = weatherHTTPClient;
255             this.weatherService = weatherService;
256             this.newFragment = ProgressDialogFragment.newInstance(
257                     R.string.progress_dialog_get_remote_data,
258                     WeatherInformationCurrentDataFragment.this
259                     .getString(R.string.progress_dialog_generic_message));
260         }
261
262         @Override
263         protected void onPreExecute() {
264             this.newFragment.show(WeatherInformationCurrentDataFragment.this.getActivity()
265                     .getFragmentManager(), "progressDialog");
266         }
267
268         @Override
269         protected CurrentWeatherData doInBackground(final Object... params) {
270             CurrentWeatherData currentWeatherData = null;
271
272             try {
273                 currentWeatherData = this.doInBackgroundThrowable(params);
274             } catch (final ClientProtocolException e) {
275                 Log.e(TAG, "doInBackground exception: ", e);
276             } catch (final MalformedURLException e) {
277                 Log.e(TAG, "doInBackground exception: ", e);
278             } catch (final URISyntaxException e) {
279                 Log.e(TAG, "doInBackground exception: ", e);
280             } catch (final JsonParseException e) {
281                 Log.e(TAG, "doInBackground exception: ", e);
282             } catch (final IOException e) {
283                 // logger infrastructure swallows UnknownHostException :/
284                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
285             } finally {
286                 this.weatherHTTPClient.close();
287             }
288
289             return currentWeatherData;
290         }
291
292         @Override
293         protected void onPostExecute(final CurrentWeatherData currentWeatherData) {
294             this.weatherHTTPClient.close();
295
296             this.newFragment.dismiss();
297
298             if (currentWeatherData != null) {
299                 try {
300                     this.onPostExecuteThrowable(currentWeatherData);
301                 } catch (final IOException e) {
302                     WeatherInformationCurrentDataFragment.this.setListShown(true);
303                     Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
304                     final DialogFragment newFragment = ErrorDialogFragment
305                             .newInstance(R.string.error_dialog_generic_error);
306                     newFragment.show(
307                             WeatherInformationCurrentDataFragment.this.getFragmentManager(),
308                             "errorDialog");
309                 }
310             } else {
311                 WeatherInformationCurrentDataFragment.this.setListShown(true);
312                 final DialogFragment newFragment = ErrorDialogFragment
313                         .newInstance(R.string.error_dialog_generic_error);
314                 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
315                         "errorDialog");
316             }
317         }
318
319         @Override
320         protected void onCancelled(final CurrentWeatherData currentWeatherData) {
321             this.weatherHTTPClient.close();
322
323             final DialogFragment newFragment = ErrorDialogFragment
324                     .newInstance(R.string.error_dialog_connection_tiemout);
325             newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
326                     "errorDialog");
327         }
328
329         private CurrentWeatherData doInBackgroundThrowable(final Object... params)
330                 throws ClientProtocolException, MalformedURLException, URISyntaxException,
331                 JsonParseException, IOException {
332
333             // 1. Coordinates
334             final GeocodingData geocodingData = (GeocodingData) params[0];
335
336             final String APIVersion = WeatherInformationCurrentDataFragment.this.getResources()
337                     .getString(R.string.api_version);
338
339             // 2. Today
340             final String urlAPI = WeatherInformationCurrentDataFragment.this.getResources()
341                     .getString(R.string.uri_api_weather_today);
342             final String url = this.weatherService.createURIAPITodayWeather(urlAPI, APIVersion,
343                     geocodingData.getLatitude(), geocodingData.getLongitude());
344             final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
345             final CurrentWeatherData currentWeatherData = this.weatherService
346                     .retrieveCurrentWeatherDataFromJPOS(jsonData);
347             final Calendar now = Calendar.getInstance();
348             currentWeatherData.setDate(now.getTime());
349
350
351             return currentWeatherData;
352         }
353
354         private void onPostExecuteThrowable(final CurrentWeatherData currentWeatherData)
355                 throws FileNotFoundException, IOException {
356
357             WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile
358             .storeCurrentWeatherData(currentWeatherData);
359
360             WeatherInformationCurrentDataFragment.this.updateCurrentWeatherData(currentWeatherData);
361         }
362     }
363
364     private void getRemoteCurrentWeatherInformation() {
365
366         final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
367
368         if (geocodingData != null) {
369             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
370             final WeatherServiceParser weatherService = new WeatherServiceParser(JPOSWeatherParser);
371             final AndroidHttpClient httpClient = AndroidHttpClient
372                     .newInstance("Android Weather Information Agent");
373             final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(httpClient);
374
375             final CurrentWeatherTask weatherTask = new CurrentWeatherTask(HTTPweatherClient,
376                     weatherService);
377
378             weatherTask.execute(geocodingData);
379         }
380     }
381 }