Android设计和开发系列第一篇:Notifications通知(Develop—Training)
Develop篇
Building a Notification
THIS LESSON TEACHES YOU TO
- Create a Notification Builder
- Define the Notification's Action
- Set the Notification's Click Behavior
- Issue the Notification
YOU SHOULD ALSO READ
- Notifications API Guide
- Intents and Intent Filters
- Notifications Design Guide
This lesson explains how to create and issue a notification.
The examples in this class are based on theNotificationCompat.Builder
class.NotificationCompat.Builder
is in the Support Library. You should use NotificationCompat
and its subclasses, particularlyNotificationCompat.Builder
, to provide the best notification support for a wide range of platforms.
Create a Notification Builder
When creating a notification, specify the UI content and actions with a NotificationCompat.Builder
object. At bare minimum, aBuilder
object must include the following:
- A small icon, set by
setSmallIcon()
- A title, set by
setContentTitle()
- Detail text, set by
setContentText()
For example:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
Define the Notification's Action
Although actions are optional, you should add at least one action to your notification. An action takes users directly from the notification to an Activity
in your application, where they can look at the event that caused the notification or do further work. Inside a notification, the action itself is defined by a PendingIntent
containing anIntent
that starts an Activity
in your application.
How you construct the PendingIntent
depends on what type of Activity
you're starting. When you start anActivity
from a notification, you must preserve the user's expected navigation experience. In the snippet below, clicking the notification opens a new activity that effectively extends the behavior of the notification. In this case there is no need to create an artificial back stack (see Preserving Navigation when Starting an Activity for more information):
Intent resultIntent = new Intent(this, ResultActivity.class);
...
// Because clicking the notification opens a new ("special") activity, there's
// no need to create an artificial back stack.
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
Set the Notification's Click Behavior
To associate the PendingIntent
created in the previous step with a gesture, call the appropriate method ofNotificationCompat.Builder
. For example, to start an activity when the user clicks the notification text in the notification drawer, add the PendingIntent
by calling setContentIntent()
. For example:
PendingIntent resultPendingIntent;
...
mBuilder.setContentIntent(resultPendingIntent);
Issue the Notification
To issue the notification:
- Get an instance of
NotificationManager
. - Use the
notify()
method to issue the notification. When you callnotify()
, specify a notification ID. You can use this ID to update the notification later on. This is described in more detail in Managing Notifications. - Call
build()
, which returns aNotification
object containing your specifications.
For example:
NotificationCompat.Builder mBuilder;
...
// Sets an ID for the notification
int mNotificationId = 001;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
Preserving Navigation when Starting an Activity
THIS LESSON TEACHES YOU TO
YOU SHOULD ALSO READ
- Notifications API Guide
- Intents and Intent Filters
- Notifications Design Guide
Part of designing a notification is preserving the user's expected navigation experience. For a detailed discussion of this topic, see the Notifications API guide. There are two general situations:
- Regular activity
- You're starting an
Activity
that's part of the application's normal workflow. - Special activity
- The user only sees this
Activity
if it's started from a notification. In a sense, theActivity
extends the notification by providing information that would be hard to display in the notification itself.
Set Up a Regular Activity PendingIntent
To set up a PendingIntent
that starts a direct entry Activity
, follow these steps:
- Define your application's
Activity
hierarchy in the manifest. The final XML should look like this:<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ResultActivity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity> - Create a back stack based on the
Intent
that starts theActivity
. For example:int id = 1;
...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());Set Up a Special Activity PendingIntent
A special
Activity
doesn't need a back stack, so you don't have to define itsActivity
hierarchy in the manifest, and you don't have to calladdParentStack()
to build a back stack. Instead, use the manifest to set up theActivity
task options, and create thePendingIntent
by callinggetActivity()
:- In your manifest, add the following attributes to the
<activity>
element for theActivity
:android:name="activityclass"
- The activity's fully-qualified class name.
android:taskAffinity=""
- Combined with the
FLAG_ACTIVITY_NEW_TASK
flag that you set in code, this ensures that thisActivity
doesn't go into the application's default task. Any existing tasks that have the application's default affinity are not affected. android:excludeFromRecents="true"
- Excludes the new task from Recents, so that the user can't accidentally navigate back to it.
This snippet shows the element:
<activity
android:name=".ResultActivity"
...
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>
... - Build and issue the notification:
- Create an
Intent
that starts theActivity
. - Set the
Activity
to start in a new, empty task by callingsetFlags()
with the flagsFLAG_ACTIVITY_NEW_TASK
andFLAG_ACTIVITY_CLEAR_TASK
. - Set any other options you need for the
Intent
. - Create a
PendingIntent
from theIntent
by callinggetActivity()
. You can then use thisPendingIntent
as the argument tosetContentIntent()
.
The following code snippet demonstrates the process:
// Instantiate a Builder object.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Creates an Intent for the Activity
Intent notifyIntent =
new Intent(new ComponentName(this, ResultActivity.class));
// Sets the Activity to start in a new, empty task
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Creates the PendingIntent
PendingIntent notifyIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
); // Puts the PendingIntent into the notification builder
builder.setContentIntent(notifyIntent);
// Notifications are issued by sending them to the
// NotificationManager system service.
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Builds an anonymous Notification object from the builder, and
// passes it to the NotificationManager
mNotificationManager.notify(id, builder.build()); - Create an
- In your manifest, add the following attributes to the
Updating Notifications
THIS LESSON TEACHES YOU TO
YOU SHOULD ALSO READ
- Notifications API Guide
- Intents and Intent Filters
- Notifications Design Guide
When you need to issue a notification multiple times for the same type of event, you should avoid making a completely new notification. Instead, you should consider updating a previous notification, either by changing some of its values or by adding to it, or both.
The following section describes how to update notifications and also how to remove them.
Modify a Notification
To set up a notification so it can be updated, issue it with a notification ID by calling NotificationManager.notify(ID, notification)
. To update this notification once you've issued it, update or create a NotificationCompat.Builder
object, build aNotification
object from it, and issue the Notification
with the same ID you used previously.
The following snippet demonstrates a notification that is updated to reflect the number of events that have occurred. It stacks the notification, showing a summary:
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
// Because the ID remains unchanged, the existing notification is
// updated.
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
...
Remove Notifications
Notifications remain visible until one of the following happens:
- The user dismisses the notification either individually or by using "Clear All" (if the notification can be cleared).
- The user touches the notification, and you called
setAutoCancel()
when you created the notification. - You call
cancel()
for a specific notification ID. This method also deletes ongoing notifications. - You call
cancelAll()
, which removes all of the notifications you previously issued.
Using Big View Styles
THIS LESSON TEACHES YOU TO
YOU SHOULD ALSO READ
- Notifications API Guide
- Intents and Intent Filters
- Notifications Design Guide
Notifications in the notification drawer appear in two main visual styles, normal view and big view. The big view of a notification only appears when the notification is expanded. This happens when the notification is at the top of the drawer, or the user clicks the notification.
Big views were introduced in Android 4.1, and they're not supported on older devices. This lesson describes how to incorporate big view notifications into your app while still providing full functionality via the normal view. See theNotifications API guide for more discussion of big views.
Here is an example of a normal view:
Figure 1. Normal view notification.
Here is an example of a big view:
Figure 2. Big view notification.
In the sample application shown in this lesson, both the normal view and the big view give users access to same functionality:
- The ability to snooze or dismiss the notification.
- A way to view the reminder text the user set as part of the timer.
The normal view provides these features through a new activity that launches when the user clicks the notification. Keep this in mind as you design your notifications—first provide the functionality in the normal view, since this is how many users will interact with the notification.
Set Up the Notification to Launch a New Activity
The sample application uses an IntentService
subclass (PingService
) to construct and issue the notification.
In this snippet, the IntentService
method onHandleIntent()
specifies the new activity that will be launched if the user clicks the notification itself. The method setContentIntent()
defines a pending intent that should be fired when the user clicks the notification, thereby launching the activity.
Intent resultIntent = new Intent(this, ResultActivity.class);
resultIntent.putExtra(CommonConstants.EXTRA_MESSAGE, msg);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Because clicking the notification launches a new ("special") activity,
// there's no need to create an artificial back stack.
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
); // This sets the pending intent that should be fired when the user clicks the
// notification. Clicking the notification launches a new activity.
builder.setContentIntent(resultPendingIntent);
Construct the Big View
This snippet shows how to set up the buttons that will appear in the big view:
// Sets up the Snooze and Dismiss action buttons that will appear in the
// big view of the notification.
Intent dismissIntent = new Intent(this, PingService.class);
dismissIntent.setAction(CommonConstants.ACTION_DISMISS);
PendingIntent piDismiss = PendingIntent.getService(this, 0, dismissIntent, 0); Intent snoozeIntent = new Intent(this, PingService.class);
snoozeIntent.setAction(CommonConstants.ACTION_SNOOZE);
PendingIntent piSnooze = PendingIntent.getService(this, 0, snoozeIntent, 0);
This snippet shows how to construct the Builder
object. It sets the style for the big view to be "big text," and sets its content to be the reminder message. It uses addAction()
to add the Snooze and Dismiss buttons (and their associated pending intents) that will appear in the notification's big view:
// Constructs the Builder object.
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(getString(R.string.notification))
.setContentText(getString(R.string.ping))
.setDefaults(Notification.DEFAULT_ALL) // requires VIBRATE permission
/*
* Sets the big view "big text" style and supplies the
* text (the user's reminder message) that will be displayed
* in the detail area of the expanded notification.
* These calls are ignored by the support library for
* pre-4.1 devices.
*/
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.addAction (R.drawable.ic_stat_dismiss,
getString(R.string.dismiss), piDismiss)
.addAction (R.drawable.ic_stat_snooze,
getString(R.string.snooze), piSnooze);
Displaying Progress in a Notification
THIS LESSON TEACHES YOU TO
YOU SHOULD ALSO READ
- Notifications API Guide
- Intents and Intent Filters
- Notifications Design Guide
Notifications can include an animated progress indicator that shows users the status of an ongoing operation. If you can estimate how long the operation takes and how much of it is complete at any time, use the "determinate" form of the indicator (a progress bar). If you can't estimate the length of the operation, use the "indeterminate" form of the indicator (an activity indicator).
Progress indicators are displayed with the platform's implementation of the ProgressBar
class.
To use a progress indicator, call setProgress()
. The determinate and indeterminate forms are described in the following sections.
Display a Fixed-duration Progress Indicator
To display a determinate progress bar, add the bar to your notification by calling setProgress(max, progress, false)
and then issue the notification. The third argument is a boolean that indicates whether the progress bar is indeterminate (true) or determinate (false). As your operation proceeds, increment progress
, and update the notification. At the end of the operation, progress
should equal max
. A common way to call setProgress()
is to setmax
to 100 and then increment progress
as a "percent complete" value for the operation.
You can either leave the progress bar showing when the operation is done, or remove it. In either case, remember to update the notification text to show that the operation is complete. To remove the progress bar, callsetProgress(0, 0, false)
. For example:
int id = 1;
...
mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_notification);
// Start a lengthy operation in a background thread
new Thread(
new Runnable() {
@Override
public void run() {
int incr;
// Do the "lengthy" operation 20 times
for (incr = 0; incr <= 100; incr+=5) {
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate"
// state
mBuilder.setProgress(100, incr, false);
// Displays the progress bar for the first time.
mNotifyManager.notify(id, mBuilder.build());
// Sleeps the thread, simulating an operation
// that takes time
try {
// Sleep for 5 seconds
Thread.sleep(5*1000);
} catch (InterruptedException e) {
Log.d(TAG, "sleep failure");
}
}
// When the loop is finished, updates the notification
mBuilder.setContentText("Download complete")
// Removes the progress bar
.setProgress(0,0,false);
mNotifyManager.notify(id, mBuilder.build());
}
}
// Starts the thread by calling the run() method in its Runnable
).start();
The resulting notifications are shown in figure 1. On the left side is a snapshot of the notification during the operation; on the right side is a snapshot of it after the operation has finished.
Figure 1. The progress bar during and after the operation.
Display a Continuing Activity Indicator
To display a continuing (indeterminate) activity indicator, add it to your notification with setProgress(0, 0, true)
and issue the notification. The first two arguments are ignored, and the third argument declares that the indicator is indeterminate. The result is an indicator that has the same style as a progress bar, except that its animation is ongoing.
Issue the notification at the beginning of the operation. The animation will run until you modify your notification. When the operation is done, call setProgress(0, 0, false)
and then update the notification to remove the activity indicator. Always do this; otherwise, the animation will run even when the operation is complete. Also remember to change the notification text to indicate that the operation is complete.
To see how continuing activity indicators work, refer to the preceding snippet. Locate the following lines:
// Sets the progress indicator to a max value, the current completion
// percentage, and "determinate" state
mBuilder.setProgress(100, incr, false);
// Issues the notification
mNotifyManager.notify(id, mBuilder.build());
Replace the lines you've found with the following lines. Notice that the third parameter in the setProgress()
call is set to true
to indicate that the progress bar is indeterminate:
// Sets an activity indicator for an operation of indeterminate length
mBuilder.setProgress(0, 0, true);
// Issues the notification
mNotifyManager.notify(id, mBuilder.build());
The resulting indicator is shown in figure 2:
Figure 2. An ongoing activity indicator.
Android设计和开发系列第一篇:Notifications通知(Develop—Training)的更多相关文章
- Android设计和开发系列第一篇:Notifications通知(Design)
Design篇 Notifications The notification system allows users to keep informed about relevant and timel ...
- Android设计和开发系列第一篇:Notifications通知(Develop—API Guides)
Notifications IN THIS DOCUMENT Design Considerations Creating a Notification Required notification c ...
- Android设计和开发系列第二篇:Navigation Drawer(Develop)
Creating a Navigation Drawer THIS LESSON TEACHES YOU TO: Create a Drawer Layout Initialize the Drawe ...
- Android设计和开发系列第二篇:Action Bar(Develop—Training)
Adding the Action Bar GET STARTED DEPENDENCIES AND PREREQUISITES Android 2.1 or higher YOU SHOULD AL ...
- Android设计和开发系列第二篇:Action Bar(Develop—API Guides)
Action Bar IN THIS DOCUMENT Adding the Action Bar Removing the action bar Using a logo instead of an ...
- Android设计和开发系列第二篇:Action Bar(Design)
Action Bar The action bar is a dedicated piece of real estate at the top of each screen that is gene ...
- Android设计和开发系列第二篇:Navigation Drawer(Design)
Navigation Drawer Creating a Navigation Drawer The navigation drawer is a panel that transitions in ...
- [转载] Android Metro风格的Launcher开发系列第一篇
前言:从毕业到现在已经三年多了,回忆一下这三年基本上没有写过博客,总是觉得忙,没时间写,也觉得写博客没什么大用.但是看到很多大牛们都在写博客,分享自己的东西,所以嘛本着向大牛看齐,分享第一,记录第二的 ...
- Android Metro风格的Launcher开发系列第一篇
前言:从毕业到现在已经三年多了,回忆一下这三年基本上没有写过博客,总是觉得忙,没时间写,也觉得写博客没什么大用.但是看到很多大牛们都在写博客,分享自己的东西,所以嘛本着向大牛看齐,分享第一,记录第二的 ...
随机推荐
- Java如何以短格式显示月份?
在Java中,如何显示短格式的月份名称? 使用DateFormatSymbols().DateFormatSymbols类的getShortMonths()方法,本示例显示了几个月的简写名称. pac ...
- Unity---------Mesh理解
Mesh顾名思义“网格”,Unity3D里面所有的模型都是由Mesh组成的,UI也不例外. 例如下图,模型上的一个个小网格就是Mesh,这些Mesh有不同的三维顶点(Vector3),共同组成了一个3 ...
- 50.EasyGank妹纸App
50.EasyGank妹纸App 前言 基于MVP模式下 , RxJava+RxAndroid+Retrofit的组合 . RxJava RxAndroid Retrofit Okhttp Gson ...
- 两个大数组foreach,找出相同的key数量,所用的时间对比
<?php function microtime_float() { list($usec, $sec) = explode(" ", microtime()); retur ...
- 【WP8】键盘弹出时控制Frame位置
WP上,当使用TextBox输入文字的时候,键盘会把TextBox向上推一段距离 当编辑第二个TextBox的时候,页面被上推,键盘刚好和TextBox靠在一起 当编辑第一个TextBox的时候,页面 ...
- Spring Boot 添加JSP支持【转】
Spring Boot 添加JSP支持 大体步骤: (1) 创建Maven web project: (2) 在pom.xml文件添加依赖: (3) ...
- Android学习笔记——保存文件(Saving Files)
本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论. 欢迎转载,转载请注明网址:http://www.cnblogs.com/J ...
- 针对降质模型中的模糊SR
(PDF) Deep Plug-and-Play Super-Resolution for Arbitrary Blur Kernels https://www.researchgate.net/pu ...
- Cannot call sendError() after the response has been committed - baiyangliu
当response提交后,不能调用sendError(),什么意思? 出现这个错误,一定是多次response导致的.可以这么理解,承载客户端和服务器进行Http交互的Socket连接已经关闭了,而你 ...
- Git项目协同开发学习笔记2:项目库开发协作相关命令
之前介绍了如何用git构建项目库及其后续操作的问题,但主要还是个人的操作问题,不太涉及到项目协作方面的问题,所以来说下这块.传送门在这里(后面的可以不用看了). 1.同步 首先就式同步问题:在项目协作 ...