WeatherInformation: notification with alarm
authorgu.martinm@gmail.com <gu.martinm@gmail.com>
Mon, 22 Sep 2014 19:52:52 +0000 (21:52 +0200)
committergu.martinm@gmail.com <gu.martinm@gmail.com>
Mon, 22 Sep 2014 19:52:52 +0000 (21:52 +0200)
AndroidManifest.xml
res/layout/notification.xml [new file with mode: 0644]
res/values/arrays.xml
res/xml/weather_preferences.xml
src/de/example/exampletdd/WeatherInformationBatch.java
src/de/example/exampletdd/WeatherInformationBootReceiver.java
src/de/example/exampletdd/fragment/current/CurrentFragment.java
src/de/example/exampletdd/fragment/overview/OverviewFragment.java
src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java

index 9da7fb2..93b2253 100644 (file)
@@ -84,7 +84,7 @@
         </activity>
         
         <receiver android:name=".WeatherInformationBootReceiver"
-            android:enabled="false">
+            android:enabled="true">
             <intent-filter>
                 <action android:name="android.intent.action.BOOT_COMPLETED"></action>
             </intent-filter>
diff --git a/res/layout/notification.xml b/res/layout/notification.xml
new file mode 100644 (file)
index 0000000..cf741fd
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:baselineAligned="false"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="center_horizontal"
+    android:orientation="horizontal"
+    android:padding="5dp" >
+
+    <LinearLayout
+    android:layout_width="0dp"
+    android:layout_weight="1"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:layout_gravity="center"
+    android:orientation="vertical" >
+    
+        <TextView
+            android:id="@+id/weather_main_entry_temperature_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="12ºC"
+            android:textAlignment="center"
+            android:textAllCaps="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="@color/weather_time_of_day_color_title"
+            android:textStyle="bold" />
+    
+    <TextView
+        android:id="@+id/weather_main_entry_temperature_min"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="5ºC"
+        android:textAlignment="center"
+        android:textAllCaps="true"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="@color/weather_time_of_day_color_title"
+        android:textStyle="normal" />
+    
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:orientation="vertical" >
+    
+    <ImageView
+        android:id="@+id/weather_main_entry_image"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:contentDescription="@string/icon_weather_description"
+        android:orientation="vertical"
+        android:src="@drawable/ic_launcher" />
+    
+    </LinearLayout>
+
+</LinearLayout>
index e7a46df..5900023 100644 (file)
         <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>0</item>
         <item>900</item>
+        <item>1800</item>
+        <item>3600</item>       
+        <item>43200</item>
+        <item>86400</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>
+        <item>no updates</item>
+        <item>fifteen minutes</item>
+        <item>half hour</item>
+        <item>one hour</item>   
+        <item>half day</item>
+        <item>one day</item>     
     </string-array>
 </resources>
index 8ee76dc..c3449ab 100644 (file)
         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:defaultValue="0"
         android:persistent="true"
         android:selectable="true"
-        android:summary="1 minute"/>
+        android:summary="no updates"/>
     <ListPreference
         android:key="@string/weather_preferences_day_forecast_key"
         android:title="@string/weather_preferences_day_forecast"
index 3a0e678..e53e1a1 100644 (file)
@@ -1,28 +1,35 @@
 package de.example.exampletdd;
 
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
 import java.util.Calendar;
+import java.util.Locale;
 
 import org.apache.http.client.ClientProtocolException;
 
 import android.app.IntentService;
+import android.app.Notification;
+import android.app.PendingIntent;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.net.http.AndroidHttpClient;
-import android.support.v4.content.LocalBroadcastManager;
+import android.preference.PreferenceManager;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.NotificationManagerCompat;
+import android.support.v4.app.TaskStackBuilder;
 import android.util.Log;
 
 import com.fasterxml.jackson.core.JsonParseException;
 
 import de.example.exampletdd.httpclient.CustomHTTPClient;
+import de.example.exampletdd.model.DatabaseQueries;
 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;
 
