0a04dc0ae9f8cb0794b2cb18a46e1a964e27f736
[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.content.SharedPreferences;
18 import android.graphics.Bitmap;
19 import android.graphics.BitmapFactory;
20 import android.net.http.AndroidHttpClient;
21 import android.os.AsyncTask;
22 import android.os.Bundle;
23 import android.preference.PreferenceManager;
24 import android.support.v4.app.DialogFragment;
25 import android.support.v4.app.ListFragment;
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.US);
132         tempFormatter.applyPattern("#####.#####");
133         final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z", Locale.US);
134
135         final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
136         final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
137
138         final int[] layouts = new int[3];
139         layouts[0] = R.layout.weather_current_data_entry_first;
140         layouts[1] = R.layout.weather_current_data_entry_second;
141         layouts[2] = R.layout.weather_current_data_entry_fifth;
142         final WeatherCurrentDataAdapter adapter = new WeatherCurrentDataAdapter(this.getActivity(),
143                 layouts);
144
145
146         String tempMax = "";
147         if (currentWeatherData.getMain().getTemp_max() != null) {
148             double conversion = (Double) currentWeatherData.getMain().getTemp_max();
149             conversion = conversion - tempUnits;
150             tempMax = tempFormatter.format(conversion) + symbol;
151         }
152         String tempMin = "";
153         if (currentWeatherData.getMain().getTemp_min() != null) {
154             double conversion = (Double) currentWeatherData.getMain().getTemp_min();
155             conversion = conversion - tempUnits;
156             tempMin = tempFormatter.format(conversion) + symbol;
157         }
158         Bitmap picture;
159         if ((currentWeatherData.getWeather().size() > 0)
160                 && (currentWeatherData.getWeather().get(0).getIcon() != null)
161                 && (IconsList.getIcon(currentWeatherData.getWeather().get(0).getIcon()) != null)) {
162             final String icon = currentWeatherData.getWeather().get(0).getIcon();
163             picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
164                     .getResourceDrawable());
165         } else {
166             picture = BitmapFactory.decodeResource(this.getResources(),
167                     R.drawable.weather_severe_alert);
168         }
169         final WeatherCurrentDataEntryFirst entryFirst = new WeatherCurrentDataEntryFirst(tempMax,
170                 tempMin, picture);
171         adapter.add(entryFirst);
172
173         String description = "no description available";
174         if (currentWeatherData.getWeather().size() > 0) {
175             description = currentWeatherData.getWeather().get(0).getDescription();
176         }
177         final WeatherCurrentDataEntrySecond entrySecond = new WeatherCurrentDataEntrySecond(
178                 description);
179         adapter.add(entrySecond);
180
181         String humidityValue = "";
182         if ((currentWeatherData.getMain() != null)
183                 && (currentWeatherData.getMain().getHumidity() != null)) {
184             final double conversion = (Double) currentWeatherData.getMain().getHumidity();
185             humidityValue = tempFormatter.format(conversion);
186         }
187         String pressureValue = "";
188         if ((currentWeatherData.getMain() != null)
189                 && (currentWeatherData.getMain().getPressure() != null)) {
190             final double conversion = (Double) currentWeatherData.getMain().getPressure();
191             pressureValue = tempFormatter.format(conversion);
192         }
193         String windValue = "";
194         if ((currentWeatherData.getWind() != null)
195                 && (currentWeatherData.getWind().getSpeed() != null)) {
196             final double conversion = (Double) currentWeatherData.getWind().getSpeed();
197             windValue = tempFormatter.format(conversion);
198         }
199         String rainValue = "";
200         if ((currentWeatherData.getRain() != null)
201                 && (currentWeatherData.getRain().get3h() != null)) {
202             final double conversion = (Double) currentWeatherData.getRain().get3h();
203             rainValue = tempFormatter.format(conversion);
204         }
205         String cloudsValue = "";
206         if ((currentWeatherData.getClouds() != null)
207                 && (currentWeatherData.getClouds().getAll() != null)) {
208             final double conversion = (Double) currentWeatherData.getClouds().getAll();
209             cloudsValue = tempFormatter.format(conversion);
210         }
211         String snowValue = "";
212         if ((currentWeatherData.getSnow() != null)
213                 && (currentWeatherData.getSnow().get3h() != null)) {
214             final double conversion = (Double) currentWeatherData.getSnow().get3h();
215             snowValue = tempFormatter.format(conversion);
216         }
217         String feelsLike = "";
218         if (currentWeatherData.getMain().getTemp() != null) {
219             double conversion = (Double) currentWeatherData.getMain().getTemp();
220             conversion = conversion - tempUnits;
221             feelsLike = tempFormatter.format(conversion);
222         }
223         String sunRiseTime = "";
224         if (currentWeatherData.getSys().getSunrise() != null) {
225             final long unixTime = (Long) currentWeatherData.getSys().getSunrise();
226             final Date unixDate = new Date(unixTime * 1000L);
227             sunRiseTime = dateFormat.format(unixDate);
228         }
229         String sunSetTime = "";
230         if (currentWeatherData.getSys().getSunset() != null) {
231             final long unixTime = (Long) currentWeatherData.getSys().getSunset();
232             final Date unixDate = new Date(unixTime * 1000L);
233             sunSetTime = dateFormat.format(unixDate);
234         }
235         final WeatherCurrentDataEntryFifth entryFifth = new WeatherCurrentDataEntryFifth(
236                 sunRiseTime, sunSetTime, humidityValue, pressureValue, windValue, rainValue,
237                 feelsLike, symbol, snowValue, cloudsValue);
238         adapter.add(entryFifth);
239
240
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.getFragmentManager(),
263                     "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                     WeatherInformationCurrentDataFragment.this.setListShown(true);
301                     Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
302                     final DialogFragment newFragment = ErrorDialogFragment
303                             .newInstance(R.string.error_dialog_generic_error);
304                     newFragment.show(
305                             WeatherInformationCurrentDataFragment.this.getFragmentManager(),
306                             "errorDialog");
307                 }
308             } else {
309                 WeatherInformationCurrentDataFragment.this.setListShown(true);
310                 final DialogFragment newFragment = ErrorDialogFragment
311                         .newInstance(R.string.error_dialog_generic_error);
312                 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
313                         "errorDialog");
314             }
315         }
316
317         @Override
318         protected void onCancelled(final CurrentWeatherData currentWeatherData) {
319             this.weatherHTTPClient.close();
320
321             final DialogFragment newFragment = ErrorDialogFragment
322                     .newInstance(R.string.error_dialog_connection_tiemout);
323             newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
324                     "errorDialog");
325         }
326
327         private CurrentWeatherData doInBackgroundThrowable(final Object... params)
328                 throws ClientProtocolException, MalformedURLException, URISyntaxException,
329                 JsonParseException, IOException {
330
331             // 1. Coordinates
332             final GeocodingData geocodingData = (GeocodingData) params[0];
333
334             final String APIVersion = WeatherInformationCurrentDataFragment.this.getResources()
335                     .getString(R.string.api_version);
336
337             // 2. Today
338             final String urlAPI = WeatherInformationCurrentDataFragment.this.getResources()
339                     .getString(R.string.uri_api_weather_today);
340             final String url = this.weatherService.createURIAPITodayWeather(urlAPI, APIVersion,
341                     geocodingData.getLatitude(), geocodingData.getLongitude());
342             final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
343             final CurrentWeatherData currentWeatherData = this.weatherService
344                     .retrieveCurrentWeatherDataFromJPOS(jsonData);
345             final Calendar now = Calendar.getInstance();
346             currentWeatherData.setDate(now.getTime());
347
348
349             return currentWeatherData;
350         }
351
352         private void onPostExecuteThrowable(final CurrentWeatherData currentWeatherData)
353                 throws FileNotFoundException, IOException {
354
355             WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile
356             .storeCurrentWeatherData(currentWeatherData);
357
358             WeatherInformationCurrentDataFragment.this.updateCurrentWeatherData(currentWeatherData);
359         }
360     }
361
362     private void getRemoteCurrentWeatherInformation() {
363
364         final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
365
366         if (geocodingData != null) {
367             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
368             final WeatherServiceParser weatherService = new WeatherServiceParser(JPOSWeatherParser);
369             final AndroidHttpClient httpClient = AndroidHttpClient
370                     .newInstance("Android Weather Information Agent");
371             final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(httpClient);
372
373             final CurrentWeatherTask weatherTask = new CurrentWeatherTask(HTTPweatherClient,
374                     weatherService);
375
376             weatherTask.execute(geocodingData);
377         }
378     }
379 }