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.ArrayList;
12 import java.util.Calendar;
13 import java.util.Collection;
14 import java.util.Date;
15 import java.util.List;
16 import java.util.Locale;
18 import org.apache.http.client.ClientProtocolException;
20 import android.app.DialogFragment;
21 import android.app.Fragment;
22 import android.content.SharedPreferences;
23 import android.graphics.Bitmap;
24 import android.graphics.BitmapFactory;
25 import android.net.http.AndroidHttpClient;
26 import android.os.AsyncTask;
27 import android.os.Bundle;
28 import android.preference.PreferenceManager;
29 import android.util.Log;
30 import android.view.LayoutInflater;
31 import android.view.View;
32 import android.view.ViewGroup;
33 import android.widget.ImageView;
34 import android.widget.ListView;
36 import com.fasterxml.jackson.core.JsonParseException;
38 import de.example.exampletdd.R;
39 import de.example.exampletdd.fragment.ErrorDialogFragment;
40 import de.example.exampletdd.fragment.ProgressDialogFragment;
41 import de.example.exampletdd.fragment.specific.WeatherSpecificDataAdapter;
42 import de.example.exampletdd.fragment.specific.WeatherSpecificDataEntry;
43 import de.example.exampletdd.httpclient.CustomHTTPClient;
44 import de.example.exampletdd.model.GeocodingData;
45 import de.example.exampletdd.model.currentweather.CurrentWeatherData;
46 import de.example.exampletdd.parser.IJPOSWeatherParser;
47 import de.example.exampletdd.parser.JPOSWeatherParser;
48 import de.example.exampletdd.service.WeatherServiceParser;
49 import de.example.exampletdd.service.WeatherServicePersistenceFile;
51 public class WeatherInformationCurrentDataFragment extends Fragment {
52 private boolean mIsFahrenheit;
53 private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
56 public void onCreate(final Bundle savedInstanceState) {
57 super.onCreate(savedInstanceState);
59 // final SharedPreferences sharedPreferences = PreferenceManager
60 // .getDefaultSharedPreferences(this.getActivity());
61 // final String keyPreference = this.getResources().getString(
62 // R.string.weather_preferences_language_key);
63 // this.mLanguage = sharedPreferences.getString(
64 // keyPreference, "");
66 this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
67 this.mWeatherServicePersistenceFile.removeCurrentWeatherData();
71 public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
72 final Bundle savedInstanceState) {
73 final View rootView = inflater.inflate(R.layout.weather_data_list, container, false);
79 public void onActivityCreated(final Bundle savedInstanceState) {
80 super.onActivityCreated(savedInstanceState);
82 final ListView listWeatherView = (ListView) this.getActivity().findViewById(
83 R.id.weather_data_list_view);
85 final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter(
86 this.getActivity(), R.layout.weather_data_entry_list);
88 if (savedInstanceState != null) {
90 final CurrentWeatherData currentWeatherData = (CurrentWeatherData) savedInstanceState
91 .getSerializable("CurrentWeatherData");
93 if (currentWeatherData != null) {
95 this.mWeatherServicePersistenceFile.storeCurrentWeatherData(currentWeatherData);
96 } catch (final IOException e) {
97 final DialogFragment newFragment = ErrorDialogFragment
98 .newInstance(R.string.error_dialog_generic_error);
99 newFragment.show(this.getFragmentManager(), "errorDialog");
104 final Collection<WeatherSpecificDataEntry> entries = this.createEmptyEntriesList();
106 adapter.addAll(entries);
107 listWeatherView.setAdapter(adapter);
112 public void onResume() {
115 final SharedPreferences sharedPreferences = PreferenceManager
116 .getDefaultSharedPreferences(this.getActivity());
118 // 1. Update units of measurement.
119 final String keyPreference = this.getResources().getString(
120 R.string.weather_preferences_units_key);
121 final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
122 final String celsius = this.getResources().getString(
123 R.string.weather_preferences_units_celsius);
124 if (unitsPreferenceValue.equals(celsius)) {
125 this.mIsFahrenheit = false;
127 this.mIsFahrenheit = true;
130 // 2. Try to restore old information
131 final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
132 .getCurrentWeatherData();
133 if (currentWeatherData != null) {
134 this.updateCurrentWeatherData(currentWeatherData);
136 // 2.1 Empty list by default
137 final List<WeatherSpecificDataEntry> entries = this.createEmptyEntriesList();
139 final ListView listWeatherView = (ListView) this.getActivity().findViewById(
140 R.id.weather_data_list_view);
142 final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter(
143 this.getActivity(), R.layout.weather_data_entry_list);
144 adapter.addAll(entries);
145 listWeatherView.setAdapter(adapter);
147 // 2.2. Try to update weather data on display with remote
149 this.getRemoteCurrentWeatherInformation();
154 // 3. If language changed, try to retrieve new data for new language
155 // (new strings with the chosen language)
156 // keyPreference = this.getResources().getString(
157 // R.string.weather_preferences_language_key);
158 // final String languagePreferenceValue = sharedPreferences.getString(
159 // keyPreference, "");
160 // if (!languagePreferenceValue.equals(this.mLanguage)) {
161 // this.mLanguage = languagePreferenceValue;
162 // this.getWeather();
167 public void onSaveInstanceState(final Bundle savedInstanceState) {
170 final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
171 .getCurrentWeatherData();
173 if (currentWeatherData != null) {
174 savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData);
177 super.onSaveInstanceState(savedInstanceState);
181 public void updateCurrentWeatherData(final CurrentWeatherData currentWeatherData) {
182 final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale
184 tempFormatter.applyPattern("#####.#####");
185 final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z",
186 Locale.getDefault());
188 final double tempUnits = this.mIsFahrenheit ? 0 : 273.15;
190 final List<WeatherSpecificDataEntry> entries = this.createEmptyEntriesList();
192 final ListView listWeatherView = (ListView) this.getActivity().findViewById(
193 R.id.weather_data_list_view);
195 final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter(
196 this.getActivity(), R.layout.weather_data_entry_list);
198 if (currentWeatherData.getWeather().size() > 0) {
200 new WeatherSpecificDataEntry(this.getString(R.string.text_field_description),
201 currentWeatherData.getWeather().get(0).getDescription()));
204 if (currentWeatherData.getMain().getTemp() != null) {
205 double conversion = (Double) currentWeatherData.getMain().getTemp();
206 conversion = conversion - tempUnits;
207 entries.set(1, new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem),
208 tempFormatter.format(conversion)));
211 if (currentWeatherData.getMain().getTemp_max() != null) {
212 double conversion = (Double) currentWeatherData.getMain().getTemp_max();
213 conversion = conversion - tempUnits;
214 entries.set(2, new WeatherSpecificDataEntry(
215 this.getString(R.string.text_field_tem_max), tempFormatter.format(conversion)));
218 if (currentWeatherData.getMain().getTemp_max() != null) {
219 double conversion = (Double) currentWeatherData.getMain().getTemp_min();
220 conversion = conversion - tempUnits;
221 entries.set(3, new WeatherSpecificDataEntry(
222 this.getString(R.string.text_field_tem_min), tempFormatter.format(conversion)));
225 if (currentWeatherData.getSys().getSunrise() != null) {
226 final long unixTime = (Long) currentWeatherData.getSys().getSunrise();
227 final Date unixDate = new Date(unixTime * 1000L);
228 final String dateFormatUnix = dateFormat.format(unixDate);
230 new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_rise),
234 if (currentWeatherData.getSys().getSunset() != null) {
235 final long unixTime = (Long) currentWeatherData.getSys().getSunset();
236 final Date unixDate = new Date(unixTime * 1000L);
237 final String dateFormatUnix = dateFormat.format(unixDate);
238 entries.set(5, new WeatherSpecificDataEntry(
239 this.getString(R.string.text_field_sun_set), dateFormatUnix));
242 if (currentWeatherData.getClouds().getAll() != null) {
243 final double cloudiness = (Double) currentWeatherData.getClouds().getAll();
245 new WeatherSpecificDataEntry(this.getString(R.string.text_field_cloudiness),
246 tempFormatter.format(cloudiness)));
249 if (currentWeatherData.getIconData() != null) {
250 final Bitmap icon = BitmapFactory.decodeByteArray(currentWeatherData.getIconData(), 0,
251 currentWeatherData.getIconData().length);
252 final ImageView imageIcon = (ImageView) this.getActivity().findViewById(
253 R.id.weather_picture);
254 imageIcon.setImageBitmap(icon);
257 listWeatherView.setAdapter(null);
258 adapter.addAll(entries);
259 listWeatherView.setAdapter(adapter);
262 public class CurrentWeatherTask extends AsyncTask<Object, Void, CurrentWeatherData> {
263 private static final String TAG = "WeatherTask";
264 private final CustomHTTPClient weatherHTTPClient;
265 private final WeatherServiceParser weatherService;
266 private final DialogFragment newFragment;
268 public CurrentWeatherTask(final CustomHTTPClient weatherHTTPClient,
269 final WeatherServiceParser weatherService) {
270 this.weatherHTTPClient = weatherHTTPClient;
271 this.weatherService = weatherService;
272 this.newFragment = ProgressDialogFragment.newInstance(
273 R.string.progress_dialog_get_remote_data,
274 WeatherInformationCurrentDataFragment.this
275 .getString(R.string.progress_dialog_generic_message));
279 protected void onPreExecute() {
280 this.newFragment.show(WeatherInformationCurrentDataFragment.this.getActivity()
281 .getFragmentManager(), "progressDialog");
285 protected CurrentWeatherData doInBackground(final Object... params) {
286 CurrentWeatherData currentWeatherData = null;
289 currentWeatherData = this.doInBackgroundThrowable(params);
290 } catch (final ClientProtocolException e) {
291 Log.e(TAG, "doInBackground exception: ", e);
292 } catch (final MalformedURLException e) {
293 Log.e(TAG, "doInBackground exception: ", e);
294 } catch (final URISyntaxException e) {
295 Log.e(TAG, "doInBackground exception: ", e);
296 } catch (final JsonParseException e) {
297 Log.e(TAG, "doInBackground exception: ", e);
298 } catch (final IOException e) {
299 // logger infrastructure swallows UnknownHostException :/
300 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
302 this.weatherHTTPClient.close();
305 return currentWeatherData;
309 protected void onPostExecute(final CurrentWeatherData currentWeatherData) {
310 this.weatherHTTPClient.close();
312 this.newFragment.dismiss();
314 if (currentWeatherData != null) {
316 this.onPostExecuteThrowable(currentWeatherData);
317 } catch (final IOException e) {
318 Log.e(TAG, "WeatherTask onPostExecute exception: ", e);
319 final DialogFragment newFragment = ErrorDialogFragment
320 .newInstance(R.string.error_dialog_generic_error);
322 WeatherInformationCurrentDataFragment.this.getFragmentManager(),
326 final DialogFragment newFragment = ErrorDialogFragment
327 .newInstance(R.string.error_dialog_generic_error);
328 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
334 protected void onCancelled(final CurrentWeatherData currentWeatherData) {
335 this.weatherHTTPClient.close();
337 final DialogFragment newFragment = ErrorDialogFragment
338 .newInstance(R.string.error_dialog_connection_tiemout);
339 newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(),
343 private CurrentWeatherData doInBackgroundThrowable(final Object... params)
344 throws ClientProtocolException, MalformedURLException, URISyntaxException,
345 JsonParseException, IOException {
346 // final SharedPreferences sharedPreferences = PreferenceManager
347 // .getDefaultSharedPreferences(WeatherInformationCurrentDataFragment.this
350 // final String keyPreference =
351 // WeatherInformationCurrentDataFragment.this
352 // .getActivity().getString(
353 // R.string.weather_preferences_language_key);
354 // final String languagePreferenceValue =
355 // sharedPreferences.getString(keyPreference, "");
358 final GeocodingData geocodingData = (GeocodingData) params[0];
360 final String APIVersion = WeatherInformationCurrentDataFragment.this.getResources()
361 .getString(R.string.api_version);
364 final String urlAPI = WeatherInformationCurrentDataFragment.this.getResources()
365 .getString(R.string.uri_api_weather_today);
366 final String url = this.weatherService.createURIAPITodayWeather(urlAPI, APIVersion,
367 geocodingData.getLatitude(), geocodingData.getLongitude());
368 final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url));
369 final CurrentWeatherData currentWeatherData = this.weatherService
370 .retrieveCurrentWeatherDataFromJPOS(jsonData);
371 final Calendar now = Calendar.getInstance();
372 currentWeatherData.setDate(now.getTime());
375 return currentWeatherData;
378 private void onPostExecuteThrowable(final CurrentWeatherData currentWeatherData)
379 throws FileNotFoundException, IOException {
381 WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile
382 .storeCurrentWeatherData(currentWeatherData);
384 WeatherInformationCurrentDataFragment.this.updateCurrentWeatherData(currentWeatherData);
388 private void getRemoteCurrentWeatherInformation() {
390 final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
392 if (geocodingData != null) {
393 final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
394 final WeatherServiceParser weatherService = new WeatherServiceParser(JPOSWeatherParser);
395 final AndroidHttpClient httpClient = AndroidHttpClient
396 .newInstance("Android Weather Information Agent");
397 final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(httpClient);
399 final CurrentWeatherTask weatherTask = new CurrentWeatherTask(HTTPweatherClient,
402 weatherTask.execute(geocodingData);
406 private List<WeatherSpecificDataEntry> createEmptyEntriesList() {
407 final List<WeatherSpecificDataEntry> entries = new ArrayList<WeatherSpecificDataEntry>();
408 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_description),
410 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem), null));
411 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem_max), null));
412 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem_min), null));
413 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_rise), null));
414 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_set), null));
415 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_cloudiness),
417 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_rain_time),
419 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_rain_amount),
421 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_wind_speed),
423 entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_humidity), null));