@@ -32,12 +39,12 @@ public class WeatherInformationBatch extends IntentService {
 
 
     public WeatherInformationBatch() {
-        super("WeatherInformationBatch");
+        super("WIB-Thread");
     }
 
     @Override
     public int onStartCommand(final Intent intent, final int flags, final int startId) {
-        Log.i(TAG, "WeatherInformationBatch onStartCommand");
+        Log.i(TAG, "onStartCommand");
 
         return super.onStartCommand(intent, flags, startId);
     }
@@ -45,18 +52,21 @@ public class WeatherInformationBatch extends IntentService {
     @Override
     protected void onHandleIntent(final Intent intent) {
 
-        Log.i(TAG, "WeatherInformationBatch onHandleIntent");
+        Log.i(TAG, "onHandleIntent");
 
-        final WeatherLocation weatherLocation = this.queryDataBase();
+        final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        
         if (weatherLocation != null) {
-            Log.i(TAG, "WeatherInformationBatch onHandleIntent, geocodingData not null");
+            Log.i(TAG, "onHandleIntent, weatherLocation not null");
             final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser());
-            final CustomHTTPClient weatherHTTPClient = new CustomHTTPClient(
+            final CustomHTTPClient HTTPClient = new CustomHTTPClient(
                     AndroidHttpClient.newInstance("Android Weather Information Agent"));
 
+            Current current = null;
             try {
-                this.doInBackgroundThrowable(weatherLocation,weatherHTTPClient, weatherService);
-                this.onPostExecuteThrowable();
+               current = this.doInBackgroundThrowable(weatherLocation, HTTPClient, weatherService);
+                
             } catch (final JsonParseException e) {
                 Log.e(TAG, "doInBackground exception: ", e);
             } catch (final ClientProtocolException e) {
@@ -69,64 +79,113 @@ public class WeatherInformationBatch extends IntentService {
                 // logger infrastructure swallows UnknownHostException :/
                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
             } finally {
-                weatherHTTPClient.close();
+                HTTPClient.close();
             }
+            
+            this.showNotification(current);
         }
     }
 
-    private void doInBackgroundThrowable(final WeatherLocation weatherLocation,
-            final CustomHTTPClient weatherHTTPClient, final ServiceParser weatherService)
+    private Current doInBackgroundThrowable(final WeatherLocation weatherLocation,
+            final CustomHTTPClient HTTPClient, final ServiceParser weatherService)
                     throws ClientProtocolException, MalformedURLException, URISyntaxException,
                     JsonParseException, IOException {
 
-        final String APIVersion = WeatherInformationBatch.this.getResources().getString(
-                R.string.api_version);
-
-        // 1. Today
-        String urlAPI = WeatherInformationBatch.this.getResources().getString(
-                R.string.uri_api_weather_today);
-        String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
-                       weatherLocation.getLatitude(), weatherLocation.getLongitude());
-        String jsonData = weatherHTTPClient.retrieveDataAsString(new URL(url));
-        final Current currentWeatherData = weatherService
-                .retrieveCurrentFromJPOS(jsonData);
+        final String APIVersion = this.getResources().getString(R.string.api_version);
+
+        final String urlAPI = this.getResources().getString(R.string.uri_api_weather_today);
+        final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
+                weatherLocation.getLatitude(), weatherLocation.getLongitude());
+        final String jsonData = HTTPClient.retrieveDataAsString(new URL(url));
+        final Current current = weatherService.retrieveCurrentFromJPOS(jsonData);
+        // TODO: what is this for? I guess I could skip it :/
         final Calendar now = Calendar.getInstance();
-        currentWeatherData.setDate(now.getTime());
-
-        // 2. Forecast
-        urlAPI = WeatherInformationBatch.this.getResources().getString(
-                R.string.uri_api_weather_forecast);
-        url = weatherService.createURIAPIForecast(urlAPI, APIVersion,
-                       weatherLocation.getLatitude(), weatherLocation.getLongitude(), resultsNumber);
-        jsonData = weatherHTTPClient.retrieveDataAsString(new URL(url));
-        final Forecast forecastWeatherData = weatherService
-                .retrieveForecastFromJPOS(jsonData);
+        current.setDate(now.getTime());
+        
+        return current;
     }
+    
+    private void showNotification(final Current current) {
+        final SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(this.getApplicationContext());
+
+        // TODO: repeating the same code in Overview, Specific and Current!!!
+        // 1. Update units of measurement.
+        boolean mIsFahrenheit = false;
+        final String keyPreference = this.getResources().getString(
+                R.string.weather_preferences_units_key);
+        final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        final String celsius = this.getResources().getString(
+                R.string.weather_preferences_units_celsius);
+        if (unitsPreferenceValue.equals(celsius)) {
+            mIsFahrenheit = false;
+        } else {
+            mIsFahrenheit = true;
+        }
+        final double tempUnits = mIsFahrenheit ? 0 : 273.15;
+        final String symbol = mIsFahrenheit ? "ºF" : "ºC";
+
 
-    private void onPostExecuteThrowable()
-            throws FileNotFoundException, IOException {
+        // 2. Formatters
+        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
+        tempFormatter.applyPattern("#####.#####");
+        final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.US);
+        
+        
+        String feelsLike = "";
+        if (current.getMain().getTemp() != null) {
+            double conversion = (Double) current.getMain().getTemp();
+            conversion = conversion - tempUnits;
+            feelsLike = tempFormatter.format(conversion);
+        }
+        
+        // TODO: static resource
+        String description = "no description available";
+        if (current.getWeather().size() > 0) {
+            description = current.getWeather().get(0).getDescription();
+        }
+       
+        
 
-        // Update weather views.
-        final Intent updateCurrentWeather = new Intent(
-                "de.example.exampletdd.UPDATECURRENTWEATHER");
-        LocalBroadcastManager.getInstance(WeatherInformationBatch.this).sendBroadcast(
-                updateCurrentWeather);
-        final Intent updateOverviewWeather = new Intent(
-                "de.example.exampletdd.UPDATEOVERVIEWWEATHER");
-        LocalBroadcastManager.getInstance(WeatherInformationBatch.this).sendBroadcast(
-                updateOverviewWeather);
 
-    }
-    
-    private WeatherLocation queryDataBase() {
+        final Intent resultIntent =  new Intent(this.getApplicationContext(), WeatherTabsActivity.class);
+        // The PendingIntent to launch our activity if the user selects this notification
+//        final PendingIntent contentIntent = PendingIntent.getActivity(
+//                     this.getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+        // The stack builder object will contain an artificial back stack for the started Activity.
+        // This ensures that navigating backward from the Activity leads out of
+        // your application to the Home screen.
+        final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext());
+        // Adds the back stack for the Intent (but not the Intent itself)
+        stackBuilder.addParentStack(WeatherTabsActivity.class);
+        // Adds the Intent that starts the Activity to the top of the stack
+        stackBuilder.addNextIntent(resultIntent);
+        final PendingIntent resultPendingIntent =
+                       stackBuilder.getPendingIntent(
+                    0,
+                    PendingIntent.FLAG_UPDATE_CURRENT
+                );
         
-       // TODO: repeating the same code!!!
-        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this);
-        try {
-               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
-               return queryDb.queryDataBase();
-        } finally {
-               dbHelper.close();
-        } 
+       final NotificationManagerCompat notificationManager =
+                       NotificationManagerCompat.from(this.getApplicationContext());
+       
+
+        final NotificationCompat.Builder notificationBuilder =
+                       new NotificationCompat.Builder(this.getApplicationContext())
+                .setSmallIcon(R.drawable.ic_launcher)
+                .setContentText(description)
+                .setContentTitle(this.getText(R.string.app_name))
+                .setAutoCancel(true)
+                .setLocalOnly(true)
+                .setContentIntent(resultPendingIntent)
+                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+                .setNumber(666);
+        final Notification notification = notificationBuilder.build();
+        notification.flags |= Notification.FLAG_AUTO_CANCEL;
+
+        // Send the notification.
+        // Sets an ID for the notification, so it can be updated (just in case)
+        int notifyID = 1;
+        notificationManager.notify(notifyID, notification);
     }
 }
