WeatherInformation: wake up service with alarm
authorgu.martinm@gmail.com <gu.martinm@gmail.com>
Mon, 5 May 2014 04:12:25 +0000 (06:12 +0200)
committergu.martinm@gmail.com <gu.martinm@gmail.com>
Mon, 5 May 2014 04:12:25 +0000 (06:12 +0200)
15 files changed:
Android/WeatherInformation/AndroidManifest.xml
Android/WeatherInformation/res/values/arrays.xml
Android/WeatherInformation/res/values/strings.xml
Android/WeatherInformation/res/xml/weather_preferences.xml
Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationActivity.java [deleted file]
Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationBatch.java
Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationBootReceiver.java [new file with mode: 0644]
Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationMapActivity.java
Android/WeatherInformation/src/de/example/exampletdd/WeatherTabsActivity.java
Android/WeatherInformation/src/de/example/exampletdd/activityinterface/GetWeather.java [deleted file]
Android/WeatherInformation/src/de/example/exampletdd/fragment/current/WeatherInformationCurrentDataFragment.java
Android/WeatherInformation/src/de/example/exampletdd/fragment/overview/WeatherInformationOverviewFragment.java
Android/WeatherInformation/src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java
Android/WeatherInformation/src/de/example/exampletdd/httpclient/CustomHTTPClient.java
Android/WeatherInformation/src/de/example/exampletdd/model/GeocodingData.java

index 9b37dd1..134f903 100644 (file)
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
     
-    <uses-permission android:name="de.example.exampletdd.UPDATEOVERVIEWWEATHER" />
-    <uses-permission android:name="de.example.exampletdd.UPDATECURRENTWEATHER" />
-    <uses-permission android:name="de.example.exampletdd.UPDATETIMERATEWEATHERBATCH" />
-    <uses-permission android:name="de.example.exampletdd.UPDATEGEOCODINGWEATHERBATCH" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 
     
     <application
         android:allowBackup="true"
             </intent-filter>
         </activity>
         
+        <receiver android:name=".WeatherInformationBootReceiver"
+            android:enabled="true">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
+            </intent-filter>
+        </receiver>
+
         <service
             android:name=".WeatherInformationBatch"
-            android:process=":weatherinformationbatch"
-            android:exported="false" />
+            android:enabled="true" />
         
 
         <meta-data
index 9eec8c4..e7a46df 100644 (file)
         <item>10-Day Forecast</item>
         <item>14-Day Forecast</item>
     </string-array>
+    <string-array name="weather_preferences_update_time_rate">
+        <item>60</item>
+        <item>120</item>
+        <item>300</item>
+        <item>600</item>
+        <item>900</item>
+    </string-array>
+    <string-array name="weather_preferences_update_time_rate_human_value">
+        <item>1 minute</item>
+        <item>2 minutes</item>
+        <item>5 minutes</item>
+        <item>10 minutes</item>
+        <item>15 minutes</item>
+    </string-array>
 </resources>
index 4beeadf..46edf0e 100644 (file)
@@ -39,8 +39,8 @@
     <string name="weather_preferences_units_fahrenheit">Fahrenheit</string>
     <string name="weather_preferences_units_celsius">Celsius</string>
     <string name="weather_preferences_units">Unit of measurement for temperature</string>
-    <string name="weather_preferences_language_key">weather_preferences_language</string>
-    <string name="weather_preferences_language">Language</string>
+    <string name="weather_preferences_update_time_rate_key">weather_preferences_update_time_rate</string>
+    <string name="weather_preferences_update_time_rate">Update Time Rate</string>
     <string name="weather_preferences_day_forecast_key">weather_preferences_day_forecast</string>
     <string name="weather_preferences_day_forecast">Forecast days number</string>
     <string name="city_not_found">city not found</string>
index 3490cb6..8ee76dc 100644 (file)
         android:persistent="true"
         android:defaultValue="Celsius" />
     <ListPreference
-        android:entries="@array/weather_preferences_language_human_value"
-        android:entryValues="@array/weather_preferences_language_value"
-        android:key="@string/weather_preferences_language_key"
-        android:title="@string/weather_preferences_language"
-        android:defaultValue="en"
+        android:entries="@array/weather_preferences_update_time_rate_human_value"
+        android:entryValues="@array/weather_preferences_update_time_rate"
+        android:key="@string/weather_preferences_update_time_rate_key"
+        android:title="@string/weather_preferences_update_time_rate"
+        android:defaultValue="60"
         android:persistent="true"
         android:selectable="true"
