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