diff options
Diffstat (limited to 'NotificationShowcase/src/com/android')
7 files changed, 651 insertions, 356 deletions
diff --git a/NotificationShowcase/src/com/android/example/notificationshowcase/FullScreenActivity.java b/NotificationShowcase/src/com/android/example/notificationshowcase/FullScreenActivity.java new file mode 100644 index 0000000..8286f69 --- /dev/null +++ b/NotificationShowcase/src/com/android/example/notificationshowcase/FullScreenActivity.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.notificationshowcase; + +import android.app.Activity; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + +public class FullScreenActivity extends Activity { + private static final String TAG = "NotificationShowcase"; + + public static final String EXTRA_ID = "id"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.full_screen); + final Intent intent = getIntent(); + if (intent != null && intent.hasExtra(EXTRA_ID)) { + final int id = intent.getIntExtra(EXTRA_ID, -1); + if (id >= 0) { + NotificationManager noMa = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + noMa.cancel(NotificationService.NOTIFICATION_ID + id); + } + } + } + + public void dismiss(View v) { + finish(); + } + + public static PendingIntent getPendingIntent(Context context, int id) { + Intent fullScreenIntent = new Intent(context, FullScreenActivity.class); + fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + fullScreenIntent.putExtra(EXTRA_ID, id); + PendingIntent pi = PendingIntent.getActivity( + context, 22, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT); + return pi; + } +} diff --git a/NotificationShowcase/src/com/android/example/notificationshowcase/NotificationService.java b/NotificationShowcase/src/com/android/example/notificationshowcase/NotificationService.java new file mode 100644 index 0000000..0b83fa0 --- /dev/null +++ b/NotificationShowcase/src/com/android/example/notificationshowcase/NotificationService.java @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.notificationshowcase; + +import android.app.IntentService; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Typeface; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.provider.ContactsContract; +import android.support.v4.app.NotificationCompat; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.style.StyleSpan; +import android.util.Log; +import android.view.View; + +import java.util.ArrayList; + +public class NotificationService extends IntentService { + + private static final String TAG = "NotificationService"; + + public static final String ACTION_CREATE = "create"; + public static final int NOTIFICATION_ID = 31338; + + public NotificationService() { + super(TAG); + } + + public NotificationService(String name) { + super(name); + } + + private static Bitmap getBitmap(Context context, int resId) { + int largeIconWidth = (int) context.getResources() + .getDimension(R.dimen.notification_large_icon_width); + int largeIconHeight = (int) context.getResources() + .getDimension(R.dimen.notification_large_icon_height); + Drawable d = context.getResources().getDrawable(resId); + Bitmap b = Bitmap.createBitmap(largeIconWidth, largeIconHeight, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(b); + d.setBounds(0, 0, largeIconWidth, largeIconHeight); + d.draw(c); + return b; + } + + private static PendingIntent makeEmailIntent(Context context, String who) { + final Intent intent = new Intent(android.content.Intent.ACTION_SENDTO, + Uri.parse("mailto:" + who)); + return PendingIntent.getActivity( + context, 0, intent, + PendingIntent.FLAG_CANCEL_CURRENT); + } + + public static Notification makeBigTextNotification(Context context, int update, int id, + long when) { + String personUri = null; + Cursor c = null; + try { + String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY }; + String selections = ContactsContract.Contacts.DISPLAY_NAME + " = 'Mike Cleron'"; + final ContentResolver contentResolver = context.getContentResolver(); + c = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, + projection, selections, null, null); + if (c != null && c.getCount() > 0) { + c.moveToFirst(); + int lookupIdx = c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY); + int idIdx = c.getColumnIndex(ContactsContract.Contacts._ID); + String lookupKey = c.getString(lookupIdx); + long contactId = c.getLong(idIdx); + Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey); + personUri = lookupUri.toString(); + } + } finally { + if (c != null) { + c.close(); + } + } + if (TextUtils.isEmpty(personUri)) { + Log.w(TAG, "failed to find contact for Mike Cleron"); + } else { + Log.w(TAG, "Mike Cleron is " + personUri); + } + + String addendum = update > 0 ? "(updated) " : ""; + String longSmsText = "Hey, looks like\nI'm getting kicked out of this conference" + + " room"; + if (update > 1) { + longSmsText += ", so stay in the hangout and I'll rejoin in about 5-10 minutes" + + ". If you don't see me, assume I got pulled into another meeting. And" + + " now \u2026 I have to find my shoes."; + } + if (update > 2) { + when = System.currentTimeMillis(); + } + NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle(); + bigTextStyle.bigText(addendum + longSmsText); + Notification bigText = new NotificationCompat.Builder(context) + .setContentTitle(addendum + "Mike Cleron") + .setContentIntent(ToastService.getPendingIntent(context, "Clicked on bigText")) + .setContentText(addendum + longSmsText) + .setTicker(addendum + "Mike Cleron: " + longSmsText) + .setWhen(when) + .setLargeIcon(getBitmap(context, R.drawable.bucket)) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .addAction(R.drawable.ic_media_next, + "update: " + update, + UpdateService.getPendingIntent(context, update + 1, id, when)) + .setSmallIcon(R.drawable.stat_notify_talk_text) + .setStyle(bigTextStyle) + .setDefaults(Notification.DEFAULT_SOUND) + .addPerson(personUri) + .build(); + return bigText; + } + + public static Notification makeUploadNotification(Context context, int progress, long when) { + NotificationCompat.Builder uploadNotification = new NotificationCompat.Builder(context) + .setContentTitle("File Upload") + .setContentText("foo.txt") + .setPriority(NotificationCompat.PRIORITY_MIN) + .setContentIntent(ToastService.getPendingIntent(context, "Clicked on Upload")) + .setWhen(when) + .setSmallIcon(R.drawable.ic_menu_upload) + .setProgress(100, Math.min(progress, 100), false); + return uploadNotification.build(); + } + + @Override + protected void onHandleIntent(Intent intent) { + ArrayList<Notification> mNotifications = new ArrayList<Notification>(); + NotificationManager noMa = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + + int bigtextId = mNotifications.size(); + mNotifications.add(makeBigTextNotification(this, 0, bigtextId, System.currentTimeMillis())); + + int uploadId = mNotifications.size(); + long uploadWhen = System.currentTimeMillis(); + mNotifications.add(makeUploadNotification(this, 10, uploadWhen)); + + int phoneId = mNotifications.size(); + final PendingIntent fullscreenIntent = FullScreenActivity.getPendingIntent(this, phoneId); + Notification phoneCall = new NotificationCompat.Builder(this) + .setContentTitle("Incoming call") + .setContentText("Matias Duarte") + .setLargeIcon(getBitmap(this, R.drawable.matias_hed)) + .setSmallIcon(R.drawable.stat_sys_phone_call) + .setPriority(NotificationCompat.PRIORITY_MAX) + .setContentIntent(fullscreenIntent) + .setFullScreenIntent(fullscreenIntent, true) + .addAction(R.drawable.ic_dial_action_call, "Answer", + PhoneService.getPendingIntent(this, phoneId, PhoneService.ACTION_ANSWER)) + .addAction(R.drawable.ic_end_call, "Ignore", + PhoneService.getPendingIntent(this, phoneId, PhoneService.ACTION_IGNORE)) + .setOngoing(true) + .addPerson(Uri.fromParts("tel", "1 (617) 555-1212", null).toString()) + .build(); + mNotifications.add(phoneCall); + + mNotifications.add(new NotificationCompat.Builder(this) + .setContentTitle("Stopwatch PRO") + .setContentText("Counting up") + .setContentIntent(ToastService.getPendingIntent(this, "Clicked on Stopwatch")) + .setSmallIcon(R.drawable.stat_notify_alarm) + .setUsesChronometer(true) + .build()); + + mNotifications.add(new NotificationCompat.Builder(this) + .setContentTitle("J Planning") + .setContentText("The Botcave") + .setWhen(System.currentTimeMillis()) + .setSmallIcon(R.drawable.stat_notify_calendar) + .setContentIntent(ToastService.getPendingIntent(this, "Clicked on calendar event")) + .setContentInfo("7PM") + .addAction(R.drawable.stat_notify_snooze, "+10 min", + ToastService.getPendingIntent(this, "snoozed 10 min")) + .addAction(R.drawable.stat_notify_snooze_longer, "+1 hour", + ToastService.getPendingIntent(this, "snoozed 1 hr")) + .addAction(R.drawable.stat_notify_email, "Email", + makeEmailIntent(this, + "gabec@example.com,mcleron@example.com,dsandler@example.com")) + .build()); + + BitmapDrawable d = + (BitmapDrawable) getResources().getDrawable(R.drawable.romainguy_rockaway); + mNotifications.add(new NotificationCompat.BigPictureStyle( + new NotificationCompat.Builder(this) + .setContentTitle("Romain Guy") + .setContentText("I was lucky to find a Canon 5D Mk III at a local Bay Area " + + "store last week but I had not been able to try it in the field " + + "until tonight. After a few days of rain the sky finally cleared " + + "up. Rockaway Beach did not disappoint and I was finally able to " + + "see what my new camera feels like when shooting landscapes.") + .setSmallIcon(R.drawable.ic_stat_gplus) + .setContentIntent( + ToastService.getPendingIntent(this, "Clicked on bigPicture")) + .setLargeIcon(getBitmap(this, R.drawable.romainguy_hed)) + .addAction(R.drawable.add, "Add to Gallery", + ToastService.getPendingIntent(this, "added! (just kidding)")) + .setSubText("talk rocks!")) + .bigPicture(d.getBitmap()) + .build()); + + // Note: this may conflict with real email notifications + StyleSpan bold = new StyleSpan(Typeface.BOLD); + SpannableString line1 = new SpannableString("Alice: hey there!"); + line1.setSpan(bold, 0, 5, 0); + SpannableString line2 = new SpannableString("Bob: hi there!"); + line2.setSpan(bold, 0, 3, 0); + SpannableString line3 = new SpannableString("Charlie: Iz IN UR EMAILZ!!"); + line3.setSpan(bold, 0, 7, 0); + mNotifications.add(new NotificationCompat.InboxStyle( + new NotificationCompat.Builder(this) + .setContentTitle("24 new messages") + .setContentText("You have mail!") + .setSubText("test.hugo2@gmail.com") + .setContentIntent(ToastService.getPendingIntent(this, "Clicked on Email")) + .setSmallIcon(R.drawable.stat_notify_email)) + .setSummaryText("+21 more") + .addLine(line1) + .addLine(line2) + .addLine(line3) + .build()); + + mNotifications.add(new NotificationCompat.Builder(this) + .setContentTitle("Twitter") + .setContentText("New mentions") + .setContentIntent(ToastService.getPendingIntent(this, "Clicked on Twitter")) + .setSmallIcon(R.drawable.twitter_icon) + .setNumber(15) + .setPriority(NotificationCompat.PRIORITY_LOW) + .build()); + + + for (int i=0; i<mNotifications.size(); i++) { + noMa.notify(NOTIFICATION_ID + i, mNotifications.get(i)); + } + + ProgressService.startProgressUpdater(this, uploadId, uploadWhen, 0); + } +} diff --git a/NotificationShowcase/src/com/android/example/notificationshowcase/NotificationShowcaseActivity.java b/NotificationShowcase/src/com/android/example/notificationshowcase/NotificationShowcaseActivity.java index ee060ce..1e0fa20 100644 --- a/NotificationShowcase/src/com/android/example/notificationshowcase/NotificationShowcaseActivity.java +++ b/NotificationShowcase/src/com/android/example/notificationshowcase/NotificationShowcaseActivity.java @@ -3,372 +3,20 @@ package com.android.example.notificationshowcase; -import java.util.ArrayList; import android.app.Activity; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Typeface; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Binder; import android.os.Bundle; -import android.os.IBinder; -import android.support.v4.app.NotificationCompat; -import android.text.SpannableString; -import android.text.style.StyleSpan; -import android.util.Log; -import android.view.View; -import android.widget.Toast; public class NotificationShowcaseActivity extends Activity { private static final String TAG = "NotificationShowcase"; - - private static final int NOTIFICATION_ID = 31338; - - private static int bigtextId; - private static int uploadId; - - private static final boolean FIRE_AND_FORGET = true; - - public static class ToastFeedbackActivity extends Activity { - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - } - - @Override - public void onResume() { - super.onResume(); - Intent i = getIntent(); - Log.v(TAG, "clicked a thing! intent=" + i.toString()); - if (i.hasExtra("text")) { - final String text = i.getStringExtra("text"); - Toast.makeText(this, text, Toast.LENGTH_LONG).show(); - } - finish(); - } - } - - public static class UpdateService extends Service { - @Override - public IBinder onBind(Intent intent) { - Log.v(TAG, "onbind"); - return null; - } - - @Override - public void onStart(Intent i, int startId) { - super.onStart(i, startId); - try { - // allow the user close the shade, if they want to test that. - Thread.sleep(3000); - } catch (Exception e) { - } - Log.v(TAG, "clicked a thing! intent=" + i.toString()); - if (i.hasExtra("id") && i.hasExtra("when")) { - final int id = i.getIntExtra("id", 0); - if (id == bigtextId) { - NotificationManager noMa = - (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - final int update = i.getIntExtra("update", 0); - final long when = i.getLongExtra("when", 0L); - Log.v(TAG, "id: " + id + " when: " + when + " update: " + update); - noMa.notify(NOTIFICATION_ID + id, - makeBigTextNotification(this, update, id, when)); - } - } else { - Log.v(TAG, "id extra was " + (i.hasExtra("id") ? "present" : "missing")); - Log.v(TAG, "when extra was " + (i.hasExtra("when") ? "present" : "missing")); - } - } - } - - public static class ProgressService extends Service { - @Override - public IBinder onBind(Intent intent) { - Log.v(TAG, "onbind"); - return null; - } - - @Override - public void onStart(Intent i, int startId) { - super.onStart(i, startId); - if (i.hasExtra("id") && i.hasExtra("when") && i.hasExtra("progress")) { - final int id = i.getIntExtra("id", 0); - if (id == uploadId) { - final long when = i.getLongExtra("when", 0L); - int progress = i.getIntExtra("progress", 0); - NotificationManager noMa = (NotificationManager) - getSystemService(Context.NOTIFICATION_SERVICE); - while (progress <= 100) { - try { - // allow the user close the shade, if they want to test that. - Thread.sleep(1000); - } catch (Exception e) { - } - Log.v(TAG, "id: " + id + " when: " + when + " progress: " + progress); - noMa.notify(NOTIFICATION_ID + id, - makeUploadNotification(this, progress, id, when)); - progress+=10; - } - } - } else { - Log.v(TAG, "id extra " + (i.hasExtra("id") ? "present" : "missing")); - Log.v(TAG, "when extra " + (i.hasExtra("when") ? "present" : "missing")); - Log.v(TAG, "progress extra " + (i.hasExtra("progress") ? "present" : "missing")); - } - } - } - - private ArrayList<Notification> mNotifications = new ArrayList<Notification>(); - NotificationManager mNoMa; - - static int mLargeIconWidth, mLargeIconHeight; - private static Bitmap getBitmap(Context context, int resId) { - Drawable d = context.getResources().getDrawable(resId); - Bitmap b = Bitmap.createBitmap(mLargeIconWidth, mLargeIconHeight, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(b); - d.setBounds(0, 0, mLargeIconWidth, mLargeIconHeight); - d.draw(c); - return b; - } - - private static PendingIntent makeToastIntent(Context context, String s) { - Intent toastIntent = new Intent(context, ToastFeedbackActivity.class); - toastIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - toastIntent.putExtra("text", s); - PendingIntent pi = PendingIntent.getActivity( - context, 58, toastIntent, PendingIntent.FLAG_CANCEL_CURRENT); - return pi; - } - - private static PendingIntent makeEmailIntent(Context context, String who) { - final Intent intent = new Intent(android.content.Intent.ACTION_SENDTO, - Uri.parse("mailto:" + who)); - return PendingIntent.getActivity( - context, 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT); - } - - // this is a service, it will only close the notification shade if used as a contentIntent. - private static int updateId = 3000; - private static PendingIntent makeUpdateIntent(Context context, int update, int id, long when) { - Intent updateIntent = new Intent(); - updateIntent.setComponent( - new ComponentName(context, UpdateService.class)); - updateIntent.putExtra("id", id); - updateIntent.putExtra("when", when); - updateIntent.putExtra("update", update); - Log.v(TAG, "added id extra " + id); - Log.v(TAG, "added when extra " + when); - PendingIntent pi = PendingIntent.getService( - context, updateId++, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT); - return pi; - } - - private static Notification makeBigTextNotification(Context context, int update, int id, - long when) { - String addendum = update > 0 ? "(updated) " : ""; - String longSmsText = "Hey, looks like\nI'm getting kicked out of this conference" + - " room"; - if (update > 1) { - longSmsText += ", so stay in the hangout and I'll rejoin in about 5-10 minutes" + - ". If you don't see me, assume I got pulled into another meeting. And" + - " now \u2026 I have to find my shoes. Four score and seven years "+ - "ago our fathers brought forth on this continent, a new nation, conceived "+ - "in Liberty, and dedicated to the proposition that all men are created "+ - "equal. Now we are engaged in a great civil war, testing whether that "+ - "nation, or any nation so conceived and so dedicated, can long "+ - "endure. We are met on a great battle-field of that war. We have come "+ - "to dedicate a portion of that field, as a final resting place for "+ - "those who here gave their lives that that nation might live. It is "+ - "altogether fitting and proper that we should do this.But, in a larger "+ - "sense, we can not dedicate -- we can not consecrate -- we can not "+ - "hallow -- this ground.The brave men, living and dead, who struggled "+ - "here, have consecrated it, far above our poor power to add or detract."+ - " The world will little note, nor long remember what we say here, but "+ - "it can never forget what they did here. It is for us the living, rather,"+ - " to be dedicated here to the unfinished work which they who fought "+ - "here have thus far so nobly advanced.It is rather for us to be here "+ - "dedicated to the great task remaining before us -- that from these "+ - "honored dead we take increased devotion to that cause for which they "+ - "gave the last full measure of devotion -- that we here highly resolve "+ - "that these dead shall not have died in vain -- that this nation, under "+ - "God, shall have a new birth of freedom -- and that government of "+ - "the people, by the people, for the people, shall not perish from the earth."; - } - if (update > 2) { - when = System.currentTimeMillis(); - } - NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle(); - bigTextStyle.bigText(addendum + longSmsText); - NotificationCompat.Builder bigTextNotification = new NotificationCompat.Builder(context) - .setContentTitle(addendum + "Mike Cleron") - .setContentIntent(makeToastIntent(context, "Clicked on bigText")) - .setContentText(addendum + longSmsText) - .setTicker(addendum + "Mike Cleron: " + longSmsText) - .setWhen(when) - .setLargeIcon(getBitmap(context, R.drawable.bucket)) - .setPriority(NotificationCompat.PRIORITY_HIGH) - .addAction(R.drawable.ic_media_next, - "update: " + update, - makeUpdateIntent(context, update+1, id, when)) - .setSmallIcon(R.drawable.stat_notify_talk_text) - .setStyle(bigTextStyle); - return bigTextNotification.build(); - } - - // this is a service, it will only close the notification shade if used as a contentIntent. - private static void startProgressUpdater(Context context, int progress, int id, long when) { - Intent progressIntent = new Intent(); - progressIntent.setComponent(new ComponentName(context, ProgressService.class)); - progressIntent.putExtra("id", id); - progressIntent.putExtra("when", when); - progressIntent.putExtra("progress", progress); - context.startService(progressIntent); - } - - private static Notification makeUploadNotification(Context context, int progress, int id, - long when) { - NotificationCompat.Builder uploadNotification = new NotificationCompat.Builder(context) - .setContentTitle("File Upload") - .setContentText("foo.txt") - .setPriority(NotificationCompat.PRIORITY_MIN) - .setContentIntent(makeToastIntent(context, "Clicked on Upload")) - .setWhen(when) - .setSmallIcon(R.drawable.ic_menu_upload) - .setProgress(100, Math.min(progress, 100), false); - return uploadNotification.build(); - } - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); - - mLargeIconWidth = (int) getResources().getDimension(R.dimen.notification_large_icon_width); - mLargeIconHeight = (int) getResources().getDimension(R.dimen.notification_large_icon_height); - - mNoMa = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - - bigtextId = mNotifications.size(); - mNotifications.add(makeBigTextNotification(this, 0, bigtextId, - System.currentTimeMillis())); - - uploadId = mNotifications.size(); - long uploadWhen = System.currentTimeMillis(); - mNotifications.add(makeUploadNotification(this, 10, uploadId, uploadWhen)); - - mNotifications.add(new NotificationCompat.Builder(this) - .setContentTitle("Incoming call") - .setContentText("Matias Duarte") - .setLargeIcon(getBitmap(this, R.drawable.matias_hed)) - .setSmallIcon(R.drawable.stat_sys_phone_call) - .setPriority(NotificationCompat.PRIORITY_MAX) - .setContentIntent(makeToastIntent(this, "Clicked on Matias")) - .addAction(R.drawable.ic_dial_action_call, "Answer", makeToastIntent(this, "call answered")) - .addAction(R.drawable.ic_end_call, "Ignore", makeToastIntent(this, "call ignored")) - .setAutoCancel(true) - .build()); - - mNotifications.add(new NotificationCompat.Builder(this) - .setContentTitle("Stopwatch PRO") - .setContentText("Counting up") - .setContentIntent(makeToastIntent(this, "Clicked on Stopwatch")) - .setSmallIcon(R.drawable.stat_notify_alarm) - .setUsesChronometer(true) - .build()); - - mNotifications.add(new NotificationCompat.Builder(this) - .setContentTitle("J Planning") - .setContentText("The Botcave") - .setWhen(System.currentTimeMillis()) - .setSmallIcon(R.drawable.stat_notify_calendar) - .setContentIntent(makeToastIntent(this, "tapped in the calendar event")) - .setContentInfo("7PM") - .addAction(R.drawable.stat_notify_snooze, "+10 min", - makeToastIntent(this, "snoozed 10 min")) - .addAction(R.drawable.stat_notify_snooze_longer, "+1 hour", - makeToastIntent(this, "snoozed 1 hr")) - .addAction(R.drawable.stat_notify_email, "Email", - makeEmailIntent(this, - "gabec@example.com,mcleron@example.com,dsandler@example.com")) - .build()); - - BitmapDrawable d = - (BitmapDrawable) getResources().getDrawable(R.drawable.romainguy_rockaway); - mNotifications.add(new NotificationCompat.BigPictureStyle( - new NotificationCompat.Builder(this) - .setContentTitle("Romain Guy") - .setContentText("I was lucky to find a Canon 5D Mk III at a local Bay Area store last " - + "week but I had not been able to try it in the field until tonight. After a " - + "few days of rain the sky finally cleared up. Rockaway Beach did not disappoint " - + "and I was finally able to see what my new camera feels like when shooting " - + "landscapes.") - .setSmallIcon(R.drawable.ic_stat_gplus) - .setContentIntent(makeToastIntent(this, "Clicked on bigPicture")) - .setLargeIcon(getBitmap(this, R.drawable.romainguy_hed)) - .addAction(R.drawable.add, "Add to Gallery", - makeToastIntent(this, "added! (just kidding)")) - .setSubText("talk rocks!") - ) - .bigPicture(d.getBitmap()) - .build()); - - // Note: this may conflict with real email notifications - StyleSpan bold = new StyleSpan(Typeface.BOLD); - SpannableString line1 = new SpannableString("Alice: hey there!"); - line1.setSpan(bold, 0, 5, 0); - SpannableString line2 = new SpannableString("Bob: hi there!"); - line2.setSpan(bold, 0, 3, 0); - SpannableString line3 = new SpannableString("Charlie: Iz IN UR EMAILZ!!"); - line3.setSpan(bold, 0, 7, 0); - mNotifications.add(new NotificationCompat.InboxStyle( - new NotificationCompat.Builder(this) - .setContentTitle("24 new messages") - .setContentText("You have mail!") - .setSubText("test.hugo2@gmail.com") - .setContentIntent(makeToastIntent(this, "Clicked on Email")) - .setSmallIcon(R.drawable.stat_notify_email)) - .setSummaryText("+21 more") - .addLine(line1) - .addLine(line2) - .addLine(line3) - .build()); - - mNotifications.add(new NotificationCompat.Builder(this) - .setContentTitle("Twitter") - .setContentText("New mentions") - .setContentIntent(makeToastIntent(this, "Clicked on Twitter")) - .setSmallIcon(R.drawable.twitter_icon) - .setNumber(15) - .setPriority(NotificationCompat.PRIORITY_LOW) - .build()); - - if (FIRE_AND_FORGET) { - doPost(null); - startProgressUpdater(this, 10, uploadId, uploadWhen); - finish(); - } - } - - public void doPost(View v) { - for (int i=0; i<mNotifications.size(); i++) { - mNoMa.notify(NOTIFICATION_ID + i, mNotifications.get(i)); - } - } - - public void doRemove(View v) { - for (int i=0; i<mNotifications.size(); i++) { - mNoMa.cancel(NOTIFICATION_ID + i); - } + Intent intent = new Intent(NotificationService.ACTION_CREATE); + intent.setComponent(new ComponentName(this, NotificationService.class)); + startService(intent); + finish(); } } diff --git a/NotificationShowcase/src/com/android/example/notificationshowcase/PhoneService.java b/NotificationShowcase/src/com/android/example/notificationshowcase/PhoneService.java new file mode 100644 index 0000000..0b4f3bd --- /dev/null +++ b/NotificationShowcase/src/com/android/example/notificationshowcase/PhoneService.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.notificationshowcase; + +import android.app.IntentService; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.util.Log; +import android.widget.Toast; + +public class PhoneService extends IntentService { + + private static final String TAG = "PhoneService"; + + public static final String ACTION_ANSWER = "answer"; + public static final String ACTION_IGNORE = "ignore"; + + public static final String EXTRA_ID = "id"; + + private Handler handler; + + public PhoneService() { + super(TAG); + } + public PhoneService(String name) { + super(name); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + handler = new Handler(); + return super.onStartCommand(intent, flags, startId); + } + + @Override + protected void onHandleIntent(Intent intent) { + Log.v(TAG, "clicked a thing! intent=" + intent.toString()); + int res = ACTION_ANSWER.equals(intent.getAction()) ? R.string.answered : R.string.ignored; + final String text = getString(res); + final int id = intent.getIntExtra(EXTRA_ID, -1); + handler.post(new Runnable() { + @Override + public void run() { + Toast.makeText(PhoneService.this, text, Toast.LENGTH_LONG).show(); + if (id >= 0) { + NotificationManager noMa = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + noMa.cancel(NotificationService.NOTIFICATION_ID + id); + } + Log.v(TAG, "phone toast " + text); + } + }); + } + + public static PendingIntent getPendingIntent(Context context, int id, String action) { + Intent phoneIntent = new Intent(context, PhoneService.class); + phoneIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + phoneIntent.setAction(action); + phoneIntent.putExtra(EXTRA_ID, id); + PendingIntent pi = PendingIntent.getService( + context, 58, phoneIntent, PendingIntent.FLAG_UPDATE_CURRENT); + return pi; + } +} diff --git a/NotificationShowcase/src/com/android/example/notificationshowcase/ProgressService.java b/NotificationShowcase/src/com/android/example/notificationshowcase/ProgressService.java new file mode 100644 index 0000000..799708d --- /dev/null +++ b/NotificationShowcase/src/com/android/example/notificationshowcase/ProgressService.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.notificationshowcase; + +import android.app.IntentService; +import android.app.NotificationManager; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.util.Log; + +public class ProgressService extends IntentService { + + private static final String TAG = "ProgressService"; + + private static final String ACTION_PROGRESS = "progress"; + + private Handler handler; + + public ProgressService() { + super(TAG); + } + public ProgressService(String name) { + super(name); + } + + class UpdateRunnable implements Runnable { + + private final int mId; + private final long mWhen; + private int mProgress; + + UpdateRunnable(int id, long when, int progress) { + mId = id; + mWhen = when; + mProgress = progress; + } + + @Override + public void run() { NotificationManager noMa = (NotificationManager) + getSystemService(Context.NOTIFICATION_SERVICE); + Log.v(TAG, "id: " + mId + " when: " + mWhen + " progress: " + mProgress); + noMa.notify(NotificationService.NOTIFICATION_ID + mId, + NotificationService.makeUploadNotification( + ProgressService.this, mProgress, mWhen)); + mProgress += 10; + if (mProgress <= 100) { + handler.postDelayed(this, 1000); + } + } + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + handler = new Handler(); + return super.onStartCommand(intent, flags, startId); + } + + + @Override + protected void onHandleIntent(Intent intent) { + final int id = intent.getIntExtra("id", 0); + final long when = intent.getLongExtra("when", 0L); + int progress = intent.getIntExtra("progress", 0); + handler.postDelayed(new UpdateRunnable(id, when, progress), 1000); + } + + public static void startProgressUpdater(Context context, int id, long when, int progress) { + Intent progressIntent = new Intent(context, ProgressService.class); + progressIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + progressIntent.setAction(ACTION_PROGRESS); + progressIntent.putExtra("id", id); + progressIntent.putExtra("when", when); + progressIntent.putExtra("progress", progress); + context.startService(progressIntent); + } +} diff --git a/NotificationShowcase/src/com/android/example/notificationshowcase/ToastService.java b/NotificationShowcase/src/com/android/example/notificationshowcase/ToastService.java new file mode 100644 index 0000000..6ecfeb2 --- /dev/null +++ b/NotificationShowcase/src/com/android/example/notificationshowcase/ToastService.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.notificationshowcase; + +import android.app.IntentService; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.util.Log; +import android.widget.Toast; + +public class ToastService extends IntentService { + + private static final String TAG = "ToastService"; + + private static final String ACTION_TOAST = "toast"; + + private Handler handler; + + public ToastService() { + super(TAG); + } + public ToastService(String name) { + super(name); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + handler = new Handler(); + return super.onStartCommand(intent, flags, startId); + } + + @Override + protected void onHandleIntent(Intent intent) { + Log.v(TAG, "clicked a thing! intent=" + intent.toString()); + if (intent.hasExtra("text")) { + final String text = intent.getStringExtra("text"); + handler.post(new Runnable() { + @Override + public void run() { + Toast.makeText(ToastService.this, text, Toast.LENGTH_LONG).show(); + Log.v(TAG, "toast " + text); + } + }); + } + } + + public static PendingIntent getPendingIntent(Context context, String text) { + Intent toastIntent = new Intent(context, ToastService.class); + toastIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + toastIntent.setAction(ACTION_TOAST + ":" + text); // one per toast message + toastIntent.putExtra("text", text); + PendingIntent pi = PendingIntent.getService( + context, 58, toastIntent, PendingIntent.FLAG_UPDATE_CURRENT); + return pi; + } +} diff --git a/NotificationShowcase/src/com/android/example/notificationshowcase/UpdateService.java b/NotificationShowcase/src/com/android/example/notificationshowcase/UpdateService.java new file mode 100644 index 0000000..23b8de5 --- /dev/null +++ b/NotificationShowcase/src/com/android/example/notificationshowcase/UpdateService.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.notificationshowcase; + +import android.app.IntentService; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class UpdateService extends IntentService { + + private static final String TAG = "UpdateService"; + + private static final String ACTION_UPDATE = "update"; + + public UpdateService() { + super(TAG); + } + + public UpdateService(String name) { + super(name); + } + + @Override + protected void onHandleIntent(Intent intent) { + + try { + // allow the user close the shade, if they want to test that. + Thread.sleep(3000); + } catch (Exception e) { + } + Log.v(TAG, "clicked a thing! intent=" + intent.toString()); + if (intent.hasExtra("id") && intent.hasExtra("when")) { + final int id = intent.getIntExtra("id", 0); + NotificationManager noMa = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + final int update = intent.getIntExtra("update", 0); + final long when = intent.getLongExtra("when", 0L); + Log.v(TAG, "id: " + id + " when: " + when + " update: " + update); + noMa.notify(NotificationService.NOTIFICATION_ID + id, + NotificationService.makeBigTextNotification(this, update, id, when)); + } else { + Log.v(TAG, "id extra was " + (intent.hasExtra("id") ? "present" : "missing")); + Log.v(TAG, "when extra was " + (intent.hasExtra("when") ? "present" : "missing")); + } + } + + public static PendingIntent getPendingIntent(Context context, int update, int id, long when) { + Intent updateIntent = new Intent(context, UpdateService.class); + updateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + updateIntent.setAction(ACTION_UPDATE); + updateIntent.putExtra("id", id); + updateIntent.putExtra("when", when); + updateIntent.putExtra("update", update); + PendingIntent pi = PendingIntent.getService( + context, 58, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT); + return pi; + } +} |