-        android:summary="English"/>
+        android:summary="1 minute"/>
     <ListPreference
         android:key="@string/weather_preferences_day_forecast_key"
         android:title="@string/weather_preferences_day_forecast"
diff --git a/Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationActivity.java b/Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationActivity.java
deleted file mode 100644 (file)
index 86c6c0b..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-package de.example.exampletdd;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.Menu;
-import android.view.MenuItem;
-import de.example.exampletdd.activityinterface.GetWeather;
-import de.example.exampletdd.model.GeocodingData;
-import de.example.exampletdd.service.WeatherServicePersistenceFile;
-
-public class WeatherInformationActivity extends Activity {
-    private GetWeather mGetWeather;
-
-    @Override
-    protected void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        this.setContentView(R.layout.weather_main);
-
-        PreferenceManager.setDefaultValues(this, R.xml.weather_preferences, false);
-
-        final ActionBar actionBar = this.getActionBar();
-
-        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
-        actionBar.setDisplayHomeAsUpEnabled(true);
-
-        // Better using xml files? How to deal with savedInstanceState with xml files?
-        // final WeatherDataFragment weatherDataFragment = new WeatherDataFragment();
-        //
-        // if (savedInstanceState == null) {
-        //      this.getFragmentManager().beginTransaction()
-        //      .add(R.id.container, weatherDataFragment).commit();
-        // }
-        //        final WeatherInformationOverviewFragment weatherOverviewFragment = (WeatherInformationOverviewFragment) this
-        //                .getFragmentManager().findFragmentById(R.id.weather_overview_fragment);
-
-        //        this.mGetWeather = weatherOverviewFragment;
-
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(final Menu menu) {
-
-        this.getMenuInflater().inflate(R.menu.weather_main_menu, menu);
-
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(final MenuItem item) {
-        // Handle action bar item clicks here. The action bar will
-        // automatically handle clicks on the Home/Up button, so long
-        // as you specify a parent activity in AndroidManifest.xml.
-        super.onOptionsItemSelected(item);
-
-        Intent intent;
-        final int itemId = item.getItemId();
-        if (itemId == R.id.weather_menu_settings) {
-            intent = new Intent("de.example.exampletdd.WEATHERINFO")
-            .setComponent(new ComponentName("de.example.exampletdd",
-                    "de.example.exampletdd.WeatherInformationPreferencesActivity"));
-            this.startActivity(intent);
-            return true;
-        } else if (itemId == R.id.weather_menu_get) {
-            this.getWeather();
-            return true;
-        } else if (itemId == R.id.weather_menu_map) {
-            intent = new Intent("de.example.exampletdd.WEATHERINFO")
-            .setComponent(new ComponentName("de.example.exampletdd",
-                    "de.example.exampletdd.WeatherInformationMapActivity"));
-            this.startActivity(intent);
-            return true;
-        } else {
-        }
-
-        return super.onOptionsItemSelected(item);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        final ActionBar actionBar = this.getActionBar();
-
-        final WeatherServicePersistenceFile weatherServicePersistenceFile = new WeatherServicePersistenceFile(this);
-        final GeocodingData geocodingData = weatherServicePersistenceFile.getGeocodingData();
-
-        if (geocodingData != null) {
-            final String city = (geocodingData.getCity() == null) ? this.getString(R.string.city_not_found)
-                    : geocodingData.getCity();
-            final String country = (geocodingData.getCountry() == null) ? this.getString(R.string.country_not_found)
-                    : geocodingData.getCountry();
-            actionBar.setTitle(city + "," + country);
-        }
-
-
-        final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this);
-        final String keyPreference = this.getResources().getString(
-                R.string.weather_preferences_day_forecast_key);
-        final String value = sharedPreferences.getString(keyPreference, "");
-        String humanValue = "";
-        if (value.equals("5")) {
-            humanValue = "5-Day Forecast";
-        } else if (value.equals("10")) {
-            humanValue = "10-Day Forecast";
-        } else if (value.equals("14")) {
-            humanValue = "14-Day Forecast";
-        }
-        actionBar.setSubtitle(humanValue);
-
-    }
-
-
-    public void getWeather() {
-        this.mGetWeather.getRemoteWeatherInformation();
-    }
-}
index f0bc835..b7d8f58 100644 (file)
@@ -6,21 +6,15 @@ import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Calendar;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
 
 import org.apache.http.client.ClientProtocolException;
 
 import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.http.AndroidHttpClient;
 import android.os.AsyncTask;
