/*
* Copyright (C) 2007 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.annotation.IntDef;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.session.MediaSession;
import android.net.Uri;
import android.os.BadParcelableException;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.util.MathUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import com.android.internal.R;
import com.android.internal.util.NotificationColorUtil;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* A class that represents how a persistent notification is to be presented to
* the user using the {@link android.app.NotificationManager}.
*
* <p>The {@link Notification.Builder Notification.Builder} has been added to make it
* easier to construct Notifications.</p>
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For a guide to creating notifications, read the
* <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
* developer guide.</p>
* </div>
*/
public class Notification implements Parcelable
{
private static final String TAG = "Notification";
/**
* An activity that provides a user interface for adjusting notification preferences for its
* containing application. Optional but recommended for apps that post
* {@link android.app.Notification Notifications}.
*/
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES
= "android.intent.category.NOTIFICATION_PREFERENCES";
/**
* Use all default values (where applicable).
*/
public static final int DEFAULT_ALL = ~0;
/**
* Use the default notification sound. This will ignore any given
* {@link #sound}.
*
* <p>
* A notification that is noisy is more likely to be presented as a heads-up notification.
* </p>
*
* @see #defaults
*/
public static final int DEFAULT_SOUND = 1;
/**
* Use the default notification vibrate. This will ignore any given
* {@link #vibrate}. Using phone vibration requires the
* {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
*
* <p>
* A notification that vibrates is more likely to be presented as a heads-up notification.
* </p>
*
* @see #defaults
*/
public static final int DEFAULT_VIBRATE = 2;
/**
* Use the default notification lights. This will ignore the
* {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
* {@link #ledOnMS}.
*
* @see #defaults
*/
public static final int DEFAULT_LIGHTS = 4;
/**
* Maximum length of CharSequences accepted by Builder and friends.
*
* <p>
* Avoids spamming the system with overly large strings such as full e-mails.
*/
private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024;
/**
* A timestamp related to this notification, in milliseconds since the epoch.
*
* Default value: {@link System#currentTimeMillis() Now}.
*
* Choose a timestamp that will be most relevant to the user. For most finite events, this
* corresponds to the time the event happened (or will happen, in the case of events that have
* yet to occur but about which the user is being informed). Indefinite events should be
* timestamped according to when the activity began.
*
* Some examples:
*
* <ul>
* <li>Notification of a new chat message should be stamped when the message was received.</li>
* <li>Notification of an ongoing file download (with a progress bar, for example) should be stamped when the download started.</li>
* <li>Notification of a completed file download should be stamped when the download finished.</li>
* <li>Notification of an upcoming meeting should be stamped with the time the meeting will begin (that is, in the future).</li>
* <li>Notification of an ongoing stopwatch (increasing timer) should be stamped with the watch's start time.
* <li>Notification of an ongoing countdown timer should be stamped with the timer's end time.
* </ul>
*
*/
public long when;
/**
* The resource id of a drawable to use as the icon in the status bar.
* This is required; notifications with an invalid icon resource will not be shown.
*/
public int icon;
/**
* If the icon in the status bar is to have more than one level, you can set this. Otherwise,
* leave it at its default value of 0.
*
* @see android.widget.ImageView#setImageLevel
* @see android.graphics.drawable.Drawable#setLevel
*/
public int iconLevel;
/**
* The number of events that this notification represents. For example, in a new mail
* notification, this could be the number of unread messages.
*
* The system may or may not use this field to modify the appearance of the notification. For
* example, before {@link android.os.Build.VERSION_CODES#HONEYCOMB}, this number was
* superimposed over the icon in the status bar. Starting with
* {@link android.os.Build.VERSION_CODES#HONEYCOMB}, the template used by
* {@link Notification.Builder} has displayed the number in the expanded notification view.
*
* If the number is 0 or negative, it is never shown.
*/
public int number;
/**
* The intent to execute when the expanded status entry is clicked. If
* this is an activity, it must include the
* {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
* that you take care of task management as described in the
* <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
* Stack</a> document. In particular, make sure to read the notification section
* <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling
* Notifications</a> for the correct ways to launch an application from a
* notification.
*/
public PendingIntent contentIntent;
/**
* The intent to execute when the notification is explicitly dismissed by the user, either with
* the "Clear All" button or by swiping it away individually.
*
* This probably shouldn't be launching an activity since several of those will be sent
* at the same time.
*/
public PendingIntent deleteIntent;
/**
* An intent to launch instead of posting the notification to the status bar.
*
* <p>
* The system UI may choose to display a heads-up notification, instead of
* launching this intent, while the user is using the device.
* </p>
*
* @see Notification.Builder#setFullScreenIntent
*/
public PendingIntent fullScreenIntent;
/**
* Text that summarizes this notification for accessibility services.
*
* As of the L release, this text is no longer shown on screen, but it is still useful to
* accessibility services (where it serves as an audible announcement of the notification's
* appearance).
*
* @see #tickerView
*/
public CharSequence tickerText;
/**
* Formerly, a view showing the {@link #tickerText}.
*
* No longer displayed in the status bar as of API 21.
*/
@Deprecated
public RemoteViews tickerView;
/**
* The view that will represent this notification in the expanded status bar.
*/
public RemoteViews contentView;
/**
* A large-format version of {@link #contentView}, giving the Notification an
* opportunity to show more detail. The system UI may choose to show this
* instead of the normal content view at its discretion.
*/
public RemoteViews bigContentView;
/**
* A medium-format version of {@link #contentView}, providing the Notification an
* opportunity to add action buttons to contentView. At its discretion, the system UI may
* choose to show this as a heads-up notification, which will pop up so the user can see
* it without leaving their current activity.
*/
public RemoteViews headsUpContentView;
/**
* The bitmap that may escape the bounds of the panel and bar.
*/
public Bitmap largeIcon;
/**
* The sound to play.
*
* <p>
* A notification that is noisy is more likely to be presented as a heads-up notification.
* </p>
*
* <p>
* To play the default notification sound, see {@link #defaults}.
* </p>
*/
public Uri sound;
/**
* Use this constant as the value for audioStreamType to request that
* the default stream type for notifications be used. Currently the
* default stream type is {@link AudioManager#STREAM_NOTIFICATION}.
*
* @deprecated Use {@link #audioAttributes} instead.
*/
@Deprecated
public static final int STREAM_DEFAULT = -1;
/**
* The audio stream type to use when playing the sound.
* Should be one of the STREAM_ constants from
* {@link android.media.AudioManager}.
*
* @deprecated Use {@link #audioAttributes} instead.
*/
@Deprecated
public int audioStreamType = STREAM_DEFAULT;
/**
* The default value of {@link #audioAttributes}.
*/
public static final AudioAttributes AUDIO_ATTRIBUTES_DEFAULT = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
/**
* The {@link AudioAttributes audio attributes} to use when playing the sound.
*/
public AudioAttributes audioAttributes = AUDIO_ATTRIBUTES_DEFAULT;
/**
* The pattern with which to vibrate.
*
* <p>
* To vibrate the default pattern, see {@link #defaults}.
* </p>
*
* <p>
* A notification that vibrates is more likely to be presented as a heads-up notification.
* </p>
*
* @see android.os.Vibrator#vibrate(long[],int)
*/
public long[] vibrate;
/**
* The color of the led. The hardware will do its best approximation.
*
* @see #FLAG_SHOW_LIGHTS
* @see #flags
*/
public int ledARGB;
/**
* The number of milliseconds for the LED to be on while it's flashing.
* The hardware will do its best approximation.
*
* @see #FLAG_SHOW_LIGHTS
* @see #flags
*/
public int ledOnMS;
/**
* The number of milliseconds for the LED to be off while it's flashing.
* The hardware will do its best approximation.
*
* @see #FLAG_SHOW_LIGHTS
* @see #flags
*/
public int ledOffMS;
/**
* Specifies which values should be taken from the defaults.
* <p>
* To set, OR the desired from {@link #DEFAULT_SOUND},
* {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
* values, use {@link #DEFAULT_ALL}.
* </p>
*/
public int defaults;
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if you want the LED on for this notification.
* <ul>
* <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
* or 0 for both ledOnMS and ledOffMS.</li>
* <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
* <li>To flash the LED, pass the number of milliseconds that it should
* be on and off to ledOnMS and ledOffMS.</li>
* </ul>
* <p>
* Since hardware varies, you are not guaranteed that any of the values
* you pass are honored exactly. Use the system defaults (TODO) if possible
* because they will be set to values that work on any given hardware.
* <p>
* The alpha channel must be set for forward compatibility.
*
*/
public static final int FLAG_SHOW_LIGHTS = 0x00000001;
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if this notification is in reference to something that is ongoing,
* like a phone call. It should not be set if this notification is in
* reference to something that happened at a particular point in time,
* like a missed phone call.
*/
public static final int FLAG_ONGOING_EVENT = 0x00000002;
/**
* Bit to be bitwise-ored into the {@link #flags} field that if set,
* the audio will be repeated until the notification is
* cancelled or the notification window is opened.
*/
public static final int FLAG_INSISTENT = 0x00000004;
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if you would only like the sound, vibrate and ticker to be played
* if the notification was not already showing.
*/
public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if the notification should be canceled when it is clicked by the
* user.
*/
public static final int FLAG_AUTO_CANCEL = 0x00000010;
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if the notification should not be canceled when the user clicks
* the Clear all button.
*/
public static final int FLAG_NO_CLEAR = 0x00000020;
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if this notification represents a currently running service. This
* will normally be set for you by {@link Service#startForeground}.
*/
public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
/**
* Obsolete flag indicating high-priority notifications; use the priority field instead.
*
* @deprecated Use {@link #priority} with a positive value.
*/
public static final int FLAG_HIGH_PRIORITY = 0x00000080;
/**
* Bit to be bitswise-ored into the {@link #flags} field that should be
* set if this notification is relevant to the current device only
* and it is not recommended that it bridge to other devices.
*/
public static final int FLAG_LOCAL_ONLY = 0x00000100;
/**
* Bit to be bitswise-ored into the {@link #flags} field that should be
* set if this notification is the group summary for a group of notifications.
* Grouped notifications may display in a cluster or stack on devices which
* support such rendering. Requires a group key also be set using {@link Builder#setGroup}.
*/
public static final int FLAG_GROUP_SUMMARY = 0x00000200;
public int flags;
/** @hide */
@IntDef({PRIORITY_DEFAULT,PRIORITY_LOW,PRIORITY_MIN,PRIORITY_HIGH,PRIORITY_MAX})
@Retention(RetentionPolicy.SOURCE)
public @interface Priority {}
/**
* Default notification {@link #priority}. If your application does not prioritize its own
* notifications, use this value for all notifications.
*/
public static final int PRIORITY_DEFAULT = 0;
/**
* Lower {@link #priority}, for items that are less important. The UI may choose to show these
* items smaller, or at a different position in the list, compared with your app's
* {@link #PRIORITY_DEFAULT} items.
*/
public static final int PRIORITY_LOW = -1;
/**
* Lowest {@link #priority}; these items might not be shown to the user except under special
* circumstances, such as detailed notification logs.
*/
public static final int PRIORITY_MIN = -2;
/**
* Higher {@link #priority}, for more important notifications or alerts. The UI may choose to
* show these items larger, or at a different position in notification lists, compared with
* your app's {@link #PRIORITY_DEFAULT} items.
*/
public static final int PRIORITY_HIGH = 1;
/**
* Highest {@link #priority}, for your application's most important items that require the
* user's prompt attention or input.
*/
public static final int PRIORITY_MAX = 2;
/**
* Relative priority for this notification.
*
* Priority is an indication of how much of the user's valuable attention should be consumed by
* this notification. Low-priority notifications may be hidden from the user in certain
* situations, while the user might be interrupted for a higher-priority notification. The
* system will make a determination about how to interpret this priority when presenting
* the notification.
*
* <p>
* A notification that is at least {@link #PRIORITY_HIGH} is more likely to be presented
* as a heads-up notification.
* </p>
*
*/
@Priority
public int priority;
/**
* Accent color (an ARGB integer like the constants in {@link android.graphics.Color})
* to be applied by the standard Style templates when presenting this notification.
*
* The current template design constructs a colorful header image by overlaying the
* {@link #icon} image (stenciled in white) atop a field of this color. Alpha components are
* ignored.
*/
public int color = COLOR_DEFAULT;
/**
* Special value of {@link #color} telling the system not to decorate this notification with
* any special color but instead use default colors when presenting this notification.
*/
public static final int COLOR_DEFAULT = 0; // AKA Color.TRANSPARENT
/**
* Sphere of visibility of this notification, which affects how and when the SystemUI reveals
* the notification's presence and contents in untrusted situations (namely, on the secure
* lockscreen).
*
* The default level, {@link #VISIBILITY_PRIVATE}, behaves exactly as notifications have always
* done on Android: The notification's {@link #icon} and {@link #tickerText} (if available) are
* shown in all situations, but the contents are only available if the device is unlocked for
* the appropriate user.
*
* A more permissive policy can be expressed by {@link #VISIBILITY_PUBLIC}; such a notification
* can be read even in an "insecure" context (that is, above a secure lockscreen).
* To modify the public version of this notificationâ |