通知----点击通知启动activity时保留导航

启动 Activity 时保留导航


从通知中启动 Activity 时,您必须保留用户的预期导航体验。 点击“返回”应该使用户将应用的正常工作流回退到主屏幕,而点击“最新动态”则应将Activity 显示为单独的任务。 要保留导航体验,您应该在全新任务中启动 Activity。如何设置 PendingIntent 以获得全新任务取决于正在启动的Activity 的性质。一般有两种情况:

常规 Activity
您要启动的  Activity 是应用的正常工作流的一部分。在这种情况下,请设置  PendingIntent 以启动全新任务并为  PendingIntent提供返回栈,这将重现应用的正常“返回”行为。

Gmail 应用中的通知演示了这一点。点击一封电子邮件消息的通知时,您将看到消息具体内容。 触摸返回将使您从 Gmail 回退到主屏幕,就好像您是从主屏幕(而不是通知)进入 Gmail 一样。

无论您触摸通知时处于哪个应用,都会发生这种情况。 例如,如果您在 Gmail 中撰写消息时点击了一封电子邮件的通知,则会立即转到该电子邮件。 触摸“返回”会依次转到收件箱和主屏幕,而不是转到您在撰写的邮件。

特殊 Activity
仅当从通知中启动时,用户才会看到此  Activity。 从某种意义上说, Activity 是通过提供很难显示在通知本身中的信息来扩展通知。对于这种情况,请将  PendingIntent 设置为在全新任务中启动。但是,由于启动的  Activity 不是应用 Activity 流程的一部分,因此无需创建返回栈。点击“返回”仍会将用户带到主屏幕。

设置常规 Activity PendingIntent

要设置可启动直接进入 Activity 的 PendingIntent,请执行以下步骤:

  1. 在清单文件中定义应用的 Activity 层次结构。
    1. 添加对 Android 4.0.3 及更低版本的支持。为此,请通过添加 <meta-data> 元素作为 <activity>的子项来指定正在启动的 Activity 的父项。

      对于此元素,请设置 android:name="android.support.PARENT_ACTIVITY"。 设置 android:value="<parent_activity_name>",其中,<parent_activity_name> 是父 <activity> 元素的 android:name 值。请参阅下面的 XML 示例。

    2. 同样添加对 Android 4.1 及更高版本的支持。为此,请将 android:parentActivityName 属性添加到正在启动的 Activity 的 <activity> 元素中。

    最终的 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 创建返回栈:
    1. 创建 Intent 以启动 Activity
    2. 通过调用 TaskStackBuilder.create() 创建堆栈生成器。
    3. 通过调用 addParentStack() 将返回栈添加到堆栈生成器。 对于在清单文件中所定义层次结构内的每个 Activity,返回栈均包含可启动 Activity 的Intent 对象。此方法还会添加一些可在全新任务中启动堆栈的标志。

      注:尽管 addParentStack() 的参数是对已启动 Activity 的引用,但是方法调用不会添加可启动 Activity 的 Intent,而是留待下一步进行处理。

    4. 通过调用 addNextIntent(),添加可从通知中启动 Activity 的 Intent。 将在第一步中创建的 Intent 作为 addNextIntent() 的参数传递。
    5. 如需,请通过调用 TaskStackBuilder.editIntentAt() 向堆栈中的 Intent 对象添加参数。有时,需要确保目标 Activity 在用户使用“返回”导航回它时会显示有意义的数据。
    6. 通过调用 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 无需返回栈,因此您不必在清单文件中定义其 Activity 层次结构,也不必调用 addParentStack() 来构建返回栈。取而代之的是,您可使用清单文件设置 Activity 任务选项,并通过调用 getActivity() 创建 PendingIntent

  1. 在清单文件中,将以下属性添加到 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. 构建并发出通知:
    1. 创建可启动 Activity的 Intent
    2. 通过使用 FLAG_ACTIVITY_NEW_TASK 和 FLAG_ACTIVITY_CLEAR_TASK 标志调用 setFlags(),将 Activity 设置为在新的空任务中启动。
    3. 为 Intent 设置所需的任何其他选项。
    4. 通过调用 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、付费专栏及课程。

余额充值