WeatherInformation Android
authorgu.martinm@gmail.com <gu.martinm@gmail.com>
Sat, 6 Sep 2014 20:52:12 +0000 (22:52 +0200)
committergu.martinm@gmail.com <gu.martinm@gmail.com>
Sat, 6 Sep 2014 20:52:12 +0000 (22:52 +0200)
Removing GeocodingData object
MapActivity is done
Read/Insert/Update database done

No tested code.

13 files changed:
Android/WeatherInformation/src/de/example/exampletdd/MapActivity.java
Android/WeatherInformation/src/de/example/exampletdd/SpecificActivity.java
Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationApplication.java
Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationBatch.java
Android/WeatherInformation/src/de/example/exampletdd/WeatherTabsActivity.java
Android/WeatherInformation/src/de/example/exampletdd/fragment/current/CurrentFragment.java
Android/WeatherInformation/src/de/example/exampletdd/fragment/overview/OverviewFragment.java
Android/WeatherInformation/src/de/example/exampletdd/fragment/specific/SpecificFragment.java
Android/WeatherInformation/src/de/example/exampletdd/model/DatabaseQueries.java [new file with mode: 0644]
Android/WeatherInformation/src/de/example/exampletdd/model/GeocodingData.java [deleted file]
Android/WeatherInformation/src/de/example/exampletdd/model/WeatherLocation.java
Android/WeatherInformation/src/de/example/exampletdd/model/WeatherLocationDbQueries.java
Android/WeatherInformation/src/de/example/exampletdd/service/ServicePersistenceStorage.java [deleted file]

index 0f871e2..c489ebd 100644 (file)
@@ -42,9 +42,8 @@ import com.google.android.gms.maps.model.MarkerOptions;
 import de.example.exampletdd.fragment.ErrorDialogFragment;
 import de.example.exampletdd.fragment.ProgressDialogFragment;
 import de.example.exampletdd.gms.GPlayServicesErrorDialogFragment;
+import de.example.exampletdd.model.DatabaseQueries;
 import de.example.exampletdd.model.WeatherLocation;
-import de.example.exampletdd.model.WeatherLocationDbHelper;
-import de.example.exampletdd.model.WeatherLocationDbQueries;
 
 public class MapActivity extends FragmentActivity implements
                                                                        GoogleApiClient.ConnectionCallbacks,
@@ -123,7 +122,8 @@ public class MapActivity extends FragmentActivity implements
                // just once
                this.mRestoreUI = null;
         } else {
-               weatherLocation = queryDataBase();
+               final DatabaseQueries query = new DatabaseQueries(this);
+               weatherLocation = query.queryDataBase();
         }
         
         if (weatherLocation != null) {
@@ -144,10 +144,11 @@ public class MapActivity extends FragmentActivity implements
             double latitude = point.latitude;
             double longitude = point.longitude;
 
-            final WeatherLocation location = new WeatherLocation.Builder().
-                       setCity(cityString).setCountry(countryString).
-                       setLatitude(latitude).setLongitude(longitude).
-                       build();
+            final WeatherLocation location = new WeatherLocation()
+                       .setCity(cityString)
+                       .setCountry(countryString)
+                       .setLatitude(latitude)
+                       .setLongitude(longitude);
             savedInstanceState.putSerializable("WeatherLocation", location);
         }
                
@@ -161,7 +162,28 @@ public class MapActivity extends FragmentActivity implements
     }
     
     public void onClickSaveLocation(final View v) {
-       
+       if (this.mMarker == null) {
+               final LatLng position = this.mMarker.getPosition();
+               
+               final DatabaseQueries query = new DatabaseQueries(this);
+               final WeatherLocation weatherLocation = query.queryDataBase();
+            if (weatherLocation != null) {
+               query.updateDataBase(weatherLocation);
+            } else {
+                final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
+                final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
+                final String cityString = city.getText().toString();
+                final String countryString = country.getText().toString();
+                
+               final WeatherLocation location = new WeatherLocation()
+                       .setCity(cityString)
+                       .setCountry(countryString)
+                       .setIsSelected(true)
+                       .setLatitude(position.latitude)
+                       .setLongitude(position.longitude);
+               query.insertIntoDataBase(location);
+            }
+       }
     }
     
     public void onClickGetLocation(final View v) {
@@ -174,6 +196,7 @@ public class MapActivity extends FragmentActivity implements
                locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                locationRequest.setInterval(1000);
                        final FusedLocationProviderApi fusedLocationApi = LocationServices.FusedLocationApi;
+                       // TODO: What if between mGoogleApiClient.isConnected() and this point mGoogleApiClient is disconnected? Android sucks?
                        fusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this);
                } else {
                        // TODO: string resource
@@ -181,17 +204,6 @@ public class MapActivity extends FragmentActivity implements
                }
         }
     }
-
-    private WeatherLocation queryDataBase() {
-        
-        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this);
-        try {
-               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
-               return queryDb.queryDataBase(this);
-        } finally {
-               dbHelper.close();
-        } 
-    }
     
     private void updateUI(final WeatherLocation weatherLocation) {
 
@@ -217,6 +229,7 @@ public class MapActivity extends FragmentActivity implements
         private static final String TAG = "GetAddressTask";
         // Store the context passed to the AsyncTask when the system instantiates it.
         private final Context localContext;
+        // TODO: siempre tuve problemas usando fragmentos y recreando activities (rotar, volver a activity, etc, etc)
         private final DialogFragment newFragment;
 
         private GetAddressTask(final Context context) {
@@ -283,10 +296,11 @@ public class MapActivity extends FragmentActivity implements
                }       
             }
 
