1 package de.example.exampletdd.fragment.overview;
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5 import java.net.MalformedURLException;
6 import java.net.URISyntaxException;
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;
17 import org.apache.http.client.ClientProtocolException;
19 import android.app.DialogFragment;
20 import android.content.SharedPreferences;
21 import android.graphics.Bitmap;
22 import android.graphics.BitmapFactory;
23 import android.net.http.AndroidHttpClient;
24 import android.os.AsyncTask;
25 import android.os.Bundle;
26 import android.os.Parcelable;
27 import android.preference.PreferenceManager;
28 import android.support.v4.app.ListFragment;
29 import android.util.Log;
30 import android.view.View;
31 import android.widget.ListView;
33 import com.fasterxml.jackson.core.JsonParseException;
35 import de.example.exampletdd.R;
36 import de.example.exampletdd.activityinterface.GetWeather;
37 import de.example.exampletdd.fragment.ProgressDialogFragment;
38 import de.example.exampletdd.httpclient.CustomHTTPClient;
39 import de.example.exampletdd.model.GeocodingData;
40 import de.example.exampletdd.model.forecastweather.ForecastWeatherData;
41 import de.example.exampletdd.parser.IJPOSWeatherParser;
42 import de.example.exampletdd.parser.JPOSWeatherParser;
43 import de.example.exampletdd.service.WeatherServiceParser;
44 import de.example.exampletdd.service.WeatherServicePersistenceFile;
46 public class WeatherInformationOverviewFragment extends ListFragment implements GetWeather {
47 private boolean mIsFahrenheit;
48 private String mDayForecast;
49 private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
50 private Parcelable mListState;
53 public void onCreate(final Bundle savedInstanceState) {
54 super.onCreate(savedInstanceState);
56 final SharedPreferences sharedPreferences = PreferenceManager
57 .getDefaultSharedPreferences(this.getActivity());
58 final String keyPreference = this.getResources().getString(
59 R.string.weather_preferences_day_forecast_key);
60 this.mDayForecast = sharedPreferences.getString(keyPreference, "");
62 this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
63 this.mWeatherServicePersistenceFile.removeForecastWeatherData();
67 public void onActivityCreated(final Bundle savedInstanceState) {
68 super.onActivityCreated(savedInstanceState);
70 final ListView listWeatherView = this.getListView();
71 listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
73 if (savedInstanceState != null) {
75 final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState
76 .getSerializable("ForecastWeatherData");
78 if (forecastWeatherData != null) {
80 this.mWeatherServicePersistenceFile
81 .storeForecastWeatherData(forecastWeatherData);
82 } catch (final IOException e) {
83 // final DialogFragment newFragment = ErrorDialogFragment
84 // .newInstance(R.string.error_dialog_generic_error);
85 // newFragment.show(this.getFragmentManager(), "errorDialog");
89 this.mListState = savedInstanceState.getParcelable("ListState");
92 this.setHasOptionsMenu(false);
94 final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(
95 this.getActivity(), R.layout.weather_main_entry_list);
98 this.setEmptyText("Press download to receive weather information");
100 this.setListAdapter(adapter);
101 this.setListShown(true);
102 this.setListShownNoAnimation(true);
106 public void onListItemClick(final ListView l, final View v, final int position, final long id) {
107 // final WeatherInformationSpecificDataFragment fragment = (WeatherInformationSpecificDataFragment) this.getFragmentManager()
108 // .findFragmentById(R.id.weather_specific_data__fragment);
109 // if (fragment == null) {
111 // final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO").
112 // setComponent(new ComponentName("de.example.exampletdd",
113 // "de.example.exampletdd.WeatherInformationSpecificDataActivity"));
114 // intent.putExtra("CHOSEN_DAY", (int) id);
115 // WeatherInformationOverviewFragment.this.getActivity().startActivity(intent);
118 // fragment.getWeatherByDay((int) id);
123 public void onSaveInstanceState(final Bundle savedInstanceState) {
126 final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
127 .getForecastWeatherData();
129 if (forecastWeatherData != null) {
130 savedInstanceState.putSerializable("ForecastWeatherData", forecastWeatherData);
133 this.mListState = this.getListView().onSaveInstanceState();
134 savedInstanceState.putParcelable("ListState", this.mListState);
136 super.onSaveInstanceState(savedInstanceState);
140 public void getRemoteWeatherInformation() {
142 final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
144 if (geocodingData != null) {
145 final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
146 final WeatherServiceParser weatherService = new WeatherServiceParser(
148 final AndroidHttpClient httpClient = AndroidHttpClient
149 .newInstance("Android Weather Information Agent");
150 final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(
153 final ForecastWeatherTask weatherTask = new ForecastWeatherTask(HTTPweatherClient,
157 weatherTask.execute(geocodingData);
162 public void getWeatherByDay(final int chosenDay) {
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);
172 final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
173 tempFormatter.applyPattern("#####.##");
174 final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.US);
175 final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d", Locale.US);
176 final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
177 final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
180 final Calendar calendar = Calendar.getInstance();
181 for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData
186 if ((forecast.getWeather().size() > 0) &&
187 (forecast.getWeather().get(0).getIcon() != null) &&
188 (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) {
189 final String icon = forecast.getWeather().get(0).getIcon();
190 picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
191 .getResourceDrawable());
193 picture = BitmapFactory.decodeResource(this.getResources(),
194 R.drawable.weather_severe_alert);
197 final Long forecastUNIXDate = (Long) forecast.getDt();
198 calendar.setTimeInMillis(forecastUNIXDate * 1000L);
199 final Date dayTime = calendar.getTime();
200 final String dayTextName = dayNameFormatter.format(dayTime);
201 final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime);
203 Double maxTemp = null;
204 if (forecast.getTemp().getMax() != null) {
205 maxTemp = (Double) forecast.getTemp().getMax();
206 maxTemp = maxTemp - tempUnits;
209 Double minTemp = null;
210 if (forecast.getTemp().getMin() != null) {
211 minTemp = (Double) forecast.getTemp().getMin();
212 minTemp = minTemp - tempUnits;
215 if ((maxTemp != null) && (minTemp != null)) {
216 entries.add(new WeatherOverviewEntry(dayTextName, monthAndDayNumberText,
217 tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol,
222 this.setListAdapter(null);
223 adapter.addAll(entries);
224 this.setListAdapter(adapter);
228 public void onResume() {
231 final SharedPreferences sharedPreferences = PreferenceManager
232 .getDefaultSharedPreferences(this.getActivity());
234 // 1. Update units of measurement.
235 String keyPreference = this.getResources().getString(
236 R.string.weather_preferences_units_key);
237 final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
238 final String celsius = this.getResources().getString(
239 R.string.weather_preferences_units_celsius);
240 if (unitsPreferenceValue.equals(celsius)) {
241 this.mIsFahrenheit = false;
243 this.mIsFahrenheit = true;
246 // 2. Update number day forecast.
247 keyPreference = this.getResources().getString(
248 R.string.weather_preferences_day_forecast_key);
249 this.mDayForecast = sharedPreferences.getString(keyPreference, "");
252 // 3. Update forecast weather data on display.
253 final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile
254 .getForecastWeatherData();
255 if ((this.mListState != null) && (forecastWeatherData != null)) {
256 this.updateForecastWeatherData(forecastWeatherData);
257 this.getListView().onRestoreInstanceState(this.mListState);
258 } else if (forecastWeatherData != null) {
259 this.updateForecastWeatherData(forecastWeatherData);
264 public class ForecastWeatherTask extends AsyncTask<Object, Void, ForecastWeatherData> {
265 private static final String TAG = "ForecastWeatherTask";
266 private final CustomHTTPClient weatherHTTPClient;
267 private final WeatherServiceParser weatherService;
268 private final DialogFragment newFragment;
270 public ForecastWeatherTask(final CustomHTTPClient weatherHTTPClient,
271 final WeatherServiceParser weatherService) {
272 this.weatherHTTPClient = weatherHTTPClient;
273 this.weatherService = weatherService;
274 this.newFragment = ProgressDialogFragment.newInstance(
275 R.string.progress_dialog_get_remote_data,
276 WeatherInformationOverviewFragment.this
277 .getString(R.string.progress_dialog_generic_message));
281 protected void onPreExecute() {
282 this.newFragment.show(WeatherInformationOverviewFragment.this.getActivity()
283 .getFragmentManager(), "progressDialog");
287 protected ForecastWeatherData doInBackground(final Object... params) {
288 ForecastWeatherData forecastWeatherData = null;
291 forecastWeatherData = this.doInBackgroundThrowable(params);
292 } catch (final ClientProtocolException e) {
293 Log.e(TAG, "doInBackground exception: ", e);
294 } catch (final MalformedURLException e) {
295 Log.e(TAG, "doInBackground exception: ", e);
296 } catch (final URISyntaxException e) {
297 Log.e(TAG, "doInBackground exception: ", e);
298 } catch (final JsonParseException e) {
299 Log.e(TAG, "doInBackground exception: ", e);
300 } catch (final IOException e) {
301 // logger infrastructure swallows UnknownHostException :/
302 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
304 this.weatherHTTPClient.close();
307 return forecastWeatherData;
311 protected void onPostExecute(final ForecastWeatherData weatherData) {
312 this.weatherHTTPClient.close();
314 this.newFragment.dismiss();
316 if (weatherData != null) {
318 this.onPostExecuteThrowable(weatherData);
319 } catch (final IOException e) {
320 Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
321 // final DialogFragment newFragment = ErrorDialogFragment
322 // .newInstance(R.string.error_dialog_generic_error);
323 // newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
326 // final DialogFragment newFragment = ErrorDialogFragment
327 // .newInstance(R.string.error_dialog_generic_error);
328 // newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
333 protected void onCancelled(final ForecastWeatherData weatherData) {
334 this.weatherHTTPClient.close();
336 // final DialogFragment newFragment = ErrorDialogFragment
337 // .newInstance(R.string.error_dialog_connection_tiemout);
338 // newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog");
341 private ForecastWeatherData doInBackgroundThrowable(final Object... params)
342 throws ClientProtocolException, MalformedURLException,
343 URISyntaxException, JsonParseException, IOException {
346 final GeocodingData geocodingData = (GeocodingData) params[0];
349 final String APIVersion = WeatherInformationOverviewFragment.this.getResources()
350 .getString(R.string.api_version);
352 final String urlAPI = WeatherInformationOverviewFragment.this.getResources()
353 .getString(R.string.uri_api_weather_forecast);
354 final String url = this.weatherService.createURIAPIForecastWeather(urlAPI, APIVersion,
355 geocodingData.getLatitude(), geocodingData.getLongitude(), WeatherInformationOverviewFragment.this.mDayForecast);
356 final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
357 final ForecastWeatherData forecastWeatherData = this.weatherService
358 .retrieveForecastWeatherDataFromJPOS(jsonData);
360 return forecastWeatherData;
363 private void onPostExecuteThrowable(final ForecastWeatherData forecastWeatherData)
364 throws FileNotFoundException, IOException {
365 WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile
366 .storeForecastWeatherData(forecastWeatherData);
368 WeatherInformationOverviewFragment.this.updateForecastWeatherData(forecastWeatherData);