1 package name.gumartinm.weather.information.notification;
3 import java.io.IOException;
4 import java.net.MalformedURLException;
5 import java.net.URISyntaxException;
7 import java.text.DecimalFormat;
8 import java.text.NumberFormat;
9 import java.util.Locale;
11 import org.apache.http.client.ClientProtocolException;
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;
28 import com.fasterxml.jackson.core.JsonParseException;
29 import name.gumartinm.weather.information.R;
30 import name.gumartinm.weather.information.activity.WeatherTabsActivity;
31 import name.gumartinm.weather.information.httpclient.CustomHTTPClient;
32 import name.gumartinm.weather.information.model.DatabaseQueries;
33 import name.gumartinm.weather.information.model.WeatherLocation;
34 import name.gumartinm.weather.information.model.currentweather.Current;
35 import name.gumartinm.weather.information.parser.JPOSCurrentParser;
36 import name.gumartinm.weather.information.service.IconsList;
37 import name.gumartinm.weather.information.service.ServiceCurrentParser;
40 public class NotificationIntentService extends IntentService {
41 private static final String TAG = "NotificationIntentService";
44 public NotificationIntentService() {
49 protected void onHandleIntent(final Intent intent) {
50 final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
51 final WeatherLocation weatherLocation = query.queryDataBase();
53 if (weatherLocation != null) {
54 final ServiceCurrentParser weatherService = new ServiceCurrentParser(new JPOSCurrentParser());
55 final CustomHTTPClient HTTPClient = new CustomHTTPClient(
56 AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent"));
58 Current current = null;
60 current = this.doInBackgroundThrowable(weatherLocation, HTTPClient, weatherService);
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);
77 if (current != null) {
78 this.showNotification(current, weatherLocation);
83 private Current doInBackgroundThrowable(final WeatherLocation weatherLocation,
84 final CustomHTTPClient HTTPClient, final ServiceCurrentParser weatherService)
85 throws ClientProtocolException, MalformedURLException, URISyntaxException,
86 JsonParseException, IOException {
88 final String APIVersion = this.getResources().getString(R.string.api_version);
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));
96 return weatherService.retrieveCurrentFromJPOS(jsonData);
99 private interface UnitsConversor {
101 public double doConversion(final double value);
104 private void showNotification(final Current current, final WeatherLocation weatherLocation) {
105 final SharedPreferences sharedPreferences = PreferenceManager
106 .getDefaultSharedPreferences(this.getApplicationContext());
108 // TODO: repeating the same code in Overview, Specific and Current!!!
109 // 1. Update units of measurement.
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(){
122 public double doConversion(final double value) {
123 return value - 273.15;
127 } else if (unitsPreferenceValue.equals(values[1])) {
128 tempSymbol = values[1];
129 tempUnitsConversor = new UnitsConversor(){
132 public double doConversion(final double value) {
133 return (value * 1.8) - 459.67;
138 tempSymbol = values[2];
139 tempUnitsConversor = new UnitsConversor(){
142 public double doConversion(final double value) {
151 final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
152 tempFormatter.applyPattern("#####.#####");
155 // 3. Prepare data for RemoteViews.
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;
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;
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());
176 picture = BitmapFactory.decodeResource(this.getResources(),
177 R.drawable.weather_severe_alert);
179 final String city = weatherLocation.getCity();
180 final String country = weatherLocation.getCountry();
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);
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(
206 PendingIntent.FLAG_UPDATE_CURRENT
209 final NotificationManagerCompat notificationManager =
210 NotificationManagerCompat.from(this.getApplicationContext());
213 // 6. Create notification.
214 final NotificationCompat.Builder notificationBuilder =
215 new NotificationCompat.Builder(this.getApplicationContext())
216 .setContent(remoteView)
217 .setSmallIcon(R.drawable.ic_launcher)
220 .setWhen(System.currentTimeMillis())
221 .setContentIntent(resultPendingIntent)
222 .setPriority(NotificationCompat.PRIORITY_DEFAULT);
224 final Notification notification = notificationBuilder.build();
225 notification.flags |= Notification.FLAG_AUTO_CANCEL;
227 // Send the notification.
228 // Sets an ID for the notification, so it can be updated (just in case)
230 notificationManager.notify(notifyID, notification);