Android 官网Train阅读记录——6

LZ阅读的是中文翻译版本:http://hukai.me/android-training-course-in-chinese/basics/activity-lifecycle/recreating.html,试验机系统版本7.1。

10、Android交互设计

10.3 通知提示用户

10.3.1 建立Notification

以下的例子都是基于NotificationCompat.Builder,它在Support Library中。

创建Notification时,可以用NotificationCompat.Builder指定Notification的UI内容与行为。一个Builder至少包含以下内容:

  • 一个小的icon,用setSmallIcon方法设置
  • 一个标题,用setContentTitle方法设置
  • 详细的文本内容,用setContentText方法设置

NotificationCompat.Builder mBuilder =
    new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("My notification")
    .setContentText("Hello World!");


定义Notification的行为

行为可以让用户从Notification进入App的Activity,在这个Activity中他们可以查看引起Notification的事件或者做下一步的处理。在Notification中,行为本身是由PendingIntent定义的,PendingIntent包含了一个启动App内Activity的Intent。

如何构建一个PendingIntent取决于要启动的Activity的类型。当从Notification中启动一个Activity时,必须保存用户的导航体验。

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
);


设置Notification的点击行为
可以通过调用Notification.Builder的setContentIntent方法将上一步定义的Notification的行为添加进去

PendingIntent resultPendingIntent;
...
mBuilder.setContentIntent(resultPendingIntent);


发布Notification

步骤:

  1. 获取一个NotificationManager对象
  2. 调用Notification.Builder对象的build方法创建通知
  3. 调用NotificationManager对象的notify方法完成发布通知的操作

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());

10.3.2  启动Activity时保留导航

设置一个常规的ActivityPendingIntent

设置一个直接启动的入口Activity的PendingIntent,遵循以下步骤:

1、在Manifest中定义application的Activity层次,最终的Manifest文件应该像下面这样:

<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>
2、在基于启动Activity的Intent中创建一个返回栈,如:

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());


设置一个特定的Activity PendingIntent

一个特定的Activity不需要一个返回栈,所以你不需要在Manifest中定义Activity的层次,你也不需要调用addParentStack方法去构建一个返回栈。作为代替,你需要用Manifest设置Activity任务选项,以及调用getActivity方法创建PendingIntent

1、Manifest中,在Activity的标签中增加下列属性:

  • android:name="activityclass" Activity的完整类名
  • android:taskAffinity="" 结合代码里设置的FLAG_ACTIVITY_NEW_TASK标识,确保这个Activity不会进入Application的默认任务。任何与Application的默认任务有密切关系的任务都不会受到影响
  • android:excludeFromRecents="true" 将新任务从最近列表中排除,目的是为了避免用户不小心返回到它

2、建立以及发布通知:

a、创建一个启动Activity的Intent

b、通过调用setFlags方法并设置标识FLAG_ACTIVITY_NEW_TASK与FLAG_ACTIVITY_CLEAR_TASK,来设置Activity在一个新的,空的任务中启动

c、在Intent中设置其他需要的选项

d、通过调用getActivity方法从Intent中创建一个PendingIntent,你可以把这个PendingIntent当做setContentIntent的参数来使用

// 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());

10.3.3 更新Notification

当你需要对同一事件发布多次通知时,你应该避免每次都生成一个新的通知对象。相反,你应该考虑去更新先前的通知对象,或者改变它的值,或者增加一些值,或者两者同时进行。


更新一个通知

想要创建一个可以被更新的通知,需要在发布它的时候调用NotificationManager的notify(id,notification)方法为它指定一个id。更新一个已经发布的通知,需要更新或者创建一个Notification.Builder对象,并从这个对象创建一个Notification对象,然后用与先前一样的id去发布这个Notification。

如:

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());
...


移除Notification

Notification将持续可见,除非下面任何一种情况发生:

  • 用户通过通知抽屉清除单独的或者所有通知
  • 你在创建通知时调用了Notification.Builder的setAutoCancel(true)方法
  • 你为一个指定了id的Notification调用了NotificationManager的cancel(id)方法
  • 你调用了NotificationManager的cancelAll方法


10.3.5 显示Notification进度

展示固定长度的进度指示器

为了展示一个确定长度的进度条,调用setProgress(max, progress, false)方法将进度条添加进Notification,然后发布,第三个参数是个boolean类型变量,决定进度条是不确定的(true)还是确定的(false)。在你操作进行时,增加progress,更新Notification。在操作结束时,progress应该等于max。一个常用的调用setProgress的方法是设置max为100,然后增加progress就像做做的“完成百分比”。

当操作完成的时候,你可以选择让进度条继续展示,或者移除它。无论哪种情况下,记得更新Notification的文字来显示操作完成。

移除进度条,可以通过调用setProgress(0, 0, false)方法来实现。

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();


展示持续活动的指示器
为了展示一个持续活动的指示器,用setProgress(0, 0, true)方法把指示器添加进Notification,然后发布。前两个参数忽略,第三个参数表示进度是不确定的。

在操作开始的时候发布Notification,动画将会一直进行直到你更新Notification。当操作完成时,调用setProgress(0, 0, false)方法,然后更新Notification来移除这个动画指示器。一定要这么做,否则即使你操作完成了,动画还是会在那继续运行。同时也要记得更新Notification的文字来显示操作完成。

基本的代码和上面差不多,只要将下面这行修改一下

// Sets the progress indicator to a max value, the current completion
// percentage, and "determinate" state
mBuilder.setProgress(100, incr, false);
改为

// Sets an activity indicator for an operation of indeterminate length
mBuilder.setProgress(0, 0, true);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值