通过通知打开一个Activity时保留导航

当你通过通知打开一个Activity时,你必须保留用户期望的导航体验。当点击back键时,你应该将用户带到Home 界面,并且你应该显示那个Activity作为一个隔离的任务(task)。为了保留导航体验,你应该在一个新的任务(task)中显示Activity。如何在一个新的任务(task)中启动一个 PendingIntent取决于你要启动的Activity的性质。这里有两个一般的情况:

1. 一般Activity

你打开的Activity是你的应用程序正常工作流程的一部分。在这种情况下,在一个新的任务(task)中启动 PendingIntent,并且给PendingIntent 提供一个回退栈用来复制应用程序的常规的返回操作。

2.  特殊的Activity

如果使用通知进入的话用户仅仅看到进入的这个Activity。有一种场景,就是一个Activity提供那些一个通知很难展示的信息。在这种情况下,在一个新的任务中启动一个PendingIntent。没有必要创建一个回退栈,因为启动的那个Activity并不是应用程序Activity的一部分。点击返回仍然会将用户带到Home 界面。

  • 建立一个一般的PendingIntent

建立一个直接打开Activity的PendingIntent,要按照下面的步骤:

1.  在manifest文件中定义你的应用程序的Activity层级
a.为Android4.0.3及更早版本添加支持。为此,通过添加<meta-data>元素作为<activity>的子元素指定你要打开的Activity的父Activity。
对于这个元素,设置 android:name=”android.support.PARENT_ACTIVITY”.设置 android:value=”<parent_activity_name>” ,<parent_activity_name>是<activity>子元素android:name 的值。
b.也要为Android4.1及之后的版本添加支持。为此,为你要打开的Activity的<activity>元素添加android:parentActivityName 属性。
最终的xml文件是这样的:

<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创建一个回退栈

a.创建一个Intent来启动Activity。
b.通过调用TaskStackBuilder.create() 来创建一个栈。
c.通过调用 addParentStack() 将回退栈添加到之前创建的那个栈中。对于任意一个你在manifest中定义的Activity,这个回退栈包含一个 Intent 对象来开始这个Activity。这种方法仍然添加了一个在新任务中打开这个栈的标志标志。

注意:尽管addParentStack()  的参数是一个要开启Activity的引用,但是这个方法并没有添加要打开的Activity的Intent。反而,你要注意下面的这一步。
d.通过调用 addNextIntent() 添加从通知进入的那个Activity的Intent,将这个Intent作为参数传递给addNextIntent()。
e.如果需要的话,通过调用 TaskStackBuilder.editIntentAt() 将参数Intent添加栈中。有些时候当用户利用返回键导航到这个Activity的时候要确保目标Activit显示有意义的数据。

f.通过调用 getPendingIntent() 来从这个回退栈中得到PendingIntent。稍后你可以利用这个PendingIntent作为方法 setContentIntent() 的参数。

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的PendingIntent

一个特殊Activity的PendingIntent不需要使用回退栈,所以你不需要在manifest文件中定义Activity的层级结构,并且也不需要调用 addParentStack() 来构建一个回退栈。取而代之的是,使用manifest文件建立Activity的任务选项,并且通过调用 getActivity()创建PendingIntent。

1.在你的manifest文件中,为Activity的<activity>元素添加以下属性:
android:name = “activityclass”
    Activity的全类名
android:taskAffinity=””
    结合你设置在代码中的标志 FLAG_ACTIVITY_NEW_TASK ,这会确保这个Activity不会进入到应用程序默认的任务。一些已经存在的与应用程序默认任务相同的任务不会受影响。

android:excludeFromRecents=”true”

    从最近你的任务中排除新的任务,这样一来用户就不会无意中导航到它。

下面的代码片段显示了这个元素:

<activity
    android:name=".ResultActivity"
...
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>

2.构建并显示通知
    a.创建一个启动ActivityIntent

    b.通过使用标志FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK调用 setFlags() 方法设置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(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 notifyPendingIntent =
        PendingIntent.getActivity(
        this,
        0,
        notifyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
);

// Puts the PendingIntent into the notification builder
builder.setContentIntent(notifyPendingIntent);
// 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个

红包金额最低5元

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

抵扣说明:

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

余额充值