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.app.ListFragment;
19 import android.content.SharedPreferences;
20 import android.graphics.Bitmap;
21 import android.graphics.BitmapFactory;
22 import android.net.http.AndroidHttpClient;
23 import android.os.AsyncTask;
24 import android.os.Bundle;
25 import android.preference.PreferenceManager;
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
133 tempFormatter.applyPattern("#####.#####");
134 final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z",
135 Locale.getDefault());
137 final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
138 final String symbol = this.mIsFahrenheit ? "ºF" : "ºC";
140 final int[] layouts = new int[3];
141 layouts[0] = R.layout.weather_current_data_entry_first;
142 layouts[1] = R.layout.weather_current_data_entry_second;
143 layouts[2] = R.layout.weather_current_data_entry_fifth;
144 final WeatherCurrentDataAdapter adapter = new WeatherCurrentDataAdapter(this.getActivity(),
149 if (currentWeatherData.getMain().getTemp_max() != null) {
150 double conversion = (Double) currentWeatherData.getMain().getTemp_max();
151 conversion = conversion - tempUnits;
152 tempMax = tempFormatter.format(conversion) + symbol;
155 if (currentWeatherData.getMain().getTemp_min() != null) {
156 double conversion = (Double) currentWeatherData.getMain().getTemp_min();
157 conversion = conversion - tempUnits;
158 tempMin = tempFormatter.format(conversion) + symbol;
161 if ((currentWeatherData.getWeather().size() > 0)
162 && (currentWeatherData.getWeather().get(0).getIcon() != null)
163 && (IconsList.getIcon(currentWeatherData.getWeather().get(0).getIcon()) != null)) {
164 final String icon = currentWeatherData.getWeather().get(0).getIcon();
165 picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
166 .getResourceDrawable());
168 picture = BitmapFactory.decodeResource(this.getResources(),
169 R.drawable.weather_severe_alert);
171 final WeatherCurrentDataEntryFirst entryFirst = new WeatherCurrentDataEntryFirst(tempMax,
173 adapter.add(entryFirst);
175 String description = "no description available";
176 if (currentWeatherData.getWeather().size() > 0) {
177 description = currentWeatherData.getWeather().get(0).getDescription();
179 final WeatherCurrentDataEntrySecond entrySecond = new WeatherCurrentDataEntrySecond(
181 adapter.add(entrySecond);
183 String humidityValue = "";
184 if ((currentWeatherData.getMain() != null)
185 && (currentWeatherData.getMain().getHumidity() != null)) {
186 final double conversion = (Double) currentWeatherData.getMain().getHumidity();
187 humidityValue = tempFormatter.format(conversion);
189 String pressureValue = "";
190 if ((currentWeatherData.getMain() != null)
191 && (currentWeatherData.getMain().getPressure() != null)) {
192 final double conversion = (Double) currentWeatherData.getMain().getPressure();
193 pressureValue = tempFormatter.format(conversion);
195 String windValue = "";
196 if ((currentWeatherData.getWind() != null)
197 && (currentWeatherData.getWind().getSpeed() != null)) {
198 final double conversion = (Double) currentWeatherData.getWind().getSpeed();
199 windValue = tempFormatter.format(conversion);
201 String rainValue = "";
202 if ((currentWeatherData.getRain() != null)
203 && (currentWeatherData.getRain().get3h() != null)) {
204 final double conversion = (Double) currentWeatherData.getRain().get3h();
205 rainValue = tempFormatter.format(conversion);
207 String cloudsValue = "";
208 if ((currentWeatherData.getClouds() != null)
209 && (currentWeatherData.getClouds().getAll() != null)) {
210 final double conversion = (Double) currentWeatherData.getClouds().getAll();
211 cloudsValue = tempFormatter.format(conversion);
213 String snowValue = "";
214 if ((currentWeatherData.getSnow() != null)
215 && (currentWeatherData.getSnow().get3h() != null)) {
216 final double conversion = (Double) currentWeatherData.getSnow().get3h();
217 snowValue = tempFormatter.format(conversion);
219 String feelsLike = "";
220 if (currentWeatherData.getMain().getTemp() != null) {
221 double conversion = (Double) currentWeatherData.getMain().getTemp();
222 conversion = conversion - tempUnits;
223 feelsLike = tempFormatter.format(conversion);
225 String sunRiseTime = "";
226 if (currentWeatherData.getSys().getSunrise() != null) {
227 final long unixTime = (Long) currentWeatherData.getSys().getSunrise();
228 final Date unixDate = new Date(unixTime * 1000L);
229 sunRiseTime = dateFormat.format(unixDate);
231 String sunSetTime = "";
232 if (currentWeatherData.getSys().getSunset() != null) {
233 final long unixTime = (Long) currentWeatherData.getSys().getSunset();
234 final Date unixDate = new Date(unixTime * 1000L);
235 sunSetTime = dateFormat.format(unixDate);
237 final WeatherCurrentDataEntryFifth entryFifth = new WeatherCurrentDataEntryFifth(
238 sunRiseTime, sunSetTime, humidityValue, pressureValue, windValue, rainValue,
239 feelsLike, symbol, snowValue, cloudsValue);
240 adapter.add(entryFifth);
243 this.setListAdapter(adapter);
246 public class CurrentWeatherTask extends AsyncTask<Object, Void, CurrentWeatherData> {
247 private static final String TAG = "WeatherTask";
248 private final CustomHTTPClient weatherHTTPClient;
249 private final WeatherServiceParser weatherService;
250 private final DialogFragment newFragment;
252 public CurrentWeatherTask(final CustomHTTPClient weatherHTTPClient,
253 final WeatherServiceParser weatherService) {
254 this.weatherHTTPClient = weatherHTTPClient;
255 this.weatherService = weatherService;
256 this.newFragment = ProgressDialogFragment.newInstance(
257 R.string.progress_dialog_get_remote_data,
258 WeatherInformationCurrentDataFragment.this
259 .getString(R.string.progress_dialog_generic_message));
263 protected void onPreExecute() {
264 this.newFragment.show(WeatherInformationCurrentDataFragment.this.getActivity()
265 .getFragmentManager(), "progressDialog");
269 protected CurrentWeatherData doInBackground(final Object... params) {
270 CurrentWeatherData currentWeatherData = null;
273 currentWeatherData = this.doInBackgroundThrowable(params);
274 } catch (final ClientProtocolException e) {
275 Log.e(TAG, "doInBackground exception: ", e);
276 } catch (final MalformedURLException e) {
277 Log.e(TAG, "doInBackground exception: ", e);
278 } catch (final URISyntaxException e) {
279 Log.e(TAG, "doInBackground exception: ", e);
280 } catch (final JsonParseException e) {
281 Log.e(TAG, "doInBackground exception: ", e);
282 } catch (final IOException e) {
283 // logger infrastructure swallows UnknownHostException :/
284 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
286 this.weatherHTTPClient.close();
289 return currentWeatherData;
293 protected void onPostExecute(final CurrentWeatherData currentWeatherData) {
294 this.weatherHTTPClient.close();
296 this.newFragment.dismiss();
298 if (currentWeatherData != null) {
300 this.onPostExecuteThrowable(currentWeatherData);
301 } catch (final IOException e) {
302 WeatherInformationCurrentDataFragment.this.setListShown(true);
303 Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
304 final DialogFragment newFragment = ErrorDialogFragment
305 .newInstance(R.string.error_dialog_generic_error);
307 WeatherInformationCurrentDataFragment.this.getFragmentManager(),
311 WeatherInformationCurrentDataFragment.this.setListShown(true);
312 final DialogFragment newFragment = ErrorDialogFragment
313 .newInstance(R.string.error_dialog_generic_error);
314 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
320 protected void onCancelled(final CurrentWeatherData currentWeatherData) {
321 this.weatherHTTPClient.close();
323 final DialogFragment newFragment = ErrorDialogFragment
324 .newInstance(R.string.error_dialog_connection_tiemout);
325 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
329 private CurrentWeatherData doInBackgroundThrowable(final Object... params)
330 throws ClientProtocolException, MalformedURLException, URISyntaxException,
331 JsonParseException, IOException {
334 final GeocodingData geocodingData = (GeocodingData) params[0];
336 final String APIVersion = WeatherInformationCurrentDataFragment.this.getResources()
337 .getString(R.string.api_version);
340 final String urlAPI = WeatherInformationCurrentDataFragment.this.getResources()
341 .getString(R.string.uri_api_weather_today);
342 final String url = this.weatherService.createURIAPITodayWeather(urlAPI, APIVersion,
343 geocodingData.getLatitude(), geocodingData.getLongitude());
344 final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
345 final CurrentWeatherData currentWeatherData = this.weatherService
346 .retrieveCurrentWeatherDataFromJPOS(jsonData);
347 final Calendar now = Calendar.getInstance();
348 currentWeatherData.setDate(now.getTime());
351 return currentWeatherData;
354 private void onPostExecuteThrowable(final CurrentWeatherData currentWeatherData)
355 throws FileNotFoundException, IOException {
357 WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile
358 .storeCurrentWeatherData(currentWeatherData);
360 WeatherInformationCurrentDataFragment.this.updateCurrentWeatherData(currentWeatherData);
364 private void getRemoteCurrentWeatherInformation() {
366 final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
368 if (geocodingData != null) {
369 final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
370 final WeatherServiceParser weatherService = new WeatherServiceParser(JPOSWeatherParser);
371 final AndroidHttpClient httpClient = AndroidHttpClient
372 .newInstance("Android Weather Information Agent");
373 final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(httpClient);
375 final CurrentWeatherTask weatherTask = new CurrentWeatherTask(HTTPweatherClient,
378 weatherTask.execute(geocodingData);