From: gu.martinm@gmail.com Date: Fri, 29 Aug 2014 15:44:00 +0000 (+0200) Subject: WeatherInformation Android. Modifications in tabs behaviour. X-Git-Tag: weatherinformation-1.0~159 X-Git-Url: https://git.gumartinm.name/?a=commitdiff_plain;h=3653b4e356ccdb9cb687bd19147dffdf5248a860;p=AndroidWeatherInformation WeatherInformation Android. Modifications in tabs behaviour. --- diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar new file mode 100644 index 0000000..c31cede Binary files /dev/null and b/libs/android-support-v4.jar differ diff --git a/libs/jackson-core-2.2.4.jar b/libs/jackson-core-2.2.4.jar new file mode 100644 index 0000000..03e965b Binary files /dev/null and b/libs/jackson-core-2.2.4.jar differ diff --git a/project.properties b/project.properties index 7612c3e..c7ce4b6 100644 --- a/project.properties +++ b/project.properties @@ -12,5 +12,5 @@ # Project target. target=android-18 -android.library.reference.1=../../../../android/android-sdk-linux/extras/google/google_play_services/libproject/google-play-services_lib +android.library.reference.1=../google-play-services_lib android.library=false diff --git a/res/layout-large/weather_main.xml b/res/layout-large/weather_main.xml index 8250d57..78e854d 100644 --- a/res/layout-large/weather_main.xml +++ b/res/layout-large/weather_main.xml @@ -11,7 +11,7 @@ android:id="@+id/weather_overview_fragment" android:layout_width="match_parent" android:layout_height="match_parent" - class="de.example.exampletdd.fragment.overview.WeatherInformationOverviewFragment" /> + class="de.example.exampletdd.fragment.overview.OverviewFragment" /> diff --git a/res/layout/activity_masterdetail_list.xml b/res/layout/activity_masterdetail_list.xml deleted file mode 100644 index 6f7c60c..0000000 --- a/res/layout/activity_masterdetail_list.xml +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/res/layout/activity_masterdetail_twopane.xml b/res/layout/activity_masterdetail_twopane.xml deleted file mode 100644 index f09e404..0000000 --- a/res/layout/activity_masterdetail_twopane.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - diff --git a/res/layout/fragment_masterdetail_detail.xml b/res/layout/fragment_masterdetail_detail.xml deleted file mode 100644 index ea1a39a..0000000 --- a/res/layout/fragment_masterdetail_detail.xml +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/res/layout/weather_current_data.xml b/res/layout/weather_current_data.xml index f4b3aad..3f490ce 100644 --- a/res/layout/weather_current_data.xml +++ b/res/layout/weather_current_data.xml @@ -13,6 +13,6 @@ android:id="@+id/weather_current_data_fragment" android:layout_width="match_parent" android:layout_height="match_parent" - class="de.example.exampletdd.fragment.current.WeatherInformationCurrentDataFragment" /> + class="de.example.exampletdd.fragment.current.CurrentDataFragment" /> \ No newline at end of file diff --git a/res/layout/weather_main.xml b/res/layout/weather_main.xml index 215fc01..6c9ce95 100644 --- a/res/layout/weather_main.xml +++ b/res/layout/weather_main.xml @@ -11,6 +11,6 @@ android:id="@+id/weather_overview_fragment" android:layout_width="match_parent" android:layout_height="match_parent" - class="de.example.exampletdd.fragment.overview.WeatherInformationOverviewFragment" /> + class="de.example.exampletdd.fragment.overview.OverviewFragment" /> \ No newline at end of file diff --git a/res/values-large/refs.xml b/res/values-large/refs.xml deleted file mode 100644 index f1ea4e6..0000000 --- a/res/values-large/refs.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - @layout/activity_masterdetail_twopane - - diff --git a/res/values-sw600dp/refs.xml b/res/values-sw600dp/refs.xml deleted file mode 100644 index f1ea4e6..0000000 --- a/res/values-sw600dp/refs.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - @layout/activity_masterdetail_twopane - - diff --git a/src/de/example/exampletdd/MasterDetailDetailActivity.java b/src/de/example/exampletdd/MasterDetailDetailActivity.java deleted file mode 100644 index 4700060..0000000 --- a/src/de/example/exampletdd/MasterDetailDetailActivity.java +++ /dev/null @@ -1,66 +0,0 @@ -package de.example.exampletdd; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.NavUtils; -import android.view.MenuItem; - -/** - * An activity representing a single MasterDetail detail screen. This activity - * is only used on handset devices. On tablet-size devices, item details are - * presented side-by-side with a list of items in a - * {@link MasterDetailListActivity}. - *

- * This activity is mostly just a 'shell' activity containing nothing more than - * a {@link MasterDetailDetailFragment}. - */ -public class MasterDetailDetailActivity extends FragmentActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_masterdetail_detail); - - // Show the Up button in the action bar. - getActionBar().setDisplayHomeAsUpEnabled(true); - - // savedInstanceState is non-null when there is fragment state - // saved from previous configurations of this activity - // (e.g. when rotating the screen from portrait to landscape). - // In this case, the fragment will automatically be re-added - // to its container so we don't need to manually add it. - // For more information, see the Fragments API guide at: - // - // http://developer.android.com/guide/components/fragments.html - // - if (savedInstanceState == null) { - // Create the detail fragment and add it to the activity - // using a fragment transaction. - Bundle arguments = new Bundle(); - arguments.putString(MasterDetailDetailFragment.ARG_ITEM_ID, - getIntent().getStringExtra(MasterDetailDetailFragment.ARG_ITEM_ID)); - MasterDetailDetailFragment fragment = new MasterDetailDetailFragment(); - fragment.setArguments(arguments); - getSupportFragmentManager().beginTransaction() - .add(R.id.masterdetail_detail_container, fragment).commit(); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - if (id == android.R.id.home) { - // This ID represents the Home or Up button. In the case of this - // activity, the Up button is shown. Use NavUtils to allow users - // to navigate up one level in the application structure. For - // more details, see the Navigation pattern on Android Design: - // - // http://developer.android.com/design/patterns/navigation.html#up-vs-back - // - NavUtils.navigateUpTo(this, new Intent(this, MasterDetailListActivity.class)); - return true; - } - return super.onOptionsItemSelected(item); - } -} diff --git a/src/de/example/exampletdd/MasterDetailDetailFragment.java b/src/de/example/exampletdd/MasterDetailDetailFragment.java deleted file mode 100644 index b679c40..0000000 --- a/src/de/example/exampletdd/MasterDetailDetailFragment.java +++ /dev/null @@ -1,59 +0,0 @@ -package de.example.exampletdd; - -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import de.example.exampletdd.dummy.DummyContent; - -/** - * A fragment representing a single MasterDetail detail screen. This fragment is - * either contained in a {@link MasterDetailListActivity} in two-pane mode (on - * tablets) or a {@link MasterDetailDetailActivity} on handsets. - */ -public class MasterDetailDetailFragment extends Fragment { - /** - * The fragment argument representing the item ID that this fragment - * represents. - */ - public static final String ARG_ITEM_ID = "item_id"; - - /** - * The dummy content this fragment is presenting. - */ - private DummyContent.DummyItem mItem; - - /** - * Mandatory empty constructor for the fragment manager to instantiate the - * fragment (e.g. upon screen orientation changes). - */ - public MasterDetailDetailFragment() { - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (getArguments().containsKey(ARG_ITEM_ID)) { - // Load the dummy content specified by the fragment - // arguments. In a real-world scenario, use a Loader - // to load content from a content provider. - mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID)); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_masterdetail_detail, container, false); - - // Show the dummy content as text in a TextView. - if (mItem != null) { - ((TextView) rootView.findViewById(R.id.masterdetail_detail)).setText(mItem.content); - } - - return rootView; - } -} diff --git a/src/de/example/exampletdd/MasterDetailListActivity.java b/src/de/example/exampletdd/MasterDetailListActivity.java deleted file mode 100644 index 7cf2a57..0000000 --- a/src/de/example/exampletdd/MasterDetailListActivity.java +++ /dev/null @@ -1,78 +0,0 @@ -package de.example.exampletdd; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.FragmentActivity; - -/** - * An activity representing a list of MasterDetails. This activity has different - * presentations for handset and tablet-size devices. On handsets, the activity - * presents a list of items, which when touched, lead to a - * {@link MasterDetailDetailActivity} representing item details. On tablets, the - * activity presents the list of items and item details side-by-side using two - * vertical panes. - *

- * The activity makes heavy use of fragments. The list of items is a - * {@link MasterDetailListFragment} and the item details (if present) is a - * {@link MasterDetailDetailFragment}. - *

