/* * Copyright (C) 2015 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 android.app; 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.os.Bundle; import android.os.Handler; import android.os.Parcel; import android.os.SystemClock; import android.provider.ContactsContract; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.Suppress; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.StyleSpan; import android.util.Log; import android.view.View; import android.widget.Toast; import java.lang.reflect.Method; import java.lang.InterruptedException; import java.lang.NoSuchMethodError; import java.lang.NoSuchMethodException; import java.util.ArrayList; import com.android.frameworks.tests.notification.R; public class NotificationTests extends AndroidTestCase { private static final String TAG = "NOTEST"; public static void L(String msg, Object... args) { Log.v(TAG, (args == null || args.length == 0) ? msg : String.format(msg, args)); } public static final String ACTION_CREATE = "create"; public static final int NOTIFICATION_ID = 31338; public static final boolean SHOW_PHONE_CALL = false; public static final boolean SHOW_INBOX = true; public static final boolean SHOW_BIG_TEXT = true; public static final boolean SHOW_BIG_PICTURE = true; public static final boolean SHOW_MEDIA = true; public static final boolean SHOW_STOPWATCH = false; public static final boolean SHOW_SOCIAL = false; public static final boolean SHOW_CALENDAR = false; public static final boolean SHOW_PROGRESS = false; 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); } static final String[] LINES = new String[] { "Uh oh", "Getting kicked out of this room", "I'll be back in 5-10 minutes.", "And now \u2026 I have to find my shoes. \uD83D\uDC63", "\uD83D\uDC5F \uD83D\uDC5F", "\uD83D\uDC60 \uD83D\uDC60", }; static final int MAX_LINES = 5; 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); } */ StringBuilder longSmsText = new StringBuilder(); int end = 2 + update; if (end > LINES.length) { end = LINES.length; } final int start = Math.max(0, end - MAX_LINES); for (int i=start; i= LINES.length) break; if (i > start) longSmsText.append("\n"); longSmsText.append(LINES[i]); } if (update > 2) { when = System.currentTimeMillis(); } Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle() .bigText(longSmsText); Notification bigText = new Notification.Builder(context) .setContentTitle("Mike Cleron") .setContentIntent(ToastService.getPendingIntent(context, "Clicked on bigText")) .setContentText(longSmsText) //.setTicker("Mike Cleron: " + longSmsText) .setWhen(when) .setLargeIcon(getBitmap(context, R.drawable.bucket)) .setPriority(Notification.PRIORITY_HIGH) .setNumber(update) .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) { Notification.Builder uploadNotification = new Notification.Builder(context) .setContentTitle("File Upload") .setContentText("foo.txt") .setPriority(Notification.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(); } static SpannableStringBuilder BOLD(CharSequence str) { final SpannableStringBuilder ssb = new SpannableStringBuilder(str); ssb.setSpan(new StyleSpan(Typeface.BOLD), 0, ssb.length(), 0); return ssb; } public static 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; } } public static void sleepIfYouCan(int ms) { try { Thread.sleep(ms); } catch (InterruptedException e) {} } @Override public void setUp() throws Exception { super.setUp(); } public static String summarize(Notification n) { return String.format("", n.extras.get(Notification.EXTRA_TITLE), n.icon, String.valueOf(n.contentView)); } public void testCreate() throws Exception { ArrayList mNotifications = new ArrayList(); NotificationManager noMa = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); L("Constructing notifications..."); if (SHOW_BIG_TEXT) { int bigtextId = mNotifications.size(); final long time = SystemClock.currentThreadTimeMillis(); final Notification n = makeBigTextNotification(mContext, 0, bigtextId, System.currentTimeMillis()); L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); mNotifications.add(n); } int uploadId = mNotifications.size(); long uploadWhen = System.currentTimeMillis(); if (SHOW_PROGRESS) { mNotifications.add(makeUploadNotification(mContext, 0, uploadWhen)); } if (SHOW_PHONE_CALL) { int phoneId = mNotifications.size(); final PendingIntent fullscreenIntent = FullScreenActivity.getPendingIntent(mContext, phoneId); final long time = SystemClock.currentThreadTimeMillis(); Notification phoneCall = new Notification.Builder(mContext) .setContentTitle("Incoming call") .setContentText("Matias Duarte") .setLargeIcon(getBitmap(mContext, R.drawable.matias_hed)) .setSmallIcon(R.drawable.stat_sys_phone_call) .setDefaults(Notification.DEFAULT_SOUND) .setPriority(Notification.PRIORITY_MAX) .setContentIntent(fullscreenIntent) .setFullScreenIntent(fullscreenIntent, true) .addAction(R.drawable.ic_dial_action_call, "Answer", ToastService.getPendingIntent(mContext, "Clicked on Answer")) .addAction(R.drawable.ic_end_call, "Ignore", ToastService.getPendingIntent(mContext, "Clicked on Ignore")) .setOngoing(true) .addPerson(Uri.fromParts("tel", "1 (617) 555-1212", null).toString()) .build(); L(" %s: create=%dms", phoneCall.toString(), SystemClock.currentThreadTimeMillis() - time); mNotifications.add(phoneCall); } if (SHOW_STOPWATCH) { final long time = SystemClock.currentThreadTimeMillis(); final Notification n = new Notification.Builder(mContext) .setContentTitle("Stopwatch PRO") .setContentText("Counting up") .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Stopwatch")) .setSmallIcon(R.drawable.stat_notify_alarm) .setUsesChronometer(true) .build(); L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); mNotifications.add(n); } if (SHOW_CALENDAR) { final long time = SystemClock.currentThreadTimeMillis(); final Notification n = new Notification.Builder(mContext) .setContentTitle("J Planning") .setContentText("The Botcave") .setWhen(System.currentTimeMillis()) .setSmallIcon(R.drawable.stat_notify_calendar) .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on calendar event")) .setContentInfo("7PM") .addAction(R.drawable.stat_notify_snooze, "+10 min", ToastService.getPendingIntent(mContext, "snoozed 10 min")) .addAction(R.drawable.stat_notify_snooze_longer, "+1 hour", ToastService.getPendingIntent(mContext, "snoozed 1 hr")) .addAction(R.drawable.stat_notify_email, "Email", ToastService.getPendingIntent(mContext, "Congratulations, you just destroyed someone's inbox zero")) .build(); L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); mNotifications.add(n); } if (SHOW_BIG_PICTURE) { BitmapDrawable d = (BitmapDrawable) mContext.getResources().getDrawable(R.drawable.romainguy_rockaway); final long time = SystemClock.currentThreadTimeMillis(); final Notification n = new Notification.Builder(mContext) .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(android.R.drawable.stat_notify_chat) .setContentIntent( ToastService.getPendingIntent(mContext, "Clicked picture")) .setLargeIcon(getBitmap(mContext, R.drawable.romainguy_hed)) .addAction(R.drawable.add, "Add to Gallery", ToastService.getPendingIntent(mContext, "Added")) .setStyle(new Notification.BigPictureStyle() .bigPicture(d.getBitmap())) .build(); L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); mNotifications.add(n); } if (SHOW_INBOX) { final long time = SystemClock.currentThreadTimeMillis(); final Notification n = new Notification.Builder(mContext) .setContentTitle("New mail") .setContentText("3 new messages") .setSubText("example@gmail.com") .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Mail")) .setSmallIcon(R.drawable.stat_notify_email) .setStyle(new Notification.InboxStyle() .setSummaryText("example@gmail.com") .addLine(BOLD("Alice:").append(" hey there!")) .addLine(BOLD("Bob:").append(" hi there!")) .addLine(BOLD("Charlie:").append(" Iz IN UR EMAILZ!!")) ).build(); L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); mNotifications.add(n); } if (SHOW_SOCIAL) { final long time = SystemClock.currentThreadTimeMillis(); final Notification n = new Notification.Builder(mContext) .setContentTitle("Social Network") .setContentText("You were mentioned in a post") .setContentInfo("example@gmail.com") .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Social")) .setSmallIcon(android.R.drawable.stat_notify_chat) .setPriority(Notification.PRIORITY_LOW) .build(); L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); mNotifications.add(n); } L("Posting notifications..."); for (int i=0; i= 0) { NotificationManager noMa = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); noMa.cancel(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; } } }