c401d643365b7a0b7ffc1726bcf0278692a32c53
[JavaForFun] /
1 package de.example.exampletdd.fragment.overview;
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.ComponentName;
22 import android.content.Intent;
23 import android.content.SharedPreferences;
24 import android.graphics.Bitmap;
25 import android.graphics.BitmapFactory;
26 import android.net.http.AndroidHttpClient;
27 import android.os.AsyncTask;
28 import android.os.Bundle;
29 import android.preference.PreferenceManager;
30 import android.util.Log;
31 import android.view.View;
32 import android.widget.ListView;
33
34 import com.fasterxml.jackson.core.JsonParseException;
35
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.CustomHTTPClient;
42 import de.example.exampletdd.model.GeocodingData;
43 import de.example.exampletdd.model.forecastweather.ForecastWeatherData;
44 import de.example.exampletdd.parser.IJPOSWeatherParser;
45 import de.example.exampletdd.parser.JPOSWeatherParser;
46 import de.example.exampletdd.service.WeatherServiceParser;
47 import de.example.exampletdd.service.WeatherServicePersistenceFile;
48
49 public class WeatherInformationOverviewFragment extends ListFragment implements GetWeather {
50     private boolean mIsFahrenheit;
51     private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
52
53     @Override
54     public void onCreate(final Bundle savedInstanceState) {
55         super.onCreate(savedInstanceState);
56
57         // final SharedPreferences sharedPreferences = PreferenceManager
58         // .getDefaultSharedPreferences(this.getActivity());
59         // final String keyPreference = this.getResources().getString(
60         // R.string.weather_preferences_language_key);
61         // this.mLanguage = sharedPreferences.getString(
62         // keyPreference, "");
63
64         this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
65         this.mWeatherServicePersistenceFile.removeForecastWeatherData();
66     }
67
68     @Override
69     public void onActivityCreated(final Bundle savedInstanceState) {
70         super.onActivityCreated(savedInstanceState);
71
72
73
74         final ListView listWeatherView = this.getListView();
75
76         listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
77
78         if (savedInstanceState != null) {
79             // Restore state
80             final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState
81                     .getSerializable("ForecastWeatherData");
82
83             if (forecastWeatherData != null) {
84                 try {
85                     this.mWeatherServicePersistenceFile
86                     .storeForecastWeatherData(forecastWeatherData);
87                 } catch (final IOException e) {
88                     final DialogFragment newFragment = ErrorDialogFragment
89                             .newInstance(R.string.error_dialog_generic_error);
90                     newFragment.show(this.getFragmentManager(), "errorDialog");
91                 }
92             }
93         }
94
95         this.setHasOptionsMenu(false);
96
97         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(
98                 this.getActivity(), R.layout.weather_main_entry_list);
99
100
101         this.setEmptyText("Press download to receive weather information");
102
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             intent.putExtra("CHOSEN_DAY", (int) id);
118             WeatherInformationOverviewFragment.this.getActivity().startActivity(intent);
119         } else {
120             // tablet layout
121             fragment.getWeatherByDay((int) id);
122         }
123     }
124
125     @Override
126     public void onSaveInstanceState(final Bundle savedInstanceState) {
127
128         // Save state
129         final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
130                 .getForecastWeatherData();
131
132         if (forecastWeatherData != null) {
133             savedInstanceState.putSerializable("ForecastWeatherData", forecastWeatherData);
134         }
135
136         super.onSaveInstanceState(savedInstanceState);
137     }
138
139     @Override
140     public void getRemoteWeatherInformation() {
141
142         final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
143
144         if (geocodingData != null) {
145             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
146             final WeatherServiceParser weatherService = new WeatherServiceParser(
147                     JPOSWeatherParser);
148             final AndroidHttpClient httpClient = AndroidHttpClient
149                     .newInstance("Android Weather Information Agent");
150             final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(
151                     httpClient);
152
153             final ForecastWeatherTask weatherTask = new ForecastWeatherTask(HTTPweatherClient,
154                     weatherService);
155
156
157             weatherTask.execute(geocodingData);
158         }
159     }
160
161     @Override
162     public void getWeatherByDay(final int chosenDay) {
163         // Nothing to do.
164     }
165
166     public void updateForecastWeatherData(final ForecastWeatherData forecastWeatherData) {
167         final List<WeatherOverviewEntry> entries = new ArrayList<WeatherOverviewEntry>();
168         final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(this.getActivity(),
169                 R.layout.weather_main_entry_list);
170
171         final Bitmap picture = BitmapFactory.decodeResource(
172                 this.getResources(), R.drawable.ic_02d);
173         final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.getDefault());
174         tempFormatter.applyPattern("#####.##");
175         final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, MMM d", Locale.getDefault());
176         final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
177         final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
178
179
180         final Calendar calendar = Calendar.getInstance();
181         for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData
182                 .getList()) {
183
184
185             final Long forecastUNIXDate = (Long) forecast.getDt();
186             calendar.setTimeInMillis(forecastUNIXDate * 1000L);
187             final Date dayTime = calendar.getTime();
188             final String dayText = dateFormat.format(dayTime);
189
190             Double maxTemp = null;
191             if (forecast.getTemp().getMax() != null) {
192                 maxTemp = (Double) forecast.getTemp().getMax();
193                 maxTemp = maxTemp - tempUnits;
194             }
195
196             Double minTemp = null;
197             if (forecast.getTemp().getMin() != null) {
198                 minTemp = (Double) forecast.getTemp().getMin();
199                 minTemp = minTemp - tempUnits;
200             }
201
202             if ((maxTemp != null) && (minTemp != null)) {
203                 entries.add(new WeatherOverviewEntry(dayText, tempFormatter.format(maxTemp)
204                         + symbol, tempFormatter.format(minTemp) + symbol, picture));
205             }
206         }
207
208         this.setListAdapter(null);
209         adapter.addAll(entries);
210         this.setListAdapter(adapter);
211     }
212
213     @Override
214     public void onResume() {
215         super.onResume();
216
217         final SharedPreferences sharedPreferences = PreferenceManager
218                 .getDefaultSharedPreferences(this.getActivity());
219
220         // 1. Update units of measurement.
221         final String keyPreference = this.getResources().getString(
222                 R.string.weather_preferences_units_key);
223         final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
224         final String celsius = this.getResources().getString(
225                 R.string.weather_preferences_units_celsius);
226         if (unitsPreferenceValue.equals(celsius)) {
227             this.mIsFahrenheit = false;
228         } else {
229             this.mIsFahrenheit = true;
230         }
231
232
233         // 2. Update forecast weather data on display.
234         final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
235                 .getForecastWeatherData();
236         if (forecastWeatherData != null) {
237             this.updateForecastWeatherData(forecastWeatherData);
238         }
239
240
241         // 3. If language changed, try to retrieve new data for new language
242         // (new strings with the chosen language)
243         // keyPreference = this.getResources().getString(
244         // R.string.weather_preferences_language_key);
245         // final String languagePreferenceValue = sharedPreferences.getString(
246         // keyPreference, "");
247         // if (!languagePreferenceValue.equals(this.mLanguage)) {
248         // this.mLanguage = languagePreferenceValue;
249         // this.getWeather();
250         // }
251     }
252
253     public class ForecastWeatherTask extends AsyncTask<Object, Void, ForecastWeatherData> {
254         private static final String TAG = "ForecastWeatherTask";
255         private final CustomHTTPClient weatherHTTPClient;
256         private final WeatherServiceParser weatherService;
257         private final DialogFragment newFragment;
258
259         public ForecastWeatherTask(final CustomHTTPClient weatherHTTPClient,
260                 final WeatherServiceParser weatherService) {
261             this.weatherHTTPClient = weatherHTTPClient;
262             this.weatherService = weatherService;
263             this.newFragment = ProgressDialogFragment.newInstance(
264                     R.string.progress_dialog_get_remote_data,
265                     WeatherInformationOverviewFragment.this
266                     .getString(R.string.progress_dialog_generic_message));
267         }
268
269         @Override
270         protected void onPreExecute() {
271             this.newFragment.show(WeatherInformationOverviewFragment.this.getActivity()
272                     .getFragmentManager(), "progressDialog");
273         }
274
275         @Override
276         protected ForecastWeatherData doInBackground(final Object... params) {
277             ForecastWeatherData forecastWeatherData = null;
278
279             try {
280                 forecastWeatherData = this.doInBackgroundThrowable(params);
281             } catch (final ClientProtocolException e) {
282                 Log.e(TAG, "doInBackground exception: ", e);
283             } catch (final MalformedURLException e) {
284                 Log.e(TAG, "doInBackground exception: ", e);
285             } catch (final URISyntaxException e) {
286                 Log.e(TAG, "doInBackground exception: ", e);
287             } catch (final JsonParseException e) {
288                 Log.e(TAG, "doInBackground exception: ", e);
289             } catch (final IOException e) {
290                 // logger infrastructure swallows UnknownHostException :/
291                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
292             } finally {
293                 this.weatherHTTPClient.close();
294             }
295
296             return forecastWeatherData;
297         }
298
299         @Override
300         protected void onPostExecute(final ForecastWeatherData weatherData) {
301             this.weatherHTTPClient.close();
302
303             this.newFragment.dismiss();
304
305             if (weatherData != null) {
306                 try {
307                     this.onPostExecuteThrowable(weatherData);
308                 } catch (final IOException e) {
309                     Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
310                     final DialogFragment newFragment = ErrorDialogFragment
311                             .newInstance(R.string.error_dialog_generic_error);
312                     newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
313                 }
314             } else {
315                 final DialogFragment newFragment = ErrorDialogFragment
316                         .newInstance(R.string.error_dialog_generic_error);
317                 newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
318             }
319         }
320
321         @Override
322         protected void onCancelled(final ForecastWeatherData weatherData) {
323             this.weatherHTTPClient.close();
324
325             final DialogFragment newFragment = ErrorDialogFragment
326                     .newInstance(R.string.error_dialog_connection_tiemout);
327             newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
328         }
329
330         private ForecastWeatherData doInBackgroundThrowable(final Object... params)
331                 throws ClientProtocolException, MalformedURLException,
332                 URISyntaxException, JsonParseException, IOException {
333             // final SharedPreferences sharedPreferences = PreferenceManager
334             // .getDefaultSharedPreferences(WeatherInformationOverviewFragment.this
335             // .getActivity());
336             //
337             // final String keyPreference =
338             // WeatherInformationOverviewFragment.this
339             // .getActivity().getString(
340             // R.string.weather_preferences_language_key);
341             // final String languagePreferenceValue =
342             // sharedPreferences.getString(keyPreference, "");
343
344             // 1. Coordinates
345             final GeocodingData geocodingData = (GeocodingData) params[0];
346
347
348             final String APIVersion = WeatherInformationOverviewFragment.this.getResources()
349                     .getString(R.string.api_version);
350             // 2. Forecast
351             final String urlAPI = WeatherInformationOverviewFragment.this.getResources()
352                     .getString(R.string.uri_api_weather_forecast);
353             final String url = this.weatherService.createURIAPIForecastWeather(urlAPI, APIVersion,
354                     geocodingData.getLatitude(), geocodingData.getLongitude(), "14");
355             final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
356             final ForecastWeatherData forecastWeatherData = this.weatherService
357                     .retrieveForecastWeatherDataFromJPOS(jsonData);
358
359             return forecastWeatherData;
360         }
361
362         private void onPostExecuteThrowable(final ForecastWeatherData forecastWeatherData)
363                 throws FileNotFoundException, IOException {
364             WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile
365                     .storeForecastWeatherData(forecastWeatherData);
366
367             WeatherInformationOverviewFragment.this.updateForecastWeatherData(forecastWeatherData);
368         }
369     }
370 }