1 package de.example.exampletdd.fragment.current;
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.Calendar;
12 import java.util.Date;
13 import java.util.Locale;
15 import org.apache.http.client.ClientProtocolException;
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;
29 import com.fasterxml.jackson.core.JsonParseException;
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;
43 public class WeatherInformationCurrentDataFragment extends ListFragment {
44 private boolean mIsFahrenheit;
45 private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
48 public void onCreate(final Bundle savedInstanceState) {
49 super.onCreate(savedInstanceState);
51 this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
52 this.mWeatherServicePersistenceFile.removeCurrentWeatherData();
56 public void onActivityCreated(final Bundle savedInstanceState) {
57 super.onActivityCreated(savedInstanceState);
59 final ListView listWeatherView = this.getListView();
60 listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
62 if (savedInstanceState != null) {
64 final CurrentWeatherData currentWeatherData = (CurrentWeatherData) savedInstanceState
65 .getSerializable("CurrentWeatherData");
67 if (currentWeatherData != null) {
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");
78 this.setHasOptionsMenu(false);
80 this.setEmptyText("No data available");
82 this.setListShownNoAnimation(false);
86 public void onResume() {
89 final SharedPreferences sharedPreferences = PreferenceManager
90 .getDefaultSharedPreferences(this.getActivity());
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;
101 this.mIsFahrenheit = true;
104 // 2. Try to restore old information
105 final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
106 .getCurrentWeatherData();
107 if (currentWeatherData != null) {
108 this.updateCurrentWeatherData(currentWeatherData);
110 // 3. Try to update weather data on display with remote
111 this.getRemoteCurrentWeatherInformation();
116 public void onSaveInstanceState(final Bundle savedInstanceState) {
119 final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
120 .getCurrentWeatherData();
122 if (currentWeatherData != null) {
123 savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData);
126 super.onSaveInstanceState(savedInstanceState);
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);
135 final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
136 final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
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(),
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;
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;
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());
166 picture = BitmapFactory.decodeResource(this.getResources(),
167 R.drawable.weather_severe_alert);
169 final WeatherCurrentDataEntryFirst entryFirst = new WeatherCurrentDataEntryFirst(tempMax,
171 adapter.add(entryFirst);
173 String description = "no description available";
174 if (currentWeatherData.getWeather().size() > 0) {
175 description = currentWeatherData.getWeather().get(0).getDescription();
177 final WeatherCurrentDataEntrySecond entrySecond = new WeatherCurrentDataEntrySecond(
179 adapter.add(entrySecond);
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);
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);
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);
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);
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);
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);
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);
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);
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);
235 final WeatherCurrentDataEntryFifth entryFifth = new WeatherCurrentDataEntryFifth(
236 sunRiseTime, sunSetTime, humidityValue, pressureValue, windValue, rainValue,
237 feelsLike, symbol, snowValue, cloudsValue);
238 adapter.add(entryFifth);
241 this.setListAdapter(adapter);
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;
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));
261 protected void onPreExecute() {
262 this.newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
267 protected CurrentWeatherData doInBackground(final Object... params) {
268 CurrentWeatherData currentWeatherData = null;
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);
284 this.weatherHTTPClient.close();
287 return currentWeatherData;
291 protected void onPostExecute(final CurrentWeatherData currentWeatherData) {
292 this.weatherHTTPClient.close();
294 this.newFragment.dismiss();
296 if (currentWeatherData != null) {
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);
305 WeatherInformationCurrentDataFragment.this.getFragmentManager(),
309 WeatherInformationCurrentDataFragment.this.setListShown(true);
310 final DialogFragment newFragment = ErrorDialogFragment
311 .newInstance(R.string.error_dialog_generic_error);
312 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
318 protected void onCancelled(final CurrentWeatherData currentWeatherData) {
319 this.weatherHTTPClient.close();
321 final DialogFragment newFragment = ErrorDialogFragment
322 .newInstance(R.string.error_dialog_connection_tiemout);
323 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
327 private CurrentWeatherData doInBackgroundThrowable(final Object... params)
328 throws ClientProtocolException, MalformedURLException, URISyntaxException,
329 JsonParseException, IOException {
332 final GeocodingData geocodingData = (GeocodingData) params[0];
334 final String APIVersion = WeatherInformationCurrentDataFragment.this.getResources()
335 .getString(R.string.api_version);
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());
349 return currentWeatherData;
352 private void onPostExecuteThrowable(final CurrentWeatherData currentWeatherData)
353 throws FileNotFoundException, IOException {
355 WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile
356 .storeCurrentWeatherData(currentWeatherData);
358 WeatherInformationCurrentDataFragment.this.updateCurrentWeatherData(currentWeatherData);
362 private void getRemoteCurrentWeatherInformation() {
364 final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
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);
373 final CurrentWeatherTask weatherTask = new CurrentWeatherTask(HTTPweatherClient,
376 weatherTask.execute(geocodingData);