-import android.os.Bundle;
 import android.os.IBinder;
+import android.support.v4.content.LocalBroadcastManager;
 import android.util.Log;
 
 import com.fasterxml.jackson.core.JsonParseException;
@@ -38,82 +32,38 @@ public class WeatherInformationBatch extends Service {
     private static final String TAG = "WeatherInformationBatch";
     private static final String resultsNumber = "14";
     private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
-    private ScheduledExecutorService mUpdateWeatherTask;
-    private int mUpdateTimeRate;
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(final Context context, final Intent intent) {
-            // This method will be run in the main thread of this service.
-            final String action = intent.getAction();
-            if (action.equals("de.example.exampletdd.UPDATETIMERATEWEATHERBATCH")) {
-                final Bundle extras = intent.getExtras();
-                WeatherInformationBatch.this.mUpdateTimeRate = extras.getInt("UPDATE_RATE_TIME", 60);
-
-                WeatherInformationBatch.this.updateWeather();
-            }
-
-            if (action.equals("de.example.exampletdd.UPDATEGEOCODINGWEATHERBATCH")) {
-                WeatherInformationBatch.this.updateWeather();
-            }
-        }
-    };
 
     @Override
     public IBinder onBind(final Intent intent) {
+        Log.i(TAG, "WeatherInformationBatch onBind");
         return null;
     }
 
     @Override
     public int onStartCommand(final Intent intent, final int flags, final int startId) {
-        final Bundle extras = intent.getExtras();
-        this.mUpdateTimeRate = extras.getInt("UPDATE_RATE_TIME", 60);
+        Log.i(TAG, "WeatherInformationBatch onStartCommand");
 
         this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this);
 
         this.updateWeather();
 
-
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction("de.example.exampletdd.UPDATETIMERATEWEATHERBATCH");
-        filter.addAction("de.example.exampletdd.UPDATEGEOCODINGWEATHERBATCH");
-        this.registerReceiver(this.mReceiver, filter);
-
-        return Service.START_REDELIVER_INTENT;
+        return super.onStartCommand(intent, flags, startId);
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
-        this.unregisterReceiver(this.mReceiver);
-        if (this.mUpdateWeatherTask != null) {
-            this.mUpdateWeatherTask.shutdownNow();
-        }
+        Log.i(TAG, "WeatherInformationBatch onDestroy");
     }
 
     private void updateWeather() {
-        if (this.mUpdateWeatherTask != null) {
-            this.mUpdateWeatherTask.shutdownNow();
-        }
-
-        this.mUpdateWeatherTask = Executors.newScheduledThreadPool(1);
-        this.mUpdateWeatherTask.scheduleAtFixedRate(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    WeatherInformationBatch.this.updateWeatherTask();
-                } catch (final Throwable e) {
-                    Log.i(TAG, "updateWeather, unexpected exception: ", e);
-                }
-            }
-        }, 0, this.mUpdateTimeRate, TimeUnit.SECONDS);
-    }
-
-    private void updateWeatherTask() {
         final GeocodingData geocodingData = this.mWeatherServicePersistenceFile.getGeocodingData();
 
+        Log.i(TAG, "WeatherInformationBatch updateWeather");
+
         if (geocodingData != null) {
+            Log.i(TAG, "WeatherInformationBatch updateWeather, geocodingData not null");
+
             final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
             final WeatherServiceParser weatherService = new WeatherServiceParser(JPOSWeatherParser);
             final AndroidHttpClient httpClient = AndroidHttpClient.newInstance("Android Weather Information Agent");
@@ -226,10 +176,12 @@ public class WeatherInformationBatch extends Service {
             // Update weather views.
             final Intent updateCurrentWeather = new Intent(
                     "de.example.exampletdd.UPDATECURRENTWEATHER");
-            WeatherInformationBatch.this.sendBroadcast(updateCurrentWeather);
+            LocalBroadcastManager.getInstance(WeatherInformationBatch.this).sendBroadcast(
+                    updateCurrentWeather);
             final Intent updateOverviewWeather = new Intent(
                     "de.example.exampletdd.UPDATEOVERVIEWWEATHER");
-            WeatherInformationBatch.this.sendBroadcast(updateOverviewWeather);
+            LocalBroadcastManager.getInstance(WeatherInformationBatch.this).sendBroadcast(
+                    updateOverviewWeather);
 
         }
     }
diff --git a/Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationBootReceiver.java b/Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationBootReceiver.java
new file mode 100644 (file)
index 0000000..29852ba
--- /dev/null
@@ -0,0 +1,39 @@
+package de.example.exampletdd;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.SystemClock;
+import android.preference.PreferenceManager;
+
+public class WeatherInformationBootReceiver extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(final Context context, final Intent intent) {
+        // TODO: there should be some option in the application if user does not want to set
+        // alarm in boot time.
+        
+        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
+            final SharedPreferences sharedPreferences = PreferenceManager
+                    .getDefaultSharedPreferences(context);
+            final String keyPreference = context
+                    .getString(R.string.weather_preferences_update_time_rate_key);
+            final String updateTimeRate = sharedPreferences.getString(keyPreference, "");
+            final int timeRate = Integer.valueOf(updateTimeRate);
+
+            final AlarmManager alarmMgr = (AlarmManager) context
+                    .getSystemService(Context.ALARM_SERVICE);
+            // TODO: better use some string instead of .class? In case I change the service class
+            // this could be a problem (I guess)
+            final Intent serviceIntent = new Intent(context, WeatherInformationBatch.class);
+            final PendingIntent alarmIntent = PendingIntent.getService(context, 0, serviceIntent,
+                    PendingIntent.FLAG_UPDATE_CURRENT);
+            alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
+                    + (timeRate * 1000), (timeRate * 1000), alarmIntent);
+        }
+    }
+
+}
index 4290104..6f9b2bb 100644 (file)
@@ -6,7 +6,6 @@ import java.util.List;
 import java.util.Locale;
 
 import android.app.ActionBar;
