30402dc3cb5f2a932ada3542f2d8e7606a7a2541
[JavaForFun] /
1 package de.example.exampletdd.fragment.overview;
2
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5 import java.io.StreamCorruptedException;
6 import java.net.MalformedURLException;
7 import java.net.URISyntaxException;
8 import java.net.URL;
9 import java.text.DecimalFormat;
10 import java.text.NumberFormat;
11 import java.text.SimpleDateFormat;
12 import java.util.ArrayList;
13 import java.util.Calendar;
14 import java.util.Collection;
15 import java.util.Date;
16 import java.util.List;
17 import java.util.Locale;
18
19 import org.apache.http.client.ClientProtocolException;
20 import org.json.JSONException;
21
22 import android.app.DialogFragment;
23 import android.app.ListFragment;
24 import android.content.ComponentName;
25 import android.content.Intent;
26 import android.content.SharedPreferences;
27 import android.graphics.Bitmap;
28 import android.graphics.BitmapFactory;
29 import android.net.http.AndroidHttpClient;
30 import android.os.AsyncTask;
31 import android.os.Bundle;
32 import android.preference.PreferenceManager;
33 import android.util.Log;
34 import android.view.View;
35 import android.widget.ListView;
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.WeatherHTTPClient;
42 import de.example.exampletdd.model.GeocodingData;
43 import de.example.exampletdd.model.WeatherData;
44 import de.example.exampletdd.parser.IJPOSWeatherParser;
45 import de.example.exampletdd.parser.JPOSWeatherParser;
46 import de.example.exampletdd.service.WeatherService;
47 import de.example.exampletdd.service.WeatherServicePersistenceFile;
48
49 public class WeatherInformationOverviewFragment extends ListFragment implements GetWeather {
50     private static final String TAG = "WeatherInformationOverviewFragment";
51     private boolean mIsFahrenheit;
52     private String mLanguage;
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(
67                 this.getActivity());
68         this.mWeatherServicePersistenceFile.removeWeatherData();
69     }
70
71     @Override
72     public void onActivityCreated(final Bundle savedInstanceState) {
73         super.onActivityCreated(savedInstanceState);
74
75         final ListView listWeatherView = this.getListView();
76
77         listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
78
79         if (savedInstanceState != null) {
80             // Restore state
81             final WeatherData weatherData = (WeatherData) savedInstanceState
82                     .getSerializable("weatherData");
83             try {
84                 this.mWeatherServicePersistenceFile
85                 .storeWeatherData(weatherData);
86             } catch (final IOException e) {
87                 final DialogFragment newFragment = ErrorDialogFragment
88                         .newInstance(R.string.error_dialog_generic_error);
89                 newFragment.show(this.getFragmentManager(), "errorDialog");
90             }
91         }
92
93         this.setHasOptionsMenu(false);
94
95         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(
96                 this.getActivity(), R.layout.weather_main_entry_list);
97
98         final Collection<WeatherOverviewEntry> entries = this
99                 .createEmptyEntriesList();
100
101         this.setListAdapter(null);
102         adapter.addAll(entries);
103         this.setListAdapter(adapter);
104         this.setListShown(true);
105         this.setListShownNoAnimation(true);
106     }
107
108     @Override
109     public void onListItemClick(final ListView l, final View v, final int position, final long id) {
110         final WeatherInformationSpecificDataFragment fragment = (WeatherInformationSpecificDataFragment) this.getFragmentManager()
111                 .findFragmentById(R.id.weather_specific_data__fragment);
112         if (fragment == null) {
113             // handset layout
114             final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO").
115                     setComponent(new ComponentName("de.example.exampletdd",
116                             "de.example.exampletdd.WeatherInformationSpecificDataActivity"));
117             WeatherInformationOverviewFragment.this.getActivity().startActivity(intent);
118         } else {
119             // tablet layout
120             fragment.getWeather();
121         }
122     }
123
124     @Override
125     public void onSaveInstanceState(final Bundle savedInstanceState) {
126
127         // Save state
128         WeatherData weatherData = null;
129         try {
130             weatherData = this.mWeatherServicePersistenceFile.getWeatherData();
131         } catch (final StreamCorruptedException e) {
132             Log.e(TAG, "onResume exception: ", e);
133         } catch (final FileNotFoundException e) {
134             Log.e(TAG, "onResume exception: ", e);
135         } catch (final IOException e) {
136             Log.e(TAG, "onResume exception: ", e);
137         } catch (final ClassNotFoundException e) {
138             Log.e(TAG, "onResume exception: ", e);
139         }
140
141         if (weatherData != null) {
142             savedInstanceState.putSerializable("weatherData", weatherData);
143         }
144
145         super.onSaveInstanceState(savedInstanceState);
146     }
147
148     @Override
149     public void getWeather() {
150
151         GeocodingData geocodingData = null;
152         try {
153             geocodingData = this.mWeatherServicePersistenceFile
154                     .getGeocodingData();
155         } catch (final StreamCorruptedException e) {
156             Log.e(TAG, "onResume exception: ", e);
157         } catch (final FileNotFoundException e) {
158             Log.e(TAG, "onResume exception: ", e);
159         } catch (final IOException e) {
160             Log.e(TAG, "onResume exception: ", e);
161         } catch (final ClassNotFoundException e) {
162             Log.e(TAG, "onResume exception: ", e);
163         }
164
165         if (geocodingData != null) {
166             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
167             final WeatherService weatherService = new WeatherService(
168                     JPOSWeatherParser);
169             final AndroidHttpClient httpClient = AndroidHttpClient
170                     .newInstance("Android Weather Information Agent");
171             final WeatherHTTPClient HTTPweatherClient = new WeatherHTTPClient(
172                     httpClient);
173
174             final WeatherTask weatherTask = new WeatherTask(HTTPweatherClient, weatherService);
175
176
177             weatherTask.execute(geocodingData);
178         }
179     }
180
181     public void updateWeatherData(final WeatherData weatherData) {
182         final List<WeatherOverviewEntry> entries = this.createEmptyEntriesList();
183         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(this.getActivity(),
184                 R.layout.weather_main_entry_list);
185
186         // Bitmap picture = null;
187         //
188         // if (weatherData.getWeather().getIcon() != null) {
189         // picture= BitmapFactory.decodeByteArray(
190         // weatherData.getIconData(), 0,
191         // weatherData.getIconData().length);
192         // }
193
194         final Bitmap picture = BitmapFactory.decodeResource(
195                 this.getResources(), R.drawable.ic_02d);
196         final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.getDefault());
197         tempFormatter.applyPattern("#####.##");
198         final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, MMM d", Locale.getDefault());
199         final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
200         double temp = weatherData.getMain().getTemp();
201         temp = temp - tempUnits;
202         double maxTemp = weatherData.getMain().getMaxTemp();
203         maxTemp = maxTemp - tempUnits;
204         double minTemp = weatherData.getMain().getMinTemp();
205         minTemp = minTemp - tempUnits;
206
207         final Calendar now = Calendar.getInstance();
208         if (weatherData.getWeather() != null) {
209             for (int i = 0; i<15; i++) {
210                 final Date day = now.getTime();
211                 entries.set(i, new WeatherOverviewEntry(dateFormat.format(day),
212                         tempFormatter.format(temp), tempFormatter
213                         .format(maxTemp), tempFormatter
214                         .format(minTemp), picture));
215                 now.add(Calendar.DAY_OF_MONTH, 1);
216             }
217         }
218
219         this.setListAdapter(null);
220         adapter.addAll(entries);
221         this.setListAdapter(adapter);
222     }
223
224     @Override
225     public void onResume() {
226         super.onResume();
227
228         final SharedPreferences sharedPreferences = PreferenceManager
229                 .getDefaultSharedPreferences(this.getActivity());
230
231         // 1. Update units of measurement.
232         String keyPreference = this.getResources().getString(
233                 R.string.weather_preferences_units_key);
234         final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
235         final String celsius = this.getResources().getString(
236                 R.string.weather_preferences_units_celsius);
237         if (unitsPreferenceValue.equals(celsius)) {
238             this.mIsFahrenheit = false;
239         } else {
240             this.mIsFahrenheit = true;
241         }
242
243
244         // 2. Update current data on display.
245         WeatherData weatherData = null;
246         try {
247             weatherData = this.mWeatherServicePersistenceFile.getWeatherData();
248         } catch (final StreamCorruptedException e) {
249             Log.e(TAG, "onResume exception: ", e);
250         } catch (final FileNotFoundException e) {
251             Log.e(TAG, "onResume exception: ", e);
252         } catch (final IOException e) {
253             Log.e(TAG, "onResume exception: ", e);
254         } catch (final ClassNotFoundException e) {
255             Log.e(TAG, "onResume exception: ", e);
256         }
257         if (weatherData != null) {
258             this.updateWeatherData(weatherData);
259         }
260
261
262         // 3. If language changed, try to retrieve new data for new language
263         // (new strings with the chosen language)
264         keyPreference = this.getResources().getString(
265                 R.string.weather_preferences_language_key);
266         final String languagePreferenceValue = sharedPreferences.getString(
267                 keyPreference, "");
268         if (!languagePreferenceValue.equals(this.mLanguage)) {
269             this.mLanguage = languagePreferenceValue;
270             this.getWeather();
271         }
272     }
273
274     public class WeatherTask extends AsyncTask<Object, Void, WeatherData> {
275         private static final String TAG = "WeatherTask";
276         private final WeatherHTTPClient weatherHTTPClient;
277         private final WeatherService weatherService;
278         private final DialogFragment newFragment;
279
280         public WeatherTask(final WeatherHTTPClient weatherHTTPClient,
281                 final WeatherService weatherService) {
282             this.weatherHTTPClient = weatherHTTPClient;
283             this.weatherService = weatherService;
284             this.newFragment = ProgressDialogFragment.newInstance(
285                     R.string.progress_dialog_get_remote_data,
286                     WeatherInformationOverviewFragment.this
287                     .getString(R.string.progress_dialog_generic_message));
288         }
289
290         @Override
291         protected void onPreExecute() {
292             this.newFragment.show(WeatherInformationOverviewFragment.this.getActivity()
293                     .getFragmentManager(), "progressDialog");
294         }
295
296         @Override
297         protected WeatherData doInBackground(final Object... params) {
298             WeatherData weatherData = null;
299
300             try {
301                 weatherData = this.doInBackgroundThrowable(params);
302             } catch (final ClientProtocolException e) {
303                 Log.e(TAG, "doInBackground exception: ", e);
304             } catch (final MalformedURLException e) {
305                 Log.e(TAG, "doInBackground exception: ", e);
306             } catch (final URISyntaxException e) {
307                 Log.e(TAG, "doInBackground exception: ", e);
308             } catch (final IOException e) {
309                 // logger infrastructure swallows UnknownHostException :/
310                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
311             } catch (final JSONException e) {
312                 Log.e(TAG, "doInBackground exception: ", e);
313             } finally {
314                 this.weatherHTTPClient.close();
315             }
316
317             return weatherData;
318         }
319
320         @Override
321         protected void onPostExecute(final WeatherData weatherData) {
322             this.weatherHTTPClient.close();
323
324             this.newFragment.dismiss();
325
326             if (weatherData != null) {
327                 try {
328                     this.onPostExecuteThrowable(weatherData);
329                 } catch (final IOException e) {
330                     Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
331                     final DialogFragment newFragment = ErrorDialogFragment
332                             .newInstance(R.string.error_dialog_generic_error);
333                     newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
334                 }
335             } else {
336                 final DialogFragment newFragment = ErrorDialogFragment
337                         .newInstance(R.string.error_dialog_generic_error);
338                 newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
339             }
340         }
341
342         @Override
343         protected void onCancelled(final WeatherData weatherData) {
344             this.weatherHTTPClient.close();
345
346             final DialogFragment newFragment = ErrorDialogFragment
347                     .newInstance(R.string.error_dialog_connection_tiemout);
348             newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
349         }
350
351         private WeatherData doInBackgroundThrowable(final Object... params)
352                 throws ClientProtocolException, MalformedURLException,
353                 URISyntaxException, IOException, JSONException {
354             final SharedPreferences sharedPreferences = PreferenceManager
355                     .getDefaultSharedPreferences(WeatherInformationOverviewFragment.this
356                             .getActivity());
357
358             final String keyPreference = WeatherInformationOverviewFragment.this
359                     .getActivity().getString(
360                             R.string.weather_preferences_language_key);
361             final String languagePreferenceValue = sharedPreferences.getString(keyPreference, "");
362
363             final GeocodingData geocodingData = (GeocodingData) params[0];
364             final String urlAPICoord = WeatherInformationOverviewFragment.this.getResources()
365                     .getString(R.string.uri_api_coord);
366             final String APIVersion = WeatherInformationOverviewFragment.this.getResources()
367                     .getString(R.string.api_version);
368             String url = this.weatherService.createURIAPICoord(geocodingData.getLatitude(),
369                     geocodingData.getLongitude(), urlAPICoord, APIVersion, languagePreferenceValue);
370
371
372             final String jsonData = this.weatherHTTPClient.retrieveJSONDataFromAPI(new URL(url));
373
374
375             final WeatherData weatherData = this.weatherService.retrieveDataFromJPOS(jsonData);
376
377
378             final String icon = weatherData.getWeather().getIcon();
379             final String urlAPIicon = WeatherInformationOverviewFragment.this
380                     .getResources().getString(R.string.uri_api_icon);
381             url = this.weatherService.createURIAPIicon(icon, urlAPIicon);
382             final byte[] iconData = this.weatherHTTPClient
383                     .retrieveDataFromAPI(new URL(url)).toByteArray();
384             weatherData.setIconData(iconData);
385
386
387             return weatherData;
388         }
389
390         private void onPostExecuteThrowable(final WeatherData weatherData)
391                 throws FileNotFoundException, IOException {
392             WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile
393                     .storeWeatherData(weatherData);
394
395             WeatherInformationOverviewFragment.this.updateWeatherData(weatherData);
396         }
397     }
398
399     private List<WeatherOverviewEntry> createEmptyEntriesList() {
400         final List<WeatherOverviewEntry> entries = new ArrayList<WeatherOverviewEntry>();
401         final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, MMM d", Locale.getDefault());
402
403         final Calendar now = Calendar.getInstance();
404         for (int i = 0; i<15; i++) {
405             final Date day = now.getTime();
406             entries.add(i, new WeatherOverviewEntry(dateFormat.format(day),
407                     null, null, null, null));
408             now.add(Calendar.DAY_OF_MONTH, 1);
409         }
410
411         return entries;
412     }
413 }