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.app.DialogFragment;
18 import android.content.SharedPreferences;
19 import android.graphics.Bitmap;
20 import android.graphics.BitmapFactory;
21 import android.net.http.AndroidHttpClient;
22 import android.os.AsyncTask;
23 import android.os.Bundle;
24 import android.preference.PreferenceManager;
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.ProgressDialogFragment;
33 import de.example.exampletdd.fragment.overview.IconsList;
34 import de.example.exampletdd.httpclient.CustomHTTPClient;
35 import de.example.exampletdd.model.GeocodingData;
36 import de.example.exampletdd.model.currentweather.CurrentWeatherData;
37 import de.example.exampletdd.parser.IJPOSWeatherParser;
38 import de.example.exampletdd.parser.JPOSWeatherParser;
39 import de.example.exampletdd.service.WeatherServiceParser;
40 import de.example.exampletdd.service.WeatherServicePersistenceFile;
42 public class WeatherInformationCurrentDataFragment extends ListFragment {
43 private boolean mIsFahrenheit;
44 private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
47 public void onCreate(final Bundle savedInstanceState) {
48 super.onCreate(savedInstanceState);
50 this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
51 this.mWeatherServicePersistenceFile.removeCurrentWeatherData();
55 public void onActivityCreated(final Bundle savedInstanceState) {
56 super.onActivityCreated(savedInstanceState);
58 final ListView listWeatherView = this.getListView();
59 listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
61 if (savedInstanceState != null) {
63 final CurrentWeatherData currentWeatherData = (CurrentWeatherData) savedInstanceState
64 .getSerializable("CurrentWeatherData");
66 if (currentWeatherData != null) {
68 this.mWeatherServicePersistenceFile.storeCurrentWeatherData(currentWeatherData);
69 } catch (final IOException e) {
70 // final DialogFragment newFragment = ErrorDialogFragment
71 // .newInstance(R.string.error_dialog_generic_error);
72 // newFragment.show(this.getFragmentManager(), "errorDialog");
77 this.setHasOptionsMenu(false);
79 this.setEmptyText("No data available");
81 this.setListShownNoAnimation(false);
85 public void onResume() {
88 final SharedPreferences sharedPreferences = PreferenceManager
89 .getDefaultSharedPreferences(this.getActivity());
91 // 1. Update units of measurement.
92 final String keyPreference = this.getResources().getString(
93 R.string.weather_preferences_units_key);
94 final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
95 final String celsius = this.getResources().getString(
96 R.string.weather_preferences_units_celsius);
97 if (unitsPreferenceValue.equals(celsius)) {
98 this.mIsFahrenheit = false;
100 this.mIsFahrenheit = true;
103 // 2. Try to restore old information
104 final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
105 .getCurrentWeatherData();
106 if (currentWeatherData != null) {
107 this.updateCurrentWeatherData(currentWeatherData);
109 // 3. Try to update weather data on display with remote
110 this.getRemoteCurrentWeatherInformation();
115 public void onSaveInstanceState(final Bundle savedInstanceState) {
118 final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
119 .getCurrentWeatherData();
121 if (currentWeatherData != null) {
122 savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData);
125 super.onSaveInstanceState(savedInstanceState);
129 public void updateCurrentWeatherData(final CurrentWeatherData currentWeatherData) {
130 final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
131 tempFormatter.applyPattern("#####.#####");
132 final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z", Locale.US);
134 final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
135 final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
137 final int[] layouts = new int[3];
138 layouts[0] = R.layout.weather_current_data_entry_first;
139 layouts[1] = R.layout.weather_current_data_entry_second;
140 layouts[2] = R.layout.weather_current_data_entry_fifth;
141 final WeatherCurrentDataAdapter adapter = new WeatherCurrentDataAdapter(this.getActivity(),
146 if (currentWeatherData.getMain().getTemp_max() != null) {
147 double conversion = (Double) currentWeatherData.getMain().getTemp_max();
148 conversion = conversion - tempUnits;
149 tempMax = tempFormatter.format(conversion) + symbol;
152 if (currentWeatherData.getMain().getTemp_min() != null) {
153 double conversion = (Double) currentWeatherData.getMain().getTemp_min();
154 conversion = conversion - tempUnits;
155 tempMin = tempFormatter.format(conversion) + symbol;
158 if ((currentWeatherData.getWeather().size() > 0)
159 && (currentWeatherData.getWeather().get(0).getIcon() != null)
160 && (IconsList.getIcon(currentWeatherData.getWeather().get(0).getIcon()) != null)) {
161 final String icon = currentWeatherData.getWeather().get(0).getIcon();
162 picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
163 .getResourceDrawable());
165 picture = BitmapFactory.decodeResource(this.getResources(),
166 R.drawable.weather_severe_alert);
168 final WeatherCurrentDataEntryFirst entryFirst = new WeatherCurrentDataEntryFirst(tempMax,
170 adapter.add(entryFirst);
172 String description = "no description available";
173 if (currentWeatherData.getWeather().size() > 0) {
174 description = currentWeatherData.getWeather().get(0).getDescription();
176 final WeatherCurrentDataEntrySecond entrySecond = new WeatherCurrentDataEntrySecond(
178 adapter.add(entrySecond);
180 String humidityValue = "";
181 if ((currentWeatherData.getMain() != null)
182 && (currentWeatherData.getMain().getHumidity() != null)) {
183 final double conversion = (Double) currentWeatherData.getMain().getHumidity();
184 humidityValue = tempFormatter.format(conversion);
186 String pressureValue = "";
187 if ((currentWeatherData.getMain() != null)
188 && (currentWeatherData.getMain().getPressure() != null)) {
189 final double conversion = (Double) currentWeatherData.getMain().getPressure();
190 pressureValue = tempFormatter.format(conversion);
192 String windValue = "";
193 if ((currentWeatherData.getWind() != null)
194 && (currentWeatherData.getWind().getSpeed() != null)) {
195 final double conversion = (Double) currentWeatherData.getWind().getSpeed();
196 windValue = tempFormatter.format(conversion);
198 String rainValue = "";
199 if ((currentWeatherData.getRain() != null)
200 && (currentWeatherData.getRain().get3h() != null)) {
201 final double conversion = (Double) currentWeatherData.getRain().get3h();
202 rainValue = tempFormatter.format(conversion);
204 String cloudsValue = "";
205 if ((currentWeatherData.getClouds() != null)
206 && (currentWeatherData.getClouds().getAll() != null)) {
207 final double conversion = (Double) currentWeatherData.getClouds().getAll();
208 cloudsValue = tempFormatter.format(conversion);
210 String snowValue = "";
211 if ((currentWeatherData.getSnow() != null)
212 && (currentWeatherData.getSnow().get3h() != null)) {
213 final double conversion = (Double) currentWeatherData.getSnow().get3h();
214 snowValue = tempFormatter.format(conversion);
216 String feelsLike = "";
217 if (currentWeatherData.getMain().getTemp() != null) {
218 double conversion = (Double) currentWeatherData.getMain().getTemp();
219 conversion = conversion - tempUnits;
220 feelsLike = tempFormatter.format(conversion);
222 String sunRiseTime = "";
223 if (currentWeatherData.getSys().getSunrise() != null) {
224 final long unixTime = (Long) currentWeatherData.getSys().getSunrise();
225 final Date unixDate = new Date(unixTime * 1000L);
226 sunRiseTime = dateFormat.format(unixDate);
228 String sunSetTime = "";
229 if (currentWeatherData.getSys().getSunset() != null) {
230 final long unixTime = (Long) currentWeatherData.getSys().getSunset();
231 final Date unixDate = new Date(unixTime * 1000L);
232 sunSetTime = dateFormat.format(unixDate);
234 final WeatherCurrentDataEntryFifth entryFifth = new WeatherCurrentDataEntryFifth(
235 sunRiseTime, sunSetTime, humidityValue, pressureValue, windValue, rainValue,
236 feelsLike, symbol, snowValue, cloudsValue);
237 adapter.add(entryFifth);
240 this.setListAdapter(adapter);
243 public class CurrentWeatherTask extends AsyncTask<Object, Void, CurrentWeatherData> {
244 private static final String TAG = "WeatherTask";
245 private final CustomHTTPClient weatherHTTPClient;
246 private final WeatherServiceParser weatherService;
247 private final DialogFragment newFragment;
249 public CurrentWeatherTask(final CustomHTTPClient weatherHTTPClient,
250 final WeatherServiceParser weatherService) {
251 this.weatherHTTPClient = weatherHTTPClient;
252 this.weatherService = weatherService;
253 this.newFragment = ProgressDialogFragment.newInstance(
254 R.string.progress_dialog_get_remote_data,
255 WeatherInformationCurrentDataFragment.this
256 .getString(R.string.progress_dialog_generic_message));
260 protected void onPreExecute() {
261 this.newFragment.show(WeatherInformationCurrentDataFragment.this.getActivity()
262 .getFragmentManager(), "progressDialog");
266 protected CurrentWeatherData doInBackground(final Object... params) {
267 CurrentWeatherData currentWeatherData = null;
270 currentWeatherData = this.doInBackgroundThrowable(params);
271 } catch (final ClientProtocolException e) {
272 Log.e(TAG, "doInBackground exception: ", e);
273 } catch (final MalformedURLException e) {
274 Log.e(TAG, "doInBackground exception: ", e);
275 } catch (final URISyntaxException e) {
276 Log.e(TAG, "doInBackground exception: ", e);
277 } catch (final JsonParseException e) {
278 Log.e(TAG, "doInBackground exception: ", e);
279 } catch (final IOException e) {
280 // logger infrastructure swallows UnknownHostException :/
281 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
283 this.weatherHTTPClient.close();
286 return currentWeatherData;
290 protected void onPostExecute(final CurrentWeatherData currentWeatherData) {
291 this.weatherHTTPClient.close();
293 this.newFragment.dismiss();
295 if (currentWeatherData != null) {
297 this.onPostExecuteThrowable(currentWeatherData);
298 } catch (final IOException e) {
299 WeatherInformationCurrentDataFragment.this.setListShown(true);
300 Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
301 // final DialogFragment newFragment = ErrorDialogFragment
302 // .newInstance(R.string.error_dialog_generic_error);
304 // WeatherInformationCurrentDataFragment.this.getFragmentManager(),
308 WeatherInformationCurrentDataFragment.this.setListShown(true);
309 // final DialogFragment newFragment = ErrorDialogFragment
310 // .newInstance(R.string.error_dialog_generic_error);
311 // newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
317 protected void onCancelled(final CurrentWeatherData currentWeatherData) {
318 this.weatherHTTPClient.close();
320 // final DialogFragment newFragment = ErrorDialogFragment
321 // .newInstance(R.string.error_dialog_connection_tiemout);
322 // newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
326 private CurrentWeatherData doInBackgroundThrowable(final Object... params)
327 throws ClientProtocolException, MalformedURLException, URISyntaxException,
328 JsonParseException, IOException {
331 final GeocodingData geocodingData = (GeocodingData) params[0];
333 final String APIVersion = WeatherInformationCurrentDataFragment.this.getResources()
334 .getString(R.string.api_version);
337 final String urlAPI = WeatherInformationCurrentDataFragment.this.getResources()
338 .getString(R.string.uri_api_weather_today);
339 final String url = this.weatherService.createURIAPITodayWeather(urlAPI, APIVersion,
340 geocodingData.getLatitude(), geocodingData.getLongitude());
341 final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
342 final CurrentWeatherData currentWeatherData = this.weatherService
343 .retrieveCurrentWeatherDataFromJPOS(jsonData);
344 final Calendar now = Calendar.getInstance();
345 currentWeatherData.setDate(now.getTime());
348 return currentWeatherData;
351 private void onPostExecuteThrowable(final CurrentWeatherData currentWeatherData)
352 throws FileNotFoundException, IOException {
354 WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile
355 .storeCurrentWeatherData(currentWeatherData);
357 WeatherInformationCurrentDataFragment.this.updateCurrentWeatherData(currentWeatherData);
361 private void getRemoteCurrentWeatherInformation() {
363 final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
365 if (geocodingData != null) {
366 final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
367 final WeatherServiceParser weatherService = new WeatherServiceParser(JPOSWeatherParser);
368 final AndroidHttpClient httpClient = AndroidHttpClient
369 .newInstance("Android Weather Information Agent");
370 final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(httpClient);
372 final CurrentWeatherTask weatherTask = new CurrentWeatherTask(HTTPweatherClient,
375 weatherTask.execute(geocodingData);