-import android.content.Intent;
 import android.location.Address;
 import android.location.Geocoder;
 import android.os.AsyncTask;
@@ -80,15 +79,6 @@ public class WeatherInformationMapActivity extends FragmentActivity {
         actionBar.setTitle("Mark your location");
     }
 
-    @Override
-    public void onPause() {
-        super.onPause();
-
-        final Intent updateOverviewWeather = new Intent(
-                "de.example.exampletdd.UPDATEGEOCODINGWEATHERBATCH");
-        this.sendBroadcast(updateOverviewWeather);
-    }
-
     private class LongClickListener implements OnMapLongClickListener {
 
         @Override
index 5c2126d..3bffec4 100644 (file)
@@ -2,17 +2,22 @@ package de.example.exampletdd;
 
 import android.app.ActionBar;
 import android.app.ActionBar.Tab;
+import android.app.AlarmManager;
 import android.app.FragmentTransaction;
+import android.app.PendingIntent;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentPagerAdapter;
 import android.support.v4.view.ViewPager;
+import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 import de.example.exampletdd.fragment.current.WeatherInformationCurrentDataFragment;
@@ -21,9 +26,12 @@ import de.example.exampletdd.model.GeocodingData;
 import de.example.exampletdd.service.WeatherServicePersistenceFile;
 
 public class WeatherTabsActivity extends FragmentActivity {
+    private static final String TAG = "WeatherTabsActivity";
     private static final int NUM_ITEMS = 2;
     private MyAdapter mAdapter;
     private ViewPager mPager;
+    private GeocodingData mGeocodingData;
+    private int mUpdateTimeRate;
 
     @Override
     protected void onCreate(final Bundle savedInstanceState) {
@@ -78,9 +86,21 @@ public class WeatherTabsActivity extends FragmentActivity {
         actionBar.addTab(actionBar.newTab().setText("CURRENTLY").setTabListener(tabListener));
         actionBar.addTab(actionBar.newTab().setText("FORECAST").setTabListener(tabListener));
 
+
+        final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+        final String keyPreference = this.getString(R.string.weather_preferences_update_time_rate_key);
+        final String updateTimeRate = sharedPreferences.getString(keyPreference, "");
+        final int timeRate = Integer.valueOf(updateTimeRate);
+        Log.i(TAG, "WeatherTabsActivity onCreate, timeRate: " + timeRate);
+
+        final AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
+        // TODO: better use some string instead of .class? In case I change the service class
+        // this could be a problem (I guess)
         final Intent intent = new Intent(this, WeatherInformationBatch.class);
-        intent.putExtra("UPDATE_RATE_TIME", 60);
-        this.startService(intent);
+        final PendingIntent alarmIntent = PendingIntent.getService(this, 0, intent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+        alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()
+                + (timeRate * 1000), (timeRate * 1000), alarmIntent);
     }
 
     @Override
@@ -118,6 +138,17 @@ public class WeatherTabsActivity extends FragmentActivity {
         return super.onOptionsItemSelected(item);
     }
 
+    @Override
+    protected void onRestoreInstanceState(final Bundle savedInstanceState) {
+        if (savedInstanceState != null) {
+            this.mGeocodingData = (GeocodingData) savedInstanceState
+                    .getSerializable("GEOCODINGDATA");
+            this.mUpdateTimeRate = savedInstanceState.getInt("UPDATE_TIME_RATE");
+        }
+
+        super.onRestoreInstanceState(savedInstanceState);
+    }
+
 
     @Override
     public void onResume() {
@@ -139,8 +170,7 @@ public class WeatherTabsActivity extends FragmentActivity {
 
         final SharedPreferences sharedPreferences = PreferenceManager
                 .getDefaultSharedPreferences(this);
-        final String keyPreference = this.getResources().getString(
-                R.string.weather_preferences_day_forecast_key);
+        String keyPreference = this.getString(R.string.weather_preferences_day_forecast_key);
         final String value = sharedPreferences.getString(keyPreference, "");
         String humanValue = "";
         if (value.equals("5")) {
@@ -152,15 +182,50 @@ public class WeatherTabsActivity extends FragmentActivity {
         }
         actionBar.getTabAt(1).setText(humanValue);
 
+
+
+        if (geocodingData != null) {
+            if ((this.mGeocodingData == null) || (!this.mGeocodingData.equals(geocodingData))) {
+                Log.i(TAG, "WeatherTabsActivity onResume, startService");
+                this.mGeocodingData = geocodingData;
+                final Intent intent = new Intent(this, WeatherInformationBatch.class);
+                this.startService(intent);
+            }
+        }
+
+        keyPreference = this.getString(R.string.weather_preferences_update_time_rate_key);
+        final String updateTimeRate = sharedPreferences.getString(keyPreference, "");
+        final int timeRate = Integer.valueOf(updateTimeRate);
+        if (this.mUpdateTimeRate != timeRate) {
+            Log.i(TAG, "WeatherTabsActivity onResume, updateTimeRate: " + timeRate);
+            this.mUpdateTimeRate = timeRate;
+            final AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
+            // TODO: better use some string instead of .class? In case I change the service class
+            // this could be a problem (I guess)
+            final Intent intent = new Intent(this, WeatherInformationBatch.class);
+            final PendingIntent alarmIntent = PendingIntent.getService(this, 0, intent,
+                    PendingIntent.FLAG_UPDATE_CURRENT);
+            alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()
+                    + (timeRate * 1000), (timeRate * 1000), alarmIntent);
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(final Bundle savedInstanceState) {
+        savedInstanceState.putSerializable("GEOCODINGDATA", this.mGeocodingData);
+        savedInstanceState.putInt("UPDATE_TIME_RATE", this.mUpdateTimeRate);
+
+        super.onSaveInstanceState(savedInstanceState);
     }
 
     @Override
-    public void onDestroy() {
-        super.onDestroy();
+    public void onStop() {
+        super.onStop();
+        Log.i(TAG, "WeatherTabsActivity onStop");
         this.stopService(new Intent(this, WeatherInformationBatch.class));
     }
 
-    public class MyAdapter extends FragmentPagerAdapter {
+    private class MyAdapter extends FragmentPagerAdapter {
         public MyAdapter(final FragmentManager fm) {
             super(fm);
         }
diff --git a/Android/WeatherInformation/src/de/example/exampletdd/activityinterface/GetWeather.java b/Android/WeatherInformation/src/de/example/exampletdd/activityinterface/GetWeather.java
deleted file mode 100644 (file)
index 4affd6a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.example.exampletdd.activityinterface;
-
-
-public interface GetWeather {
-
-    public void getWeatherByDay(final int chosenDay);
-
-    public void getRemoteWeatherInformation();
-
-}
index de396fd..7ffd441 100644 (file)
@@ -18,6 +18,7 @@ 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;
@@ -57,10 +58,6 @@ public class WeatherInformationCurrentDataFragment extends ListFragment {
                 }
             }
         };
-
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction("de.example.exampletdd.UPDATECURRENTWEATHER");
-        this.getActivity().registerReceiver(this.mReceiver, filter);
     }
 
     @Override
@@ -87,20 +84,25 @@ public class WeatherInformationCurrentDataFragment extends ListFragment {
         }
 
         this.setHasOptionsMenu(false);
-
         this.setEmptyText("No data available");
-
-        this.setListShownNoAnimation(false);
+        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());
 
-        // 1. Update units of measurement.
+        // 2. Update units of measurement.
         final String keyPreference = this.getResources().getString(
                 R.string.weather_preferences_units_key);
         final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
@@ -112,7 +114,7 @@ public class WeatherInformationCurrentDataFragment extends ListFragment {
             this.mIsFahrenheit = true;
         }
 
-        // 2. Try to restore old information
+        // 3. Try to restore old information
         final CurrentWeatherData currentWeatherData = this.mWeatherServicePersistenceFile
                 .getCurrentWeatherData();
         if (currentWeatherData != null) {
@@ -121,6 +123,12 @@ public class WeatherInformationCurrentDataFragment extends ListFragment {
     }
 
     @Override
+    public void onPause() {
+        super.onPause();
+        LocalBroadcastManager.getInstance(this.getActivity()).unregisterReceiver(this.mReceiver);
+    }
+
+    @Override
     public void onSaveInstanceState(final Bundle savedInstanceState) {
 
         // Save state
@@ -134,16 +142,10 @@ public class WeatherInformationCurrentDataFragment extends ListFragment {
         super.onSaveInstanceState(savedInstanceState);
     }
 
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        this.getActivity().unregisterReceiver(this.mReceiver);
-    }
-
     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 Z", Locale.US);
+        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";
index c646255..aaf140e 100644 (file)
@@ -23,6 +23,7 @@ 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;
@@ -35,7 +36,7 @@ import de.example.exampletdd.service.WeatherServicePersistenceFile;
 public class WeatherInformationOverviewFragment extends ListFragment {
     private static final String TAG = "WeatherInformationOverviewFragment";
     private boolean mIsFahrenheit;
-    private String mDayForecast;
+    private int mDayForecast;
     private WeatherServicePersistenceFile mWeatherServicePersistenceFile;
     private Parcelable mListState;
     private BroadcastReceiver mReceiver;
@@ -48,7 +49,8 @@ public class WeatherInformationOverviewFragment extends ListFragment {
                 .getDefaultSharedPreferences(this.getActivity());
         final String keyPreference = this.getResources().getString(
                 R.string.weather_preferences_day_forecast_key);
-        this.mDayForecast = sharedPreferences.getString(keyPreference, "");
+        final String dayForecast = sharedPreferences.getString(keyPreference, "");
+        this.mDayForecast = Integer.valueOf(dayForecast);
 
         this.mWeatherServicePersistenceFile = new WeatherServicePersistenceFile(this.getActivity());
 
@@ -71,10 +73,6 @@ public class WeatherInformationOverviewFragment extends ListFragment {
                 }
             }
         };
-
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction("de.example.exampletdd.UPDATEOVERVIEWWEATHER");
-        this.getActivity().registerReceiver(this.mReceiver, filter);
     }
 
     @Override
@@ -109,7 +107,7 @@ public class WeatherInformationOverviewFragment extends ListFragment {
                 this.getActivity(), R.layout.weather_main_entry_list);
 
 
-        this.setEmptyText("Press download to receive weather information");
+        this.setEmptyText("No data available");
 
         this.setListAdapter(adapter);
         this.setListShown(true);
@@ -117,20 +115,51 @@ public class WeatherInformationOverviewFragment extends ListFragment {
     }
 
     @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);
+    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 {
-            // tablet layout
-            fragment.getWeatherByDay((int) id);
+            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
@@ -151,9 +180,20 @@ public class WeatherInformationOverviewFragment extends ListFragment {
     }
 
     @Override
-    public void onDestroy() {
-        super.onDestroy();
-        this.getActivity().unregisterReceiver(this.mReceiver);
+    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) {
@@ -171,6 +211,7 @@ public class WeatherInformationOverviewFragment extends ListFragment {
 
 
         final Calendar calendar = Calendar.getInstance();
+        int count = this.mDayForecast;
         for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData
                 .getList()) {
 
@@ -210,47 +251,15 @@ public class WeatherInformationOverviewFragment extends ListFragment {
                         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);
     }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this.getActivity());
-
-        // 1. Update units of measurement.
-        String keyPreference = this.getResources().getString(
-                R.string.weather_preferences_units_key);
-        final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        final String celsius = this.getResources().getString(
-                R.string.weather_preferences_units_celsius);
-        if (unitsPreferenceValue.equals(celsius)) {
-            this.mIsFahrenheit = false;
-        } else {
-            this.mIsFahrenheit = true;
-        }
-
-        // 2. Update number day forecast.
-        keyPreference = this.getResources().getString(
-                R.string.weather_preferences_day_forecast_key);
-        this.mDayForecast = sharedPreferences.getString(keyPreference, "");
-
-
-        // 3. 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);
-        }
-
-    }
 }
index 4dc70d6..c4a7573 100644 (file)
@@ -24,16 +24,29 @@ implements OnSharedPreferenceChangeListener {
                 .getSharedPreferences().getString(keyPreference, ""));
 
         keyPreference = this.getActivity().getString(
-                R.string.weather_preferences_language_key);
+                R.string.weather_preferences_update_time_rate_key);
         connectionPref = this.findPreference(keyPreference);
-        connectionPref.setSummary(this.getPreferenceManager()
-                .getSharedPreferences().getString(keyPreference, ""));
+        String value = this.getPreferenceManager().getSharedPreferences()
+                .getString(keyPreference, "");
+        String humanValue = "";
+        if (value.equals("60")) {
+            humanValue = "1 minute";
+        } else if (value.equals("120")) {
+            humanValue = "2 minutes";
+        } else if (value.equals("300")) {
+            humanValue = "5 minutes";
+        } else if (value.equals("600")) {
+            humanValue = "10 minutes";
+        } else if (value.equals("900")) {
+            humanValue = "15 minutes";
+        }
+        connectionPref.setSummary(humanValue);
 
         keyPreference = this.getActivity().getString(
                 R.string.weather_preferences_day_forecast_key);
         connectionPref = this.findPreference(keyPreference);
-        final String value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
-        String humanValue = "";
+        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
+        humanValue = "";
         if (value.equals("5")) {
             humanValue = "5-Day Forecast";
         } else if (value.equals("10")) {
@@ -71,11 +84,23 @@ implements OnSharedPreferenceChangeListener {
             return;
         }
 
-        keyValue = this.getActivity().getString(
-                R.string.weather_preferences_language_key);
+        keyValue = this.getActivity().getString(R.string.weather_preferences_update_time_rate_key);
         if (key.equals(keyValue)) {
             final Preference connectionPref = this.findPreference(key);
-            connectionPref.setSummary(sharedPreferences.getString(key, ""));
+            final String value = sharedPreferences.getString(key, "");
+            String humanValue = "";
+            if (value.equals("60")) {
+                humanValue = "1 minute";
+            } else if (value.equals("120")) {
+                humanValue = "2 minutes";
+            } else if (value.equals("300")) {
+                humanValue = "5 minutes";
+            } else if (value.equals("600")) {
+                humanValue = "10 minutes";
+            } else if (value.equals("900")) {
+                humanValue = "15 minutes";
+            }
+            connectionPref.setSummary(humanValue);
             return;
         }
 
index 14d0b85..a041ef3 100644 (file)
@@ -82,7 +82,11 @@ public class CustomHTTPClient {
         return this.httpClient.execute(httpGet, handler);
     }
 
-    public ByteArrayOutputStream sortResponse(final HttpResponse httpResponse)
+    public void close() {
+        this.httpClient.close();
+    }
+
+    private ByteArrayOutputStream sortResponse(final HttpResponse httpResponse)
             throws IOException {
 
         if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
@@ -100,10 +104,6 @@ public class CustomHTTPClient {
                 + httpResponse.getStatusLine().getStatusCode());
     }
 
-    public void close() {
-        this.httpClient.close();
-    }
-
     private ByteArrayOutputStream readInputStream (final InputStream inputStream) throws IOException {
         final ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
         final int bufferSize = 1024;
index c6a129e..0627bcd 100644 (file)
@@ -63,4 +63,44 @@ public class GeocodingData implements Serializable {
     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;
+    }
 }