From cb3de591ae74c40c2e5a068cd142ec8463af4306 Mon Sep 17 00:00:00 2001 From: "gu.martinm@gmail.com" Date: Thu, 10 Apr 2014 18:17:09 +0200 Subject: [PATCH] No time for comments --- res/layout-large/weather_main.xml | 22 + res/layout/weather_data_list.xml | 4 +- res/layout/weather_specific_data.xml | 16 + .../exampletdd/WeatherInformationActivity.java | 11 +- .../WeatherInformationPreferencesActivity.java | 2 +- .../WeatherInformationSpecificDataActivity.java | 89 ++++ .../exampletdd/activityinterface/ErrorMessage.java | 6 - .../exampletdd/activityinterface/GetWeather.java | 3 - .../exampletdd/fragment/WeatherDataAdapter.java | 91 ---- .../exampletdd/fragment/WeatherDataEntry.java | 20 - .../fragment/WeatherInformationDataFragment.java | 470 --------------------- .../WeatherInformationPreferencesFragment.java | 68 --- .../WeatherInformationOverviewFragment.java | 80 ++-- .../WeatherInformationPreferencesFragment.java | 68 +++ .../WeatherInformationSpecificDataFragment.java | 301 +++++++++++++ .../specific/WeatherSpecificDataAdapter.java | 92 ++++ .../specific/WeatherSpecificDataEntry.java | 20 + .../service/WeatherServicePersistence.java | 93 ++++ 18 files changed, 738 insertions(+), 718 deletions(-) create mode 100644 res/layout-large/weather_main.xml create mode 100644 res/layout/weather_specific_data.xml create mode 100644 src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java delete mode 100644 src/de/example/exampletdd/activityinterface/ErrorMessage.java delete mode 100644 src/de/example/exampletdd/fragment/WeatherDataAdapter.java delete mode 100644 src/de/example/exampletdd/fragment/WeatherDataEntry.java delete mode 100644 src/de/example/exampletdd/fragment/WeatherInformationDataFragment.java delete mode 100644 src/de/example/exampletdd/fragment/WeatherInformationPreferencesFragment.java create mode 100644 src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java create mode 100644 src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java create mode 100644 src/de/example/exampletdd/fragment/specific/WeatherSpecificDataAdapter.java create mode 100644 src/de/example/exampletdd/fragment/specific/WeatherSpecificDataEntry.java create mode 100644 src/de/example/exampletdd/service/WeatherServicePersistence.java diff --git a/res/layout-large/weather_main.xml b/res/layout-large/weather_main.xml new file mode 100644 index 0000000..8250d57 --- /dev/null +++ b/res/layout-large/weather_main.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/res/layout/weather_data_list.xml b/res/layout/weather_data_list.xml index e10ceb3..1abb201 100644 --- a/res/layout/weather_data_list.xml +++ b/res/layout/weather_data_list.xml @@ -7,8 +7,8 @@ diff --git a/res/layout/weather_specific_data.xml b/res/layout/weather_specific_data.xml new file mode 100644 index 0000000..8c9fc01 --- /dev/null +++ b/res/layout/weather_specific_data.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/src/de/example/exampletdd/WeatherInformationActivity.java b/src/de/example/exampletdd/WeatherInformationActivity.java index 9864454..978160c 100644 --- a/src/de/example/exampletdd/WeatherInformationActivity.java +++ b/src/de/example/exampletdd/WeatherInformationActivity.java @@ -8,7 +8,6 @@ import java.io.StreamCorruptedException; import android.app.ActionBar; import android.app.Activity; -import android.app.DialogFragment; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; @@ -16,13 +15,11 @@ import android.preference.PreferenceManager; import android.util.Log; import android.view.Menu; import android.view.MenuItem; -import de.example.exampletdd.activityinterface.ErrorMessage; import de.example.exampletdd.activityinterface.GetWeather; -import de.example.exampletdd.fragment.ErrorDialogFragment; import de.example.exampletdd.fragment.overview.WeatherInformationOverviewFragment; import de.example.exampletdd.model.GeocodingData; -public class WeatherInformationActivity extends Activity implements ErrorMessage { +public class WeatherInformationActivity extends Activity { private static final String WEATHER_GEOCODING_FILE = "weathergeocoding.file"; private static final String TAG = "WeatherInformationActivity"; private GetWeather mGetWeather; @@ -120,12 +117,6 @@ public class WeatherInformationActivity extends Activity implements ErrorMessage } - @Override - public void createErrorDialog(final int title) { - final DialogFragment newFragment = ErrorDialogFragment - .newInstance(title); - newFragment.show(this.getFragmentManager(), "errorDialog"); - } public void getWeather() { this.mGetWeather.getWeather(); diff --git a/src/de/example/exampletdd/WeatherInformationPreferencesActivity.java b/src/de/example/exampletdd/WeatherInformationPreferencesActivity.java index 3fe6e9a..e70cfc1 100644 --- a/src/de/example/exampletdd/WeatherInformationPreferencesActivity.java +++ b/src/de/example/exampletdd/WeatherInformationPreferencesActivity.java @@ -2,7 +2,7 @@ package de.example.exampletdd; import android.app.Activity; import android.os.Bundle; -import de.example.exampletdd.fragment.WeatherInformationPreferencesFragment; +import de.example.exampletdd.fragment.preferences.WeatherInformationPreferencesFragment; public class WeatherInformationPreferencesActivity extends Activity { diff --git a/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java b/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java new file mode 100644 index 0000000..ab7b326 --- /dev/null +++ b/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java @@ -0,0 +1,89 @@ +package de.example.exampletdd; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.StreamCorruptedException; + +import android.app.ActionBar; +import android.app.Activity; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.Log; +import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment; +import de.example.exampletdd.model.GeocodingData; + +public class WeatherInformationSpecificDataActivity extends Activity { + private static final String WEATHER_GEOCODING_FILE = "weathergeocoding.file"; + private static final String TAG = "WeatherInformationSpecificDataActivity"; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + 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); + 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(); + } + + } + + @Override + public void onResume() { + super.onResume(); + + final ActionBar actionBar = this.getActionBar(); + + GeocodingData geocodingData = null; + try { + geocodingData = this.restoreGeocodingDataFromFile(); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "onCreate exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "onCreate exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "onCreate exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "onCreate exception: ", e); + } + 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(city + "," + country); + } + + } + + private GeocodingData restoreGeocodingDataFromFile() + throws StreamCorruptedException, FileNotFoundException, + IOException, ClassNotFoundException { + final InputStream persistenceFile = this.openFileInput( + WEATHER_GEOCODING_FILE); + + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(persistenceFile); + + return (GeocodingData) ois.readObject(); + } finally { + if (ois != null) { + ois.close(); + } + } + } +} diff --git a/src/de/example/exampletdd/activityinterface/ErrorMessage.java b/src/de/example/exampletdd/activityinterface/ErrorMessage.java deleted file mode 100644 index 50907b9..0000000 --- a/src/de/example/exampletdd/activityinterface/ErrorMessage.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.example.exampletdd.activityinterface; - -public interface ErrorMessage { - - public void createErrorDialog(final int title); -} diff --git a/src/de/example/exampletdd/activityinterface/GetWeather.java b/src/de/example/exampletdd/activityinterface/GetWeather.java index 9e8b330..98734cd 100644 --- a/src/de/example/exampletdd/activityinterface/GetWeather.java +++ b/src/de/example/exampletdd/activityinterface/GetWeather.java @@ -1,11 +1,8 @@ package de.example.exampletdd.activityinterface; -import de.example.exampletdd.model.WeatherData; public interface GetWeather { public void getWeather(); - public void updateWeatherData(final WeatherData weatherData); - } diff --git a/src/de/example/exampletdd/fragment/WeatherDataAdapter.java b/src/de/example/exampletdd/fragment/WeatherDataAdapter.java deleted file mode 100644 index 71d6cb2..0000000 --- a/src/de/example/exampletdd/fragment/WeatherDataAdapter.java +++ /dev/null @@ -1,91 +0,0 @@ -package de.example.exampletdd.fragment; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; -import de.example.exampletdd.R; - -public class WeatherDataAdapter extends ArrayAdapter { - private final int resource; - - public WeatherDataAdapter(final Context context, final int resource) { - super(context, 0); - - this.resource = resource; - } - - @Override - public View getView(final int position, final View convertView, - final ViewGroup parent) { - - // We need to get the best view (re-used if possible) and then - // retrieve its corresponding ViewHolder, which optimizes lookup - // efficiency - final View view = this.getWorkingView(convertView); - final ViewHolder viewHolder = this.getViewHolder(view); - final WeatherDataEntry entry = this.getItem(position); - - - // Setting the text view - viewHolder.headerView.setText(entry.getHeader()); - viewHolder.bodyView.setText(entry.getBody()); - - - return view; - } - - private View getWorkingView(final View convertView) { - // The workingView is basically just the convertView re-used if possible - // or inflated new if not possible - View workingView = null; - - if(null == convertView) { - final Context context = this.getContext(); - final LayoutInflater inflater = (LayoutInflater)context.getSystemService - (Context.LAYOUT_INFLATER_SERVICE); - - workingView = inflater.inflate(this.resource, null); - } else { - workingView = convertView; - } - - return workingView; - } - - private ViewHolder getViewHolder(final View workingView) { - // The viewHolder allows us to avoid re-looking up view references - // Since views are recycled, these references will never change - final Object tag = workingView.getTag(); - ViewHolder viewHolder = null; - - - if((null == tag) || !(tag instanceof ViewHolder)) { - viewHolder = new ViewHolder(); - - viewHolder.headerView = (TextView) workingView - .findViewById(R.id.weather_data_entry_header); - viewHolder.bodyView = (TextView) workingView - .findViewById(R.id.weather_data_entry_body); - - workingView.setTag(viewHolder); - - } else { - viewHolder = (ViewHolder) tag; - } - - return viewHolder; - } - - /** - * ViewHolder allows us to avoid re-looking up view references - * Since views are recycled, these references will never change - */ - private static class ViewHolder { - public TextView headerView; - public TextView bodyView; - } - -} diff --git a/src/de/example/exampletdd/fragment/WeatherDataEntry.java b/src/de/example/exampletdd/fragment/WeatherDataEntry.java deleted file mode 100644 index 45dd979..0000000 --- a/src/de/example/exampletdd/fragment/WeatherDataEntry.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.example.exampletdd.fragment; - -public class WeatherDataEntry { - private final String header; - private final String body; - - public WeatherDataEntry(final String header, final String body) { - this.header = header; - this.body = body; - } - - public String getHeader() { - return this.header; - } - - public String getBody() { - return this.body; - } - -} diff --git a/src/de/example/exampletdd/fragment/WeatherInformationDataFragment.java b/src/de/example/exampletdd/fragment/WeatherInformationDataFragment.java deleted file mode 100644 index 5d60ecf..0000000 --- a/src/de/example/exampletdd/fragment/WeatherInformationDataFragment.java +++ /dev/null @@ -1,470 +0,0 @@ -package de.example.exampletdd.fragment; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.io.StreamCorruptedException; -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.Collection; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -import org.apache.http.client.ClientProtocolException; -import org.json.JSONException; - -import android.app.DialogFragment; -import android.app.Fragment; -import android.content.Context; -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 de.example.exampletdd.R; -import de.example.exampletdd.activityinterface.ErrorMessage; -import de.example.exampletdd.activityinterface.GetWeather; -import de.example.exampletdd.httpclient.WeatherHTTPClient; -import de.example.exampletdd.model.GeocodingData; -import de.example.exampletdd.model.WeatherData; -import de.example.exampletdd.parser.IJPOSWeatherParser; -import de.example.exampletdd.parser.JPOSWeatherParser; -import de.example.exampletdd.service.WeatherService; - -public class WeatherInformationDataFragment extends Fragment implements GetWeather { - private static final String WEATHER_DATA_FILE = "weatherdata.file"; - private static final String WEATHER_GEOCODING_FILE = "weathergeocoding.file"; - private static final String TAG = "WeatherInformationDataFragment"; - private boolean mIsFahrenheit; - private String mLanguage; - - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - this.getActivity().deleteFile(WEATHER_DATA_FILE); - - final SharedPreferences sharedPreferences = PreferenceManager - .getDefaultSharedPreferences(this.getActivity()); - final String keyPreference = this.getResources().getString( - R.string.weather_preferences_language_key); - this.mLanguage = sharedPreferences.getString( - keyPreference, ""); - } - - @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 WeatherDataAdapter adapter = new WeatherDataAdapter(this.getActivity(), - R.layout.weather_data_entry_list); - - final Collection entries = this.createEmptyEntriesList(); - - adapter.addAll(entries); - listWeatherView.setAdapter(adapter); - - if (savedInstanceState != null) { - // Restore state - final WeatherData weatherData = (WeatherData) savedInstanceState - .getSerializable("weatherData"); - try { - this.storeWeatherDataToFile(weatherData); - } catch (final IOException e) { - ((ErrorMessage) WeatherInformationDataFragment.this - .getActivity()) - .createErrorDialog(R.string.error_dialog_generic_error); - } - } - } - - @Override - public void onSaveInstanceState(final Bundle savedInstanceState) { - - // Save state - WeatherData weatherData = null; - try { - weatherData = this.restoreWeatherDataFromFile(); - } catch (final StreamCorruptedException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final FileNotFoundException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final IOException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final ClassNotFoundException e) { - Log.e(TAG, "onResume exception: ", e); - } - - if (weatherData != null) { - savedInstanceState.putSerializable("weatherData", weatherData); - } - - super.onSaveInstanceState(savedInstanceState); - } - - @Override - public void getWeather() { - - GeocodingData geocodingData = null; - try { - geocodingData = this.restoreGeocodingDataFromFile(); - } catch (final StreamCorruptedException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final FileNotFoundException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final IOException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final ClassNotFoundException e) { - Log.e(TAG, "onResume exception: ", e); - } - - if (geocodingData != null) { - final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser(); - final WeatherService weatherService = new WeatherService( - JPOSWeatherParser); - final AndroidHttpClient httpClient = AndroidHttpClient - .newInstance("Android Weather Information Agent"); - final WeatherHTTPClient HTTPweatherClient = new WeatherHTTPClient( - httpClient); - - final WeatherTask weatherTask = new WeatherTask(HTTPweatherClient, weatherService); - - - weatherTask.execute(geocodingData); - } - } - - @Override - public void updateWeatherData(final WeatherData weatherData) { - 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 WeatherDataAdapter adapter = new WeatherDataAdapter(this.getActivity(), - R.layout.weather_data_entry_list); - - if (weatherData.getWeather() != null) { - entries.set(0, new WeatherDataEntry(this.getString(R.string.text_field_description), weatherData.getWeather() - .getDescription())); - double conversion = weatherData.getMain().getTemp(); - conversion = conversion - tempUnits; - entries.set(1, new WeatherDataEntry(this.getString(R.string.text_field_tem), tempFormatter.format(conversion))); - conversion = weatherData.getMain().getMaxTemp(); - conversion = conversion - tempUnits; - entries.set(2, new WeatherDataEntry(this.getString(R.string.text_field_tem_max), tempFormatter.format(conversion))); - conversion = weatherData.getMain().getMinTemp(); - conversion = conversion - tempUnits; - entries.set(3, new WeatherDataEntry(this.getString(R.string.text_field_tem_min), tempFormatter.format(conversion))); - } - - if (weatherData.getSystem() != null) { - long unixTime = weatherData.getSystem().getSunRiseTime(); - Date unixDate = new Date(unixTime * 1000L); - String dateFormatUnix = dateFormat.format(unixDate); - entries.set(4, new WeatherDataEntry(this.getString(R.string.text_field_sun_rise), dateFormatUnix)); - - unixTime = weatherData.getSystem().getSunSetTime(); - unixDate = new Date(unixTime * 1000L); - dateFormatUnix = dateFormat.format(unixDate); - entries.set(5, new WeatherDataEntry(this.getString(R.string.text_field_sun_set), dateFormatUnix)); - } - - if (weatherData.getClouds() != null) { - final double cloudiness = weatherData.getClouds().getCloudiness(); - entries.set(6, new WeatherDataEntry(this.getString(R.string.text_field_cloudiness), tempFormatter.format(cloudiness))); - } - - if (weatherData.getWeather().getIcon() != null) { - final Bitmap icon = BitmapFactory.decodeByteArray( - weatherData.getIconData(), 0, - weatherData.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); - } - - @Override - public void onResume() { - super.onResume(); - - final SharedPreferences sharedPreferences = PreferenceManager - .getDefaultSharedPreferences(this.getActivity()); - - // 1. Update units of measurement. - 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. Update current data on display. - WeatherData weatherData = null; - try { - weatherData = this.restoreWeatherDataFromFile(); - } catch (final StreamCorruptedException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final FileNotFoundException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final IOException e) { - Log.e(TAG, "onResume exception: ", e); - } catch (final ClassNotFoundException e) { - Log.e(TAG, "onResume exception: ", e); - } - if (weatherData != null) { - this.updateWeatherData(weatherData); - } - - - // 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(); - } - } - - public class WeatherTask extends AsyncTask { - private static final String TAG = "WeatherTask"; - private final WeatherHTTPClient weatherHTTPClient; - private final WeatherService weatherService; - private final DialogFragment newFragment; - - public WeatherTask(final WeatherHTTPClient weatherHTTPClient, - final WeatherService weatherService) { - this.weatherHTTPClient = weatherHTTPClient; - this.weatherService = weatherService; - this.newFragment = ProgressDialogFragment.newInstance( - R.string.progress_dialog_get_remote_data, - WeatherInformationDataFragment.this - .getString(R.string.progress_dialog_generic_message)); - } - - @Override - protected void onPreExecute() { - this.newFragment.show(WeatherInformationDataFragment.this.getActivity() - .getFragmentManager(), "progressDialog"); - } - - @Override - protected WeatherData doInBackground(final Object... params) { - WeatherData weatherData = null; - - try { - weatherData = 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 IOException e) { - // logger infrastructure swallows UnknownHostException :/ - Log.e(TAG, "doInBackground exception: " + e.getMessage(), e); - } catch (final JSONException e) { - Log.e(TAG, "doInBackground exception: ", e); - } finally { - this.weatherHTTPClient.close(); - } - - return weatherData; - } - - @Override - protected void onPostExecute(final WeatherData weatherData) { - this.weatherHTTPClient.close(); - - this.newFragment.dismiss(); - - if (weatherData != null) { - try { - this.onPostExecuteThrowable(weatherData); - } catch (final IOException e) { - Log.e(TAG, "WeatherTask onPostExecute exception: ", e); - ((ErrorMessage) WeatherInformationDataFragment.this - .getActivity()) - .createErrorDialog(R.string.error_dialog_generic_error); - } - } else { - ((ErrorMessage) WeatherInformationDataFragment.this - .getActivity()) - .createErrorDialog(R.string.error_dialog_generic_error); - } - } - - @Override - protected void onCancelled(final WeatherData weatherData) { - this.weatherHTTPClient.close(); - - ((ErrorMessage) WeatherInformationDataFragment.this.getActivity()) - .createErrorDialog(R.string.error_dialog_connection_tiemout); - } - - private WeatherData doInBackgroundThrowable(final Object... params) - throws ClientProtocolException, MalformedURLException, - URISyntaxException, IOException, JSONException { - final SharedPreferences sharedPreferences = PreferenceManager - .getDefaultSharedPreferences(WeatherInformationDataFragment.this - .getActivity()); - - final String keyPreference = WeatherInformationDataFragment.this - .getActivity().getString( - R.string.weather_preferences_language_key); - final String languagePreferenceValue = sharedPreferences.getString(keyPreference, ""); - - final GeocodingData geocodingData = (GeocodingData) params[0]; - final String urlAPICoord = WeatherInformationDataFragment.this.getResources() - .getString(R.string.uri_api_coord); - final String APIVersion = WeatherInformationDataFragment.this.getResources() - .getString(R.string.api_version); - String url = this.weatherService.createURIAPICoord(geocodingData.getLatitude(), - geocodingData.getLongitude(), urlAPICoord, APIVersion, languagePreferenceValue); - - - final String jsonData = this.weatherHTTPClient.retrieveJSONDataFromAPI(new URL(url)); - - - final WeatherData weatherData = this.weatherService.retrieveDataFromJPOS(jsonData); - - - final String icon = weatherData.getWeather().getIcon(); - final String urlAPIicon = WeatherInformationDataFragment.this - .getResources().getString(R.string.uri_api_icon); - url = this.weatherService.createURIAPIicon(icon, urlAPIicon); - final byte[] iconData = this.weatherHTTPClient - .retrieveDataFromAPI(new URL(url)).toByteArray(); - weatherData.setIconData(iconData); - - - return weatherData; - } - - private void onPostExecuteThrowable(final WeatherData weatherData) - throws FileNotFoundException, IOException { - WeatherInformationDataFragment.this.storeWeatherDataToFile(weatherData); - - WeatherInformationDataFragment.this.updateWeatherData(weatherData); - } - } - - private List createEmptyEntriesList() { - final List entries = new ArrayList(); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_description), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_tem), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_tem_max), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_tem_min), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_sun_rise), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_sun_set), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_cloudiness), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_rain_time), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_rain_amount), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_wind_speed), null)); - entries.add(new WeatherDataEntry(this.getString(R.string.text_field_humidity), null)); - - return entries; - } - - private void storeWeatherDataToFile(final WeatherData weatherData) - throws FileNotFoundException, IOException { - final OutputStream persistenceFile = this.getActivity().openFileOutput( - WEATHER_DATA_FILE, Context.MODE_PRIVATE); - - ObjectOutputStream oos = null; - try { - oos = new ObjectOutputStream(persistenceFile); - - oos.writeObject(weatherData); - } finally { - if (oos != null) { - oos.close(); - } - } - } - - private WeatherData restoreWeatherDataFromFile() throws StreamCorruptedException, - FileNotFoundException, IOException, ClassNotFoundException { - final InputStream persistenceFile = this.getActivity().openFileInput( - WEATHER_DATA_FILE); - - ObjectInputStream ois = null; - try { - ois = new ObjectInputStream(persistenceFile); - - return (WeatherData) ois.readObject(); - } finally { - if (ois != null) { - ois.close(); - } - } - } - - private GeocodingData restoreGeocodingDataFromFile() - throws StreamCorruptedException, FileNotFoundException, - IOException, ClassNotFoundException { - final InputStream persistenceFile = this.getActivity() - .openFileInput(WEATHER_GEOCODING_FILE); - - ObjectInputStream ois = null; - try { - ois = new ObjectInputStream(persistenceFile); - - return (GeocodingData) ois.readObject(); - } finally { - if (ois != null) { - ois.close(); - } - } - } -} diff --git a/src/de/example/exampletdd/fragment/WeatherInformationPreferencesFragment.java b/src/de/example/exampletdd/fragment/WeatherInformationPreferencesFragment.java deleted file mode 100644 index 5e43c0c..0000000 --- a/src/de/example/exampletdd/fragment/WeatherInformationPreferencesFragment.java +++ /dev/null @@ -1,68 +0,0 @@ -package de.example.exampletdd.fragment; - -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.os.Bundle; -import android.preference.Preference; -import android.preference.PreferenceFragment; -import de.example.exampletdd.R; - -public class WeatherInformationPreferencesFragment extends PreferenceFragment -implements OnSharedPreferenceChangeListener { - - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Load the preferences from an XML resource - this.addPreferencesFromResource(R.xml.weather_preferences); - - String keyPreference = this.getActivity().getString( - R.string.weather_preferences_units_key); - Preference connectionPref = this.findPreference(keyPreference); - connectionPref.setSummary(this.getPreferenceManager() - .getSharedPreferences().getString(keyPreference, "")); - - keyPreference = this.getActivity().getString( - R.string.weather_preferences_language_key); - connectionPref = this.findPreference(keyPreference); - connectionPref.setSummary(this.getPreferenceManager() - .getSharedPreferences().getString(keyPreference, "")); - } - - @Override - public void onResume() { - super.onResume(); - this.getPreferenceManager().getSharedPreferences() - .registerOnSharedPreferenceChangeListener(this); - - } - - @Override - public void onPause() { - super.onPause(); - this.getPreferenceManager().getSharedPreferences() - .unregisterOnSharedPreferenceChangeListener(this); - } - - @Override - public void onSharedPreferenceChanged( - final SharedPreferences sharedPreferences, final String key) { - String keyValue = this.getActivity().getString( - R.string.weather_preferences_units_key); - - if (key.equals(keyValue)) { - final Preference connectionPref = this.findPreference(key); - connectionPref.setSummary(sharedPreferences.getString(key, "")); - } - - keyValue = this.getActivity().getString( - R.string.weather_preferences_language_key); - if (key.equals(keyValue)) { - final Preference connectionPref = this.findPreference(key); - connectionPref.setSummary(sharedPreferences.getString(key, "")); - } - - } - -} diff --git a/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java b/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java index 2c973d9..5061dd5 100644 --- a/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java +++ b/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java @@ -25,7 +25,9 @@ import org.json.JSONException; import android.app.DialogFragment; import android.app.ListFragment; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -34,15 +36,13 @@ import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; -import android.view.ActionMode; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.AbsListView.MultiChoiceModeListener; +import android.view.View; import android.widget.ListView; import de.example.exampletdd.R; -import de.example.exampletdd.activityinterface.ErrorMessage; import de.example.exampletdd.activityinterface.GetWeather; +import de.example.exampletdd.fragment.ErrorDialogFragment; import de.example.exampletdd.fragment.ProgressDialogFragment; +import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment; import de.example.exampletdd.httpclient.WeatherHTTPClient; import de.example.exampletdd.model.GeocodingData; import de.example.exampletdd.model.WeatherData; @@ -79,36 +79,6 @@ GetWeather { final ListView listWeatherView = this.getListView(); listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE); - listWeatherView.setMultiChoiceModeListener(new MultiChoiceModeListener() { - - @Override - public boolean onCreateActionMode(final ActionMode mode, - final Menu menu) { - return false; - } - - @Override - public boolean onPrepareActionMode(final ActionMode mode, - final Menu menu) { - return false; - } - - @Override - public boolean onActionItemClicked(final ActionMode mode, - final MenuItem item) { - return false; - } - - @Override - public void onDestroyActionMode(final ActionMode mode) { - } - - @Override - public void onItemCheckedStateChanged( - final ActionMode mode, final int position, - final long id, final boolean checked) { - } - }); if (savedInstanceState != null) { // Restore state @@ -117,9 +87,9 @@ GetWeather { try { this.storeWeatherDataToFile(weatherData); } catch (final IOException e) { - ((ErrorMessage) WeatherInformationOverviewFragment.this - .getActivity()) - .createErrorDialog(R.string.error_dialog_generic_error); + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_generic_error); + newFragment.show(this.getFragmentManager(), "errorDialog"); } } @@ -139,6 +109,22 @@ GetWeather { } @Override + public void onListItemClick(final ListView l, final View v, final int position, final long id) { + final WeatherInformationSpecificDataFragment fragment = (WeatherInformationSpecificDataFragment) getFragmentManager() + .findFragmentById(R.id.weather_specific_data__fragment); + if (fragment == null) { + // handset layout + final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO"). + setComponent(new ComponentName("de.example.exampletdd", + "de.example.exampletdd.specific.WeatherInformationSpecificDataActivity")); + WeatherInformationOverviewFragment.this.getActivity().startActivity(intent); + } else { + // tablet layout + fragment.getWeather(); + } + } + + @Override public void onSaveInstanceState(final Bundle savedInstanceState) { // Save state @@ -194,7 +180,6 @@ GetWeather { } } - @Override public void updateWeatherData(final WeatherData weatherData) { final List entries = this.createEmptyEntriesList(); final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(this.getActivity(), @@ -345,14 +330,14 @@ GetWeather { this.onPostExecuteThrowable(weatherData); } catch (final IOException e) { Log.e(TAG, "WeatherTask onPostExecute exception: ", e); - ((ErrorMessage) WeatherInformationOverviewFragment.this - .getActivity()) - .createErrorDialog(R.string.error_dialog_generic_error); + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_generic_error); + newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog"); } } else { - ((ErrorMessage) WeatherInformationOverviewFragment.this - .getActivity()) - .createErrorDialog(R.string.error_dialog_generic_error); + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_generic_error); + newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog"); } } @@ -360,8 +345,9 @@ GetWeather { protected void onCancelled(final WeatherData weatherData) { this.weatherHTTPClient.close(); - ((ErrorMessage) WeatherInformationOverviewFragment.this.getActivity()) - .createErrorDialog(R.string.error_dialog_connection_tiemout); + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_connection_tiemout); + newFragment.show(WeatherInformationOverviewFragment.this.getFragmentManager(), "errorDialog"); } private WeatherData doInBackgroundThrowable(final Object... params) diff --git a/src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java b/src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java new file mode 100644 index 0000000..13f77db --- /dev/null +++ b/src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java @@ -0,0 +1,68 @@ +package de.example.exampletdd.fragment.preferences; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import de.example.exampletdd.R; + +public class WeatherInformationPreferencesFragment extends PreferenceFragment +implements OnSharedPreferenceChangeListener { + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + this.addPreferencesFromResource(R.xml.weather_preferences); + + String keyPreference = this.getActivity().getString( + R.string.weather_preferences_units_key); + Preference connectionPref = this.findPreference(keyPreference); + connectionPref.setSummary(this.getPreferenceManager() + .getSharedPreferences().getString(keyPreference, "")); + + keyPreference = this.getActivity().getString( + R.string.weather_preferences_language_key); + connectionPref = this.findPreference(keyPreference); + connectionPref.setSummary(this.getPreferenceManager() + .getSharedPreferences().getString(keyPreference, "")); + } + + @Override + public void onResume() { + super.onResume(); + this.getPreferenceManager().getSharedPreferences() + .registerOnSharedPreferenceChangeListener(this); + + } + + @Override + public void onPause() { + super.onPause(); + this.getPreferenceManager().getSharedPreferences() + .unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onSharedPreferenceChanged( + final SharedPreferences sharedPreferences, final String key) { + String keyValue = this.getActivity().getString( + R.string.weather_preferences_units_key); + + if (key.equals(keyValue)) { + final Preference connectionPref = this.findPreference(key); + connectionPref.setSummary(sharedPreferences.getString(key, "")); + } + + keyValue = this.getActivity().getString( + R.string.weather_preferences_language_key); + if (key.equals(keyValue)) { + final Preference connectionPref = this.findPreference(key); + connectionPref.setSummary(sharedPreferences.getString(key, "")); + } + + } + +} diff --git a/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java b/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java new file mode 100644 index 0000000..b53d4a6 --- /dev/null +++ b/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java @@ -0,0 +1,301 @@ +package de.example.exampletdd.fragment.specific; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.StreamCorruptedException; +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.Context; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +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 de.example.exampletdd.R; +import de.example.exampletdd.activityinterface.GetWeather; +import de.example.exampletdd.fragment.ErrorDialogFragment; +import de.example.exampletdd.model.WeatherData; + +public class WeatherInformationSpecificDataFragment extends Fragment implements GetWeather { + private static final String WEATHER_DATA_FILE = "weatherdata.file"; + private static final String TAG = "WeatherInformationDataFragment"; + private boolean mIsFahrenheit; + private String mLanguage; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + this.getActivity().deleteFile(WEATHER_DATA_FILE); + + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getActivity()); + final String keyPreference = this.getResources().getString( + R.string.weather_preferences_language_key); + this.mLanguage = sharedPreferences.getString( + keyPreference, ""); + } + + @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); + + final Collection entries = this.createEmptyEntriesList(); + + adapter.addAll(entries); + listWeatherView.setAdapter(adapter); + + if (savedInstanceState != null) { + // Restore state + final WeatherData weatherData = (WeatherData) savedInstanceState + .getSerializable("weatherData"); + try { + this.storeWeatherDataToFile(weatherData); + } catch (final IOException e) { + final DialogFragment newFragment = ErrorDialogFragment + .newInstance(R.string.error_dialog_generic_error); + newFragment.show(this.getFragmentManager(), "errorDialog"); + } + } + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + + // Save state + WeatherData weatherData = null; + try { + weatherData = this.restoreWeatherDataFromFile(); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "onResume exception: ", e); + } + + if (weatherData != null) { + savedInstanceState.putSerializable("weatherData", weatherData); + } + + super.onSaveInstanceState(savedInstanceState); + } + + @Override + public void getWeather() { + WeatherData weatherData = null; + try { + weatherData = this.restoreWeatherDataFromFile(); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "onResume exception: ", e); + } + if (weatherData != null) { + this.updateWeatherData(weatherData); + } + } + + public void updateWeatherData(final WeatherData weatherData) { + 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 (weatherData.getWeather() != null) { + entries.set(0, new WeatherSpecificDataEntry(this.getString(R.string.text_field_description), weatherData.getWeather() + .getDescription())); + double conversion = weatherData.getMain().getTemp(); + conversion = conversion - tempUnits; + entries.set(1, new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem), tempFormatter.format(conversion))); + conversion = weatherData.getMain().getMaxTemp(); + conversion = conversion - tempUnits; + entries.set(2, new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem_max), tempFormatter.format(conversion))); + conversion = weatherData.getMain().getMinTemp(); + conversion = conversion - tempUnits; + entries.set(3, new WeatherSpecificDataEntry(this.getString(R.string.text_field_tem_min), tempFormatter.format(conversion))); + } + + if (weatherData.getSystem() != null) { + long unixTime = weatherData.getSystem().getSunRiseTime(); + Date unixDate = new Date(unixTime * 1000L); + String dateFormatUnix = dateFormat.format(unixDate); + entries.set(4, new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_rise), dateFormatUnix)); + + unixTime = weatherData.getSystem().getSunSetTime(); + unixDate = new Date(unixTime * 1000L); + dateFormatUnix = dateFormat.format(unixDate); + entries.set(5, new WeatherSpecificDataEntry(this.getString(R.string.text_field_sun_set), dateFormatUnix)); + } + + if (weatherData.getClouds() != null) { + final double cloudiness = weatherData.getClouds().getCloudiness(); + entries.set(6, new WeatherSpecificDataEntry(this.getString(R.string.text_field_cloudiness), tempFormatter.format(cloudiness))); + } + + if (weatherData.getWeather().getIcon() != null) { + final Bitmap icon = BitmapFactory.decodeByteArray( + weatherData.getIconData(), 0, + weatherData.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); + } + + @Override + public void onResume() { + super.onResume(); + + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getActivity()); + + // 1. Update units of measurement. + 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. Update current data on display. + WeatherData weatherData = null; + try { + weatherData = this.restoreWeatherDataFromFile(); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "onResume exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "onResume exception: ", e); + } + if (weatherData != null) { + this.updateWeatherData(weatherData); + } + + + // 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(); + } + } + + 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; + } + + private void storeWeatherDataToFile(final WeatherData weatherData) + throws FileNotFoundException, IOException { + final OutputStream persistenceFile = this.getActivity().openFileOutput( + WEATHER_DATA_FILE, Context.MODE_PRIVATE); + + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(persistenceFile); + + oos.writeObject(weatherData); + } finally { + if (oos != null) { + oos.close(); + } + } + } + + private WeatherData restoreWeatherDataFromFile() throws StreamCorruptedException, + FileNotFoundException, IOException, ClassNotFoundException { + final InputStream persistenceFile = this.getActivity().openFileInput( + WEATHER_DATA_FILE); + + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(persistenceFile); + + return (WeatherData) ois.readObject(); + } finally { + if (ois != null) { + ois.close(); + } + } + } +} diff --git a/src/de/example/exampletdd/fragment/specific/WeatherSpecificDataAdapter.java b/src/de/example/exampletdd/fragment/specific/WeatherSpecificDataAdapter.java new file mode 100644 index 0000000..0b9491d --- /dev/null +++ b/src/de/example/exampletdd/fragment/specific/WeatherSpecificDataAdapter.java @@ -0,0 +1,92 @@ +package de.example.exampletdd.fragment.specific; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; +import de.example.exampletdd.R; +import de.example.exampletdd.fragment.specific.WeatherSpecificDataEntry; + +public class WeatherSpecificDataAdapter extends ArrayAdapter { + private final int resource; + + public WeatherSpecificDataAdapter(final Context context, final int resource) { + super(context, 0); + + this.resource = resource; + } + + @Override + public View getView(final int position, final View convertView, + final ViewGroup parent) { + + // We need to get the best view (re-used if possible) and then + // retrieve its corresponding ViewHolder, which optimizes lookup + // efficiency + final View view = this.getWorkingView(convertView); + final ViewHolder viewHolder = this.getViewHolder(view); + final WeatherSpecificDataEntry entry = this.getItem(position); + + + // Setting the text view + viewHolder.headerView.setText(entry.getHeader()); + viewHolder.bodyView.setText(entry.getBody()); + + + return view; + } + + private View getWorkingView(final View convertView) { + // The workingView is basically just the convertView re-used if possible + // or inflated new if not possible + View workingView = null; + + if(null == convertView) { + final Context context = this.getContext(); + final LayoutInflater inflater = (LayoutInflater)context.getSystemService + (Context.LAYOUT_INFLATER_SERVICE); + + workingView = inflater.inflate(this.resource, null); + } else { + workingView = convertView; + } + + return workingView; + } + + private ViewHolder getViewHolder(final View workingView) { + // The viewHolder allows us to avoid re-looking up view references + // Since views are recycled, these references will never change + final Object tag = workingView.getTag(); + ViewHolder viewHolder = null; + + + if((null == tag) || !(tag instanceof ViewHolder)) { + viewHolder = new ViewHolder(); + + viewHolder.headerView = (TextView) workingView + .findViewById(R.id.weather_data_entry_header); + viewHolder.bodyView = (TextView) workingView + .findViewById(R.id.weather_data_entry_body); + + workingView.setTag(viewHolder); + + } else { + viewHolder = (ViewHolder) tag; + } + + return viewHolder; + } + + /** + * ViewHolder allows us to avoid re-looking up view references + * Since views are recycled, these references will never change + */ + private static class ViewHolder { + public TextView headerView; + public TextView bodyView; + } + +} diff --git a/src/de/example/exampletdd/fragment/specific/WeatherSpecificDataEntry.java b/src/de/example/exampletdd/fragment/specific/WeatherSpecificDataEntry.java new file mode 100644 index 0000000..2d5f492 --- /dev/null +++ b/src/de/example/exampletdd/fragment/specific/WeatherSpecificDataEntry.java @@ -0,0 +1,20 @@ +package de.example.exampletdd.fragment.specific; + +public class WeatherSpecificDataEntry { + private final String header; + private final String body; + + public WeatherSpecificDataEntry(final String header, final String body) { + this.header = header; + this.body = body; + } + + public String getHeader() { + return this.header; + } + + public String getBody() { + return this.body; + } + +} diff --git a/src/de/example/exampletdd/service/WeatherServicePersistence.java b/src/de/example/exampletdd/service/WeatherServicePersistence.java new file mode 100644 index 0000000..e76e625 --- /dev/null +++ b/src/de/example/exampletdd/service/WeatherServicePersistence.java @@ -0,0 +1,93 @@ +package de.example.exampletdd.service; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.StreamCorruptedException; + +import android.content.Context; +import de.example.exampletdd.model.GeocodingData; +import de.example.exampletdd.model.WeatherData; + +public class WeatherServicePersistence { + private static final String WEATHER_DATA_FILE = "weatherdata.file"; + private static final String WEATHER_GEOCODING_FILE = "weathergeocoding.file"; + private final Context context; + + public WeatherServicePersistence(final Context context) { + this.context = context; + } + + public void storeGeocodingDataToFile(final GeocodingData geocodingData) + throws FileNotFoundException, IOException { + final OutputStream persistenceFile = context.openFileOutput( + WEATHER_GEOCODING_FILE, Context.MODE_PRIVATE); + + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(persistenceFile); + + oos.writeObject(geocodingData); + } finally { + if (oos != null) { + oos.close(); + } + } + } + + public GeocodingData restoreGeocodingDataFromFile() + throws StreamCorruptedException, FileNotFoundException, + IOException, ClassNotFoundException { + final InputStream persistenceFile = context.openFileInput( + WEATHER_GEOCODING_FILE); + + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(persistenceFile); + + return (GeocodingData) ois.readObject(); + } finally { + if (ois != null) { + ois.close(); + } + } + } + + public void storeWeatherDataToFile(final WeatherData weatherData) + throws FileNotFoundException, IOException { + final OutputStream persistenceFile = context.openFileOutput( + WEATHER_DATA_FILE, Context.MODE_PRIVATE); + + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(persistenceFile); + + oos.writeObject(weatherData); + } finally { + if (oos != null) { + oos.close(); + } + } + } + + public WeatherData restoreWeatherDataFromFile() + throws StreamCorruptedException, + FileNotFoundException, IOException, ClassNotFoundException { + final InputStream persistenceFile = context.openFileInput( + WEATHER_DATA_FILE); + + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(persistenceFile); + + return (WeatherData) ois.readObject(); + } finally { + if (ois != null) { + ois.close(); + } + } + } +} -- 2.1.4