- * This activity also implements the required - * {@link MasterDetailListFragment.Callbacks} interface to listen for item - * selections. - */ -public class MasterDetailListActivity extends FragmentActivity implements - MasterDetailListFragment.Callbacks { - - /** - * Whether or not the activity is in two-pane mode, i.e. running on a tablet - * device. - */ - private boolean mTwoPane; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_masterdetail_list); - - if (findViewById(R.id.masterdetail_detail_container) != null) { - // The detail container view will be present only in the - // large-screen layouts (res/values-large and - // res/values-sw600dp). If this view is present, then the - // activity should be in two-pane mode. - mTwoPane = true; - - // In two-pane mode, list items should be given the - // 'activated' state when touched. - ((MasterDetailListFragment) getSupportFragmentManager().findFragmentById( - R.id.masterdetail_list)).setActivateOnItemClick(true); - } - - // TODO: If exposing deep links into your app, handle intents here. - } - - /** - * Callback method from {@link MasterDetailListFragment.Callbacks} - * indicating that the item with the given ID was selected. - */ - @Override - public void onItemSelected(String id) { - if (mTwoPane) { - // In two-pane mode, show the detail view in this activity by - // adding or replacing the detail fragment using a - // fragment transaction. - Bundle arguments = new Bundle(); - arguments.putString(MasterDetailDetailFragment.ARG_ITEM_ID, id); - MasterDetailDetailFragment fragment = new MasterDetailDetailFragment(); - fragment.setArguments(arguments); - getSupportFragmentManager().beginTransaction() - .replace(R.id.masterdetail_detail_container, fragment).commit(); - - } else { - // In single-pane mode, simply start the detail activity - // for the selected item ID. - Intent detailIntent = new Intent(this, MasterDetailDetailActivity.class); - detailIntent.putExtra(MasterDetailDetailFragment.ARG_ITEM_ID, id); - startActivity(detailIntent); - } - } -} diff --git a/src/de/example/exampletdd/MasterDetailListFragment.java b/src/de/example/exampletdd/MasterDetailListFragment.java deleted file mode 100644 index e81b39b..0000000 --- a/src/de/example/exampletdd/MasterDetailListFragment.java +++ /dev/null @@ -1,147 +0,0 @@ -package de.example.exampletdd; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.ListFragment; -import android.view.View; -import android.widget.ArrayAdapter; -import android.widget.ListView; - -import de.example.exampletdd.dummy.DummyContent; - -/** - * A list fragment representing a list of MasterDetails. This fragment also - * supports tablet devices by allowing list items to be given an 'activated' - * state upon selection. This helps indicate which item is currently being - * viewed in a {@link MasterDetailDetailFragment}. - *

- * Activities containing this fragment MUST implement the {@link Callbacks} - * interface. - */ -public class MasterDetailListFragment extends ListFragment { - - /** - * The serialization (saved instance state) Bundle key representing the - * activated item position. Only used on tablets. - */ - private static final String STATE_ACTIVATED_POSITION = "activated_position"; - - /** - * The fragment's current callback object, which is notified of list item - * clicks. - */ - private Callbacks mCallbacks = sDummyCallbacks; - - /** - * The current activated item position. Only used on tablets. - */ - private int mActivatedPosition = ListView.INVALID_POSITION; - - /** - * A callback interface that all activities containing this fragment must - * implement. This mechanism allows activities to be notified of item - * selections. - */ - public interface Callbacks { - /** - * Callback for when an item has been selected. - */ - public void onItemSelected(String id); - } - - /** - * A dummy implementation of the {@link Callbacks} interface that does - * nothing. Used only when this fragment is not attached to an activity. - */ - private static Callbacks sDummyCallbacks = new Callbacks() { - @Override - public void onItemSelected(String id) { - } - }; - - /** - * Mandatory empty constructor for the fragment manager to instantiate the - * fragment (e.g. upon screen orientation changes). - */ - public MasterDetailListFragment() { - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // TODO: replace with a real list adapter. - setListAdapter(new ArrayAdapter(getActivity(), - android.R.layout.simple_list_item_activated_1, android.R.id.text1, - DummyContent.ITEMS)); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - // Restore the previously serialized activated item position. - if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) { - setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION)); - } - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - // Activities containing this fragment must implement its callbacks. - if (!(activity instanceof Callbacks)) { - throw new IllegalStateException("Activity must implement fragment's callbacks."); - } - - mCallbacks = (Callbacks) activity; - } - - @Override - public void onDetach() { - super.onDetach(); - - // Reset the active callbacks interface to the dummy implementation. - mCallbacks = sDummyCallbacks; - } - - @Override - public void onListItemClick(ListView listView, View view, int position, long id) { - super.onListItemClick(listView, view, position, id); - - // Notify the active callbacks interface (the activity, if the - // fragment is attached to one) that an item has been selected. - mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - if (mActivatedPosition != ListView.INVALID_POSITION) { - // Serialize and persist the activated item position. - outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition); - } - } - - /** - * Turns on activate-on-click mode. When this mode is on, list items will be - * given the 'activated' state when touched. - */ - public void setActivateOnItemClick(boolean activateOnItemClick) { - // When setting CHOICE_MODE_SINGLE, ListView will automatically - // give items the 'activated' state when touched. - getListView().setChoiceMode( - activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE); - } - - private void setActivatedPosition(int position) { - if (position == ListView.INVALID_POSITION) { - getListView().setItemChecked(mActivatedPosition, false); - } else { - getListView().setItemChecked(position, true); - } - - mActivatedPosition = position; - } -} diff --git a/src/de/example/exampletdd/WeatherInformationApplication.java b/src/de/example/exampletdd/WeatherInformationApplication.java index e9fe4a4..972899e 100644 --- a/src/de/example/exampletdd/WeatherInformationApplication.java +++ b/src/de/example/exampletdd/WeatherInformationApplication.java @@ -2,8 +2,10 @@ package de.example.exampletdd; import android.app.Application; import de.example.exampletdd.model.GeocodingData; +import de.example.exampletdd.model.forecastweather.Forecast; public class WeatherInformationApplication extends Application { + private Forecast mForecast; private GeocodingData mGeocodingData; protected void setGeocodingData(final GeocodingData geocodingData) { @@ -13,4 +15,12 @@ public class WeatherInformationApplication extends Application { protected GeocodingData getGeocodingData() { return this.mGeocodingData; } + + public void setForecast(final Forecast forecast) { + this.mForecast = forecast; + } + + public Forecast getForecast() { + return this.mForecast; + } } diff --git a/src/de/example/exampletdd/WeatherInformationBatch.java b/src/de/example/exampletdd/WeatherInformationBatch.java index 3ec9f55..73d764b 100644 --- a/src/de/example/exampletdd/WeatherInformationBatch.java +++ b/src/de/example/exampletdd/WeatherInformationBatch.java @@ -19,16 +19,16 @@ import com.fasterxml.jackson.core.JsonParseException; 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.model.currentweather.Current; +import de.example.exampletdd.model.forecastweather.Forecast; import de.example.exampletdd.parser.JPOSWeatherParser; -import de.example.exampletdd.service.WeatherServiceParser; -import de.example.exampletdd.service.WeatherServicePersistenceFile; +import de.example.exampletdd.service.ServiceParser; +import de.example.exampletdd.service.ServicePersistenceStorage; public class WeatherInformationBatch extends IntentService { private static final String TAG = "WeatherInformationBatch"; private static final String resultsNumber = "14"; - private WeatherServicePersistenceFile mWeatherServicePersistenceFile; + private ServicePersistenceStorage mWeatherServicePersistenceFile; public WeatherInformationBatch() { @@ -38,7 +38,7 @@ public class WeatherInformationBatch extends IntentService { @Override public int onStartCommand(final Intent intent, final int flags, final int startId) { Log.i(TAG, "WeatherInformationBatch onStartCommand"); - this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this); + this.mWeatherServicePersistenceFile = new ServicePersistenceStorage(this); return super.onStartCommand(intent, flags, startId); } @@ -51,7 +51,7 @@ public class WeatherInformationBatch extends IntentService { if (geocodingData != null) { Log.i(TAG, "WeatherInformationBatch onHandleIntent, geocodingData not null"); - final WeatherServiceParser weatherService = new WeatherServiceParser(new JPOSWeatherParser()); + final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser()); final CustomHTTPClient weatherHTTPClient = new CustomHTTPClient( AndroidHttpClient.newInstance("Android Weather Information Agent")); @@ -77,7 +77,7 @@ public class WeatherInformationBatch extends IntentService { } private WeatherData doInBackgroundThrowable(final GeocodingData geocodingData, - final CustomHTTPClient weatherHTTPClient, final WeatherServiceParser weatherService) + final CustomHTTPClient weatherHTTPClient, final ServiceParser weatherService) throws ClientProtocolException, MalformedURLException, URISyntaxException, JsonParseException, IOException { @@ -90,7 +90,7 @@ public class WeatherInformationBatch extends IntentService { String url = weatherService.createURIAPITodayWeather(urlAPI, APIVersion, geocodingData.getLatitude(), geocodingData.getLongitude()); String jsonData = weatherHTTPClient.retrieveDataAsString(new URL(url)); - final CurrentWeatherData currentWeatherData = weatherService + final Current currentWeatherData = weatherService .retrieveCurrentWeatherDataFromJPOS(jsonData); final Calendar now = Calendar.getInstance(); currentWeatherData.setDate(now.getTime()); @@ -101,7 +101,7 @@ public class WeatherInformationBatch extends IntentService { url = weatherService.createURIAPIForecastWeather(urlAPI, APIVersion, geocodingData.getLatitude(), geocodingData.getLongitude(), resultsNumber); jsonData = weatherHTTPClient.retrieveDataAsString(new URL(url)); - final ForecastWeatherData forecastWeatherData = weatherService + final Forecast forecastWeatherData = weatherService .retrieveForecastWeatherDataFromJPOS(jsonData); return new WeatherData(forecastWeatherData, currentWeatherData); @@ -128,20 +128,20 @@ public class WeatherInformationBatch extends IntentService { } private class WeatherData { - private final ForecastWeatherData mForecastWeatherData; - private final CurrentWeatherData mCurrentWeatherData; + private final Forecast mForecastWeatherData; + private final Current mCurrentWeatherData; - public WeatherData(final ForecastWeatherData mForecastWeatherData, - final CurrentWeatherData mCurrentWeatherData) { + public WeatherData(final Forecast mForecastWeatherData, + final Current mCurrentWeatherData) { this.mForecastWeatherData = mForecastWeatherData; this.mCurrentWeatherData = mCurrentWeatherData; } - public ForecastWeatherData getForecastWeatherData() { + public Forecast getForecastWeatherData() { return this.mForecastWeatherData; } - public CurrentWeatherData getCurrentWeatherData() { + public Current getCurrentWeatherData() { return this.mCurrentWeatherData; } } diff --git a/src/de/example/exampletdd/WeatherInformationCurrentDataActivity.java b/src/de/example/exampletdd/WeatherInformationCurrentDataActivity.java index 4fd78f8..21277cc 100644 --- a/src/de/example/exampletdd/WeatherInformationCurrentDataActivity.java +++ b/src/de/example/exampletdd/WeatherInformationCurrentDataActivity.java @@ -4,7 +4,7 @@ import android.app.ActionBar; import android.app.Activity; import android.os.Bundle; import de.example.exampletdd.model.GeocodingData; -import de.example.exampletdd.service.WeatherServicePersistenceFile; +import de.example.exampletdd.service.ServicePersistenceStorage; public class WeatherInformationCurrentDataActivity extends Activity { @@ -29,7 +29,7 @@ public class WeatherInformationCurrentDataActivity extends Activity { actionBar.setTitle("Current weather information"); - final WeatherServicePersistenceFile weatherServicePersistenceFile = new WeatherServicePersistenceFile(this); + final ServicePersistenceStorage weatherServicePersistenceFile = new ServicePersistenceStorage(this); final GeocodingData geocodingData = weatherServicePersistenceFile.getGeocodingData(); if (geocodingData != null) { diff --git a/src/de/example/exampletdd/WeatherInformationMapActivity.java b/src/de/example/exampletdd/WeatherInformationMapActivity.java index 6f9b2bb..84b99d9 100644 --- a/src/de/example/exampletdd/WeatherInformationMapActivity.java +++ b/src/de/example/exampletdd/WeatherInformationMapActivity.java @@ -26,12 +26,12 @@ import com.google.android.gms.maps.model.MarkerOptions; import de.example.exampletdd.fragment.ErrorDialogFragment; import de.example.exampletdd.fragment.ProgressDialogFragment; import de.example.exampletdd.model.GeocodingData; -import de.example.exampletdd.service.WeatherServicePersistenceFile; +import de.example.exampletdd.service.ServicePersistenceStorage; public class WeatherInformationMapActivity extends FragmentActivity { private GoogleMap mMap; private Marker mMarker; - private WeatherServicePersistenceFile mWeatherServicePersistenceFile; + private ServicePersistenceStorage mWeatherServicePersistenceFile; @Override protected void onCreate(final Bundle savedInstanceState) { @@ -46,7 +46,7 @@ public class WeatherInformationMapActivity extends FragmentActivity { this.mMap.getUiSettings().setCompassEnabled(false); this.mMap.setOnMapLongClickListener(new LongClickListener()); - this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this); + this.mWeatherServicePersistenceFile = new ServicePersistenceStorage(this); final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData(); diff --git a/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java b/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java index 42eff40..425ea59 100644 --- a/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java +++ b/src/de/example/exampletdd/WeatherInformationSpecificDataActivity.java @@ -4,7 +4,7 @@ import android.app.ActionBar; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import de.example.exampletdd.model.GeocodingData; -import de.example.exampletdd.service.WeatherServicePersistenceFile; +import de.example.exampletdd.service.ServicePersistenceStorage; public class WeatherInformationSpecificDataActivity extends FragmentActivity { @@ -27,7 +27,7 @@ public class WeatherInformationSpecificDataActivity extends FragmentActivity { final ActionBar actionBar = this.getActionBar(); - final WeatherServicePersistenceFile weatherServicePersistenceFile = new WeatherServicePersistenceFile(this); + final ServicePersistenceStorage weatherServicePersistenceFile = new ServicePersistenceStorage(this); final GeocodingData geocodingData = weatherServicePersistenceFile.getGeocodingData(); if (geocodingData != null) { diff --git a/src/de/example/exampletdd/WeatherTabsActivity.java b/src/de/example/exampletdd/WeatherTabsActivity.java index 0cf2431..df7cd0f 100644 --- a/src/de/example/exampletdd/WeatherTabsActivity.java +++ b/src/de/example/exampletdd/WeatherTabsActivity.java @@ -15,23 +15,23 @@ import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.view.Menu; import android.view.MenuItem; -import de.example.exampletdd.fragment.current.WeatherInformationCurrentDataFragment; -import de.example.exampletdd.fragment.overview.WeatherInformationOverviewFragment; +import de.example.exampletdd.fragment.current.CurrentDataFragment; +import de.example.exampletdd.fragment.overview.OverviewFragment; import de.example.exampletdd.model.GeocodingData; -import de.example.exampletdd.service.WeatherServicePersistenceFile; +import de.example.exampletdd.service.ServicePersistenceStorage; public class WeatherTabsActivity extends FragmentActivity { private static final int NUM_ITEMS = 2; private MyAdapter mAdapter; private ViewPager mPager; - private WeatherServicePersistenceFile mWeatherServicePersistenceFile; + private ServicePersistenceStorage mWeatherServicePersistenceFile; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.fragment_pager); - this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this); + this.mWeatherServicePersistenceFile = new ServicePersistenceStorage(this); this.mAdapter = new MyAdapter(this.getSupportFragmentManager()); this.mPager = (ViewPager)this.findViewById(R.id.pager); @@ -165,7 +165,7 @@ public class WeatherTabsActivity extends FragmentActivity { final ActionBar actionBar = this.getActionBar(); - final WeatherServicePersistenceFile weatherServicePersistenceFile = new WeatherServicePersistenceFile(this); + final ServicePersistenceStorage weatherServicePersistenceFile = new ServicePersistenceStorage(this); final GeocodingData geocodingData = weatherServicePersistenceFile.getGeocodingData(); if (geocodingData != null) { @@ -258,9 +258,9 @@ public class WeatherTabsActivity extends FragmentActivity { @Override public Fragment getItem(final int position) { if (position == 0) { - return new WeatherInformationCurrentDataFragment(); + return new CurrentDataFragment(); } else { - final Fragment fragment = new WeatherInformationOverviewFragment(); + final Fragment fragment = new OverviewFragment(); return fragment; } diff --git a/src/de/example/exampletdd/fragment/current/CurrentDataFragment.java b/src/de/example/exampletdd/fragment/current/CurrentDataFragment.java new file mode 100644 index 0000000..8d51822 --- /dev/null +++ b/src/de/example/exampletdd/fragment/current/CurrentDataFragment.java @@ -0,0 +1,258 @@ +package de.example.exampletdd.fragment.current; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.ListFragment; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; +import android.widget.ListView; +import de.example.exampletdd.R; +import de.example.exampletdd.fragment.ErrorDialogFragment; +import de.example.exampletdd.fragment.overview.IconsList; +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.service.ServicePersistenceStorage; + +public class CurrentDataFragment extends ListFragment { + private static final String TAG = "WeatherInformationCurrentDataFragment"; + private boolean mIsFahrenheit; + private ServicePersistenceStorage mWeatherServicePersistenceFile; + private BroadcastReceiver mReceiver; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + this.mWeatherServicePersistenceFile = new ServicePersistenceStorage(this.getActivity()); + + this.mReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(final Context context, final Intent intent) { + // This method will be run in the main thread. + final String action = intent.getAction(); + if (action.equals("de.example.exampletdd.UPDATECURRENTWEATHER")) { + Log.i(TAG, "WeatherInformationCurrentDataFragment Update Weather Data"); + final Current currentWeatherData = + CurrentDataFragment.this.mWeatherServicePersistenceFile + .getCurrentWeatherData(); + if (currentWeatherData != null) { + CurrentDataFragment.this + .updateCurrentWeatherData(currentWeatherData); + } + + } + } + }; + } + + @Override + public void onActivityCreated(final Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + final ListView listWeatherView = this.getListView(); + listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE); + + if (savedInstanceState != null) { + // Restore state + final Current currentWeatherData = (Current) 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"); + } + } + } + + this.setHasOptionsMenu(false); + this.setEmptyText("No data available"); + this.setListShown(true); + this.setListShownNoAnimation(true); + } + + @Override + public void onResume() { + super.onResume(); + + // 1. Register receiver + final IntentFilter filter = new IntentFilter(); + filter.addAction("de.example.exampletdd.UPDATECURRENTWEATHER"); + LocalBroadcastManager.getInstance(this.getActivity()).registerReceiver(this.mReceiver, + filter); + + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getActivity()); + + // 2. 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; + } + + // 3. Try to restore old information + final Current currentWeatherData = this.mWeatherServicePersistenceFile + .getCurrentWeatherData(); + if (currentWeatherData != null) { + this.updateCurrentWeatherData(currentWeatherData); + } + } + + @Override + public void onPause() { + super.onPause(); + LocalBroadcastManager.getInstance(this.getActivity()).unregisterReceiver(this.mReceiver); + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + + // Save state + final Current currentWeatherData = this.mWeatherServicePersistenceFile + .getCurrentWeatherData(); + + if (currentWeatherData != null) { + savedInstanceState.putSerializable("CurrentWeatherData", currentWeatherData); + } + + super.onSaveInstanceState(savedInstanceState); + } + + public void updateCurrentWeatherData(final Current currentWeatherData) { + final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); + tempFormatter.applyPattern("#####.#####"); + final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.US); + + final double tempUnits = this.mIsFahrenheit ? 0 : 273.15; + final String symbol = this.mIsFahrenheit ? "ºF" : "ºC"; + + final int[] layouts = new int[3]; + layouts[0] = R.layout.weather_current_data_entry_first; + layouts[1] = R.layout.weather_current_data_entry_second; + layouts[2] = R.layout.weather_current_data_entry_fifth; + final WeatherCurrentDataAdapter adapter = new WeatherCurrentDataAdapter(this.getActivity(), + layouts); + + + String tempMax = ""; + if (currentWeatherData.getMain().getTemp_max() != null) { + double conversion = (Double) currentWeatherData.getMain().getTemp_max(); + conversion = conversion - tempUnits; + tempMax = tempFormatter.format(conversion) + symbol; + } + String tempMin = ""; + if (currentWeatherData.getMain().getTemp_min() != null) { + double conversion = (Double) currentWeatherData.getMain().getTemp_min(); + conversion = conversion - tempUnits; + tempMin = tempFormatter.format(conversion) + symbol; + } + Bitmap picture; + if ((currentWeatherData.getWeather().size() > 0) + && (currentWeatherData.getWeather().get(0).getIcon() != null) + && (IconsList.getIcon(currentWeatherData.getWeather().get(0).getIcon()) != null)) { + final String icon = currentWeatherData.getWeather().get(0).getIcon(); + picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) + .getResourceDrawable()); + } else { + picture = BitmapFactory.decodeResource(this.getResources(), + R.drawable.weather_severe_alert); + } + final WeatherCurrentDataEntryFirst entryFirst = new WeatherCurrentDataEntryFirst(tempMax, + tempMin, picture); + adapter.add(entryFirst); + + String description = "no description available"; + if (currentWeatherData.getWeather().size() > 0) { + description = currentWeatherData.getWeather().get(0).getDescription(); + } + final WeatherCurrentDataEntrySecond entrySecond = new WeatherCurrentDataEntrySecond( + description); + adapter.add(entrySecond); + + String humidityValue = ""; + if ((currentWeatherData.getMain() != null) + && (currentWeatherData.getMain().getHumidity() != null)) { + final double conversion = (Double) currentWeatherData.getMain().getHumidity(); + humidityValue = tempFormatter.format(conversion); + } + String pressureValue = ""; + if ((currentWeatherData.getMain() != null) + && (currentWeatherData.getMain().getPressure() != null)) { + final double conversion = (Double) currentWeatherData.getMain().getPressure(); + pressureValue = tempFormatter.format(conversion); + } + String windValue = ""; + if ((currentWeatherData.getWind() != null) + && (currentWeatherData.getWind().getSpeed() != null)) { + final double conversion = (Double) currentWeatherData.getWind().getSpeed(); + windValue = tempFormatter.format(conversion); + } + String rainValue = ""; + if ((currentWeatherData.getRain() != null) + && (currentWeatherData.getRain().get3h() != null)) { + final double conversion = (Double) currentWeatherData.getRain().get3h(); + rainValue = tempFormatter.format(conversion); + } + String cloudsValue = ""; + if ((currentWeatherData.getClouds() != null) + && (currentWeatherData.getClouds().getAll() != null)) { + final double conversion = (Double) currentWeatherData.getClouds().getAll(); + cloudsValue = tempFormatter.format(conversion); + } + String snowValue = ""; + if ((currentWeatherData.getSnow() != null) + && (currentWeatherData.getSnow().get3h() != null)) { + final double conversion = (Double) currentWeatherData.getSnow().get3h(); + snowValue = tempFormatter.format(conversion); + } + String feelsLike = ""; + if (currentWeatherData.getMain().getTemp() != null) { + double conversion = (Double) currentWeatherData.getMain().getTemp(); + conversion = conversion - tempUnits; + feelsLike = tempFormatter.format(conversion); + } + String sunRiseTime = ""; + if (currentWeatherData.getSys().getSunrise() != null) { + final long unixTime = (Long) currentWeatherData.getSys().getSunrise(); + final Date unixDate = new Date(unixTime * 1000L); + sunRiseTime = dateFormat.format(unixDate); + } + String sunSetTime = ""; + if (currentWeatherData.getSys().getSunset() != null) { + final long unixTime = (Long) currentWeatherData.getSys().getSunset(); + final Date unixDate = new Date(unixTime * 1000L); + sunSetTime = dateFormat.format(unixDate); + } + final WeatherCurrentDataEntryFifth entryFifth = new WeatherCurrentDataEntryFifth( + sunRiseTime, sunSetTime, humidityValue, pressureValue, windValue, rainValue, + feelsLike, symbol, snowValue, cloudsValue); + adapter.add(entryFifth); + + + this.setListAdapter(adapter); + } +} diff --git a/src/de/example/exampletdd/fragment/current/WeatherInformationCurrentDataFragment.java b/src/de/example/exampletdd/fragment/current/WeatherInformationCurrentDataFragment.java deleted file mode 100644 index 7ffd441..0000000 --- a/src/de/example/exampletdd/fragment/current/WeatherInformationCurrentDataFragment.java +++ /dev/null @@ -1,258 +0,0 @@ -package de.example.exampletdd.fragment.current; - -import java.io.IOException; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.ListFragment; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; -import android.widget.ListView; -import de.example.exampletdd.R; -import de.example.exampletdd.fragment.ErrorDialogFragment; -import de.example.exampletdd.fragment.overview.IconsList; -import de.example.exampletdd.model.currentweather.CurrentWeatherData; -import de.example.exampletdd.service.WeatherServicePersistenceFile; - -public class WeatherInformationCurrentDataFragment extends ListFragment { - private static final String TAG = "WeatherInformationCurrentDataFragment"; - private boolean mIsFahrenheit; - private WeatherServicePersistenceFile mWeatherServicePersistenceFile; - private BroadcastReceiver mReceiver; - - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity()); - - this.mReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(final Context context, final Intent intent) { - // This method will be run in the main thread. - final String action = intent.getAction(); - if (action.equals("de.example.exampletdd.UPDATECURRENTWEATHER")) { - Log.i(TAG, "WeatherInformationCurrentDataFragment Update Weather Data"); - final CurrentWeatherData currentWeatherData = - WeatherInformationCurrentDataFragment.this.mWeatherServicePersistenceFile - .getCurrentWeatherData(); - if (currentWeatherData != null) { - WeatherInformationCurrentDataFragment.this - .updateCurrentWeatherData(currentWeatherData); - } - - } - } - }; - } - - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - final ListView listWeatherView = this.getListView(); - listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE); - - 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"); - } - } - } - - this.setHasOptionsMenu(false); - this.setEmptyText("No data available"); - this.setListShown(true); - this.setListShownNoAnimation(true); - } - - @Override - public void onResume() { - super.onResume(); - - // 1. Register receiver - final IntentFilter filter = new IntentFilter(); - filter.addAction("de.example.exampletdd.UPDATECURRENTWEATHER"); - LocalBroadcastManager.getInstance(this.getActivity()).registerReceiver(this.mReceiver, - filter); - - final SharedPreferences sharedPreferences = PreferenceManager - .getDefaultSharedPreferences(this.getActivity()); - - // 2. 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; - } - - // 3. Try to restore old information - final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile - .getCurrentWeatherData(); - if (currentWeatherData != null) { - this.updateCurrentWeatherData(currentWeatherData); - } - } - - @Override - public void onPause() { - super.onPause(); - LocalBroadcastManager.getInstance(this.getActivity()).unregisterReceiver(this.mReceiver); - } - - @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.US); - tempFormatter.applyPattern("#####.#####"); - final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.US); - - final double tempUnits = this.mIsFahrenheit ? 0 : 273.15; - final String symbol = this.mIsFahrenheit ? "ºF" : "ºC"; - - final int[] layouts = new int[3]; - layouts[0] = R.layout.weather_current_data_entry_first; - layouts[1] = R.layout.weather_current_data_entry_second; - layouts[2] = R.layout.weather_current_data_entry_fifth; - final WeatherCurrentDataAdapter adapter = new WeatherCurrentDataAdapter(this.getActivity(), - layouts); - - - String tempMax = ""; - if (currentWeatherData.getMain().getTemp_max() != null) { - double conversion = (Double) currentWeatherData.getMain().getTemp_max(); - conversion = conversion - tempUnits; - tempMax = tempFormatter.format(conversion) + symbol; - } - String tempMin = ""; - if (currentWeatherData.getMain().getTemp_min() != null) { - double conversion = (Double) currentWeatherData.getMain().getTemp_min(); - conversion = conversion - tempUnits; - tempMin = tempFormatter.format(conversion) + symbol; - } - Bitmap picture; - if ((currentWeatherData.getWeather().size() > 0) - && (currentWeatherData.getWeather().get(0).getIcon() != null) - && (IconsList.getIcon(currentWeatherData.getWeather().get(0).getIcon()) != null)) { - final String icon = currentWeatherData.getWeather().get(0).getIcon(); - picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) - .getResourceDrawable()); - } else { - picture = BitmapFactory.decodeResource(this.getResources(), - R.drawable.weather_severe_alert); - } - final WeatherCurrentDataEntryFirst entryFirst = new WeatherCurrentDataEntryFirst(tempMax, - tempMin, picture); - adapter.add(entryFirst); - - String description = "no description available"; - if (currentWeatherData.getWeather().size() > 0) { - description = currentWeatherData.getWeather().get(0).getDescription(); - } - final WeatherCurrentDataEntrySecond entrySecond = new WeatherCurrentDataEntrySecond( - description); - adapter.add(entrySecond); - - String humidityValue = ""; - if ((currentWeatherData.getMain() != null) - && (currentWeatherData.getMain().getHumidity() != null)) { - final double conversion = (Double) currentWeatherData.getMain().getHumidity(); - humidityValue = tempFormatter.format(conversion); - } - String pressureValue = ""; - if ((currentWeatherData.getMain() != null) - && (currentWeatherData.getMain().getPressure() != null)) { - final double conversion = (Double) currentWeatherData.getMain().getPressure(); - pressureValue = tempFormatter.format(conversion); - } - String windValue = ""; - if ((currentWeatherData.getWind() != null) - && (currentWeatherData.getWind().getSpeed() != null)) { - final double conversion = (Double) currentWeatherData.getWind().getSpeed(); - windValue = tempFormatter.format(conversion); - } - String rainValue = ""; - if ((currentWeatherData.getRain() != null) - && (currentWeatherData.getRain().get3h() != null)) { - final double conversion = (Double) currentWeatherData.getRain().get3h(); - rainValue = tempFormatter.format(conversion); - } - String cloudsValue = ""; - if ((currentWeatherData.getClouds() != null) - && (currentWeatherData.getClouds().getAll() != null)) { - final double conversion = (Double) currentWeatherData.getClouds().getAll(); - cloudsValue = tempFormatter.format(conversion); - } - String snowValue = ""; - if ((currentWeatherData.getSnow() != null) - && (currentWeatherData.getSnow().get3h() != null)) { - final double conversion = (Double) currentWeatherData.getSnow().get3h(); - snowValue = tempFormatter.format(conversion); - } - String feelsLike = ""; - if (currentWeatherData.getMain().getTemp() != null) { - double conversion = (Double) currentWeatherData.getMain().getTemp(); - conversion = conversion - tempUnits; - feelsLike = tempFormatter.format(conversion); - } - String sunRiseTime = ""; - if (currentWeatherData.getSys().getSunrise() != null) { - final long unixTime = (Long) currentWeatherData.getSys().getSunrise(); - final Date unixDate = new Date(unixTime * 1000L); - sunRiseTime = dateFormat.format(unixDate); - } - String sunSetTime = ""; - if (currentWeatherData.getSys().getSunset() != null) { - final long unixTime = (Long) currentWeatherData.getSys().getSunset(); - final Date unixDate = new Date(unixTime * 1000L); - sunSetTime = dateFormat.format(unixDate); - } - final WeatherCurrentDataEntryFifth entryFifth = new WeatherCurrentDataEntryFifth( - sunRiseTime, sunSetTime, humidityValue, pressureValue, windValue, rainValue, - feelsLike, symbol, snowValue, cloudsValue); - adapter.add(entryFifth); - - - this.setListAdapter(adapter); - } -} diff --git a/src/de/example/exampletdd/fragment/overview/OverviewAdapter.java b/src/de/example/exampletdd/fragment/overview/OverviewAdapter.java new file mode 100644 index 0000000..13641b6 --- /dev/null +++ b/src/de/example/exampletdd/fragment/overview/OverviewAdapter.java @@ -0,0 +1,108 @@ +package de.example.exampletdd.fragment.overview; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; +import de.example.exampletdd.R; + +public class OverviewAdapter extends ArrayAdapter { + private final int resource; + + public OverviewAdapter(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 OverviewEntry entry = this.getItem(position); + + + // Setting date + viewHolder.dateNameView.setText(entry.getDateName()); + viewHolder.dateNumberView.setText(entry.getDateNumber()); + + // Setting temperature max/min + viewHolder.temperatureMaxView.setText(entry.getMaxTemp()); + viewHolder.temperatureMinView.setText(entry.getMinTemp()); + + // Set image view + viewHolder.pictureView.setImageBitmap(entry.getPicture()); + + + 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.dateNameView = (TextView) workingView + .findViewById(R.id.weather_main_entry_date_name); + viewHolder.dateNumberView = (TextView) workingView + .findViewById(R.id.weather_main_entry_date_number); + viewHolder.temperatureMaxView = (TextView) workingView + .findViewById(R.id.weather_main_entry_temperature_max); + viewHolder.temperatureMinView = (TextView) workingView + .findViewById(R.id.weather_main_entry_temperature_min); + viewHolder.pictureView = (ImageView) workingView + .findViewById(R.id.weather_main_entry_image); + + 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 dateNameView; + public TextView dateNumberView; + public TextView temperatureMaxView; + public TextView temperatureMinView; + public ImageView pictureView; + } + +} diff --git a/src/de/example/exampletdd/fragment/overview/OverviewEntry.java b/src/de/example/exampletdd/fragment/overview/OverviewEntry.java new file mode 100644 index 0000000..16135f9 --- /dev/null +++ b/src/de/example/exampletdd/fragment/overview/OverviewEntry.java @@ -0,0 +1,41 @@ +package de.example.exampletdd.fragment.overview; + +import android.graphics.Bitmap; + +public class OverviewEntry { + private final String dateName; + private final String dateNumber; + private final String maxTemp; + private final String minTemp; + private final Bitmap picture; + + public OverviewEntry(final String dateName, final String dateNumber, + final String maxTemp, final String minTemp, + final Bitmap picture) { + this.dateName = dateName; + this.dateNumber = dateNumber; + this.maxTemp = maxTemp; + this.minTemp = minTemp; + this.picture = picture; + } + + public String getDateName() { + return this.dateName; + } + + public String getDateNumber() { + return this.dateNumber; + } + + public String getMaxTemp() { + return this.maxTemp; + } + + public String getMinTemp() { + return this.minTemp; + } + + public Bitmap getPicture() { + return this.picture; + } +} diff --git a/src/de/example/exampletdd/fragment/overview/OverviewFragment.java b/src/de/example/exampletdd/fragment/overview/OverviewFragment.java new file mode 100644 index 0000000..40b7cbd --- /dev/null +++ b/src/de/example/exampletdd/fragment/overview/OverviewFragment.java @@ -0,0 +1,311 @@ +package de.example.exampletdd.fragment.overview; + +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.Date; +import java.util.List; +import java.util.Locale; + +import org.apache.http.client.ClientProtocolException; + +import android.content.ComponentName; +import android.content.Intent; +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.os.Parcelable; +import android.preference.PreferenceManager; +import android.support.v4.app.ListFragment; +import android.util.Log; +import android.view.View; +import android.widget.ListView; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.R; +import de.example.exampletdd.WeatherInformationApplication; +import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment; +import de.example.exampletdd.httpclient.CustomHTTPClient; +import de.example.exampletdd.model.GeocodingData; +import de.example.exampletdd.model.forecastweather.Forecast; +import de.example.exampletdd.parser.JPOSWeatherParser; +import de.example.exampletdd.service.ServiceParser; + +public class OverviewFragment extends ListFragment { + private static final String TAG = "OverviewFragment"; + private Parcelable mListState; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public void onActivityCreated(final Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + final ListView listWeatherView = this.getListView(); + listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE); + + if (savedInstanceState != null) { + // Restore UI state + final Forecast forecast = (Forecast) savedInstanceState.getSerializable("Forecast"); + + // TODO: Could it be better to store in global data forecast even if it is null value? + // So, perhaps do not check for null value and always store in global variable. + if (forecast != null) { + final WeatherInformationApplication application = (WeatherInformationApplication) getActivity().getApplication(); + application.setForecast(forecast); + } + + this.mListState = savedInstanceState.getParcelable("ListState"); + } + + this.setHasOptionsMenu(false); + + final OverviewAdapter adapter = new OverviewAdapter( + this.getActivity(), R.layout.weather_main_entry_list); + + // TODO: string static resource + this.setEmptyText("No data available"); + + this.setListAdapter(adapter); + this.setListShown(true); + this.setListShownNoAnimation(true); + } + + @Override + public void onResume() { + super.onResume(); + + // TODO: retrive data from data base (like I do on WindowsPhone 8) + final GeocodingData geocodingData = new GeocodingData.Builder().build(); + if (geocodingData == null) { + // Nothing to do. + return; + } + + final WeatherInformationApplication application = (WeatherInformationApplication) getActivity().getApplication(); + final Forecast forecast = application.getForecast(); + + // TODO: Also check whether data is fresh (like I do on WindowsPhone 8) using data base + if (forecast != null /* && dataIsFresh() */) { + this.updateForecastWeatherData(forecast); + } else { + // Load remote data (aynchronous) + // Gets the data from the web. + final OverviewTask task = new OverviewTask( + new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")), + new ServiceParser(new JPOSWeatherParser())); + + task.execute(geocodingData); + // TODO: make sure thread UI keeps running in parallel after that. I guess. + } + + // TODO: could mListState be an old value? It is just updated in onActivityCreated method... :/ + if (this.mListState != null) { + this.getListView().onRestoreInstanceState(this.mListState); + } + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + + // Save UI state + final WeatherInformationApplication application = (WeatherInformationApplication) getActivity().getApplication(); + final Forecast forecast = application.getForecast(); + + if (forecast != null) { + savedInstanceState.putSerializable("Forecast", forecast); + } + + this.mListState = this.getListView().onSaveInstanceState(); + savedInstanceState.putParcelable("ListState", this.mListState); + + super.onSaveInstanceState(savedInstanceState); + } + + @Override + public void onListItemClick(final ListView l, final View v, final int position, final long id) { + final WeatherInformationSpecificDataFragment fragment = (WeatherInformationSpecificDataFragment) this + .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.WeatherInformationSpecificDataActivity")); + intent.putExtra("CHOSEN_DAY", (int) id); + OverviewFragment.this.getActivity().startActivity(intent); + } else { + // tablet layout + fragment.getWeatherByDay((int) id); + } + } + + private void updateForecastWeatherData(final Forecast forecastWeatherData) { + + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getActivity()); + + + // 1. Update units of measurement. + boolean mIsFahrenheit = false; + String keyPreference = this.getResources() + .getString(R.string.weather_preferences_units_key); + final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "Celsius"); + final String celsius = this.getResources().getString( + R.string.weather_preferences_units_celsius); + if (unitsPreferenceValue.equals(celsius)) { + mIsFahrenheit = false; + } else { + mIsFahrenheit = true; + } + final double tempUnits = mIsFahrenheit ? 0 : 273.15; + final String symbol = mIsFahrenheit ? "ºF" : "ºC"; + + + // 2. Update number day forecast. + int mDayForecast; + keyPreference = this.getResources() + .getString(R.string.weather_preferences_day_forecast_key); + final String dayForecast = sharedPreferences.getString(keyPreference, "5"); + mDayForecast = Integer.valueOf(dayForecast); + + + // 3. Date format + final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); + tempFormatter.applyPattern("#####.##"); + final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.US); + final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d", Locale.US); + + + // 4. Prepare data for UI. + final List entries = new ArrayList(); + final OverviewAdapter adapter = new OverviewAdapter(this.getActivity(), + R.layout.weather_main_entry_list); + final Calendar calendar = Calendar.getInstance(); + int count = mDayForecast; + for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData + .getList()) { + + Bitmap picture; + + if ((forecast.getWeather().size() > 0) && + (forecast.getWeather().get(0).getIcon() != null) && + (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) { + final String icon = forecast.getWeather().get(0).getIcon(); + picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) + .getResourceDrawable()); + } else { + picture = BitmapFactory.decodeResource(this.getResources(), + R.drawable.weather_severe_alert); + } + + final Long forecastUNIXDate = (Long) forecast.getDt(); + calendar.setTimeInMillis(forecastUNIXDate * 1000L); + final Date dayTime = calendar.getTime(); + final String dayTextName = dayNameFormatter.format(dayTime); + final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime); + + Double maxTemp = null; + if (forecast.getTemp().getMax() != null) { + maxTemp = (Double) forecast.getTemp().getMax(); + maxTemp = maxTemp - tempUnits; + } + + Double minTemp = null; + if (forecast.getTemp().getMin() != null) { + minTemp = (Double) forecast.getTemp().getMin(); + minTemp = minTemp - tempUnits; + } + + if ((maxTemp != null) && (minTemp != null)) { + entries.add(new OverviewEntry(dayTextName, monthAndDayNumberText, + tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol, + picture)); + } + + count = count - 1; + if (count == 0) { + break; + } + } + + + // 5. Update UI. + this.setListAdapter(null); + adapter.addAll(entries); + this.setListAdapter(adapter); + } + + + public class OverviewTask extends AsyncTask { + final CustomHTTPClient weatherHTTPClient; + final ServiceParser weatherService; + + public OverviewTask(final CustomHTTPClient weatherHTTPClient, final ServiceParser weatherService) { + this.weatherHTTPClient = weatherHTTPClient; + this.weatherService = weatherService; + } + + @Override + protected Forecast doInBackground(final GeocodingData... params) { + Log.i(TAG, "OverviewFragment doInBackground"); + Forecast weatherData = null; + + try { + weatherData = this.doInBackgroundThrowable(params[0], weatherHTTPClient, weatherService); + } catch (final JsonParseException e) { + Log.e(TAG, "doInBackground exception: ", e); + } 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); + } finally { + weatherHTTPClient.close(); + } + + return weatherData; + } + + private Forecast doInBackgroundThrowable(final GeocodingData geocodingData, + final CustomHTTPClient HTTPClient, final ServiceParser serviceParser) + throws URISyntaxException, ClientProtocolException, JsonParseException, IOException { + + final String APIVersion = getResources().getString(R.string.api_version); + final String urlAPI = getResources().getString(R.string.uri_api_weather_forecast); + // TODO: number as resource + final String url = serviceParser.createURIAPIForecastWeather(urlAPI, APIVersion, + geocodingData.getLatitude(), geocodingData.getLongitude(), "14"); + final String jsonData = HTTPClient.retrieveDataAsString(new URL(url)); + + return serviceParser.retrieveForecastWeatherDataFromJPOS(jsonData); + } + + @Override + protected void onPostExecute(final Forecast forecast) { + // Call UpdateUI on the UI thread. + updateForecastWeatherData(forecast); + + final WeatherInformationApplication application = (WeatherInformationApplication) getActivity().getApplication(); + application.setForecast(forecast); + + // TODO: update last time update using data base (like I do on Windows Phone 8) + } + } +} diff --git a/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java b/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java deleted file mode 100644 index aaf140e..0000000 --- a/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java +++ /dev/null @@ -1,265 +0,0 @@ -package de.example.exampletdd.fragment.overview; - -import java.io.IOException; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.Bundle; -import android.os.Parcelable; -import android.preference.PreferenceManager; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.ListFragment; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; -import android.view.View; -import android.widget.ListView; -import de.example.exampletdd.R; -import de.example.exampletdd.fragment.ErrorDialogFragment; -import de.example.exampletdd.fragment.specific.WeatherInformationSpecificDataFragment; -import de.example.exampletdd.model.forecastweather.ForecastWeatherData; -import de.example.exampletdd.service.WeatherServicePersistenceFile; - -public class WeatherInformationOverviewFragment extends ListFragment { - private static final String TAG = "WeatherInformationOverviewFragment"; - private boolean mIsFahrenheit; - private int mDayForecast; - private WeatherServicePersistenceFile mWeatherServicePersistenceFile; - private Parcelable mListState; - private BroadcastReceiver mReceiver; - - @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_day_forecast_key); - final String dayForecast = sharedPreferences.getString(keyPreference, ""); - this.mDayForecast = Integer.valueOf(dayForecast); - - this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity()); - - this.mReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(final Context context, final Intent intent) { - // This method will be run in the main thread. - final String action = intent.getAction(); - if (action.equals("de.example.exampletdd.UPDATEOVERVIEWWEATHER")) { - Log.i(TAG, "WeatherInformationOverviewFragment Update Weather Data"); - final ForecastWeatherData forecastWeatherData = - WeatherInformationOverviewFragment.this.mWeatherServicePersistenceFile - .getForecastWeatherData(); - if (forecastWeatherData != null) { - WeatherInformationOverviewFragment.this - .updateForecastWeatherData(forecastWeatherData); - } - - } - } - }; - } - - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - final ListView listWeatherView = this.getListView(); - listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE); - - if (savedInstanceState != null) { - // Restore state - final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState - .getSerializable("ForecastWeatherData"); - - if (forecastWeatherData != null) { - try { - this.mWeatherServicePersistenceFile - .storeForecastWeatherData(forecastWeatherData); - } catch (final IOException e) { - final DialogFragment newFragment = ErrorDialogFragment - .newInstance(R.string.error_dialog_generic_error); - newFragment.show(this.getFragmentManager(), "errorDialog"); - } - } - - this.mListState = savedInstanceState.getParcelable("ListState"); - } - - this.setHasOptionsMenu(false); - - final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter( - this.getActivity(), R.layout.weather_main_entry_list); - - - this.setEmptyText("No data available"); - - this.setListAdapter(adapter); - this.setListShown(true); - this.setListShownNoAnimation(true); - } - - @Override - public void onResume() { - super.onResume(); - - // 1. Register receiver. - final IntentFilter filter = new IntentFilter(); - filter.addAction("de.example.exampletdd.UPDATEOVERVIEWWEATHER"); - LocalBroadcastManager.getInstance(this.getActivity()).registerReceiver(this.mReceiver, filter); - - final SharedPreferences sharedPreferences = PreferenceManager - .getDefaultSharedPreferences(this.getActivity()); - - // 2. 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; - } - - // 3. Update number day forecast. - keyPreference = this.getResources() - .getString(R.string.weather_preferences_day_forecast_key); - final String dayForecast = sharedPreferences.getString(keyPreference, ""); - this.mDayForecast = Integer.valueOf(dayForecast); - - // 4. Update forecast weather data on display. - final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile - .getForecastWeatherData(); - if ((this.mListState != null) && (forecastWeatherData != null)) { - this.updateForecastWeatherData(forecastWeatherData); - this.getListView().onRestoreInstanceState(this.mListState); - } else if (forecastWeatherData != null) { - this.updateForecastWeatherData(forecastWeatherData); - } - - } - - @Override - public void onPause() { - super.onPause(); - LocalBroadcastManager.getInstance(this.getActivity()).unregisterReceiver(this.mReceiver); - } - - @Override - public void onSaveInstanceState(final Bundle savedInstanceState) { - - // Save state - final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile - .getForecastWeatherData(); - - if (forecastWeatherData != null) { - savedInstanceState.putSerializable("ForecastWeatherData", forecastWeatherData); - } - - this.mListState = this.getListView().onSaveInstanceState(); - savedInstanceState.putParcelable("ListState", this.mListState); - - super.onSaveInstanceState(savedInstanceState); - } - - @Override - public void onListItemClick(final ListView l, final View v, final int position, final long id) { - final WeatherInformationSpecificDataFragment fragment = (WeatherInformationSpecificDataFragment) this - .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.WeatherInformationSpecificDataActivity")); - intent.putExtra("CHOSEN_DAY", (int) id); - WeatherInformationOverviewFragment.this.getActivity().startActivity(intent); - } else { - // tablet layout - fragment.getWeatherByDay((int) id); - } - } - - private void updateForecastWeatherData(final ForecastWeatherData forecastWeatherData) { - final List entries = new ArrayList(); - final WeatherOverviewAdapter adapter = new WeatherOverviewAdapter(this.getActivity(), - R.layout.weather_main_entry_list); - - - final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); - tempFormatter.applyPattern("#####.##"); - final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.US); - final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d", Locale.US); - final double tempUnits = this.mIsFahrenheit ? 0 : 273.15; - final String symbol = this.mIsFahrenheit ? "ºF" : "ºC"; - - - final Calendar calendar = Calendar.getInstance(); - int count = this.mDayForecast; - for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData - .getList()) { - - Bitmap picture; - - if ((forecast.getWeather().size() > 0) && - (forecast.getWeather().get(0).getIcon() != null) && - (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) { - final String icon = forecast.getWeather().get(0).getIcon(); - picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) - .getResourceDrawable()); - } else { - picture = BitmapFactory.decodeResource(this.getResources(), - R.drawable.weather_severe_alert); - } - - final Long forecastUNIXDate = (Long) forecast.getDt(); - calendar.setTimeInMillis(forecastUNIXDate * 1000L); - final Date dayTime = calendar.getTime(); - final String dayTextName = dayNameFormatter.format(dayTime); - final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime); - - Double maxTemp = null; - if (forecast.getTemp().getMax() != null) { - maxTemp = (Double) forecast.getTemp().getMax(); - maxTemp = maxTemp - tempUnits; - } - - Double minTemp = null; - if (forecast.getTemp().getMin() != null) { - minTemp = (Double) forecast.getTemp().getMin(); - minTemp = minTemp - tempUnits; - } - - if ((maxTemp != null) && (minTemp != null)) { - entries.add(new WeatherOverviewEntry(dayTextName, monthAndDayNumberText, - tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol, - picture)); - } - - count = count - 1; - if (count == 0) { - break; - } - } - - this.setListAdapter(null); - adapter.addAll(entries); - this.setListAdapter(adapter); - } -} diff --git a/src/de/example/exampletdd/fragment/overview/WeatherOverviewAdapter.java b/src/de/example/exampletdd/fragment/overview/WeatherOverviewAdapter.java deleted file mode 100644 index 6d2a26d..0000000 --- a/src/de/example/exampletdd/fragment/overview/WeatherOverviewAdapter.java +++ /dev/null @@ -1,108 +0,0 @@ -package de.example.exampletdd.fragment.overview; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.TextView; -import de.example.exampletdd.R; - -public class WeatherOverviewAdapter extends ArrayAdapter { - private final int resource; - - public WeatherOverviewAdapter(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 WeatherOverviewEntry entry = this.getItem(position); - - - // Setting date - viewHolder.dateNameView.setText(entry.getDateName()); - viewHolder.dateNumberView.setText(entry.getDateNumber()); - - // Setting temperature max/min - viewHolder.temperatureMaxView.setText(entry.getMaxTemp()); - viewHolder.temperatureMinView.setText(entry.getMinTemp()); - - // Set image view - viewHolder.pictureView.setImageBitmap(entry.getPicture()); - - - 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.dateNameView = (TextView) workingView - .findViewById(R.id.weather_main_entry_date_name); - viewHolder.dateNumberView = (TextView) workingView - .findViewById(R.id.weather_main_entry_date_number); - viewHolder.temperatureMaxView = (TextView) workingView - .findViewById(R.id.weather_main_entry_temperature_max); - viewHolder.temperatureMinView = (TextView) workingView - .findViewById(R.id.weather_main_entry_temperature_min); - viewHolder.pictureView = (ImageView) workingView - .findViewById(R.id.weather_main_entry_image); - - 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 dateNameView; - public TextView dateNumberView; - public TextView temperatureMaxView; - public TextView temperatureMinView; - public ImageView pictureView; - } - -} diff --git a/src/de/example/exampletdd/fragment/overview/WeatherOverviewEntry.java b/src/de/example/exampletdd/fragment/overview/WeatherOverviewEntry.java deleted file mode 100644 index c8d6b05..0000000 --- a/src/de/example/exampletdd/fragment/overview/WeatherOverviewEntry.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.example.exampletdd.fragment.overview; - -import android.graphics.Bitmap; - -public class WeatherOverviewEntry { - private final String dateName; - private final String dateNumber; - private final String maxTemp; - private final String minTemp; - private final Bitmap picture; - - public WeatherOverviewEntry(final String dateName, final String dateNumber, - final String maxTemp, final String minTemp, - final Bitmap picture) { - this.dateName = dateName; - this.dateNumber = dateNumber; - this.maxTemp = maxTemp; - this.minTemp = minTemp; - this.picture = picture; - } - - public String getDateName() { - return this.dateName; - } - - public String getDateNumber() { - return this.dateNumber; - } - - public String getMaxTemp() { - return this.maxTemp; - } - - public String getMinTemp() { - return this.minTemp; - } - - public Bitmap getPicture() { - return this.picture; - } -} diff --git a/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java b/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java index 57d8589..b38ce57 100644 --- a/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java +++ b/src/de/example/exampletdd/fragment/specific/WeatherInformationSpecificDataFragment.java @@ -19,13 +19,13 @@ import android.widget.ListView; import de.example.exampletdd.R; import de.example.exampletdd.fragment.ErrorDialogFragment; import de.example.exampletdd.fragment.overview.IconsList; -import de.example.exampletdd.model.forecastweather.ForecastWeatherData; -import de.example.exampletdd.service.WeatherServicePersistenceFile; +import de.example.exampletdd.model.forecastweather.Forecast; +import de.example.exampletdd.service.ServicePersistenceStorage; public class WeatherInformationSpecificDataFragment extends ListFragment { private boolean mIsFahrenheit; private int mChosenDay; - private WeatherServicePersistenceFile mWeatherServicePersistenceFile; + private ServicePersistenceStorage mWeatherServicePersistenceFile; @Override public void onCreate(final Bundle savedInstanceState) { @@ -39,7 +39,7 @@ public class WeatherInformationSpecificDataFragment extends ListFragment { this.mChosenDay = 0; } - this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile( + this.mWeatherServicePersistenceFile = new ServicePersistenceStorage( this.getActivity()); } @@ -56,7 +56,7 @@ public class WeatherInformationSpecificDataFragment extends ListFragment { if (savedInstanceState != null) { // Restore state - final ForecastWeatherData forecastWeatherData = (ForecastWeatherData) savedInstanceState + final Forecast forecastWeatherData = (Forecast) savedInstanceState .getSerializable("ForecastWeatherData"); if (forecastWeatherData != null) { @@ -78,7 +78,7 @@ public class WeatherInformationSpecificDataFragment extends ListFragment { public void onSaveInstanceState(final Bundle savedInstanceState) { // Save state - final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile + final Forecast forecastWeatherData = this.mWeatherServicePersistenceFile .getForecastWeatherData(); if (forecastWeatherData != null) { @@ -92,7 +92,7 @@ public class WeatherInformationSpecificDataFragment extends ListFragment { public void getWeatherByDay(final int chosenDay) { - final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile + final Forecast forecastWeatherData = this.mWeatherServicePersistenceFile .getForecastWeatherData(); if (forecastWeatherData != null) { this.updateForecastWeatherData(forecastWeatherData, chosenDay); @@ -101,7 +101,7 @@ public class WeatherInformationSpecificDataFragment extends ListFragment { } - public void updateForecastWeatherData(final ForecastWeatherData forecastWeatherData, + public void updateForecastWeatherData(final Forecast forecastWeatherData, final int chosenDay) { final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); tempFormatter.applyPattern("#####.#####"); @@ -245,7 +245,7 @@ public class WeatherInformationSpecificDataFragment extends ListFragment { // 2. Update weather data on display. - final ForecastWeatherData forecastWeatherData = this.mWeatherServicePersistenceFile + final Forecast forecastWeatherData = this.mWeatherServicePersistenceFile .getForecastWeatherData(); if (forecastWeatherData != null) { this.updateForecastWeatherData(forecastWeatherData, this.mChosenDay); diff --git a/src/de/example/exampletdd/model/currentweather/Current.java b/src/de/example/exampletdd/model/currentweather/Current.java new file mode 100644 index 0000000..a7bc22e --- /dev/null +++ b/src/de/example/exampletdd/model/currentweather/Current.java @@ -0,0 +1,139 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * Auto generated by: http://jsongen.byingtondesign.com/ + * (with my own modifications) + * + */ +public class Current implements Serializable { + private static final long serialVersionUID = -730690341739860818L; + private String base; + private Clouds clouds; + private Number cod; + private Coord coord; + private Number dt; + private Number id; + private Main main; + private String name; + private Rain rain; + private Snow snow; + private Sys sys; + private List weather; + private Wind wind; + private byte[] iconData; + private Date date; + + public String getBase(){ + return this.base; + } + public void setBase(final String base){ + this.base = base; + } + public Clouds getClouds(){ + return this.clouds; + } + public void setClouds(final Clouds clouds){ + this.clouds = clouds; + } + + public Number getCod() { + return this.cod; + } + + public void setCod(final Number cod) { + this.cod = cod; + } + public Coord getCoord(){ + return this.coord; + } + public void setCoord(final Coord coord){ + this.coord = coord; + } + public Number getDt(){ + return this.dt; + } + public void setDt(final Number dt){ + this.dt = dt; + } + public Number getId(){ + return this.id; + } + public void setId(final Number id){ + this.id = id; + } + public Main getMain(){ + return this.main; + } + public void setMain(final Main main){ + this.main = main; + } + public String getName(){ + return this.name; + } + public void setName(final String name){ + this.name = name; + } + public Rain getRain(){ + return this.rain; + } + public void setRain(final Rain rain){ + this.rain = rain; + } + public Snow getSnow() { + return this.snow; + } + public void setSnow(final Snow snow) { + this.snow = snow; + } + public Sys getSys(){ + return this.sys; + } + public void setSys(final Sys sys){ + this.sys = sys; + } + public List getWeather(){ + return this.weather; + } + public void setWeather(final List weather){ + this.weather = weather; + } + public Wind getWind(){ + return this.wind; + } + public void setWind(final Wind wind){ + this.wind = wind; + } + + public byte[] getIconData() { + return this.iconData; + } + + public void setIconData(final byte[] iconData) { + this.iconData = iconData; + } + + public Date getDate() { + return this.date; + } + + public void setDate(final Date date) { + this.date = date; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Current [base=").append(this.base).append(", clouds=") + .append(this.clouds).append(", cod=").append(this.cod).append(", coord=") + .append(this.coord).append(", dt=").append(this.dt).append(", id=").append(this.id) + .append(", main=").append(this.main).append(", name=").append(this.name) + .append(", rain=").append(this.rain).append(", snow=").append(this.snow) + .append(", sys=").append(this.sys).append(", weather=").append(this.weather) + .append(", wind=").append(this.wind).append("]"); + return builder.toString(); + } +} diff --git a/src/de/example/exampletdd/model/currentweather/CurrentWeatherData.java b/src/de/example/exampletdd/model/currentweather/CurrentWeatherData.java deleted file mode 100644 index d6d042c..0000000 --- a/src/de/example/exampletdd/model/currentweather/CurrentWeatherData.java +++ /dev/null @@ -1,139 +0,0 @@ -package de.example.exampletdd.model.currentweather; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; - -/** - * Auto generated by: http://jsongen.byingtondesign.com/ - * (with my own modifications) - * - */ -public class CurrentWeatherData implements Serializable { - private static final long serialVersionUID = -730690341739860818L; - private String base; - private Clouds clouds; - private Number cod; - private Coord coord; - private Number dt; - private Number id; - private Main main; - private String name; - private Rain rain; - private Snow snow; - private Sys sys; - private List weather; - private Wind wind; - private byte[] iconData; - private Date date; - - public String getBase(){ - return this.base; - } - public void setBase(final String base){ - this.base = base; - } - public Clouds getClouds(){ - return this.clouds; - } - public void setClouds(final Clouds clouds){ - this.clouds = clouds; - } - - public Number getCod() { - return this.cod; - } - - public void setCod(final Number cod) { - this.cod = cod; - } - public Coord getCoord(){ - return this.coord; - } - public void setCoord(final Coord coord){ - this.coord = coord; - } - public Number getDt(){ - return this.dt; - } - public void setDt(final Number dt){ - this.dt = dt; - } - public Number getId(){ - return this.id; - } - public void setId(final Number id){ - this.id = id; - } - public Main getMain(){ - return this.main; - } - public void setMain(final Main main){ - this.main = main; - } - public String getName(){ - return this.name; - } - public void setName(final String name){ - this.name = name; - } - public Rain getRain(){ - return this.rain; - } - public void setRain(final Rain rain){ - this.rain = rain; - } - public Snow getSnow() { - return this.snow; - } - public void setSnow(final Snow snow) { - this.snow = snow; - } - public Sys getSys(){ - return this.sys; - } - public void setSys(final Sys sys){ - this.sys = sys; - } - public List getWeather(){ - return this.weather; - } - public void setWeather(final List weather){ - this.weather = weather; - } - public Wind getWind(){ - return this.wind; - } - public void setWind(final Wind wind){ - this.wind = wind; - } - - public byte[] getIconData() { - return this.iconData; - } - - public void setIconData(final byte[] iconData) { - this.iconData = iconData; - } - - public Date getDate() { - return this.date; - } - - public void setDate(final Date date) { - this.date = date; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("CurrentWeatherData [base=").append(this.base).append(", clouds=") - .append(this.clouds).append(", cod=").append(this.cod).append(", coord=") - .append(this.coord).append(", dt=").append(this.dt).append(", id=").append(this.id) - .append(", main=").append(this.main).append(", name=").append(this.name) - .append(", rain=").append(this.rain).append(", snow=").append(this.snow) - .append(", sys=").append(this.sys).append(", weather=").append(this.weather) - .append(", wind=").append(this.wind).append("]"); - return builder.toString(); - } -} diff --git a/src/de/example/exampletdd/model/forecastweather/Forecast.java b/src/de/example/exampletdd/model/forecastweather/Forecast.java new file mode 100644 index 0000000..5a59a02 --- /dev/null +++ b/src/de/example/exampletdd/model/forecastweather/Forecast.java @@ -0,0 +1,62 @@ +package de.example.exampletdd.model.forecastweather; + +import java.io.Serializable; +import java.util.List; + +/** + * Auto generated by: http://jsongen.byingtondesign.com/ + * (with my own modifications) + * + */ +public class Forecast implements Serializable { + private static final long serialVersionUID = 5095443678019686190L; + private City city; + private Number cnt; + private Number cod; + private List list; + private Number message; + + public City getCity(){ + return this.city; + } + public void setCity(final City city){ + this.city = city; + } + public Number getCnt(){ + return this.cnt; + } + public void setCnt(final Number cnt){ + this.cnt = cnt; + } + + public Number getCod() { + return this.cod; + } + + public void setCod(final Number cod) { + this.cod = cod; + } + + public List getList() { + return this.list; + } + + public void setList(final List list) { + this.list = list; + } + public Number getMessage(){ + return this.message; + } + public void setMessage(final Number message){ + this.message = message; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Forecast [city=").append(this.city).append(", cnt=") + .append(this.cnt).append(", cod=").append(this.cod).append(", list=") + .append(this.list).append(", message=").append(this.message).append("]"); + return builder.toString(); + } +} diff --git a/src/de/example/exampletdd/model/forecastweather/ForecastWeatherData.java b/src/de/example/exampletdd/model/forecastweather/ForecastWeatherData.java deleted file mode 100644 index 1b9cef7..0000000 --- a/src/de/example/exampletdd/model/forecastweather/ForecastWeatherData.java +++ /dev/null @@ -1,62 +0,0 @@ -package de.example.exampletdd.model.forecastweather; - -import java.io.Serializable; -import java.util.List; - -/** - * Auto generated by: http://jsongen.byingtondesign.com/ - * (with my own modifications) - * - */ -public class ForecastWeatherData implements Serializable { - private static final long serialVersionUID = 5095443678019686190L; - private City city; - private Number cnt; - private Number cod; - private List list; - private Number message; - - public City getCity(){ - return this.city; - } - public void setCity(final City city){ - this.city = city; - } - public Number getCnt(){ - return this.cnt; - } - public void setCnt(final Number cnt){ - this.cnt = cnt; - } - - public Number getCod() { - return this.cod; - } - - public void setCod(final Number cod) { - this.cod = cod; - } - - public List getList() { - return this.list; - } - - public void setList(final List list) { - this.list = list; - } - public Number getMessage(){ - return this.message; - } - public void setMessage(final Number message){ - this.message = message; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("ForecastWeatherData [city=").append(this.city).append(", cnt=") - .append(this.cnt).append(", cod=").append(this.cod).append(", list=") - .append(this.list).append(", message=").append(this.message).append("]"); - return builder.toString(); - } -} diff --git a/src/de/example/exampletdd/parser/IJPOSParser.java b/src/de/example/exampletdd/parser/IJPOSParser.java new file mode 100644 index 0000000..14a1d55 --- /dev/null +++ b/src/de/example/exampletdd/parser/IJPOSParser.java @@ -0,0 +1,17 @@ +package de.example.exampletdd.parser; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.model.forecastweather.Forecast; + +public interface IJPOSParser { + + public Current retrieveCurrenFromJPOS(final String jsonData) + throws JsonParseException, IOException; + + public Forecast retrieveForecastFromJPOS(final String jsonData) + throws JsonParseException, IOException; +} diff --git a/src/de/example/exampletdd/parser/IJPOSWeatherParser.java b/src/de/example/exampletdd/parser/IJPOSWeatherParser.java deleted file mode 100644 index db6e2df..0000000 --- a/src/de/example/exampletdd/parser/IJPOSWeatherParser.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.example.exampletdd.parser; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonParseException; - -import de.example.exampletdd.model.currentweather.CurrentWeatherData; -import de.example.exampletdd.model.forecastweather.ForecastWeatherData; - -public interface IJPOSWeatherParser { - - public CurrentWeatherData retrieveCurrentWeatherDataFromJPOS(final String jsonData) - throws JsonParseException, IOException; - - public ForecastWeatherData retrieveForecastWeatherDataFromJPOS(final String jsonData) - throws JsonParseException, IOException; -} diff --git a/src/de/example/exampletdd/parser/JPOSWeatherParser.java b/src/de/example/exampletdd/parser/JPOSWeatherParser.java index 56cc9e2..b71e342 100644 --- a/src/de/example/exampletdd/parser/JPOSWeatherParser.java +++ b/src/de/example/exampletdd/parser/JPOSWeatherParser.java @@ -10,23 +10,23 @@ import com.fasterxml.jackson.core.JsonToken; import de.example.exampletdd.model.currentweather.Clouds; import de.example.exampletdd.model.currentweather.Coord; -import de.example.exampletdd.model.currentweather.CurrentWeatherData; +import de.example.exampletdd.model.currentweather.Current; import de.example.exampletdd.model.currentweather.Main; import de.example.exampletdd.model.currentweather.Rain; import de.example.exampletdd.model.currentweather.Sys; import de.example.exampletdd.model.currentweather.Wind; import de.example.exampletdd.model.forecastweather.City; -import de.example.exampletdd.model.forecastweather.ForecastWeatherData; +import de.example.exampletdd.model.forecastweather.Forecast; import de.example.exampletdd.model.forecastweather.Temp; -public class JPOSWeatherParser implements IJPOSWeatherParser { +public class JPOSWeatherParser implements IJPOSParser { @Override - public CurrentWeatherData retrieveCurrentWeatherDataFromJPOS(final String jsonData) + public Current retrieveCurrenFromJPOS(final String jsonData) throws JsonParseException, IOException { final JsonFactory f = new JsonFactory(); - final CurrentWeatherData currentWeatherData = new CurrentWeatherData(); + final Current currentWeatherData = new Current(); currentWeatherData.setClouds(new Clouds()); currentWeatherData.setCoord(new Coord()); currentWeatherData.setMain(new Main()); @@ -43,11 +43,11 @@ public class JPOSWeatherParser implements IJPOSWeatherParser { } @Override - public ForecastWeatherData retrieveForecastWeatherDataFromJPOS(final String jsonData) + public Forecast retrieveForecastFromJPOS(final String jsonData) throws JsonParseException, IOException { final JsonFactory f = new JsonFactory(); - final ForecastWeatherData forecastWeatherData = new ForecastWeatherData(); + final Forecast forecastWeatherData = new Forecast(); forecastWeatherData .setList(new ArrayList(15)); final City city = new City(); @@ -60,7 +60,7 @@ public class JPOSWeatherParser implements IJPOSWeatherParser { return forecastWeatherData; } - private void getCurrentWeatherData(final CurrentWeatherData currentWeatherData, + private void getCurrentWeatherData(final Current currentWeatherData, final JsonParser jParser) throws JsonParseException, IOException { if (jParser.nextToken() == JsonToken.START_OBJECT) { @@ -87,7 +87,7 @@ public class JPOSWeatherParser implements IJPOSWeatherParser { } } - private void getCurrentWeatherDataObjects(final CurrentWeatherData currentWeatherData, + private void getCurrentWeatherDataObjects(final Current currentWeatherData, final JsonParser jParser, final String fieldname) throws JsonParseException, IOException { if (fieldname == "coord") { @@ -224,7 +224,7 @@ public class JPOSWeatherParser implements IJPOSWeatherParser { } } - private void getForecastWeatherData(final ForecastWeatherData forecastWeatherData, + private void getForecastWeatherData(final Forecast forecastWeatherData, final JsonParser jParser) throws JsonParseException, IOException { if (jParser.nextToken() == JsonToken.START_OBJECT) { @@ -251,7 +251,7 @@ public class JPOSWeatherParser implements IJPOSWeatherParser { } } - private void getForecastWeatherDataObjects(final ForecastWeatherData forecastWeatherData, + private void getForecastWeatherDataObjects(final Forecast forecastWeatherData, final JsonParser jParser, final String fieldname) throws JsonParseException, IOException { diff --git a/src/de/example/exampletdd/service/ServiceParser.java b/src/de/example/exampletdd/service/ServiceParser.java new file mode 100644 index 0000000..3b68340 --- /dev/null +++ b/src/de/example/exampletdd/service/ServiceParser.java @@ -0,0 +1,64 @@ +package de.example.exampletdd.service; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Locale; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.model.forecastweather.Forecast; +import de.example.exampletdd.parser.IJPOSParser; + +public class ServiceParser { + private final IJPOSParser JPOSParser; + + public ServiceParser(final IJPOSParser JPOSWeatherParser) { + this.JPOSParser = JPOSWeatherParser; + } + + public Current retrieveCurrentWeatherDataFromJPOS(final String jsonData) + throws JsonParseException, IOException { + return this.JPOSParser.retrieveCurrenFromJPOS(jsonData); + } + + public Forecast retrieveForecastWeatherDataFromJPOS(final String jsonData) + throws JsonParseException, IOException { + return this.JPOSParser.retrieveForecastFromJPOS(jsonData); + } + + public String createURIAPIForecastWeather(final String urlAPI, final String APIVersion, + final double latitude, final double longitude, final String resultsNumber) { + + final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); + final Object[] values = new Object[4]; + values[0] = APIVersion; + values[1] = latitude; + values[2] = longitude; + values[3] = resultsNumber; + + return formatURIAPI.format(values); + } + + public String createURIAPITodayWeather(final String urlAPI, final String APIVersion, + final double latitude, final double longitude) { + + final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); + final Object[] values = new Object[3]; + values[0] = APIVersion; + values[1] = latitude; + values[2] = longitude; + + return formatURIAPI.format(values); + } + + public String createURIAPIicon(final String icon, final String urlAPI) { + + final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); + final Object[] values = new Object[1]; + values[0] = icon; + + return formatURIAPI.format(values); + } + +} diff --git a/src/de/example/exampletdd/service/ServicePersistenceStorage.java b/src/de/example/exampletdd/service/ServicePersistenceStorage.java new file mode 100644 index 0000000..139ce46 --- /dev/null +++ b/src/de/example/exampletdd/service/ServicePersistenceStorage.java @@ -0,0 +1,217 @@ +package de.example.exampletdd.service; + +import java.io.File; +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 android.util.Log; +import de.example.exampletdd.model.GeocodingData; +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.model.forecastweather.Forecast; + +/** + * TODO: show some error message when there is no enough space for saving files. :/ + * + */ +public class ServicePersistenceStorage { + private static final String TAG = "ServicePersistenceStorage"; + private static final String CURRENT_WEATHER_DATA_FILE = "current_weatherdata.file"; + private static final String CURRENT_WEATHER_DATA_TEMPORARY_FILE = "current_weatherdata.tmp.file"; + private static final String FORECAST_WEATHER_DATA_FILE = "forecast_weatherdata.file"; + private static final String FORECAST_WEATHER_DATA_TEMPORARY_FILE = "forecast_weatherdata.tmp.file"; + private static final String WEATHER_GEOCODING_FILE = "weathergeocoding.file"; + private static final String WEATHER_GEOCODING_TEMPORARY_FILE = "weathergeocoding.tmp.file"; + private final Context context; + + public ServicePersistenceStorage(final Context context) { + this.context = context; + } + + public void storeGeocodingData(final GeocodingData geocodingData) + throws FileNotFoundException, IOException { + final OutputStream persistenceFile = this.context.openFileOutput( + WEATHER_GEOCODING_TEMPORARY_FILE, Context.MODE_PRIVATE); + + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(persistenceFile); + + oos.writeObject(geocodingData); + } finally { + if (oos != null) { + oos.close(); + } + } + + this.renameFile(WEATHER_GEOCODING_TEMPORARY_FILE, WEATHER_GEOCODING_FILE); + } + + public GeocodingData getGeocodingData() { + GeocodingData geocodingData = null; + + try { + geocodingData = this.getGeocodingDataThrowable(); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "getGeocodingData exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "getGeocodingData exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "getGeocodingData exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "getGeocodingData exception: ", e); + } + + return geocodingData; + } + + private GeocodingData getGeocodingDataThrowable() + throws StreamCorruptedException, FileNotFoundException, + IOException, ClassNotFoundException { + final InputStream persistenceFile = this.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 removeGeocodingData() { + this.context.deleteFile(WEATHER_GEOCODING_FILE); + } + + public void storeCurrentWeatherData(final Current currentWeatherData) + throws FileNotFoundException, IOException { + final OutputStream persistenceFile = this.context.openFileOutput( + CURRENT_WEATHER_DATA_FILE, Context.MODE_PRIVATE); + + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(persistenceFile); + + oos.writeObject(currentWeatherData); + } finally { + if (oos != null) { + oos.close(); + } + } + + this.renameFile(CURRENT_WEATHER_DATA_TEMPORARY_FILE, CURRENT_WEATHER_DATA_FILE); + } + + public Current getCurrentWeatherData() { + Current currentWeatherData = null; + + try { + currentWeatherData = this.getCurrentWeatherDataThrowable(); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "getWeatherData exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "getWeatherData exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "getWeatherData exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "getWeatherData exception: ", e); + } + + return currentWeatherData; + } + + private Current getCurrentWeatherDataThrowable() + throws StreamCorruptedException, + FileNotFoundException, IOException, ClassNotFoundException { + final InputStream persistenceFile = this.context.openFileInput( + CURRENT_WEATHER_DATA_FILE); + + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(persistenceFile); + + return (Current) ois.readObject(); + } finally { + if (ois != null) { + ois.close(); + } + } + } + + public void removeCurrentWeatherData() { + this.context.deleteFile(CURRENT_WEATHER_DATA_FILE); + } + + public void storeForecastWeatherData(final Forecast forecastWeatherData) + throws FileNotFoundException, IOException { + final OutputStream persistenceFile = this.context.openFileOutput(FORECAST_WEATHER_DATA_FILE, + Context.MODE_PRIVATE); + + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(persistenceFile); + + oos.writeObject(forecastWeatherData); + } finally { + if (oos != null) { + oos.close(); + } + } + + this.renameFile(FORECAST_WEATHER_DATA_TEMPORARY_FILE, FORECAST_WEATHER_DATA_FILE); + } + + public Forecast getForecastWeatherData() { + Forecast forecastWeatherData = null; + + try { + forecastWeatherData = this.getForecastWeatherDataThrowable(); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "getWeatherData exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "getWeatherData exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "getWeatherData exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "getWeatherData exception: ", e); + } + + return forecastWeatherData; + } + + private Forecast getForecastWeatherDataThrowable() throws StreamCorruptedException, + FileNotFoundException, IOException, ClassNotFoundException { + final InputStream persistenceFile = this.context.openFileInput(FORECAST_WEATHER_DATA_FILE); + + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(persistenceFile); + + return (Forecast) ois.readObject(); + } finally { + if (ois != null) { + ois.close(); + } + } + } + + public void removeForecastWeatherData() { + this.context.deleteFile(FORECAST_WEATHER_DATA_FILE); + } + + private void renameFile(final String temporaryName, final String finalName) { + final File filesDir = this.context.getFilesDir(); + final File temporaryFile = new File(filesDir, temporaryName); + final File endFile = new File(filesDir, finalName); + temporaryFile.renameTo(endFile); + } +} diff --git a/src/de/example/exampletdd/service/WeatherServiceParser.java b/src/de/example/exampletdd/service/WeatherServiceParser.java deleted file mode 100644 index 847707d..0000000 --- a/src/de/example/exampletdd/service/WeatherServiceParser.java +++ /dev/null @@ -1,64 +0,0 @@ -package de.example.exampletdd.service; - -import java.io.IOException; -import java.text.MessageFormat; -import java.util.Locale; - -import com.fasterxml.jackson.core.JsonParseException; - -import de.example.exampletdd.model.currentweather.CurrentWeatherData; -import de.example.exampletdd.model.forecastweather.ForecastWeatherData; -import de.example.exampletdd.parser.IJPOSWeatherParser; - -public class WeatherServiceParser { - private final IJPOSWeatherParser JPOSWeatherParser; - - public WeatherServiceParser(final IJPOSWeatherParser JPOSWeatherParser) { - this.JPOSWeatherParser = JPOSWeatherParser; - } - - public CurrentWeatherData retrieveCurrentWeatherDataFromJPOS(final String jsonData) - throws JsonParseException, IOException { - return this.JPOSWeatherParser.retrieveCurrentWeatherDataFromJPOS(jsonData); - } - - public ForecastWeatherData retrieveForecastWeatherDataFromJPOS(final String jsonData) - throws JsonParseException, IOException { - return this.JPOSWeatherParser.retrieveForecastWeatherDataFromJPOS(jsonData); - } - - public String createURIAPIForecastWeather(final String urlAPI, final String APIVersion, - final double latitude, final double longitude, final String resultsNumber) { - - final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); - final Object[] values = new Object[4]; - values[0] = APIVersion; - values[1] = latitude; - values[2] = longitude; - values[3] = resultsNumber; - - return formatURIAPI.format(values); - } - - public String createURIAPITodayWeather(final String urlAPI, final String APIVersion, - final double latitude, final double longitude) { - - final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); - final Object[] values = new Object[3]; - values[0] = APIVersion; - values[1] = latitude; - values[2] = longitude; - - return formatURIAPI.format(values); - } - - public String createURIAPIicon(final String icon, final String urlAPI) { - - final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); - final Object[] values = new Object[1]; - values[0] = icon; - - return formatURIAPI.format(values); - } - -} diff --git a/src/de/example/exampletdd/service/WeatherServicePersistenceFile.java b/src/de/example/exampletdd/service/WeatherServicePersistenceFile.java deleted file mode 100644 index 7d9c8c3..0000000 --- a/src/de/example/exampletdd/service/WeatherServicePersistenceFile.java +++ /dev/null @@ -1,217 +0,0 @@ -package de.example.exampletdd.service; - -import java.io.File; -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 android.util.Log; -import de.example.exampletdd.model.GeocodingData; -import de.example.exampletdd.model.currentweather.CurrentWeatherData; -import de.example.exampletdd.model.forecastweather.ForecastWeatherData; - -/** - * TODO: show some error message when there is no enough space for saving files. :/ - * - */ -public class WeatherServicePersistenceFile { - private static final String TAG = "WeatherServicePersistenceFile"; - private static final String CURRENT_WEATHER_DATA_FILE = "current_weatherdata.file"; - private static final String CURRENT_WEATHER_DATA_TEMPORARY_FILE = "current_weatherdata.tmp.file"; - private static final String FORECAST_WEATHER_DATA_FILE = "forecast_weatherdata.file"; - private static final String FORECAST_WEATHER_DATA_TEMPORARY_FILE = "forecast_weatherdata.tmp.file"; - private static final String WEATHER_GEOCODING_FILE = "weathergeocoding.file"; - private static final String WEATHER_GEOCODING_TEMPORARY_FILE = "weathergeocoding.tmp.file"; - private final Context context; - - public WeatherServicePersistenceFile(final Context context) { - this.context = context; - } - - public void storeGeocodingData(final GeocodingData geocodingData) - throws FileNotFoundException, IOException { - final OutputStream persistenceFile = this.context.openFileOutput( - WEATHER_GEOCODING_TEMPORARY_FILE, Context.MODE_PRIVATE); - - ObjectOutputStream oos = null; - try { - oos = new ObjectOutputStream(persistenceFile); - - oos.writeObject(geocodingData); - } finally { - if (oos != null) { - oos.close(); - } - } - - this.renameFile(WEATHER_GEOCODING_TEMPORARY_FILE, WEATHER_GEOCODING_FILE); - } - - public GeocodingData getGeocodingData() { - GeocodingData geocodingData = null; - - try { - geocodingData = this.getGeocodingDataThrowable(); - } catch (final StreamCorruptedException e) { - Log.e(TAG, "getGeocodingData exception: ", e); - } catch (final FileNotFoundException e) { - Log.e(TAG, "getGeocodingData exception: ", e); - } catch (final IOException e) { - Log.e(TAG, "getGeocodingData exception: ", e); - } catch (final ClassNotFoundException e) { - Log.e(TAG, "getGeocodingData exception: ", e); - } - - return geocodingData; - } - - private GeocodingData getGeocodingDataThrowable() - throws StreamCorruptedException, FileNotFoundException, - IOException, ClassNotFoundException { - final InputStream persistenceFile = this.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 removeGeocodingData() { - this.context.deleteFile(WEATHER_GEOCODING_FILE); - } - - public void storeCurrentWeatherData(final CurrentWeatherData currentWeatherData) - throws FileNotFoundException, IOException { - final OutputStream persistenceFile = this.context.openFileOutput( - CURRENT_WEATHER_DATA_FILE, Context.MODE_PRIVATE); - - ObjectOutputStream oos = null; - try { - oos = new ObjectOutputStream(persistenceFile); - - oos.writeObject(currentWeatherData); - } finally { - if (oos != null) { - oos.close(); - } - } - - this.renameFile(CURRENT_WEATHER_DATA_TEMPORARY_FILE, CURRENT_WEATHER_DATA_FILE); - } - - public CurrentWeatherData getCurrentWeatherData() { - CurrentWeatherData currentWeatherData = null; - - try { - currentWeatherData = this.getCurrentWeatherDataThrowable(); - } catch (final StreamCorruptedException e) { - Log.e(TAG, "getWeatherData exception: ", e); - } catch (final FileNotFoundException e) { - Log.e(TAG, "getWeatherData exception: ", e); - } catch (final IOException e) { - Log.e(TAG, "getWeatherData exception: ", e); - } catch (final ClassNotFoundException e) { - Log.e(TAG, "getWeatherData exception: ", e); - } - - return currentWeatherData; - } - - private CurrentWeatherData getCurrentWeatherDataThrowable() - throws StreamCorruptedException, - FileNotFoundException, IOException, ClassNotFoundException { - final InputStream persistenceFile = this.context.openFileInput( - CURRENT_WEATHER_DATA_FILE); - - ObjectInputStream ois = null; - try { - ois = new ObjectInputStream(persistenceFile); - - return (CurrentWeatherData) ois.readObject(); - } finally { - if (ois != null) { - ois.close(); - } - } - } - - public void removeCurrentWeatherData() { - this.context.deleteFile(CURRENT_WEATHER_DATA_FILE); - } - - public void storeForecastWeatherData(final ForecastWeatherData forecastWeatherData) - throws FileNotFoundException, IOException { - final OutputStream persistenceFile = this.context.openFileOutput(FORECAST_WEATHER_DATA_FILE, - Context.MODE_PRIVATE); - - ObjectOutputStream oos = null; - try { - oos = new ObjectOutputStream(persistenceFile); - - oos.writeObject(forecastWeatherData); - } finally { - if (oos != null) { - oos.close(); - } - } - - this.renameFile(FORECAST_WEATHER_DATA_TEMPORARY_FILE, FORECAST_WEATHER_DATA_FILE); - } - - public ForecastWeatherData getForecastWeatherData() { - ForecastWeatherData forecastWeatherData = null; - - try { - forecastWeatherData = this.getForecastWeatherDataThrowable(); - } catch (final StreamCorruptedException e) { - Log.e(TAG, "getWeatherData exception: ", e); - } catch (final FileNotFoundException e) { - Log.e(TAG, "getWeatherData exception: ", e); - } catch (final IOException e) { - Log.e(TAG, "getWeatherData exception: ", e); - } catch (final ClassNotFoundException e) { - Log.e(TAG, "getWeatherData exception: ", e); - } - - return forecastWeatherData; - } - - private ForecastWeatherData getForecastWeatherDataThrowable() throws StreamCorruptedException, - FileNotFoundException, IOException, ClassNotFoundException { - final InputStream persistenceFile = this.context.openFileInput(FORECAST_WEATHER_DATA_FILE); - - ObjectInputStream ois = null; - try { - ois = new ObjectInputStream(persistenceFile); - - return (ForecastWeatherData) ois.readObject(); - } finally { - if (ois != null) { - ois.close(); - } - } - } - - public void removeForecastWeatherData() { - this.context.deleteFile(FORECAST_WEATHER_DATA_FILE); - } - - private void renameFile(final String temporaryName, final String finalName) { - final File filesDir = this.context.getFilesDir(); - final File temporaryFile = new File(filesDir, temporaryName); - final File endFile = new File(filesDir, finalName); - temporaryFile.renameTo(endFile); - } -}