From 7321e2664c82e50ec70ba2c9506918767e537d0a Mon Sep 17 00:00:00 2001 From: "gu.martinm@gmail.com" Date: Tue, 15 Apr 2014 12:58:56 +0200 Subject: [PATCH] Current and forecast weather information. --- AndroidManifest.xml | 9 + res/layout/weather_current_data.xml | 16 + res/layout/weather_map.xml | 2 +- res/layout/weather_specific_data.xml | 2 +- res/menu/weather_main_menu.xml | 13 +- res/values/strings.xml | 1 + .../exampletdd/WeatherInformationActivity.java | 12 +- .../WeatherInformationCurrentDataActivity.java | 54 +++ .../WeatherInformationSpecificDataActivity.java | 3 - .../WeatherInformationCurrentDataFragment.java | 427 +++++++++++++++++++++ .../WeatherInformationOverviewFragment.java | 176 ++------- .../WeatherInformationSpecificDataFragment.java | 147 +------ 12 files changed, 588 insertions(+), 274 deletions(-) create mode 100644 res/layout/weather_current_data.xml create mode 100644 src/de/example/exampletdd/WeatherInformationCurrentDataActivity.java create mode 100644 src/de/example/exampletdd/fragment/current/WeatherInformationCurrentDataFragment.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 488258d..096164b 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -66,6 +66,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/weather_map.xml b/res/layout/weather_map.xml index c08aaa9..e3a4d5b 100644 --- a/res/layout/weather_map.xml +++ b/res/layout/weather_map.xml @@ -8,7 +8,7 @@ android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" - tools:context="de.example.exampletdd.WeatherInformationActivity" > + tools:context="de.example.exampletdd.WeatherInformationMapActivity" > - + + diff --git a/res/values/strings.xml b/res/values/strings.xml index bd03e46..2e4725b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5,6 +5,7 @@ Settings City,country Get weather + Current weather Select Location Set Location http://api.openweathermap.org/data/{0}/weather?lat={1}&lon={2}&cnt=1 diff --git a/src/de/example/exampletdd/WeatherInformationActivity.java b/src/de/example/exampletdd/WeatherInformationActivity.java index 1e97ba3..876310b 100644 --- a/src/de/example/exampletdd/WeatherInformationActivity.java +++ b/src/de/example/exampletdd/WeatherInformationActivity.java @@ -64,8 +64,8 @@ public class WeatherInformationActivity extends Activity { Intent intent; switch (item.getItemId()) { case R.id.weather_menu_settings: - intent = new Intent("de.example.exampletdd.WEATHERINFO"). - setComponent(new ComponentName("de.example.exampletdd", + intent = new Intent("de.example.exampletdd.WEATHERINFO") + .setComponent(new ComponentName("de.example.exampletdd", "de.example.exampletdd.WeatherInformationPreferencesActivity")); this.startActivity(intent); return true; @@ -74,8 +74,14 @@ public class WeatherInformationActivity extends Activity { return true; case R.id.weather_menu_map: intent = new Intent("de.example.exampletdd.WEATHERINFO") + .setComponent(new ComponentName("de.example.exampletdd", + "de.example.exampletdd.WeatherInformationMapActivity")); + this.startActivity(intent); + return true; + case R.id.weather_menu_current: + intent = new Intent("de.example.exampletdd.WEATHERINFO") .setComponent(new ComponentName("de.example.exampletdd", - "de.example.exampletdd.WeatherInformationMapActivity")); + "de.example.exampletdd.WeatherInformationCurrentDataActivity")); this.startActivity(intent); return true; default: diff --git a/src/de/example/exampletdd/WeatherInformationCurrentDataActivity.java b/src/de/example/exampletdd/WeatherInformationCurrentDataActivity.java new file mode 100644 index 0000000..ff6da3d --- /dev/null +++ b/src/de/example/exampletdd/WeatherInformationCurrentDataActivity.java @@ -0,0 +1,54 @@ +package de.example.exampletdd; + +import android.app.ActionBar; +import android.app.Activity; +import android.os.Bundle; +import android.preference.PreferenceManager; +import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment; +import de.example.exampletdd.model.GeocodingData; +import de.example.exampletdd.service.WeatherServicePersistenceFile; + +public class WeatherInformationCurrentDataActivity extends Activity { + private WeatherServicePersistenceFile mWeatherServicePersistenceFile; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.setContentView(R.layout.weather_current_data); + + final ActionBar actionBar = this.getActionBar(); + + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE); + actionBar.setDisplayHomeAsUpEnabled(true); + + final WeatherInformationSpecificDataFragment fragment = new WeatherInformationSpecificDataFragment(); + + if (savedInstanceState == null) { + this.getFragmentManager().beginTransaction().add(R.id.container, fragment).commit(); + } + + this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this); + } + + @Override + public void onResume() { + super.onResume(); + + final ActionBar actionBar = this.getActionBar(); + + actionBar.setTitle("Current weather information"); + + final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData(); + + if (geocodingData != null) { + final String city = (geocodingData.getCity() == null) ? this + .getString(R.string.city_not_found) : geocodingData.getCity(); + final String country = (geocodingData.getCountry() == null) ? this + .getString(R.string.country_not_found) : geocodingData.getCountry(); + actionBar.setTitle("Current weather data information"); + actionBar.setSubtitle(city + "," + country); + } + + } +} diff --git a/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java b/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java index 130831c..0b8e3fb 100644 --- a/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java +++ b/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java @@ -3,7 +3,6 @@ package de.example.exampletdd; import android.app.ActionBar; import android.app.Activity; import android.os.Bundle; -import android.preference.PreferenceManager; import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment; import de.example.exampletdd.model.GeocodingData; import de.example.exampletdd.service.WeatherServicePersistenceFile; @@ -16,8 +15,6 @@ public class WeatherInformationSpecificDataActivity extends Activity { super.onCreate(savedInstanceState); this.setContentView(R.layout.weather_specific_data); - PreferenceManager.setDefaultValues(this, R.xml.weather_preferences, false); - final ActionBar actionBar = this.getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); diff --git a/src/de/example/exampletdd/fragment/current/WeatherInformationCurrentDataFragment.java b/src/de/example/exampletdd/fragment/current/WeatherInformationCurrentDataFragment.java new file mode 100644 index 0000000..4f4a2ba --- /dev/null +++ b/src/de/example/exampletdd/fragment/current/WeatherInformationCurrentDataFragment.java @@ -0,0 +1,427 @@ +package de.example.exampletdd.fragment.current; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import org.apache.http.client.ClientProtocolException; + +import android.app.DialogFragment; +import android.app.Fragment; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.http.AndroidHttpClient; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ListView; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.R; +import de.example.exampletdd.fragment.ErrorDialogFragment; +import de.example.exampletdd.fragment.ProgressDialogFragment; +import de.example.exampletdd.fragment.specific.WeatherSpecificDataAdapter; +import de.example.exampletdd.fragment.specific.WeatherSpecificDataEntry; +import de.example.exampletdd.httpclient.CustomHTTPClient; +import de.example.exampletdd.model.GeocodingData; +import de.example.exampletdd.model.currentweather.CurrentWeatherData; +import de.example.exampletdd.parser.IJPOSWeatherParser; +import de.example.exampletdd.parser.JPOSWeatherParser; +import de.example.exampletdd.service.WeatherServiceParser; +import de.example.exampletdd.service.WeatherServicePersistenceFile; + +public class WeatherInformationCurrentDataFragment extends Fragment { + private boolean mIsFahrenheit; + private WeatherServicePersistenceFile mWeatherServicePersistenceFile; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // final SharedPreferences sharedPreferences = PreferenceManager + // .getDefaultSharedPreferences(this.getActivity()); + // final String keyPreference = this.getResources().getString( + // R.string.weather_preferences_language_key); + // this.mLanguage = sharedPreferences.getString( + // keyPreference, ""); + + this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity()); + this.mWeatherServicePersistenceFile.removeCurrentWeatherData(); + } + + @Override + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, + final Bundle savedInstanceState) { + final View rootView = inflater.inflate(R.layout.weather_data_list, container, false); + + return rootView; + } + + @Override + public void onActivityCreated(final Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + final ListView listWeatherView = (ListView) this.getActivity().findViewById( + R.id.weather_data_list_view); + + final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter( + this.getActivity(), R.layout.weather_data_entry_list); + + if (savedInstanceState != null) { + // Restore state + final CurrentWeatherData currentWeatherData = (CurrentWeatherData) savedInstanceState + .getSerializable("CurrentWeatherData"); + + if (currentWeatherData != null) { + try { + this.mWeatherServicePersistenceFile.storeCurrentWeatherData(currentWeatherData); + } catch (final IOException e) { + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_generic_error); + newFragment.show(this.getFragmentManager(), "errorDialog"); + } + } + } + + final Collection entries = this.createEmptyEntriesList(); + + adapter.addAll(entries); + listWeatherView.setAdapter(adapter); + + } + + @Override + public void onResume() { + super.onResume(); + + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getActivity()); + + // 1. Update units of measurement. + final String keyPreference = this.getResources().getString( + R.string.weather_preferences_units_key); + final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + final String celsius = this.getResources().getString( + R.string.weather_preferences_units_celsius); + if (unitsPreferenceValue.equals(celsius)) { + this.mIsFahrenheit = false; + } else { + this.mIsFahrenheit = true; + } + + // 2. Try to restore old information + final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile + .getCurrentWeatherData(); + if (currentWeatherData != null) { + this.updateCurrentWeatherData(currentWeatherData); + } else { + // 2.1 Empty list by default + final List entries = this.createEmptyEntriesList(); + + final ListView listWeatherView = (ListView) this.getActivity().findViewById( + R.id.weather_data_list_view); + + final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter( + this.getActivity(), R.layout.weather_data_entry_list); + adapter.addAll(entries); + listWeatherView.setAdapter(adapter); + + // 2.2. Try to update weather data on display with remote + // information. + this.getRemoteCurrentWeatherInformation(); + } + + + + // 3. If language changed, try to retrieve new data for new language + // (new strings with the chosen language) + // keyPreference = this.getResources().getString( + // R.string.weather_preferences_language_key); + // final String languagePreferenceValue = sharedPreferences.getString( + // keyPreference, ""); + // if (!languagePreferenceValue.equals(this.mLanguage)) { + // this.mLanguage = languagePreferenceValue; + // this.getWeather(); + // } + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + + // Save state + final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile + .getCurrentWeatherData(); + + if (currentWeatherData != null) { + savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData); + } + + super.onSaveInstanceState(savedInstanceState); + } + + + public void updateCurrentWeatherData(final CurrentWeatherData currentWeatherData) { + final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale + .getDefault()); + tempFormatter.applyPattern("#####.#####"); + final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z", + Locale.getDefault()); + + final double tempUnits = this.mIsFahrenheit ? 0 : 273.15; + + final List entries = this.createEmptyEntriesList(); + + final ListView listWeatherView = (ListView) this.getActivity().findViewById( + R.id.weather_data_list_view); + + final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter( + this.getActivity(), R.layout.weather_data_entry_list); + + if (currentWeatherData.getWeather().size() > 0) { + entries.set(0, + new WeatherSpecificDataEntry(this.getString(R.string.text_field_description), + currentWeatherData.getWeather().get(0).getDescription())); + } + + if (currentWeatherData.getMain().getTemp() != null) { + double conversion = (Double) currentWeatherData.getMain().getTemp(); + conversion = conversion - tempUnits; + entries.set(1, new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem), + tempFormatter.format(conversion))); + } + + if (currentWeatherData.getMain().getTemp_max() != null) { + double conversion = (Double) currentWeatherData.getMain().getTemp_max(); + conversion = conversion - tempUnits; + entries.set(2, new WeatherSpecificDataEntry( + this.getString(R.string.text_field_tem_max), tempFormatter.format(conversion))); + } + + if (currentWeatherData.getMain().getTemp_max() != null) { + double conversion = (Double) currentWeatherData.getMain().getTemp_min(); + conversion = conversion - tempUnits; + entries.set(3, new WeatherSpecificDataEntry( + this.getString(R.string.text_field_tem_min), tempFormatter.format(conversion))); + } + + if (currentWeatherData.getSys().getSunrise() != null) { + final long unixTime = (Long) currentWeatherData.getSys().getSunrise(); + final Date unixDate = new Date(unixTime * 1000L); + final String dateFormatUnix = dateFormat.format(unixDate); + entries.set(4, + new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_rise), + dateFormatUnix)); + } + + if (currentWeatherData.getSys().getSunset() != null) { + final long unixTime = (Long) currentWeatherData.getSys().getSunset(); + final Date unixDate = new Date(unixTime * 1000L); + final String dateFormatUnix = dateFormat.format(unixDate); + entries.set(5, new WeatherSpecificDataEntry( + this.getString(R.string.text_field_sun_set), dateFormatUnix)); + } + + if (currentWeatherData.getClouds().getAll() != null) { + final double cloudiness = (Double) currentWeatherData.getClouds().getAll(); + entries.set(6, + new WeatherSpecificDataEntry(this.getString(R.string.text_field_cloudiness), + tempFormatter.format(cloudiness))); + } + + if (currentWeatherData.getIconData() != null) { + final Bitmap icon = BitmapFactory.decodeByteArray(currentWeatherData.getIconData(), 0, + currentWeatherData.getIconData().length); + final ImageView imageIcon = (ImageView) this.getActivity().findViewById( + R.id.weather_picture); + imageIcon.setImageBitmap(icon); + } + + listWeatherView.setAdapter(null); + adapter.addAll(entries); + listWeatherView.setAdapter(adapter); + } + + public class CurrentWeatherTask extends AsyncTask { + private static final String TAG = "WeatherTask"; + private final CustomHTTPClient weatherHTTPClient; + private final WeatherServiceParser weatherService; + private final DialogFragment newFragment; + + public CurrentWeatherTask(final CustomHTTPClient weatherHTTPClient, + final WeatherServiceParser weatherService) { + this.weatherHTTPClient = weatherHTTPClient; + this.weatherService = weatherService; + this.newFragment = ProgressDialogFragment.newInstance( + R.string.progress_dialog_get_remote_data, + WeatherInformationCurrentDataFragment.this + .getString(R.string.progress_dialog_generic_message)); + } + + @Override + protected void onPreExecute() { + this.newFragment.show(WeatherInformationCurrentDataFragment.this.getActivity() + .getFragmentManager(), "progressDialog"); + } + + @Override + protected CurrentWeatherData doInBackground(final Object... params) { + CurrentWeatherData currentWeatherData = null; + + try { + currentWeatherData = this.doInBackgroundThrowable(params); + } catch (final ClientProtocolException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final MalformedURLException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final URISyntaxException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final JsonParseException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final IOException e) { + // logger infrastructure swallows UnknownHostException :/ + Log.e(TAG, "doInBackground exception: " + e.getMessage(), e); + } finally { + this.weatherHTTPClient.close(); + } + + return currentWeatherData; + } + + @Override + protected void onPostExecute(final CurrentWeatherData currentWeatherData) { + this.weatherHTTPClient.close(); + + this.newFragment.dismiss(); + + if (currentWeatherData != null) { + try { + this.onPostExecuteThrowable(currentWeatherData); + } catch (final IOException e) { + Log.e(TAG, "WeatherTask onPostExecute exception: ", e); + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_generic_error); + newFragment.show( + WeatherInformationCurrentDataFragment.this.getFragmentManager(), + "errorDialog"); + } + } else { + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_generic_error); + newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(), + "errorDialog"); + } + } + + @Override + protected void onCancelled(final CurrentWeatherData currentWeatherData) { + this.weatherHTTPClient.close(); + + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_connection_tiemout); + newFragment.show(WeatherInformationCurrentDataFragment.this.getFragmentManager(), + "errorDialog"); + } + + private CurrentWeatherData doInBackgroundThrowable(final Object... params) + throws ClientProtocolException, MalformedURLException, URISyntaxException, + JsonParseException, IOException { + // final SharedPreferences sharedPreferences = PreferenceManager + // .getDefaultSharedPreferences(WeatherInformationCurrentDataFragment.this + // .getActivity()); + // + // final String keyPreference = + // WeatherInformationCurrentDataFragment.this + // .getActivity().getString( + // R.string.weather_preferences_language_key); + // final String languagePreferenceValue = + // sharedPreferences.getString(keyPreference, ""); + + // 1. Coordinates + final GeocodingData geocodingData = (GeocodingData) params[0]; + + final String APIVersion = WeatherInformationCurrentDataFragment.this.getResources() + .getString(R.string.api_version); + + // 2. Today + final String urlAPI = WeatherInformationCurrentDataFragment.this.getResources() + .getString(R.string.uri_api_weather_today); + final String url = this.weatherService.createURIAPITodayWeather(urlAPI, APIVersion, + geocodingData.getLatitude(), geocodingData.getLongitude()); + final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url)); + final CurrentWeatherData currentWeatherData = this.weatherService + .retrieveCurrentWeatherDataFromJPOS(jsonData); + final Calendar now = Calendar.getInstance(); + currentWeatherData.setDate(now.getTime()); + + + return currentWeatherData; + } + + private void onPostExecuteThrowable(final CurrentWeatherData currentWeatherData) + throws FileNotFoundException, IOException { + + WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile + .storeCurrentWeatherData(currentWeatherData); + + WeatherInformationCurrentDataFragment.this.updateCurrentWeatherData(currentWeatherData); + } + } + + private void getRemoteCurrentWeatherInformation() { + + final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData(); + + if (geocodingData != null) { + final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser(); + final WeatherServiceParser weatherService = new WeatherServiceParser(JPOSWeatherParser); + final AndroidHttpClient httpClient = AndroidHttpClient + .newInstance("Android Weather Information Agent"); + final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient(httpClient); + + final CurrentWeatherTask weatherTask = new CurrentWeatherTask(HTTPweatherClient, + weatherService); + + weatherTask.execute(geocodingData); + } + } + + private List createEmptyEntriesList() { + final List entries = new ArrayList(); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_description), + null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem), null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem_max), null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem_min), null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_rise), null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_set), null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_cloudiness), + null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_rain_time), + null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_rain_amount), + null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_wind_speed), + null)); + entries.add(new WeatherSpecificDataEntry(this.getString(R.string.text_field_humidity), null)); + + return entries; + } +} diff --git a/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java b/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java index 227e374..c401d64 100644 --- a/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java +++ b/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java @@ -11,7 +11,6 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; -import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -41,7 +40,6 @@ import de.example.exampletdd.fragment.ProgressDialogFragment; import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment; import de.example.exampletdd.httpclient.CustomHTTPClient; import de.example.exampletdd.model.GeocodingData; -import de.example.exampletdd.model.currentweather.CurrentWeatherData; import de.example.exampletdd.model.forecastweather.ForecastWeatherData; import de.example.exampletdd.parser.IJPOSWeatherParser; import de.example.exampletdd.parser.JPOSWeatherParser; @@ -71,6 +69,8 @@ public class WeatherInformationOverviewFragment extends ListFragment implements public void onActivityCreated(final Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); + + final ListView listWeatherView = this.getListView(); listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE); @@ -79,14 +79,11 @@ public class WeatherInformationOverviewFragment extends ListFragment implements // Restore state final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState .getSerializable("ForecastWeatherData"); - final CurrentWeatherData currentWeatherData = (CurrentWeatherData) savedInstanceState - .getSerializable("CurrentWeatherData"); - if ((forecastWeatherData != null) && (currentWeatherData != null)) { + if (forecastWeatherData != null) { try { this.mWeatherServicePersistenceFile .storeForecastWeatherData(forecastWeatherData); - this.mWeatherServicePersistenceFile.storeCurrentWeatherData(currentWeatherData); } catch (final IOException e) { final DialogFragment newFragment = ErrorDialogFragment .newInstance(R.string.error_dialog_generic_error); @@ -117,11 +114,11 @@ public class WeatherInformationOverviewFragment extends ListFragment implements final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO"). setComponent(new ComponentName("de.example.exampletdd", "de.example.exampletdd.WeatherInformationSpecificDataActivity")); - intent.putExtra("CHOSEN_DAY", id); + intent.putExtra("CHOSEN_DAY", (int) id); WeatherInformationOverviewFragment.this.getActivity().startActivity(intent); } else { // tablet layout - fragment.getWeatherByDay(position); + fragment.getWeatherByDay((int) id); } } @@ -132,12 +129,8 @@ public class WeatherInformationOverviewFragment extends ListFragment implements final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile .getForecastWeatherData(); - final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile - .getCurrentWeatherData(); - - if ((forecastWeatherData != null) && (currentWeatherData != null)) { + if (forecastWeatherData != null) { savedInstanceState.putSerializable("ForecastWeatherData", forecastWeatherData); - savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData); } super.onSaveInstanceState(savedInstanceState); @@ -157,7 +150,8 @@ public class WeatherInformationOverviewFragment extends ListFragment implements final CustomHTTPClient HTTPweatherClient = new CustomHTTPClient( httpClient); - final WeatherTask weatherTask = new WeatherTask(HTTPweatherClient, weatherService); + final ForecastWeatherTask weatherTask = new ForecastWeatherTask(HTTPweatherClient, + weatherService); weatherTask.execute(geocodingData); @@ -169,7 +163,7 @@ public class WeatherInformationOverviewFragment extends ListFragment implements // Nothing to do. } - public void updateForecastWeatherData(final WeatherData weatherData) { + public void updateForecastWeatherData(final ForecastWeatherData forecastWeatherData) { final List entries = new ArrayList(); final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(this.getActivity(), R.layout.weather_main_entry_list); @@ -182,70 +176,33 @@ public class WeatherInformationOverviewFragment extends ListFragment implements final double tempUnits = this.mIsFahrenheit ? 0 : 273.15; final String symbol = this.mIsFahrenheit ? "ºF" : "ºC"; - final CurrentWeatherData currentWeatherData = weatherData.getCurrentWeatherData(); - - String formatMaxTemp; - String formatMinTemp; - - if (currentWeatherData.getMain().getTemp_max() != null) { - double maxTemp = (Double) currentWeatherData.getMain().getTemp_max(); - maxTemp = maxTemp - tempUnits; - formatMaxTemp = tempFormatter.format(maxTemp) + symbol; - } else { - formatMaxTemp = "no data"; - } - if (currentWeatherData.getMain().getTemp_min() != null) { - double minTemp = (Double) currentWeatherData.getMain().getTemp_min(); - minTemp = minTemp - tempUnits; - formatMinTemp = tempFormatter.format(minTemp) + symbol; - } else { - formatMinTemp = "no data"; - } - - entries.add(new WeatherOverviewEntry(dateFormat.format(currentWeatherData.getDate()), - formatMaxTemp, formatMinTemp, picture)); - - - final ForecastWeatherData forecastWeatherData = weatherData.getForecastWeatherData(); final Calendar calendar = Calendar.getInstance(); - calendar.setTime(currentWeatherData.getDate()); + for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData + .getList()) { - final int forecastSize = forecastWeatherData.getList().size(); - final int chosenForecastDays = 14; - final int index = forecastSize < chosenForecastDays ? forecastSize : chosenForecastDays; - for (int i = 0; i < index; i++) { - calendar.add(Calendar.DAY_OF_MONTH, 1); - final de.example.exampletdd.model.forecastweather.List forecast = forecastWeatherData - .getList().get(i); + final Long forecastUNIXDate = (Long) forecast.getDt(); + calendar.setTimeInMillis(forecastUNIXDate * 1000L); + final Date dayTime = calendar.getTime(); + final String dayText = dateFormat.format(dayTime); + Double maxTemp = null; if (forecast.getTemp().getMax() != null) { - double maxTemp = (Double) forecast.getTemp().getMax(); + maxTemp = (Double) forecast.getTemp().getMax(); maxTemp = maxTemp - tempUnits; - formatMaxTemp = tempFormatter.format(maxTemp) + symbol; - } else { - formatMaxTemp = "no data"; } + Double minTemp = null; if (forecast.getTemp().getMin() != null) { - double minTemp = (Double) forecast.getTemp().getMin(); + minTemp = (Double) forecast.getTemp().getMin(); minTemp = minTemp - tempUnits; - formatMinTemp = tempFormatter.format(minTemp) + symbol; - } else { - formatMinTemp = "no data"; } - final Date day = calendar.getTime(); - entries.add(new WeatherOverviewEntry(dateFormat.format(day), formatMaxTemp, - formatMinTemp, picture)); - } - - final int leftDays = chosenForecastDays - index; - for (int i = 0; i < leftDays; i++) { - calendar.add(Calendar.DAY_OF_MONTH, 1); - final Date day = calendar.getTime(); - entries.add(new WeatherOverviewEntry(dateFormat.format(day), "no data", "no data", picture)); + if ((maxTemp != null) && (minTemp != null)) { + entries.add(new WeatherOverviewEntry(dayText, tempFormatter.format(maxTemp) + + symbol, tempFormatter.format(minTemp) + symbol, picture)); + } } this.setListAdapter(null); @@ -276,11 +233,8 @@ public class WeatherInformationOverviewFragment extends ListFragment implements // 2. Update forecast weather data on display. final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile .getForecastWeatherData(); - final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile - .getCurrentWeatherData(); - if ((forecastWeatherData != null) && (currentWeatherData != null)) { - final WeatherData weatherData = new WeatherData(forecastWeatherData, currentWeatherData); - this.updateForecastWeatherData(weatherData); + if (forecastWeatherData != null) { + this.updateForecastWeatherData(forecastWeatherData); } @@ -296,13 +250,13 @@ public class WeatherInformationOverviewFragment extends ListFragment implements // } } - public class WeatherTask extends AsyncTask { - private static final String TAG = "WeatherTask"; + public class ForecastWeatherTask extends AsyncTask { + private static final String TAG = "ForecastWeatherTask"; private final CustomHTTPClient weatherHTTPClient; private final WeatherServiceParser weatherService; private final DialogFragment newFragment; - public WeatherTask(final CustomHTTPClient weatherHTTPClient, + public ForecastWeatherTask(final CustomHTTPClient weatherHTTPClient, final WeatherServiceParser weatherService) { this.weatherHTTPClient = weatherHTTPClient; this.weatherService = weatherService; @@ -319,11 +273,11 @@ public class WeatherInformationOverviewFragment extends ListFragment implements } @Override - protected WeatherData doInBackground(final Object... params) { - WeatherData weatherData = null; + protected ForecastWeatherData doInBackground(final Object... params) { + ForecastWeatherData forecastWeatherData = null; try { - weatherData = this.doInBackgroundThrowable(params); + forecastWeatherData = this.doInBackgroundThrowable(params); } catch (final ClientProtocolException e) { Log.e(TAG, "doInBackground exception: ", e); } catch (final MalformedURLException e) { @@ -339,11 +293,11 @@ public class WeatherInformationOverviewFragment extends ListFragment implements this.weatherHTTPClient.close(); } - return weatherData; + return forecastWeatherData; } @Override - protected void onPostExecute(final WeatherData weatherData) { + protected void onPostExecute(final ForecastWeatherData weatherData) { this.weatherHTTPClient.close(); this.newFragment.dismiss(); @@ -365,7 +319,7 @@ public class WeatherInformationOverviewFragment extends ListFragment implements } @Override - protected void onCancelled(final WeatherData weatherData) { + protected void onCancelled(final ForecastWeatherData weatherData) { this.weatherHTTPClient.close(); final DialogFragment newFragment = ErrorDialogFragment @@ -373,7 +327,7 @@ public class WeatherInformationOverviewFragment extends ListFragment implements newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog"); } - private WeatherData doInBackgroundThrowable(final Object... params) + private ForecastWeatherData doInBackgroundThrowable(final Object... params) throws ClientProtocolException, MalformedURLException, URISyntaxException, JsonParseException, IOException { // final SharedPreferences sharedPreferences = PreferenceManager @@ -391,72 +345,26 @@ public class WeatherInformationOverviewFragment extends ListFragment implements final GeocodingData geocodingData = (GeocodingData) params[0]; - final Calendar now = Calendar.getInstance(); final String APIVersion = WeatherInformationOverviewFragment.this.getResources() .getString(R.string.api_version); // 2. Forecast - String urlAPI = WeatherInformationOverviewFragment.this.getResources() + final String urlAPI = WeatherInformationOverviewFragment.this.getResources() .getString(R.string.uri_api_weather_forecast); - String url = this.weatherService.createURIAPIForecastWeather(urlAPI, APIVersion, + final String url = this.weatherService.createURIAPIForecastWeather(urlAPI, APIVersion, geocodingData.getLatitude(), geocodingData.getLongitude(), "14"); - String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url)); + final String jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url)); final ForecastWeatherData forecastWeatherData = this.weatherService .retrieveForecastWeatherDataFromJPOS(jsonData); - final Iterator iterator = - forecastWeatherData.getList().iterator(); - while (iterator.hasNext()) { - final de.example.exampletdd.model.forecastweather.List forecast = iterator.next(); - - final Long forecastUNIXDate = (Long) forecast.getDt(); - final Calendar forecastCalendar = Calendar.getInstance(); - forecastCalendar.setTimeInMillis(forecastUNIXDate * 1000L); - if (now.compareTo(forecastCalendar) == 1) { - iterator.remove(); - } - } - - // 3. Today - urlAPI = WeatherInformationOverviewFragment.this.getResources().getString( - R.string.uri_api_weather_today); - url = this.weatherService.createURIAPITodayWeather(urlAPI, APIVersion, - geocodingData.getLatitude(), geocodingData.getLongitude()); - jsonData = this.weatherHTTPClient.retrieveDataAsString(new URL(url)); - final CurrentWeatherData currentWeatherData = this.weatherService - .retrieveCurrentWeatherDataFromJPOS(jsonData); - currentWeatherData.setDate(now.getTime()); - - final WeatherData weatherData = new WeatherData(forecastWeatherData, currentWeatherData); - - return weatherData; + return forecastWeatherData; } - private void onPostExecuteThrowable(final WeatherData weatherData) + private void onPostExecuteThrowable(final ForecastWeatherData forecastWeatherData) throws FileNotFoundException, IOException { WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile - .storeForecastWeatherData(weatherData.getForecastWeatherData()); - WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile - .storeCurrentWeatherData(weatherData.getCurrentWeatherData()); - - WeatherInformationOverviewFragment.this.updateForecastWeatherData(weatherData); - } - } - - private class WeatherData { - private final ForecastWeatherData forecastWeatherData; - private final CurrentWeatherData currentWeatherData; - - private WeatherData(final ForecastWeatherData forecastWeatherData, final CurrentWeatherData currentWeatherData) { - this.forecastWeatherData = forecastWeatherData; - this.currentWeatherData = currentWeatherData; - } - - private ForecastWeatherData getForecastWeatherData() { - return this.forecastWeatherData; - } + .storeForecastWeatherData(forecastWeatherData); - private CurrentWeatherData getCurrentWeatherData() { - return this.currentWeatherData; + WeatherInformationOverviewFragment.this.updateForecastWeatherData(forecastWeatherData); } } } diff --git a/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java b/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java index 19ea58f..8de11a0 100644 --- a/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java +++ b/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java @@ -3,35 +3,29 @@ package de.example.exampletdd.fragment.specific; import java.io.IOException; import java.text.DecimalFormat; import java.text.NumberFormat; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; -import java.util.Date; import java.util.List; import java.util.Locale; import android.app.DialogFragment; import android.app.Fragment; import android.content.SharedPreferences; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; import android.widget.ListView; import de.example.exampletdd.R; import de.example.exampletdd.activityinterface.GetWeather; import de.example.exampletdd.fragment.ErrorDialogFragment; -import de.example.exampletdd.model.currentweather.CurrentWeatherData; import de.example.exampletdd.model.forecastweather.ForecastWeatherData; import de.example.exampletdd.service.WeatherServicePersistenceFile; public class WeatherInformationSpecificDataFragment extends Fragment implements GetWeather { private boolean mIsFahrenheit; - private long mChosenDay; + private int mChosenDay; private WeatherServicePersistenceFile mWeatherServicePersistenceFile; @Override @@ -41,7 +35,7 @@ public class WeatherInformationSpecificDataFragment extends Fragment implements final Bundle extras = this.getActivity().getIntent().getExtras(); if (extras != null) { - this.mChosenDay = extras.getLong("CHOSEN_DAY", 0); + this.mChosenDay = extras.getInt("CHOSEN_DAY", 0); } else { this.mChosenDay = 0; } @@ -85,14 +79,11 @@ public class WeatherInformationSpecificDataFragment extends Fragment implements // Restore state final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState .getSerializable("ForecastWeatherData"); - final CurrentWeatherData currentWeatherData = (CurrentWeatherData) savedInstanceState - .getSerializable("CurrentWeatherData"); - if ((forecastWeatherData != null) && (currentWeatherData != null)) { + if (forecastWeatherData != null) { try { this.mWeatherServicePersistenceFile .storeForecastWeatherData(forecastWeatherData); - this.mWeatherServicePersistenceFile.storeCurrentWeatherData(currentWeatherData); } catch (final IOException e) { final DialogFragment newFragment = ErrorDialogFragment .newInstance(R.string.error_dialog_generic_error); @@ -109,12 +100,8 @@ public class WeatherInformationSpecificDataFragment extends Fragment implements final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile .getForecastWeatherData(); - final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile - .getCurrentWeatherData(); - - if ((forecastWeatherData != null) && (currentWeatherData != null)) { + if (forecastWeatherData != null) { savedInstanceState.putSerializable("ForecastWeatherData", forecastWeatherData); - savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData); } super.onSaveInstanceState(savedInstanceState); @@ -122,20 +109,13 @@ public class WeatherInformationSpecificDataFragment extends Fragment implements @Override public void getWeatherByDay(final int chosenDay) { - if (chosenDay == 0) { - final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile - .getCurrentWeatherData(); - if (currentWeatherData != null) { - this.updateCurrentWeatherData(currentWeatherData); - } - } else { - final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile - .getForecastWeatherData(); - if (forecastWeatherData != null) { - this.updateForecastWeatherData(forecastWeatherData, chosenDay); - } + final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile + .getForecastWeatherData(); + if (forecastWeatherData != null) { + this.updateForecastWeatherData(forecastWeatherData, chosenDay); } + } @Override @@ -143,87 +123,6 @@ public class WeatherInformationSpecificDataFragment extends Fragment implements // Nothing to do. } - public void updateCurrentWeatherData(final CurrentWeatherData currentWeatherData) { - final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.getDefault()); - tempFormatter.applyPattern("#####.#####"); - final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z", Locale.getDefault()); - - final double tempUnits = this.mIsFahrenheit ? 0 : 273.15; - - final List entries = this.createEmptyEntriesList(); - - final ListView listWeatherView = (ListView) this.getActivity().findViewById( - R.id.weather_data_list_view); - - final WeatherSpecificDataAdapter adapter = new WeatherSpecificDataAdapter(this.getActivity(), - R.layout.weather_data_entry_list); - - if (currentWeatherData.getWeather().size() > 0) { - entries.set(0, new WeatherSpecificDataEntry(this.getString(R.string.text_field_description), - currentWeatherData.getWeather().get(0).getDescription())); - } - - if (currentWeatherData.getMain().getTemp() != null) { - double conversion = (Double) currentWeatherData.getMain().getTemp(); - conversion = conversion - tempUnits; - entries.set(1, new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem), - tempFormatter.format(conversion))); - } - - if (currentWeatherData.getMain().getTemp_max() != null) { - double conversion = (Double) currentWeatherData.getMain().getTemp_max(); - conversion = conversion - tempUnits; - entries.set(2, new WeatherSpecificDataEntry( - this.getString(R.string.text_field_tem_max), tempFormatter.format(conversion))); - } - - if (currentWeatherData.getMain().getTemp_max() != null) { - double conversion = (Double) currentWeatherData.getMain().getTemp_min(); - conversion = conversion - tempUnits; - entries.set(3, new WeatherSpecificDataEntry( - this.getString(R.string.text_field_tem_min), tempFormatter.format(conversion))); - } - - - if (currentWeatherData.getSys().getSunrise() != null) { - final long unixTime = (Long) currentWeatherData.getSys().getSunrise(); - final Date unixDate = new Date(unixTime * 1000L); - final String dateFormatUnix = dateFormat.format(unixDate); - entries.set(4, - new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_rise), - dateFormatUnix)); - } - - if (currentWeatherData.getSys().getSunset() != null) { - final long unixTime = (Long) currentWeatherData.getSys().getSunset(); - final Date unixDate = new Date(unixTime * 1000L); - final String dateFormatUnix = dateFormat.format(unixDate); - entries.set(5, new WeatherSpecificDataEntry( - this.getString(R.string.text_field_sun_set), dateFormatUnix)); - } - - if (currentWeatherData.getClouds().getAll() != null) { - final double cloudiness = (Double) currentWeatherData.getClouds().getAll(); - entries.set(6, - new WeatherSpecificDataEntry(this.getString(R.string.text_field_cloudiness), - tempFormatter.format(cloudiness))); - } - - if (currentWeatherData.getIconData() != null) { - final Bitmap icon = BitmapFactory.decodeByteArray( - currentWeatherData.getIconData(), 0, - currentWeatherData.getIconData().length); - final ImageView imageIcon = (ImageView) this.getActivity() - .findViewById(R.id.weather_picture); - imageIcon.setImageBitmap(icon); - } - - - - listWeatherView.setAdapter(null); - adapter.addAll(entries); - listWeatherView.setAdapter(adapter); - } public void updateForecastWeatherData(final ForecastWeatherData forecastWeatherData, final int chosenDay) { @@ -239,20 +138,13 @@ public class WeatherInformationSpecificDataFragment extends Fragment implements this.getActivity(), R.layout.weather_data_entry_list); - final int forecastSize = forecastWeatherData.getList().size(); - if (chosenDay > forecastSize) { - // Nothing to do. - return; - } - - final de.example.exampletdd.model.forecastweather.List forecast = forecastWeatherData - .getList().get((chosenDay - 1)); + .getList().get((chosenDay)); if (forecast.getWeather().size() > 0) { entries.set(0, new WeatherSpecificDataEntry(this.getString(R.string.text_field_description), - forecast.getWeather().get(0).getDescription())); + forecast.getWeather().get(0).getDescription())); } if (forecast.getTemp().getDay() != null) { @@ -310,22 +202,15 @@ public class WeatherInformationSpecificDataFragment extends Fragment implements // 2. Update weather data on display. - if (this.mChosenDay == 0) { - final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile - .getCurrentWeatherData(); - if (currentWeatherData != null) { - this.updateCurrentWeatherData(currentWeatherData); - } - } else { - final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile - .getForecastWeatherData(); - if (forecastWeatherData != null) { - this.updateForecastWeatherData(forecastWeatherData, (int) this.mChosenDay); - } + final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile + .getForecastWeatherData(); + if (forecastWeatherData != null) { + this.updateForecastWeatherData(forecastWeatherData, this.mChosenDay); } + // 3. If language changed, try to retrieve new data for new language // (new strings with the chosen language) // keyPreference = this.getResources().getString( -- 2.1.4