index 29852ba..a2a8f14 100644 (file)
@@ -13,26 +13,38 @@ 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")) {
+               
+               // Update Time Rate
             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 String updateTimeRate = sharedPreferences.getString(keyPreference, "");            
+            long chosenInterval = 0;
+            if (updateTimeRate.equals("900")) {
+               chosenInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
+            } else if (updateTimeRate.equals("1800")) {
+               chosenInterval = AlarmManager.INTERVAL_HALF_HOUR;
+            } else if (updateTimeRate.equals("3600")) {
+               chosenInterval = AlarmManager.INTERVAL_HOUR;
+            } else if (updateTimeRate.equals("43200")) {
+               chosenInterval = AlarmManager.INTERVAL_HALF_DAY;
+            } else if (updateTimeRate.equals("86400")) {
+               chosenInterval = AlarmManager.INTERVAL_DAY;
+            }
 
-            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);
+            if (chosenInterval != 0) {
+                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.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()
+                        + chosenInterval, chosenInterval, alarmIntent);
+            }
         }
     }
 
index cb21ffb..b9737a7 100644 (file)
@@ -167,7 +167,7 @@ public class CurrentFragment extends Fragment {
     private void updateUI(final Current current) {
        
         final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this.getActivity());
+                .getDefaultSharedPreferences(this.getActivity().getApplicationContext());
 
         // TODO: repeating the same code in Overview, Specific and Current!!!
         // 1. Update units of measurement.
@@ -332,13 +332,13 @@ public class CurrentFragment extends Fragment {
     private class CurrentTask extends AsyncTask<Object, Void, Current> {
        // Store the context passed to the AsyncTask when the system instantiates it.
         private final Context localContext;
-        final CustomHTTPClient weatherHTTPClient;
+        final CustomHTTPClient HTTPClient;
         final ServiceParser weatherService;
 
-        public CurrentTask(final Context context, final CustomHTTPClient weatherHTTPClient,
+        public CurrentTask(final Context context, final CustomHTTPClient HTTPClient,
                        final ServiceParser weatherService) {
                this.localContext = context;
-            this.weatherHTTPClient = weatherHTTPClient;
+            this.HTTPClient = HTTPClient;
             this.weatherService = weatherService;
         }
 
@@ -350,7 +350,7 @@ public class CurrentFragment extends Fragment {
   
             Current current = null;
             try {
-               current = this.doInBackgroundThrowable(latitude, longitude, weatherHTTPClient, weatherService);
+               current = this.doInBackgroundThrowable(latitude, longitude);
             } catch (final JsonParseException e) {
                 Log.e(TAG, "CurrentTask doInBackground exception: ", e);
             } catch (final ClientProtocolException e) {
@@ -363,22 +363,20 @@ public class CurrentFragment extends Fragment {
                 // logger infrastructure swallows UnknownHostException :/
                 Log.e(TAG, "CurrentTask doInBackground exception: " + e.getMessage(), e);
             } finally {
-                weatherHTTPClient.close();
+               HTTPClient.close();
             }
 
             return current;
         }
 
-        private Current doInBackgroundThrowable(final double latitude, final double longitude,
-                final CustomHTTPClient HTTPClient, final ServiceParser serviceParser)
+        private Current doInBackgroundThrowable(final double latitude, final double longitude)
                         throws URISyntaxException, ClientProtocolException, JsonParseException, IOException {
 
                final String APIVersion = localContext.getResources().getString(R.string.api_version);
             final String urlAPI = localContext.getResources().getString(R.string.uri_api_weather_today);
             final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion, latitude, longitude);
-            final String jsonData = weatherHTTPClient.retrieveDataAsString(new URL(url));
-            final Current current = weatherService
-                    .retrieveCurrentFromJPOS(jsonData);
+            final String jsonData = HTTPClient.retrieveDataAsString(new URL(url));
+            final Current current = weatherService.retrieveCurrentFromJPOS(jsonData);
             // TODO: what is this for? I guess I could skip it :/
             final Calendar now = Calendar.getInstance();
             current.setDate(now.getTime());
index 88d4863..28da6cf 100644 (file)
@@ -127,6 +127,9 @@ public class OverviewFragment extends ListFragment {
         final WeatherLocation weatherLocation = query.queryDataBase();
         if (weatherLocation == null) {
             // Nothing to do.
+               // Empty list and show error message (see setEmptyText in onCreate)
+                       this.setListAdapter(null);
+                       this.setListShownNoAnimation(true);
             return;
         }
 
@@ -194,7 +197,7 @@ public class OverviewFragment extends ListFragment {
     private void updateUI(final Forecast forecastWeatherData) {
 
         final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this.getActivity());
+                .getDefaultSharedPreferences(this.getActivity().getApplicationContext());
 
         // TODO: repeating the same code in Overview, Specific and Current!!!
         // 1. Update units of measurement.
@@ -306,13 +309,13 @@ public class OverviewFragment extends ListFragment {
     private class OverviewTask extends AsyncTask<Object, Void, Forecast> {
        // Store the context passed to the AsyncTask when the system instantiates it.
         private final Context localContext;
-        private final CustomHTTPClient weatherHTTPClient;
+        private final CustomHTTPClient HTTPClient;
         private final ServiceParser weatherService;
 
-        public OverviewTask(final Context context, final CustomHTTPClient weatherHTTPClient,
+        public OverviewTask(final Context context, final CustomHTTPClient HTTPClient,
                        final ServiceParser weatherService) {
                this.localContext = context;
-            this.weatherHTTPClient = weatherHTTPClient;
+            this.HTTPClient = HTTPClient;
             this.weatherService = weatherService;
         }
         
@@ -325,7 +328,7 @@ public class OverviewFragment extends ListFragment {
             Forecast forecast = null;
 
             try {
-                forecast = this.doInBackgroundThrowable(latitude, longitude, weatherHTTPClient, weatherService);
+                forecast = this.doInBackgroundThrowable(latitude, longitude);
             } catch (final JsonParseException e) {
                 Log.e(TAG, "OverviewTask doInBackground exception: ", e);
             } catch (final ClientProtocolException e) {
@@ -338,23 +341,22 @@ public class OverviewFragment extends ListFragment {
                 // logger infrastructure swallows UnknownHostException :/
                 Log.e(TAG, "OverviewTask doInBackground exception: " + e.getMessage(), e);
             } finally {
-                weatherHTTPClient.close();
+               HTTPClient.close();
             }
 
             return forecast;
         }
 
-        private Forecast doInBackgroundThrowable(final double latitude, final double longitude,
-                final CustomHTTPClient HTTPClient, final ServiceParser serviceParser)
+        private Forecast doInBackgroundThrowable(final double latitude, final double longitude)
                         throws URISyntaxException, ClientProtocolException, JsonParseException, IOException {
 
             final String APIVersion = localContext.getResources().getString(R.string.api_version);
             final String urlAPI = localContext.getResources().getString(R.string.uri_api_weather_forecast);
             // TODO: number as resource
-            final String url = serviceParser.createURIAPIForecast(urlAPI, APIVersion, latitude, longitude, "14");
+            final String url = weatherService.createURIAPIForecast(urlAPI, APIVersion, latitude, longitude, "14");
             final String jsonData = HTTPClient.retrieveDataAsString(new URL(url));
 
-            return serviceParser.retrieveForecastFromJPOS(jsonData);
+            return weatherService.retrieveForecastFromJPOS(jsonData);
         }
 
         @Override
index c4a7573..f8a4838 100644 (file)
@@ -1,14 +1,20 @@
 package de.example.exampletdd.fragment.preferences;
 
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
 import de.example.exampletdd.R;
+import de.example.exampletdd.WeatherInformationBatch;
 
-public class WeatherInformationPreferencesFragment extends PreferenceFragment
-implements OnSharedPreferenceChangeListener {
+public class WeatherInformationPreferencesFragment extends PreferenceFragment 
+                                                                                                       implements OnSharedPreferenceChangeListener {
 
     @Override
     public void onCreate(final Bundle savedInstanceState) {
@@ -16,33 +22,39 @@ implements OnSharedPreferenceChangeListener {
 
         // Load the preferences from an XML resource
         this.addPreferencesFromResource(R.xml.weather_preferences);
-
-        String keyPreference = this.getActivity().getString(
+        
+        
+        // Units of Measurement
+        String keyPreference = this.getActivity().getApplicationContext().getString(
                 R.string.weather_preferences_units_key);
         Preference connectionPref = this.findPreference(keyPreference);
         connectionPref.setSummary(this.getPreferenceManager()
                 .getSharedPreferences().getString(keyPreference, ""));
-
-        keyPreference = this.getActivity().getString(
+        
+        // Update Time Rate
+        keyPreference = this.getActivity().getApplicationContext().getString(
                 R.string.weather_preferences_update_time_rate_key);
         connectionPref = this.findPreference(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";
+        if (value.equals("0")) {
+            humanValue = "no updates";
         } else if (value.equals("900")) {
-            humanValue = "15 minutes";
+            humanValue = "fifteen minutes";
+        } else if (value.equals("1800")) {
+            humanValue = "half hour";
+        } else if (value.equals("3600")) {
+            humanValue = "one hour";
+        } else if (value.equals("43200")) {
+            humanValue = "half day";
+        } else if (value.equals("86400")) {
+            humanValue = "one day";
         }
         connectionPref.setSummary(humanValue);
-
-        keyPreference = this.getActivity().getString(
+        
+        // Forecast days number
+        keyPreference = this.getActivity().getApplicationContext().getString(
                 R.string.weather_preferences_day_forecast_key);
         connectionPref = this.findPreference(keyPreference);
         value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
@@ -75,7 +87,9 @@ implements OnSharedPreferenceChangeListener {
     @Override
     public void onSharedPreferenceChanged(
             final SharedPreferences sharedPreferences, final String key) {
-        String keyValue = this.getActivity().getString(
+       
+       // Units of Measurement
+        String keyValue = this.getActivity().getApplicationContext().getString(
                 R.string.weather_preferences_units_key);
 
         if (key.equals(keyValue)) {
@@ -84,26 +98,33 @@ implements OnSharedPreferenceChangeListener {
             return;
         }
 
-        keyValue = this.getActivity().getString(R.string.weather_preferences_update_time_rate_key);
+        // Update Time Rate
+        keyValue = this.getActivity().getApplicationContext().getString(
+                       R.string.weather_preferences_update_time_rate_key);
         if (key.equals(keyValue)) {
             final Preference connectionPref = this.findPreference(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";
+            if (value.equals("0")) {
+                humanValue = "no updates";
             } else if (value.equals("900")) {
-                humanValue = "15 minutes";
+                humanValue = "fifteen minutes";
+            } else if (value.equals("1800")) {
+                humanValue = "half hour";
+            } else if (value.equals("3600")) {
+                humanValue = "one hour";
+            } else if (value.equals("43200")) {
+                humanValue = "half day";
+            } else if (value.equals("86400")) {
+                humanValue = "one day";
             }
+            
+            this.updateAlarm(value);
             connectionPref.setSummary(humanValue);
             return;
         }
 
+        // Forecast days number
         keyValue = this.getActivity().getString(
                 R.string.weather_preferences_day_forecast_key);
         if (key.equals(keyValue)) {
@@ -123,4 +144,40 @@ implements OnSharedPreferenceChangeListener {
 
     }
 
+    private void updateAlarm(final String updateTimeRate) {
+        long chosenInterval = 0;
+        if (updateTimeRate.equals("900")) {
+               chosenInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
+        } else if (updateTimeRate.equals("1800")) {
+               chosenInterval = AlarmManager.INTERVAL_HALF_HOUR;
+        } else if (updateTimeRate.equals("3600")) {
+               chosenInterval = AlarmManager.INTERVAL_HOUR;
+        } else if (updateTimeRate.equals("43200")) {
+               chosenInterval = AlarmManager.INTERVAL_HALF_DAY;
+        } else if (updateTimeRate.equals("86400")) {
+               chosenInterval = AlarmManager.INTERVAL_DAY;
+        }
+
+        final AlarmManager alarmMgr =
+                       (AlarmManager) this.getActivity().getApplicationContext().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(this.getActivity().getApplicationContext(), WeatherInformationBatch.class);
+        final PendingIntent alarmIntent =
+                       PendingIntent.getService(
+                                       this.getActivity().getApplicationContext(),
+                                       0,
+                                       serviceIntent,
+                                       PendingIntent.FLAG_UPDATE_CURRENT);
+        if (chosenInterval != 0) {   
+            alarmMgr.setInexactRepeating(
+                       AlarmManager.ELAPSED_REALTIME,
+                       SystemClock.elapsedRealtime(),
+                       chosenInterval,
+                       alarmIntent);
+        } else {
+               alarmMgr.cancel(alarmIntent);
+        }
+    }
 }