• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.example.notificationshowcase;
18 
19 import android.app.AlarmManager;
20 import android.app.IntentService;
21 import android.app.Notification;
22 import android.app.PendingIntent;
23 import android.content.ComponentName;
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.SharedPreferences;
28 import android.database.Cursor;
29 import android.graphics.Bitmap;
30 import android.graphics.Canvas;
31 import android.graphics.Typeface;
32 import android.graphics.drawable.BitmapDrawable;
33 import android.graphics.drawable.Drawable;
34 import android.net.Uri;
35 import android.os.SystemClock;
36 import android.provider.ContactsContract;
37 import android.support.v4.app.NotificationCompat;
38 import android.support.v4.app.NotificationManagerCompat;
39 import android.support.v7.preference.PreferenceManager;
40 import android.text.SpannableString;
41 import android.text.TextUtils;
42 import android.text.style.StyleSpan;
43 import android.util.Log;
44 
45 import com.android.example.notificationshowcase.R;
46 
47 import java.util.ArrayList;
48 
49 public class NotificationService extends IntentService {
50 
51     private static final String TAG = "NotificationService";
52 
53     public static final String ACTION_CREATE = "create";
54     public static final String ACTION_DESTROY = "destroy";
55     public static final int NOTIFICATION_ID = 31338;
56     private static final long FADE_TIME_MILLIS = 1000 * 60 * 5;
57 
NotificationService()58     public NotificationService() {
59         super(TAG);
60     }
61 
NotificationService(String name)62     public NotificationService(String name) {
63         super(name);
64     }
65 
makeCancelAllIntent(Context context)66     private static PendingIntent makeCancelAllIntent(Context context) {
67         final Intent intent = new Intent(ACTION_DESTROY);
68         intent.setComponent(new ComponentName(context, NotificationService.class));
69         return PendingIntent.getService(
70                 context, 0, intent,
71                 PendingIntent.FLAG_UPDATE_CURRENT);
72     }
73 
getBitmap(Context context, int resId)74     private static Bitmap getBitmap(Context context, int resId) {
75         int largeIconWidth = (int) context.getResources()
76                 .getDimension(R.dimen.notification_large_icon_width);
77         int largeIconHeight = (int) context.getResources()
78                 .getDimension(R.dimen.notification_large_icon_height);
79         Drawable d = context.getResources().getDrawable(resId);
80         Bitmap b = Bitmap.createBitmap(largeIconWidth, largeIconHeight, Bitmap.Config.ARGB_8888);
81         Canvas c = new Canvas(b);
82         d.setBounds(0, 0, largeIconWidth, largeIconHeight);
83         d.draw(c);
84         return b;
85     }
86 
makeEmailIntent(Context context, String who)87     private static PendingIntent makeEmailIntent(Context context, String who) {
88         final Intent intent = new Intent(android.content.Intent.ACTION_SENDTO,
89                 Uri.parse("mailto:" + who));
90         return PendingIntent.getActivity(
91                 context, 0, intent,
92                 PendingIntent.FLAG_CANCEL_CURRENT);
93     }
94 
makeSmsNotification(Context context, int update, int id, long when)95     public static Notification makeSmsNotification(Context context, int update, int id, long when) {
96         final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
97         String sender = context.getString(R.string.sms_sender);
98 
99         String personUri = null;
100         if (sharedPref.getBoolean(SettingsActivity.KEY_SMS_PERSON, false)) {
101             Cursor c = null;
102             try {
103                 String[] projection = new String[] { ContactsContract.Contacts._ID,
104                         ContactsContract.Contacts.LOOKUP_KEY };
105                 String selections = ContactsContract.Contacts.DISPLAY_NAME + " = ?";
106                 String[] selectionArgs = { sender };
107                 final ContentResolver contentResolver = context.getContentResolver();
108                 c = contentResolver.query(ContactsContract.Contacts.CONTENT_URI,
109                         projection, selections, selectionArgs, null);
110                 if (c != null && c.getCount() > 0) {
111                     c.moveToFirst();
112                     int lookupIdx = c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
113                     int idIdx = c.getColumnIndex(ContactsContract.Contacts._ID);
114                     String lookupKey = c.getString(lookupIdx);
115                     long contactId = c.getLong(idIdx);
116                     Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
117                     personUri = lookupUri.toString();
118                 }
119             } finally {
120                 if (c != null) {
121                     c.close();
122                 }
123             }
124         }
125 
126         if (update > 2) {
127             when = System.currentTimeMillis();
128         }
129         final String priorityName = sharedPref.getString(SettingsActivity.KEY_SMS_PRIORITY, "0");
130         final int priority = Integer.valueOf(priorityName);
131         NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
132         bigTextStyle.bigText(context.getString(R.string.sms_message));
133         PendingIntent ci = ToastService.getPendingIntent(context, R.string.sms_click);
134         PendingIntent ai = UpdateService.getPendingIntent(context, update + 1, id, when);
135         NotificationCompat.Builder bigText = new NotificationCompat.Builder(context)
136                 .setContentTitle(sender)
137                 .setCategory(NotificationCompat.CATEGORY_MESSAGE)
138                 .setContentIntent(ci)
139                 .setContentText(context.getString(R.string.sms_message))
140                 .setWhen(when)
141                 .setLargeIcon(getBitmap(context, R.drawable.bucket))
142                 .setPriority(priority)
143                 .addAction(R.drawable.ic_media_next, context.getString(R.string.sms_reply), ai)
144                 .setSmallIcon(R.drawable.stat_notify_talk_text)
145                 .setStyle(bigTextStyle)
146                 .setOnlyAlertOnce(sharedPref.getBoolean(SettingsActivity.KEY_SMS_ONCE, true));
147 
148         if (TextUtils.isEmpty(personUri)) {
149             Log.w(TAG, "failed to find contact for Mike Cleron");
150         } else {
151             bigText.addPerson(personUri);
152             Log.w(TAG, "Mike Cleron is " + personUri);
153         }
154 
155         int defaults = 0;
156         if(sharedPref.getBoolean(SettingsActivity.KEY_SMS_NOISY, true)) {
157             String uri = sharedPref.getString(SettingsActivity.KEY_SMS_SOUND, null);
158             if(uri == null) {
159                 defaults |= Notification.DEFAULT_SOUND;
160             } else {
161                 bigText.setSound(Uri.parse(uri));
162             }
163         }
164         if(sharedPref.getBoolean(SettingsActivity.KEY_SMS_BUZZY, false)) {
165             defaults |= Notification.DEFAULT_VIBRATE;
166         }
167         bigText.setDefaults(defaults);
168 
169         return bigText.build();
170     }
171 
makeUploadNotification(Context context, int progress, long when)172     public static Notification makeUploadNotification(Context context, int progress, long when) {
173         PendingIntent pi = ToastService.getPendingIntent(context, R.string.upload_click);
174         NotificationCompat.Builder uploadNotification = new NotificationCompat.Builder(context)
175                 .setContentTitle(context.getString(R.string.upload_title))
176                 .setContentText(context.getString(R.string.upload_text))
177                 .setCategory(NotificationCompat.CATEGORY_PROGRESS)
178                 .setPriority(NotificationCompat.PRIORITY_MIN)
179                 .setContentIntent(pi)
180                 .setWhen(when)
181                 .setSmallIcon(R.drawable.ic_menu_upload)
182                 .setProgress(100, Math.min(progress, 100), false);
183         return uploadNotification.build();
184     }
185 
186     @Override
onHandleIntent(Intent intent)187     protected void onHandleIntent(Intent intent) {
188         NotificationManagerCompat noMa = NotificationManagerCompat.from(this);
189         if (ACTION_DESTROY.equals(intent.getAction())) {
190             noMa.cancelAll();
191             return;
192         }
193 
194         SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
195         ArrayList<Notification> mNotifications = new ArrayList<Notification>();
196 
197         if(sharedPref.getBoolean(SettingsActivity.KEY_SMS_ENABLE, true)) {
198             final int id = mNotifications.size();
199             mNotifications.add(makeSmsNotification(this, 2, id, System.currentTimeMillis()));
200         }
201 
202         if(sharedPref.getBoolean(SettingsActivity.KEY_UPLOAD_ENABLE, false)) {
203             final int id = mNotifications.size();
204             final long uploadWhen = System.currentTimeMillis();
205             mNotifications.add(makeUploadNotification(this, 10, uploadWhen));
206             ProgressService.startProgressUpdater(this, id, uploadWhen, 0);
207         }
208 
209         if(sharedPref.getBoolean(SettingsActivity.KEY_PHONE_ENABLE, false)) {
210             final int id = mNotifications.size();
211             final PendingIntent fullscreen = FullScreenActivity.getPendingIntent(this, id);
212             PendingIntent ans = PhoneService.getPendingIntent(this, id,
213                     PhoneService.ACTION_ANSWER);
214             PendingIntent ign =
215                     PhoneService.getPendingIntent(this, id, PhoneService.ACTION_IGNORE);
216             NotificationCompat.Builder phoneCall = new NotificationCompat.Builder(this)
217                     .setContentTitle(getString(R.string.call_title))
218                     .setContentText(getString(R.string.call_text))
219                     .setLargeIcon(getBitmap(this, R.drawable.matias_hed))
220                     .setSmallIcon(R.drawable.stat_sys_phone_call)
221                     .setPriority(NotificationCompat.PRIORITY_MAX)
222                     .setCategory(NotificationCompat.CATEGORY_CALL)
223                     .setContentIntent(fullscreen)
224                     .addAction(R.drawable.ic_dial_action_call, getString(R.string.call_answer), ans)
225                     .addAction(R.drawable.ic_end_call, getString(R.string.call_ignore), ign)
226                     .setOngoing(true);
227 
228             if(sharedPref.getBoolean(SettingsActivity.KEY_PHONE_FULLSCREEN, false)) {
229                 phoneCall.setFullScreenIntent(fullscreen, true);
230             }
231 
232             if(sharedPref.getBoolean(SettingsActivity.KEY_PHONE_NOISY, false)) {
233                 phoneCall.setDefaults(Notification.DEFAULT_SOUND);
234             }
235 
236             if (sharedPref.getBoolean(SettingsActivity.KEY_PHONE_PERSON, false)) {
237                 phoneCall.addPerson(Uri.fromParts("tel",
238                         "1 (617) 555-1212", null)
239                         .toString());
240             }
241             mNotifications.add(phoneCall.build());
242         }
243 
244         if(sharedPref.getBoolean(SettingsActivity.KEY_TIMER_ENABLE, false)) {
245             PendingIntent pi = ToastService.getPendingIntent(this, R.string.timer_click);
246             mNotifications.add(new NotificationCompat.Builder(this)
247                     .setContentTitle(getString(R.string.timer_title))
248                     .setContentText(getString(R.string.timer_text))
249                     .setCategory(NotificationCompat.CATEGORY_PROGRESS)
250                     .setContentIntent(pi)
251                     .setSmallIcon(R.drawable.stat_notify_alarm)
252                     .setUsesChronometer(true)
253                             .build());
254         }
255 
256         if(sharedPref.getBoolean(SettingsActivity.KEY_CALENDAR_ENABLE, false)) {
257             mNotifications.add(new NotificationCompat.Builder(this)
258                     .setContentTitle(getString(R.string.calendar_title))
259                     .setContentText(getString(R.string.calendar_text))
260                     .setCategory(NotificationCompat.CATEGORY_EVENT)
261                     .setWhen(System.currentTimeMillis())
262                     .setSmallIcon(R.drawable.stat_notify_calendar)
263                     .setContentIntent(ToastService.getPendingIntent(this, R.string.calendar_click))
264                     .setContentInfo("7PM")
265                     .addAction(R.drawable.stat_notify_snooze, getString(R.string.calendar_10),
266                             ToastService.getPendingIntent(this, R.string.calendar_10_click))
267                     .addAction(R.drawable.stat_notify_snooze_longer, getString(R.string.calendar_60),
268                             ToastService.getPendingIntent(this, R.string.calendar_60_click))
269                             .addAction(R.drawable.stat_notify_email, "Email",
270                                     makeEmailIntent(this,
271                                             "gabec@example.com,mcleron@example.com,dsandler@example.com"))
272                             .build());
273         }
274 
275         if(sharedPref.getBoolean(SettingsActivity.KEY_PICTURE_ENABLE, false)) {
276             BitmapDrawable d =
277                     (BitmapDrawable) getResources().getDrawable(R.drawable.romainguy_rockaway);
278             PendingIntent ci = ToastService.getPendingIntent(this, R.string.picture_click);
279             PendingIntent ai = ToastService.getPendingIntent(this, R.string.picture_add_click);
280             mNotifications.add(new NotificationCompat.BigPictureStyle(
281                     new NotificationCompat.Builder(this)
282                             .setCategory(NotificationCompat.CATEGORY_SOCIAL)
283                             .setContentTitle(getString(R.string.picture_title))
284                             .setContentText(getString(R.string.picture_text))
285                             .setSmallIcon(R.drawable.ic_stat_gplus)
286                             .setContentIntent(ci)
287                             .setLargeIcon(getBitmap(this, R.drawable.romainguy_hed))
288                             .addAction(R.drawable.add, getString(R.string.picture_add), ai)
289                             .setSubText(getString(R.string.picture_sub_text)))
290                     .bigPicture(d.getBitmap())
291                     .build());
292         }
293 
294         if(sharedPref.getBoolean(SettingsActivity.KEY_INBOX_ENABLE, false)) {
295             PendingIntent pi = ToastService.getPendingIntent(this, R.string.email_click);
296             mNotifications.add(new NotificationCompat.InboxStyle(
297                     new NotificationCompat.Builder(this)
298                             .setContentTitle(getString(R.string.email_title))
299                             .setContentText(getString(R.string.email_text))
300                             .setSubText(getString(R.string.email_sub_text))
301                             .setCategory(NotificationCompat.CATEGORY_EMAIL)
302                             .setContentIntent(pi)
303                             .setSmallIcon(R.drawable.stat_notify_email))
304                     .setSummaryText("+21 more")
305                     .addLine(getString(R.string.email_a))
306                     .addLine(getString(R.string.email_b))
307                     .addLine(getString(R.string.email_c))
308                     .build());
309         }
310 
311         if(sharedPref.getBoolean(SettingsActivity.KEY_SOCIAL_ENABLE, false)) {
312             PendingIntent pi = ToastService.getPendingIntent(this, R.string.social_click);
313             mNotifications.add(new NotificationCompat.Builder(this)
314                     .setContentTitle(getString(R.string.social_title))
315                     .setContentText(getString(R.string.social_text))
316                     .setCategory(NotificationCompat.CATEGORY_SOCIAL)
317                     .setContentIntent(pi)
318                     .setSmallIcon(R.drawable.twitter_icon)
319                     .setNumber(15)
320                     .setPriority(NotificationCompat.PRIORITY_LOW)
321                     .build());
322         }
323 
324         for (int i=0; i<mNotifications.size(); i++) {
325             noMa.notify(NOTIFICATION_ID + i, mNotifications.get(i));
326         }
327 
328         // always cancel any previous alarm
329         PendingIntent pendingCancel = makeCancelAllIntent(this);
330         AlarmManager alMa = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
331         alMa.cancel(pendingCancel);
332         if(sharedPref.getBoolean(SettingsActivity.KEY_GLOBAL_FADE, false)) {
333             long t = SystemClock.elapsedRealtime() + FADE_TIME_MILLIS;
334             alMa.set(AlarmManager.ELAPSED_REALTIME, t, pendingCancel);
335         }
336     }
337 }
338