Notification.java revision d24b8183b93e781080b2c16c487e60d51c12da31
1/* 2 * Copyright (C) 2007 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 17package android.app; 18 19import java.util.Date; 20 21import android.app.PendingIntent; 22import android.content.Context; 23import android.content.Intent; 24import android.media.AudioManager; 25import android.net.Uri; 26import android.os.Parcel; 27import android.os.Parcelable; 28import android.text.TextUtils; 29import android.text.format.DateFormat; 30import android.text.format.DateUtils; 31import android.widget.RemoteViews; 32 33/** 34 * A class that represents how a persistent notification is to be presented to 35 * the user using the {@link android.app.NotificationManager}. 36 * 37 */ 38public class Notification implements Parcelable 39{ 40 /** 41 * Use all default values (where applicable). 42 */ 43 public static final int DEFAULT_ALL = ~0; 44 45 /** 46 * Use the default notification sound. This will ignore any given 47 * {@link #sound}. 48 * 49 * @see #defaults 50 */ 51 public static final int DEFAULT_SOUND = 1; 52 53 /** 54 * Use the default notification vibrate. This will ignore any given 55 * {@link #vibrate}. 56 * 57 * @see #defaults 58 */ 59 public static final int DEFAULT_VIBRATE = 2; 60 61 /** 62 * Use the default notification lights. This will ignore the 63 * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or 64 * {@link #ledOnMS}. 65 * 66 * @see #defaults 67 */ 68 public static final int DEFAULT_LIGHTS = 4; 69 70 /** 71 * The timestamp for the notification. The icons and expanded views 72 * are sorted by this key. 73 */ 74 public long when; 75 76 /** 77 * The resource id of a drawable to use as the icon in the status bar. 78 */ 79 public int icon; 80 81 /** 82 * The number of events that this notification represents. For example, if this is the 83 * new mail notification, this would be the number of unread messages. This number is 84 * be superimposed over the icon in the status bar. If the number is 0 or negative, it 85 * is not shown in the status bar. 86 */ 87 public int number; 88 89 /** 90 * The intent to execute when the expanded status entry is clicked. If 91 * this is an activity, it must include the 92 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires 93 * that you take care of task management as described in the <em>Activities and Tasks</em> 94 * section of the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application 95 * Fundamentals</a> document. 96 */ 97 public PendingIntent contentIntent; 98 99 /** 100 * The intent to execute when the status entry is deleted by the user 101 * with the "Clear All Notifications" button. This probably shouldn't 102 * be launching an activity since several of those will be sent at the 103 * same time. 104 */ 105 public PendingIntent deleteIntent; 106 107 /** 108 * Text to scroll across the screen when this item is added to 109 * the status bar. 110 */ 111 public CharSequence tickerText; 112 113 /** 114 * The view that shows when this notification is shown in the expanded status bar. 115 */ 116 public RemoteViews contentView; 117 118 /** 119 * If the icon in the status bar is to have more than one level, you can set this. Otherwise, 120 * leave it at its default value of 0. 121 * 122 * @see android.widget.ImageView#setImageLevel 123 * @see android.graphics.drawable#setLevel 124 */ 125 public int iconLevel; 126 127 /** 128 * The sound to play. 129 * 130 * <p> 131 * To play the default notification sound, see {@link #defaults}. 132 * </p> 133 */ 134 public Uri sound; 135 136 /** 137 * Use this constant as the value for audioStreamType to request that 138 * the default stream type for notifications be used. Currently the 139 * default stream type is STREAM_RING. 140 */ 141 public static final int STREAM_DEFAULT = -1; 142 143 /** 144 * The audio stream type to use when playing the sound. 145 * Should be one of the STREAM_ constants from 146 * {@link android.media.AudioManager}. 147 */ 148 public int audioStreamType = STREAM_DEFAULT; 149 150 151 /** 152 * The pattern with which to vibrate. This pattern will repeat if {@link 153 * #FLAG_INSISTENT} bit is set in the {@link #flags} field. 154 * 155 * <p> 156 * To vibrate the default pattern, see {@link #defaults}. 157 * </p> 158 * 159 * @see android.os.Vibrator#vibrate(long[],int) 160 */ 161 public long[] vibrate; 162 163 /** 164 * The color of the led. The hardware will do its best approximation. 165 * 166 * @see #FLAG_SHOW_LIGHTS 167 * @see #flags 168 */ 169 public int ledARGB; 170 171 /** 172 * The number of milliseconds for the LED to be on while it's flashing. 173 * The hardware will do its best approximation. 174 * 175 * @see #FLAG_SHOW_LIGHTS 176 * @see #flags 177 */ 178 public int ledOnMS; 179 180 /** 181 * The number of milliseconds for the LED to be off while it's flashing. 182 * The hardware will do its best approximation. 183 * 184 * @see #FLAG_SHOW_LIGHTS 185 * @see #flags 186 */ 187 public int ledOffMS; 188 189 /** 190 * Specifies which values should be taken from the defaults. 191 * <p> 192 * To set, OR the desired from {@link #DEFAULT_SOUND}, 193 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default 194 * values, use {@link #DEFAULT_ALL}. 195 * </p> 196 */ 197 public int defaults; 198 199 200 /** 201 * Bit to be bitwise-ored into the {@link #flags} field that should be 202 * set if you want the LED on for this notification. 203 * <ul> 204 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB 205 * or 0 for both ledOnMS and ledOffMS.</li> 206 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li> 207 * <li>To flash the LED, pass the number of milliseconds that it should 208 * be on and off to ledOnMS and ledOffMS.</li> 209 * </ul> 210 * <p> 211 * Since hardware varies, you are not guaranteed that any of the values 212 * you pass are honored exactly. Use the system defaults (TODO) if possible 213 * because they will be set to values that work on any given hardware. 214 * <p> 215 * The alpha channel must be set for forward compatibility. 216 * 217 */ 218 public static final int FLAG_SHOW_LIGHTS = 0x00000001; 219 220 /** 221 * Bit to be bitwise-ored into the {@link #flags} field that should be 222 * set if this notification is in reference to something that is ongoing, 223 * like a phone call. It should not be set if this notification is in 224 * reference to something that happened at a particular point in time, 225 * like a missed phone call. 226 */ 227 public static final int FLAG_ONGOING_EVENT = 0x00000002; 228 229 /** 230 * Bit to be bitwise-ored into the {@link #flags} field that if set, 231 * the audio and vibration will be repeated until the notification is 232 * cancelled. 233 * 234 * <p> 235 * NOTE: This notion will change when we have decided exactly 236 * what the UI will be. 237 * </p> 238 */ 239 public static final int FLAG_INSISTENT = 0x00000004; 240 241 /** 242 * Bit to be bitwise-ored into the {@link #flags} field that should be 243 * set if you want the sound and/or vibration play each time the 244 * notification is sent, even if it has not been canceled before that. 245 */ 246 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008; 247 248 /** 249 * Bit to be bitwise-ored into the {@link #flags} field that should be 250 * set if the notification should be canceled when it is clicked by the 251 * user. 252 */ 253 public static final int FLAG_AUTO_CANCEL = 0x00000010; 254 255 /** 256 * Bit to be bitwise-ored into the {@link #flags} field that should be 257 * set if the notification should not be canceled when the user clicks 258 * the Clear all button. 259 */ 260 public static final int FLAG_NO_CLEAR = 0x00000020; 261 262 public int flags; 263 264 /** 265 * Constructs a Notification object with everything set to 0. 266 */ 267 public Notification() 268 { 269 this.when = System.currentTimeMillis(); 270 } 271 272 /** 273 * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}. 274 * @hide 275 */ 276 public Notification(Context context, int icon, CharSequence tickerText, long when, 277 CharSequence contentTitle, CharSequence contentText, Intent contentIntent) 278 { 279 this.when = when; 280 this.icon = icon; 281 this.tickerText = tickerText; 282 setLatestEventInfo(context, contentTitle, contentText, 283 PendingIntent.getActivity(context, 0, contentIntent, 0)); 284 } 285 286 /** 287 * Constructs a Notification object with the information needed to 288 * have a status bar icon without the standard expanded view. 289 * 290 * @param icon The resource id of the icon to put in the status bar. 291 * @param tickerText The text that flows by in the status bar when the notification first 292 * activates. 293 * @param when The time to show in the time field. In the System.currentTimeMillis 294 * timebase. 295 */ 296 public Notification(int icon, CharSequence tickerText, long when) 297 { 298 this.icon = icon; 299 this.tickerText = tickerText; 300 this.when = when; 301 } 302 303 /** 304 * Unflatten the notification from a parcel. 305 */ 306 public Notification(Parcel parcel) 307 { 308 int version = parcel.readInt(); 309 310 when = parcel.readLong(); 311 icon = parcel.readInt(); 312 number = parcel.readInt(); 313 if (parcel.readInt() != 0) { 314 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel); 315 } 316 if (parcel.readInt() != 0) { 317 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel); 318 } 319 if (parcel.readInt() != 0) { 320 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 321 } 322 if (parcel.readInt() != 0) { 323 contentView = RemoteViews.CREATOR.createFromParcel(parcel); 324 } 325 defaults = parcel.readInt(); 326 flags = parcel.readInt(); 327 if (parcel.readInt() != 0) { 328 sound = Uri.CREATOR.createFromParcel(parcel); 329 } 330 331 audioStreamType = parcel.readInt(); 332 vibrate = parcel.createLongArray(); 333 ledARGB = parcel.readInt(); 334 ledOnMS = parcel.readInt(); 335 ledOffMS = parcel.readInt(); 336 iconLevel = parcel.readInt(); 337 } 338 339 public int describeContents() { 340 return 0; 341 } 342 343 /** 344 * Flatten this notification from a parcel. 345 */ 346 public void writeToParcel(Parcel parcel, int flags) 347 { 348 parcel.writeInt(1); 349 350 parcel.writeLong(when); 351 parcel.writeInt(icon); 352 parcel.writeInt(number); 353 if (contentIntent != null) { 354 parcel.writeInt(1); 355 contentIntent.writeToParcel(parcel, 0); 356 } else { 357 parcel.writeInt(0); 358 } 359 if (deleteIntent != null) { 360 parcel.writeInt(1); 361 deleteIntent.writeToParcel(parcel, 0); 362 } else { 363 parcel.writeInt(0); 364 } 365 if (tickerText != null) { 366 parcel.writeInt(1); 367 TextUtils.writeToParcel(tickerText, parcel, flags); 368 } else { 369 parcel.writeInt(0); 370 } 371 if (contentView != null) { 372 parcel.writeInt(1); 373 contentView.writeToParcel(parcel, 0); 374 } else { 375 parcel.writeInt(0); 376 } 377 378 parcel.writeInt(defaults); 379 parcel.writeInt(this.flags); 380 381 if (sound != null) { 382 parcel.writeInt(1); 383 sound.writeToParcel(parcel, 0); 384 } else { 385 parcel.writeInt(0); 386 } 387 parcel.writeInt(audioStreamType); 388 parcel.writeLongArray(vibrate); 389 parcel.writeInt(ledARGB); 390 parcel.writeInt(ledOnMS); 391 parcel.writeInt(ledOffMS); 392 parcel.writeInt(iconLevel); 393 } 394 395 /** 396 * Parcelable.Creator that instantiates Notification objects 397 */ 398 public static final Parcelable.Creator<Notification> CREATOR 399 = new Parcelable.Creator<Notification>() 400 { 401 public Notification createFromParcel(Parcel parcel) 402 { 403 return new Notification(parcel); 404 } 405 406 public Notification[] newArray(int size) 407 { 408 return new Notification[size]; 409 } 410 }; 411 412 /** 413 * Sets the {@link #contentView} field to be a view with the standard "Latest Event" 414 * layout. 415 * 416 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields 417 * in the view.</p> 418 * @param context The context for your application / activity. 419 * @param contentTitle The title that goes in the expanded entry. 420 * @param contentText The text that goes in the expanded entry. 421 * @param contentIntent The intent to launch when the user clicks the expanded notification. 422 * If this is an activity, it must include the 423 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires 424 * that you take care of task management as described in 425 * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>. 426 */ 427 public void setLatestEventInfo(Context context, 428 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) { 429 RemoteViews contentView = new RemoteViews(context.getPackageName(), 430 com.android.internal.R.layout.status_bar_latest_event_content); 431 if (this.icon != 0) { 432 contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon); 433 } 434 if (contentTitle != null) { 435 contentView.setTextViewText(com.android.internal.R.id.title, contentTitle); 436 } 437 if (contentText != null) { 438 contentView.setTextViewText(com.android.internal.R.id.text, contentText); 439 } 440 if (this.when != 0) { 441 Date date = new Date(when); 442 CharSequence str = 443 DateUtils.isToday(when) ? DateFormat.getTimeFormat(context).format(date) 444 : DateFormat.getDateFormat(context).format(date); 445 contentView.setTextViewText(com.android.internal.R.id.time, str); 446 } 447 448 this.contentView = contentView; 449 this.contentIntent = contentIntent; 450 } 451 452 @Override 453 public String toString() { 454 StringBuilder sb = new StringBuilder(); 455 sb.append("Notification(vibrate="); 456 if (this.vibrate != null) { 457 int N = this.vibrate.length-1; 458 sb.append("["); 459 for (int i=0; i<N; i++) { 460 sb.append(this.vibrate[i]); 461 sb.append(','); 462 } 463 sb.append(this.vibrate[N]); 464 sb.append("]"); 465 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) { 466 sb.append("default"); 467 } else { 468 sb.append("null"); 469 } 470 sb.append(",sound="); 471 if (this.sound != null) { 472 sb.append(this.sound.toString()); 473 } else if ((this.defaults & DEFAULT_SOUND) != 0) { 474 sb.append("default"); 475 } else { 476 sb.append("null"); 477 } 478 sb.append(",defaults=0x"); 479 sb.append(Integer.toHexString(this.defaults)); 480 sb.append(")"); 481 return sb.toString(); 482 } 483} 484