b926149a6136b4957e36cb9feec4c309a85299a7
[JavaForFun] /
1 package com.weather.information.notification;
2
3 import java.io.IOException;
4 import java.net.MalformedURLException;
5 import java.net.URISyntaxException;
6 import java.net.URL;
7 import java.text.DecimalFormat;
8 import java.text.NumberFormat;
9 import java.util.Locale;
10
11 import org.apache.http.client.ClientProtocolException;
12
13 import android.app.IntentService;
14 import android.app.Notification;
15 import android.app.PendingIntent;
16 import android.content.Intent;
17 import android.content.SharedPreferences;
18 import android.graphics.Bitmap;
19 import android.graphics.BitmapFactory;
20 import android.net.http.AndroidHttpClient;
21 import android.preference.PreferenceManager;
22 import android.support.v4.app.NotificationCompat;
23 import android.support.v4.app.NotificationManagerCompat;
24 import android.support.v4.app.TaskStackBuilder;
25 import android.util.Log;
26 import android.widget.RemoteViews;
27
28 import com.fasterxml.jackson.core.JsonParseException;
29 import com.weather.information.R;
30 import com.weather.information.activity.WeatherTabsActivity;
31 import com.weather.information.httpclient.CustomHTTPClient;
32 import com.weather.information.model.DatabaseQueries;
33 import com.weather.information.model.WeatherLocation;
34 import com.weather.information.model.currentweather.Current;
35 import com.weather.information.parser.JPOSWeatherParser;
36 import com.weather.information.service.IconsList;
37 import com.weather.information.service.ServiceParser;
38
39
40 public class NotificationIntentService extends IntentService {
41     private static final String TAG = "NotificationIntentService";
42
43
44     public NotificationIntentService() {
45         super("NIS-Thread");
46     }
47
48     @Override
49     protected void onHandleIntent(final Intent intent) {
50         final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
51         final WeatherLocation weatherLocation = query.queryDataBase();
52         
53         if (weatherLocation != null) {
54             final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser());
55             final CustomHTTPClient HTTPClient = new CustomHTTPClient(
56                     AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent"));
57
58             Current current = null;
59             try {
60                 current = this.doInBackgroundThrowable(weatherLocation, HTTPClient, weatherService);
61                 
62             } catch (final JsonParseException e) {
63                 Log.e(TAG, "doInBackground exception: ", e);
64             } catch (final ClientProtocolException e) {
65                 Log.e(TAG, "doInBackground exception: ", e);
66             } catch (final MalformedURLException e) {
67                 Log.e(TAG, "doInBackground exception: ", e);
68             } catch (final URISyntaxException e) {
69                 Log.e(TAG, "doInBackground exception: ", e);
70             } catch (final IOException e) {
71                 // logger infrastructure swallows UnknownHostException :/
72                 Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
73             } finally {
74                 HTTPClient.close();
75             }
76             
77             if (current != null) {
78                 this.showNotification(current, weatherLocation);
79             }
80         }
81     }
82
83     private Current doInBackgroundThrowable(final WeatherLocation weatherLocation,
84             final CustomHTTPClient HTTPClient, final ServiceParser weatherService)
85                     throws ClientProtocolException, MalformedURLException, URISyntaxException,
86                     JsonParseException, IOException {
87
88         final String APIVersion = this.getResources().getString(R.string.api_version);
89
90         final String urlAPI = this.getResources().getString(R.string.uri_api_weather_today);
91         final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
92                 weatherLocation.getLatitude(), weatherLocation.getLongitude());
93         final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
94         final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
95
96         return weatherService.retrieveCurrentFromJPOS(jsonData);
97     }
98     
99     private interface UnitsConversor {
100         
101         public double doConversion(final double value);
102     }
103     
104     private void showNotification(final Current current, final WeatherLocation weatherLocation) {
105         final SharedPreferences sharedPreferences = PreferenceManager
106                 .getDefaultSharedPreferences(this.getApplicationContext());
107
108                 // TODO: repeating the same code in Overview, Specific and Current!!!
109                 // 1. Update units of measurement.
110         // 1.1 Temperature
111         String tempSymbol;
112         UnitsConversor tempUnitsConversor;
113         final String keyPreference = this.getApplicationContext().getString(R.string.weather_preferences_notifications_temperature_key);
114         final String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
115         final String unitsPreferenceValue = sharedPreferences.getString(
116                 keyPreference, this.getString(R.string.weather_preferences_temperature_celsius));
117         if (unitsPreferenceValue.equals(values[0])) {
118                 tempSymbol = values[0];
119                 tempUnitsConversor = new UnitsConversor(){
120
121                                 @Override
122                                 public double doConversion(final double value) {
123                                         return value - 273.15;
124                                 }
125
126                 };
127         } else if (unitsPreferenceValue.equals(values[1])) {
128                 tempSymbol = values[1];
129                 tempUnitsConversor = new UnitsConversor(){
130
131                                 @Override
132                                 public double doConversion(final double value) {
133                                         return (value * 1.8) - 459.67;
134                                 }
135                         
136                 };
137         } else {
138                 tempSymbol = values[2];
139                 tempUnitsConversor = new UnitsConversor(){
140
141                                 @Override
142                                 public double doConversion(final double value) {
143                                         return value;
144                                 }
145                         
146                 };
147         }
148
149
150         // 2. Formatters
151         final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
152         tempFormatter.applyPattern("#####.#####");
153
154
155         // 3. Prepare data for RemoteViews.
156         String tempMax = "";
157         if (current.getMain().getTemp_max() != null) {
158             double conversion = (Double) current.getMain().getTemp_max();
159             conversion = tempUnitsConversor.doConversion(conversion);
160             tempMax = tempFormatter.format(conversion) + tempSymbol;
161         }
162         String tempMin = "";
163         if (current.getMain().getTemp_min() != null) {
164             double conversion = (Double) current.getMain().getTemp_min();
165             conversion = tempUnitsConversor.doConversion(conversion);
166             tempMin = tempFormatter.format(conversion) + tempSymbol;
167         }
168         Bitmap picture;
169         if ((current.getWeather().size() > 0)
170                 && (current.getWeather().get(0).getIcon() != null)
171                 && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) {
172             final String icon = current.getWeather().get(0).getIcon();
173             picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
174                     .getResourceDrawable());
175         } else {
176             picture = BitmapFactory.decodeResource(this.getResources(),
177                     R.drawable.weather_severe_alert);
178         }
179         final String city = weatherLocation.getCity();
180         final String country = weatherLocation.getCountry();
181         
182         // 4. Insert data in RemoteViews.
183         final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.notification);
184         remoteView.setImageViewBitmap(R.id.weather_notification_image, picture);
185         remoteView.setTextViewText(R.id.weather_notification_temperature_max, tempMax);
186         remoteView.setTextViewText(R.id.weather_notification_temperature_min, tempMin);
187         remoteView.setTextViewText(R.id.weather_notification_city, city);
188         remoteView.setTextViewText(R.id.weather_notification_country, country);
189
190         // 5. Activity launcher.
191         final Intent resultIntent =  new Intent(this.getApplicationContext(), WeatherTabsActivity.class);
192         // The PendingIntent to launch our activity if the user selects this notification
193 //        final PendingIntent contentIntent = PendingIntent.getActivity(
194 //                      this.getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
195         // The stack builder object will contain an artificial back stack for the started Activity.
196         // This ensures that navigating backward from the Activity leads out of
197         // your application to the Home screen.
198         final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext());
199         // Adds the back stack for the Intent (but not the Intent itself)
200         stackBuilder.addParentStack(WeatherTabsActivity.class);
201         // Adds the Intent that starts the Activity to the top of the stack
202         stackBuilder.addNextIntent(resultIntent);
203         final PendingIntent resultPendingIntent =
204                         stackBuilder.getPendingIntent(
205                     0,
206                     PendingIntent.FLAG_UPDATE_CURRENT
207                 );
208         
209         final NotificationManagerCompat notificationManager =
210                         NotificationManagerCompat.from(this.getApplicationContext());
211         
212
213         // 6. Create notification.
214         final NotificationCompat.Builder notificationBuilder =
215                         new NotificationCompat.Builder(this.getApplicationContext())
216                         .setContent(remoteView)
217                 .setSmallIcon(R.drawable.ic_launcher)
218                 .setAutoCancel(true)
219                 .setLocalOnly(true)
220                 .setWhen(System.currentTimeMillis())
221                 .setContentIntent(resultPendingIntent)
222                 .setPriority(NotificationCompat.PRIORITY_DEFAULT);
223         
224         final Notification notification = notificationBuilder.build();
225         notification.flags |= Notification.FLAG_AUTO_CANCEL;
226
227         // Send the notification.
228         // Sets an ID for the notification, so it can be updated (just in case)
229         int notifyID = 1;
230         notificationManager.notify(notifyID, notification);
231     }
232 }