-            return new WeatherLocation.Builder()
-                       .setLatitude(latitude).setLongitude(longitude)
-                       .setCity(city).setCountry(country)
-                       .build();
+            return new WeatherLocation()
+                       .setLatitude(latitude)
+                       .setLongitude(longitude)
+                       .setCity(city)
+                       .setCountry(country);
         }
 
     }
@@ -333,10 +347,11 @@ public class MapActivity extends FragmentActivity implements
             // Default values
             final String city = this.getString(R.string.city_not_found);
             final String country = this.getString(R.string.country_not_found); 
-            final WeatherLocation weatherLocation = new WeatherLocation.Builder().
-                       setLatitude(latitude).setLongitude(longitude).
-                       setCity(city).setCountry(country).
-                       build();
+            final WeatherLocation weatherLocation = new WeatherLocation()
+                       .setLatitude(latitude)
+                       .setLongitude(longitude)
+                       .setCity(city)
+                       .setCountry(country);
             
             updateUI(weatherLocation);
         }
@@ -512,6 +527,7 @@ public class MapActivity extends FragmentActivity implements
                        
                                // Make sure the app is not already connected or attempting to connect
                         if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) {
+                                       // TODO: What if between mGoogleApiClient.isConnected() and this point mGoogleApiClient is disconnected? Android sucks?
                             mGoogleApiClient.connect();
                         }
                                
@@ -577,6 +593,7 @@ public class MapActivity extends FragmentActivity implements
                        final FusedLocationProviderApi fusedLocationApi = LocationServices.FusedLocationApi;
                        // TODO: if user clicks many times onClickGetLocation I may not assure how many times
                        // onLocationChanged will be called. Is it a problem? AFAIK it isn't.
+                       // TODO: What if between mGoogleApiClient.isConnected() and this point mGoogleApiClient is disconnected? Android sucks?
                        fusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
                }
 
index 9465571..3cb5da4 100644 (file)
@@ -3,7 +3,8 @@ package de.example.exampletdd;
 import android.app.ActionBar;
 import android.os.Bundle;
 import android.support.v4.app.FragmentActivity;
-import de.example.exampletdd.model.GeocodingData;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
 
 public class SpecificActivity extends FragmentActivity {
 
@@ -24,17 +25,13 @@ public class SpecificActivity extends FragmentActivity {
     public void onResume() {
         super.onResume();
 
-        // TODO: retrive data from data base (like I do on WindowsPhone 8)
         // 1. Update title.
-        final GeocodingData geocodingData = new GeocodingData.Builder().build();
-        if (geocodingData != null) {
-               final String city = (geocodingData.getCity() == null) ? this.getString(R.string.city_not_found)
-                    : geocodingData.getCity();
-            final String country = (geocodingData.getCountry() == null) ? this.getString(R.string.country_not_found)
-                    : geocodingData.getCountry();
-            final ActionBar actionBar = this.getActionBar();
+        final DatabaseQueries query = new DatabaseQueries(this);
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        if (weatherLocation != null) {
+               final ActionBar actionBar = this.getActionBar();
             // TODO: I18N and comma :/
-            actionBar.setTitle(city + "," + country);  
+            actionBar.setTitle(weatherLocation.getCity() + "," + weatherLocation.getCountry());        
         }
     }
 }
index 7067c3b..679a2ca 100644 (file)
@@ -1,22 +1,15 @@
 package de.example.exampletdd;
 
 import android.app.Application;
-import de.example.exampletdd.model.GeocodingData;
 import de.example.exampletdd.model.currentweather.Current;
 import de.example.exampletdd.model.forecastweather.Forecast;
 
 public class WeatherInformationApplication extends Application {
     private Forecast mForecast;
     private Current mCurrent;
-    private GeocodingData mGeocodingData;
+    private String mCity;
+    private String mCountry;
 
-    protected void setGeocodingData(final GeocodingData geocodingData) {
-        this.mGeocodingData = geocodingData;
-    }
-
-    protected GeocodingData getGeocodingData() {
-        return this.mGeocodingData;
-    }
 
     public void setForecast(final Forecast forecast) {
         this.mForecast = forecast;
@@ -33,4 +26,20 @@ public class WeatherInformationApplication extends Application {
     public Current getCurrent() {
        return this.mCurrent;
     }
-}
+    
+    public void setCity(final String city) {
+       this.mCity = city;
+    }
+    
+    public String getCity() {
+       return this.mCity;
+    }
+    
+    public void setCountry(final String country) {
+       this.mCountry = country;
+    }
+    
+    public String getCountry() {
+       return this.mCountry;
+    }
+} 
index 22591d4..3a0e678 100644 (file)
@@ -18,17 +18,17 @@ import android.util.Log;
 import com.fasterxml.jackson.core.JsonParseException;
 
 import de.example.exampletdd.httpclient.CustomHTTPClient;
-import de.example.exampletdd.model.GeocodingData;
+import de.example.exampletdd.model.WeatherLocation;
+import de.example.exampletdd.model.WeatherLocationDbHelper;
+import de.example.exampletdd.model.WeatherLocationDbQueries;
 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.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 ServicePersistenceStorage mWeatherServicePersistenceFile;
 
 
     public WeatherInformationBatch() {
@@ -38,7 +38,6 @@ 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 ServicePersistenceStorage(this);
 
         return super.onStartCommand(intent, flags, startId);
     }
@@ -46,19 +45,18 @@ public class WeatherInformationBatch extends IntentService {
     @Override
     protected void onHandleIntent(final Intent intent) {
 
-        final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
         Log.i(TAG, "WeatherInformationBatch onHandleIntent");
 
-        if (geocodingData != null) {
+        final WeatherLocation weatherLocation = this.queryDataBase();
+        if (weatherLocation != null) {
             Log.i(TAG, "WeatherInformationBatch onHandleIntent, geocodingData not null");
             final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser());
             final CustomHTTPClient weatherHTTPClient = new CustomHTTPClient(
                     AndroidHttpClient.newInstance("Android Weather Information Agent"));
 
             try {
-                final WeatherData weatherData = this.doInBackgroundThrowable(geocodingData,
-                        weatherHTTPClient, weatherService);
-                this.onPostExecuteThrowable(weatherData);
+                this.doInBackgroundThrowable(weatherLocation,weatherHTTPClient, weatherService);
+                this.onPostExecuteThrowable();
             } catch (final JsonParseException e) {
                 Log.e(TAG, "doInBackground exception: ", e);
             } catch (final ClientProtocolException e) {
@@ -76,7 +74,7 @@ public class WeatherInformationBatch extends IntentService {
         }
     }
 
-    private WeatherData doInBackgroundThrowable(final GeocodingData geocodingData,
+    private void doInBackgroundThrowable(final WeatherLocation weatherLocation,
             final CustomHTTPClient weatherHTTPClient, final ServiceParser weatherService)
                     throws ClientProtocolException, MalformedURLException, URISyntaxException,
                     JsonParseException, IOException {
@@ -88,7 +86,7 @@ public class WeatherInformationBatch extends IntentService {
         String urlAPI = WeatherInformationBatch.this.getResources().getString(
                 R.string.uri_api_weather_today);
         String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
-                geocodingData.getLatitude(), geocodingData.getLongitude());
+                       weatherLocation.getLatitude(), weatherLocation.getLongitude());
         String jsonData = weatherHTTPClient.retrieveDataAsString(new URL(url));
         final Current currentWeatherData = weatherService
                 .retrieveCurrentFromJPOS(jsonData);
@@ -99,22 +97,15 @@ public class WeatherInformationBatch extends IntentService {
         urlAPI = WeatherInformationBatch.this.getResources().getString(
                 R.string.uri_api_weather_forecast);
         url = weatherService.createURIAPIForecast(urlAPI, APIVersion,
-                geocodingData.getLatitude(), geocodingData.getLongitude(), resultsNumber);
+                       weatherLocation.getLatitude(), weatherLocation.getLongitude(), resultsNumber);
         jsonData = weatherHTTPClient.retrieveDataAsString(new URL(url));
         final Forecast forecastWeatherData = weatherService
                 .retrieveForecastFromJPOS(jsonData);
-
-        return new WeatherData(forecastWeatherData, currentWeatherData);
     }
 
-    private void onPostExecuteThrowable(final WeatherData weatherData)
+    private void onPostExecuteThrowable()
             throws FileNotFoundException, IOException {
 
-        WeatherInformationBatch.this.mWeatherServicePersistenceFile
-        .storeCurrentWeatherData(weatherData.getCurrentWeatherData());
-        WeatherInformationBatch.this.mWeatherServicePersistenceFile
-        .storeForecastWeatherData(weatherData.getForecastWeatherData());
-
         // Update weather views.
         final Intent updateCurrentWeather = new Intent(
                 "de.example.exampletdd.UPDATECURRENTWEATHER");
@@ -126,23 +117,16 @@ public class WeatherInformationBatch extends IntentService {
                 updateOverviewWeather);
 
     }
-
-    private class WeatherData {
-        private final Forecast mForecastWeatherData;
-        private final Current mCurrentWeatherData;
-
-        public WeatherData(final Forecast mForecastWeatherData,
-                final Current mCurrentWeatherData) {
-            this.mForecastWeatherData = mForecastWeatherData;
-            this.mCurrentWeatherData = mCurrentWeatherData;
-        }
-
-        public Forecast getForecastWeatherData() {
-            return this.mForecastWeatherData;
-        }
-
-        public Current getCurrentWeatherData() {
-            return this.mCurrentWeatherData;
-        }
+    
+    private WeatherLocation queryDataBase() {
+        
+       // TODO: repeating the same code!!!
+        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this);
+        try {
+               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
+               return queryDb.queryDataBase();
+        } finally {
+               dbHelper.close();
+        } 
     }
 }
index bf48f00..cf89a7c 100644 (file)
@@ -17,7 +17,8 @@ import android.view.Menu;
 import android.view.MenuItem;
 import de.example.exampletdd.fragment.current.CurrentFragment;
 import de.example.exampletdd.fragment.overview.OverviewFragment;
-import de.example.exampletdd.model.GeocodingData;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
 
 public class WeatherTabsActivity extends FragmentActivity {
     private static final int NUM_ITEMS = 2;
@@ -126,16 +127,12 @@ public class WeatherTabsActivity extends FragmentActivity {
 
         final ActionBar actionBar = this.getActionBar();
         
-        // TODO: retrive data from data base (like I do on WindowsPhone 8)
         // 1. Update title.
-        final GeocodingData geocodingData = new GeocodingData.Builder().build();
-        if (geocodingData != null) {
-               final String city = (geocodingData.getCity() == null) ? this.getString(R.string.city_not_found)
-                    : geocodingData.getCity();
-            final String country = (geocodingData.getCountry() == null) ? this.getString(R.string.country_not_found)
-                    : geocodingData.getCountry();
+        final DatabaseQueries query = new DatabaseQueries(this);
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        if (weatherLocation != null) {
             // TODO: I18N and comma :/
-            actionBar.setTitle(city + "," + country);  
+            actionBar.setTitle(weatherLocation.getCity() + "," + weatherLocation.getCountry());        
         }
 
         // 2. Update forecast tab text.
@@ -156,10 +153,6 @@ public class WeatherTabsActivity extends FragmentActivity {
 
     @Override
     public void onSaveInstanceState(final Bundle savedInstanceState) {
-        final WeatherInformationApplication application = (WeatherInformationApplication) this
-                .getApplication();
-        savedInstanceState.putSerializable("GEOCODINGDATA", application.getGeocodingData());
-
         super.onSaveInstanceState(savedInstanceState);
     }
 
index cc177ad..3f41ba0 100644 (file)
@@ -33,7 +33,8 @@ import com.fasterxml.jackson.core.JsonParseException;
 import de.example.exampletdd.R;
 import de.example.exampletdd.WeatherInformationApplication;
 import de.example.exampletdd.httpclient.CustomHTTPClient;
-import de.example.exampletdd.model.GeocodingData;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
 import de.example.exampletdd.model.currentweather.Current;
 import de.example.exampletdd.parser.JPOSWeatherParser;
 import de.example.exampletdd.service.IconsList;
@@ -77,9 +78,9 @@ public class CurrentFragment extends Fragment {
     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) {
+        final DatabaseQueries query = new DatabaseQueries(this.getActivity());
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        if (weatherLocation == null) {
             // Nothing to do.
             return;
         }
@@ -88,17 +89,17 @@ public class CurrentFragment extends Fragment {
                        (WeatherInformationApplication) getActivity().getApplication();
         final Current current = application.getCurrent();
 
-        // TODO: Also check whether data is fresh (like I do on WindowsPhone 8) using data base
-        if (current != null /* && dataIsFresh() */) {
+        if (current != null && this.isDataFresh(weatherLocation.getLastCurrentUIUpdate())) {
             this.updateUI(current);
         } else {
             // Load remote data (aynchronous)
             // Gets the data from the web.
             final CurrentTask task = new CurrentTask(
+                       this,
                     new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")),
                     new ServiceParser(new JPOSWeatherParser()));
 
-            task.execute(geocodingData);
+            task.execute(weatherLocation.getLatitude(), weatherLocation.getLongitude());
             // TODO: make sure UI thread keeps running in parallel after that. I guess.
         }
     }
@@ -268,26 +269,45 @@ public class CurrentFragment extends Fragment {
         sunSetTimeView.setText(sunSetTime);
     }
     
+    private boolean isDataFresh(final Date lastUpdate) {
+       if (lastUpdate == null) {
+               return false;
+       }
+       
+       final Calendar calendar = Calendar.getInstance();
+       final Date currentTime = calendar.getTime();
+       if (((currentTime.getTime() - lastUpdate.getTime()) / 1000) < 30) {
+               return true;
+       }
+       
+       return false;
+    }
+    
     // TODO: How could I show just one progress dialog when I have two fragments in tabs
     //       activity doing the same in background?
     //       I mean, if OverviewTask shows one progress dialog and CurrentTask does the same I will have
     //       have two progress dialogs... How may I solve this problem? I HATE ANDROID.
-    private class CurrentTask extends AsyncTask<GeocodingData, Void, Current> {
+    private class CurrentTask extends AsyncTask<Object, Void, Current> {
+        private final Fragment localFragment;
         final CustomHTTPClient weatherHTTPClient;
         final ServiceParser weatherService;
 
-        public CurrentTask(final CustomHTTPClient weatherHTTPClient, final ServiceParser weatherService) {
+        public CurrentTask(final Fragment fragment, final CustomHTTPClient weatherHTTPClient,
+                       final ServiceParser weatherService) {
+               this.localFragment = fragment;
             this.weatherHTTPClient = weatherHTTPClient;
             this.weatherService = weatherService;
         }
 
         @Override
-        protected Current doInBackground(final GeocodingData... params) {
-            Log.i(TAG, "CurrentTask doInBackground");
+        protected Current doInBackground(final Object... params) {
+               Log.i(TAG, "CurrentTask doInBackground");
+               final double latitude = (Double) params[0];
+            final double longitude = (Double) params[1];
+  
             Current current = null;
-
             try {
-               current = this.doInBackgroundThrowable(params[0], weatherHTTPClient, weatherService);
+               current = this.doInBackgroundThrowable(latitude, longitude, weatherHTTPClient, weatherService);
             } catch (final JsonParseException e) {
                 Log.e(TAG, "CurrentTask doInBackground exception: ", e);
             } catch (final ClientProtocolException e) {
@@ -306,14 +326,13 @@ public class CurrentFragment extends Fragment {
             return current;
         }
 
-        private Current doInBackgroundThrowable(final GeocodingData geocodingData,
+        private Current doInBackgroundThrowable(final double latitude, final double longitude,
                 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_today);
-            final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
-                    geocodingData.getLatitude(), geocodingData.getLongitude());
+            final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion, latitude, longitude);
             final String jsonData = weatherHTTPClient.retrieveDataAsString(new URL(url));
             final Current current = weatherService
                     .retrieveCurrentFromJPOS(jsonData);
@@ -341,7 +360,10 @@ public class CurrentFragment extends Fragment {
                        (WeatherInformationApplication) getActivity().getApplication();
             application.setCurrent(current);
 
-            // TODO: update last time update using data base (like I do on Windows Phone 8)
+            final DatabaseQueries query = new DatabaseQueries(this.localFragment.getActivity());
+            final WeatherLocation weatherLocation = query.queryDataBase();
+            weatherLocation.setLastCurrentUIUpdate(new Date());
+            query.updateDataBase(weatherLocation);
         }
     }
 }
index a326a1b..f112dfa 100644 (file)
@@ -25,6 +25,7 @@ import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
 import android.support.v4.app.ListFragment;
 import android.util.Log;
 import android.view.View;
@@ -36,7 +37,8 @@ import de.example.exampletdd.R;
 import de.example.exampletdd.WeatherInformationApplication;
 import de.example.exampletdd.fragment.specific.SpecificFragment;
 import de.example.exampletdd.httpclient.CustomHTTPClient;
-import de.example.exampletdd.model.GeocodingData;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
 import de.example.exampletdd.model.forecastweather.Forecast;
 import de.example.exampletdd.parser.JPOSWeatherParser;
 import de.example.exampletdd.service.IconsList;
@@ -90,9 +92,9 @@ public class OverviewFragment extends ListFragment {
     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) {
+        final DatabaseQueries query = new DatabaseQueries(this.getActivity());
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        if (weatherLocation == null) {
             // Nothing to do.
             return;
         }
@@ -101,17 +103,17 @@ public class OverviewFragment extends ListFragment {
                        (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() */) {
+        if (forecast != null && this.isDataFresh(weatherLocation.getLastCurrentUIUpdate())) {
             this.updateUI(forecast);
         } else {
             // Load remote data (aynchronous)
             // Gets the data from the web.
             final OverviewTask task = new OverviewTask(
+                       this,
                     new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")),
                     new ServiceParser(new JPOSWeatherParser()));
 
-            task.execute(geocodingData);
+            task.execute(weatherLocation.getLatitude(), weatherLocation.getLongitude());
             // TODO: make sure thread UI keeps running in parallel after that. I guess.
         }
 
@@ -255,27 +257,46 @@ public class OverviewFragment extends ListFragment {
         this.setListAdapter(adapter);
     }
 
+    private boolean isDataFresh(final Date lastUpdate) {
+       if (lastUpdate == null) {
+               return false;
+       }
+       
+       final Calendar calendar = Calendar.getInstance();
+       final Date currentTime = calendar.getTime();
+       if (((currentTime.getTime() - lastUpdate.getTime()) / 1000) < 30) {
+               return true;
+       }
+       
+       return false;
+    }
 
     // TODO: How could I show just one progress dialog when I have two fragments in tabs
     //       activity doing the same in background?
     //       I mean, if OverviewTask shows one progress dialog and CurrentTask does the same I will have
     //       have two progress dialogs... How may I solve this problem? I HATE ANDROID.
-    private class OverviewTask extends AsyncTask<GeocodingData, Void, Forecast> {
+    private class OverviewTask extends AsyncTask<Object, Void, Forecast> {
+       private final Fragment localFragment;
         final CustomHTTPClient weatherHTTPClient;
         final ServiceParser weatherService;
 
-        public OverviewTask(final CustomHTTPClient weatherHTTPClient, final ServiceParser weatherService) {
+        public OverviewTask(final Fragment fragment, final CustomHTTPClient weatherHTTPClient,
+                       final ServiceParser weatherService) {
+               this.localFragment = fragment;
             this.weatherHTTPClient = weatherHTTPClient;
             this.weatherService = weatherService;
         }
 
         @Override
-        protected Forecast doInBackground(final GeocodingData... params) {
+        protected Forecast doInBackground(final Object... params) {
             Log.i(TAG, "OverviewFragment doInBackground");
+            final double latitude = (Double) params[0];
+            final double longitude = (Double) params[1];
+
             Forecast forecast = null;
 
             try {
-                forecast = this.doInBackgroundThrowable(params[0], weatherHTTPClient, weatherService);
+                forecast = this.doInBackgroundThrowable(latitude, longitude, weatherHTTPClient, weatherService);
             } catch (final JsonParseException e) {
                 Log.e(TAG, "OverviewTask doInBackground exception: ", e);
             } catch (final ClientProtocolException e) {
@@ -294,15 +315,14 @@ public class OverviewFragment extends ListFragment {
             return forecast;
         }
 
-        private Forecast doInBackgroundThrowable(final GeocodingData geocodingData,
+        private Forecast doInBackgroundThrowable(final double latitude, final double longitude,
                 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.createURIAPIForecast(urlAPI, APIVersion,
-                    geocodingData.getLatitude(), geocodingData.getLongitude(), "14");
+            final String url = serviceParser.createURIAPIForecast(urlAPI, APIVersion, latitude, longitude, "14");
             final String jsonData = HTTPClient.retrieveDataAsString(new URL(url));
 
             return serviceParser.retrieveForecastFromJPOS(jsonData);
@@ -325,7 +345,10 @@ public class OverviewFragment extends ListFragment {
                        (WeatherInformationApplication) getActivity().getApplication();
             application.setForecast(forecast);
 
-            // TODO: update last time update using data base (like I do on Windows Phone 8)
+            final DatabaseQueries query = new DatabaseQueries(this.localFragment.getActivity());
+            final WeatherLocation weatherLocation = query.queryDataBase();
+            weatherLocation.setLastForecastUIUpdate(new Date());
+            query.updateDataBase(weatherLocation);
         }
     }
 }
index 4a1dc3f..27b4ad7 100644 (file)
@@ -8,7 +8,6 @@ import java.util.Date;
 import java.util.Locale;
 
 import android.content.SharedPreferences;
-import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Bundle;
@@ -30,22 +29,7 @@ public class SpecificFragment extends Fragment {
     @Override
     public void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-    }
-    
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                             Bundle savedInstanceState) {
-    
-       // Inflate the layout for this fragment
-        return inflater.inflate(R.layout.weather_specific_fragment, container, false);
-    }
-
-    @Override
-    public void onConfigurationChanged(final Configuration newConfig) {
-       // I could do the same in onCreate because I allow rotations.
-       // see: http://stackoverflow.com/a/11286961
-       // Anyhow I wanted to try this way just for fun.
-       
+        
         final Bundle extras = this.getActivity().getIntent().getExtras();
 
         if (extras != null) {
@@ -59,6 +43,14 @@ public class SpecificFragment extends Fragment {
     }
     
     @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+    
+       // Inflate the layout for this fragment
+        return inflater.inflate(R.layout.weather_specific_fragment, container, false);
+    }
+    
+    @Override
     public void onActivityCreated(final Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
@@ -74,7 +66,7 @@ public class SpecificFragment extends Fragment {
                 application.setForecast(forecast);
             }
 
-            this.mChosenDay = savedInstanceState.getInt("Chosen day");
+            this.mChosenDay = savedInstanceState.getInt("mChosenDay");
         }
     }
 
@@ -92,9 +84,7 @@ public class SpecificFragment extends Fragment {
             savedInstanceState.putSerializable("Forecast", forecast);
         }
 
-        savedInstanceState.putInt("Chosend day", this.mChosenDay);
-        
-        // TODO: Why don't I need mListState?
+        savedInstanceState.putInt("mChosenDay", this.mChosenDay);
 
         super.onSaveInstanceState(savedInstanceState);
     }
diff --git a/Android/WeatherInformation/src/de/example/exampletdd/model/DatabaseQueries.java b/Android/WeatherInformation/src/de/example/exampletdd/model/DatabaseQueries.java
new file mode 100644 (file)
index 0000000..e53f97d
--- /dev/null
@@ -0,0 +1,44 @@
+package de.example.exampletdd.model;
+
+import android.content.Context;
+
+public class DatabaseQueries {
+       private final Context localContext;
+
+       public DatabaseQueries(final Context context) {
+               this.localContext = context;
+       }
+       
+       public WeatherLocation queryDataBase() {
+        
+        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
+        try {
+               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
+               return queryDb.queryDataBase();
+        } finally {
+               dbHelper.close();
+        } 
+    }
+    
+       public long insertIntoDataBase(final WeatherLocation weatherLocation) {
+        
+        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
+        try {
+               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
+               return queryDb.insertIntoDataBase(weatherLocation);
+        } finally {
+               dbHelper.close();
+        } 
+    }
+    
+       public void updateDataBase(final WeatherLocation weatherLocation) {
+        
+        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
+        try {
+               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
+               queryDb.updateDataBase(weatherLocation);
+        } finally {
+               dbHelper.close();
+        } 
+    }
+}
diff --git a/Android/WeatherInformation/src/de/example/exampletdd/model/GeocodingData.java b/Android/WeatherInformation/src/de/example/exampletdd/model/GeocodingData.java
deleted file mode 100644 (file)
index 0627bcd..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-package de.example.exampletdd.model;
-
-import java.io.Serializable;
-
-
-public class GeocodingData implements Serializable {
-    private static final long serialVersionUID = 8607995242110846833L;
-    private final String city;
-    private final String country;
-    private final double latitude;
-    private final double longitude;
-
-    public static class Builder {
-        private String mCity;
-        private String mCountry;
-        private double mLatitude;
-        private double mLongitude;
-
-        public Builder setCity(final String city) {
-            this.mCity = city;
-            return this;
-        }
-
-        public Builder setCountry(final String country) {
-            this.mCountry = country;
-            return this;
-        }
-
-        public Builder setLatitude(final double latitude) {
-            this.mLatitude = latitude;
-            return this;
-        }
-
-        public Builder setLongitude(final double longitude) {
-            this.mLongitude = longitude;
-            return this;
-        }
-
-        public GeocodingData build() {
-            return new GeocodingData(this);
-        }
-    }
-
-    private GeocodingData(final Builder builder) {
-        this.city = builder.mCity;
-        this.country = builder.mCountry;
-        this.latitude = builder.mLatitude;
-        this.longitude = builder.mLongitude;
-    }
-
-    public String getCity() {
-        return this.city;
-    }
-
-    public String getCountry() {
-        return this.country;
-    }
-
-    public double getLatitude() {
-        return this.latitude;
-    }
-
-    public double getLongitude() {
-        return this.longitude;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = (prime * result) + ((this.city == null) ? 0 : this.city.hashCode());
-        result = (prime * result) + ((this.country == null) ? 0 : this.country.hashCode());
-        long temp;
-        temp = Double.doubleToLongBits(this.latitude);
-        result = (prime * result) + (int) (temp ^ (temp >>> 32));
-        temp = Double.doubleToLongBits(this.longitude);
-        result = (prime * result) + (int) (temp ^ (temp >>> 32));
-        return result;
-    }
-
-    @Override
-    public boolean equals(final Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (this.getClass() != obj.getClass())
-            return false;
-        final GeocodingData other = (GeocodingData) obj;
-        if (this.city == null) {
-            if (other.city != null)
-                return false;
-        } else if (!this.city.equals(other.city))
-            return false;
-        if (this.country == null) {
-            if (other.country != null)
-                return false;
-        } else if (!this.country.equals(other.country))
-            return false;
-        if (Double.doubleToLongBits(this.latitude) != Double.doubleToLongBits(other.latitude))
-            return false;
-        if (Double.doubleToLongBits(this.longitude) != Double.doubleToLongBits(other.longitude))
-            return false;
-        return true;
-    }
-}
index ae21c8f..f20b0b6 100644 (file)
@@ -5,66 +5,60 @@ import java.util.Date;
 
 
 public class WeatherLocation implements Serializable {
-       private static final long serialVersionUID = 1379832318334553377L;
-       private final String city;
-    private final String country;
-    private final double latitude;
-    private final double longitude;
-    private final Date lastCurrentUIUpdate;
-    private final Date lastForecastUIUpdate;
+       private static final long serialVersionUID = -1469725417020355109L;
+       private int id;
+       private String city;
+    private String country;
+    private boolean isSelected;
+    private double latitude;
+    private double longitude;
+    private Date lastCurrentUIUpdate;
+    private Date lastForecastUIUpdate;
 
-    public static class Builder {
-        private String mCity;
-        private String mCountry;
-        private double mLatitude;
-        private double mLongitude;
-        private Date mlastCurrentUIUpdate;
-        private Date mlastForecastUIUpdate;
+    public WeatherLocation setId(int id) {
+               this.id = id;
+               return this;
+       }
 
-        public Builder setCity(final String city) {
-            this.mCity = city;
-            return this;
-        }
+       public WeatherLocation setCity(String city) {
+               this.city = city;
+               return this;
+       }
 
-        public Builder setCountry(final String country) {
-            this.mCountry = country;
-            return this;
-        }
+       public WeatherLocation setCountry(String country) {
+               this.country = country;
+               return this;
+       }
 
-        public Builder setLatitude(final double latitude) {
-            this.mLatitude = latitude;
-            return this;
-        }
+       public WeatherLocation setIsSelected(boolean isSelected) {
+               this.isSelected = isSelected;
+               return this;
+       }
 
-        public Builder setLongitude(final double longitude) {
-            this.mLongitude = longitude;
-            return this;
-        }
-        
-        public Builder setlastCurrentUIUpdate(final Date lastCurrentUIUpdate) {
-               this.mlastCurrentUIUpdate = lastCurrentUIUpdate;
-               return this;
-        }
-        
-        public Builder setlastForecastUIUpdate(final Date lastForecastUIUpdate) {
-               this.mlastForecastUIUpdate = lastForecastUIUpdate;
-               return this;
-        }
+       public WeatherLocation setLatitude(double latitude) {
+               this.latitude = latitude;
+               return this;
+       }
 
-        public WeatherLocation build() {
-            return new WeatherLocation(this);
-        }
-    }
+       public WeatherLocation setLongitude(double longitude) {
+               this.longitude = longitude;
+               return this;
+       }
 
-    private WeatherLocation(final Builder builder) {
-        this.city = builder.mCity;
-        this.country = builder.mCountry;
-        this.latitude = builder.mLatitude;
-        this.longitude = builder.mLongitude;
-        this.lastCurrentUIUpdate = builder.mlastCurrentUIUpdate;
-        this.lastForecastUIUpdate = builder.mlastForecastUIUpdate;
-    }
+       public WeatherLocation setLastCurrentUIUpdate(Date lastCurrentUIUpdate) {
+               this.lastCurrentUIUpdate = lastCurrentUIUpdate;
+               return this;
+       }
 
+       public WeatherLocation setLastForecastUIUpdate(Date lastForecastUIUpdate) {
+               this.lastForecastUIUpdate = lastForecastUIUpdate;
+               return this;
+       }
+
+       public int getId() {
+       return this.id;
+    }
+    
     public String getCity() {
         return this.city;
     }
@@ -72,6 +66,10 @@ public class WeatherLocation implements Serializable {
     public String getCountry() {
         return this.country;
     }
+    
+    public boolean getIsSelected() {
+       return this.isSelected;
+    }
 
     public double getLatitude() {
         return this.latitude;
@@ -81,11 +79,11 @@ public class WeatherLocation implements Serializable {
         return this.longitude;
     }
     
-    public Date getlastCurrentUIUpdate() {
+    public Date getLastCurrentUIUpdate() {
        return this.lastCurrentUIUpdate;
     }
     
-    public Date getlastForecastUIUpdate() {
+    public Date getLastForecastUIUpdate() {
        return this.lastForecastUIUpdate;
     }
 }
index da96165..9f2e3e8 100644 (file)
@@ -1,6 +1,9 @@
 package de.example.exampletdd.model;
 
-import android.content.Context;
+import java.util.Calendar;
+import java.util.Date;
+
+import android.content.ContentValues;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
@@ -17,7 +20,7 @@ public class WeatherLocationDbQueries {
                this.mDbHelper = dbHelper;
        }
        
-       public WeatherLocation queryDataBase(final Context context) {
+       public WeatherLocation queryDataBase() {
         final String selection = WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " = ?";
         final String[] selectionArgs = { "1" };
         final String[] projection = {
@@ -36,19 +39,46 @@ public class WeatherLocationDbQueries {
 
                @Override
                public WeatherLocation doQuery(final Cursor cursor) {
-                       String city = cursor.getString(cursor.
+                       final Calendar calendar = Calendar.getInstance();
+                       
+                       final int id = cursor.getInt(cursor.getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation._ID));
+                       final String city = cursor.getString(cursor.
                                        getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY));
-                       String country = cursor.getString(cursor.
+                       final String country = cursor.getString(cursor.
                                        getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY));
-                       double latitude = cursor.getDouble(cursor.
+                       final boolean isSelected = (cursor.getInt(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED)) == 0) ? false : true;  
+                       Date lastCurrentUIUpdate = null;
+                       if (!cursor.isNull(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE))) {
+                       final int UNIXTime = cursor.getInt(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE));
+                       calendar.setTimeInMillis((long)UNIXTime * 1000L);
+                       lastCurrentUIUpdate = calendar.getTime();
+                       }
+                       Date lasForecastUIUpdate = null;
+                       if (!cursor.isNull(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE))) {
+                       final int UNIXTime = cursor.getInt(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE));
+                       calendar.setTimeInMillis((long)UNIXTime * 1000L);
+                       lastCurrentUIUpdate = calendar.getTime();
+                       }
+                       final double latitude = cursor.getDouble(cursor.
                                        getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE));
-                       double longitude = cursor.getDouble(cursor.
+                       final double longitude = cursor.getDouble(cursor.
                                        getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE));
+                       
                        
-                       return new WeatherLocation.Builder().
-                                       setCity(city).setCountry(country).
-                                       setLatitude(latitude).setLongitude(longitude).
-                                       build();
+                       return new WeatherLocation()
+                                       .setId(id)
+                                       .setCity(city)
+                                       .setCountry(country)
+                                       .setIsSelected(isSelected)
+                                       .setLastCurrentUIUpdate(lastCurrentUIUpdate)
+                                       .setLastForecastUIUpdate(lasForecastUIUpdate)
+                                       .setLatitude(latitude)
+                                       .setLongitude(longitude);
                }
         };
 
@@ -56,7 +86,45 @@ public class WeatherLocationDbQueries {
                        WeatherLocationContract.WeatherLocation.TABLE_NAME, projection,
                        selectionArgs, selection, doQuery);
     }
-    
+       
+       public long insertIntoDataBase(final WeatherLocation weatherLocation) {
+               // Create a new map of values, where column names are the keys
+               final ContentValues values = new ContentValues();
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, weatherLocation.getCity());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, weatherLocation.getCountry());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, weatherLocation.getIsSelected());
+               Date javaTime = weatherLocation.getLastCurrentUIUpdate();
+               if (javaTime != null) {
+                       final int UNIXTime = (int) javaTime.getTime() / 1000;
+                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE, UNIXTime);
+               }
+               javaTime = weatherLocation.getLastForecastUIUpdate();
+               if (javaTime != null) {
+                       final int UNIXTime = (int) javaTime.getTime() / 1000;
+                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE, UNIXTime);
+               }
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, weatherLocation.getLatitude());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE, weatherLocation.getLongitude());
+               
+               return this.insertIntoDataBase(WeatherLocationContract.WeatherLocation.TABLE_NAME, values);
+       }
+       
+       public void updateDataBase(final WeatherLocation weatherLocation) {
+               final String selection = WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " = ?";
+        final String[] selectionArgs = { "1" };
+               // Create a new map of values, where column names are the keys
+               final ContentValues values = new ContentValues();
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, weatherLocation.getCity());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, weatherLocation.getCountry());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, weatherLocation.getIsSelected());
+               values.putNull(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE);
+               values.putNull(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE);
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, weatherLocation.getLatitude());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE, weatherLocation.getLongitude());
+               
+               this.updateDataBase(WeatherLocationContract.WeatherLocation.TABLE_NAME, selectionArgs, selection, values);
+       }
+       
        // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
        private WeatherLocation queryDataBase(final String table,
                        final String[] projection, final String[] selectionArgs,
@@ -80,4 +148,25 @@ public class WeatherLocationDbQueries {
         }
     }
        
+       // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
+       private long insertIntoDataBase(final String table, final ContentValues values) {
+        final SQLiteDatabase db = this.mDbHelper.getWritableDatabase();
+        try {
+               return db.insert(table, null, values);
+        } finally {
+               db.close();
+        }
+    }
+       
+       // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
+       private long updateDataBase(final String table, final String[] selectionArgs,
+                       final String selection, final ContentValues values) {
+        final SQLiteDatabase db = this.mDbHelper.getReadableDatabase();
+        try {
+               return db.update(table, values, selection, selectionArgs);
+        } finally {
+               db.close();
+        }
+    }
+       
 }
diff --git a/Android/WeatherInformation/src/de/example/exampletdd/service/ServicePersistenceStorage.java b/Android/WeatherInformation/src/de/example/exampletdd/service/ServicePersistenceStorage.java
deleted file mode 100644 (file)
index 139ce46..0000000
+++ /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.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);
-    }
-}