從通知啟動活動

透過通知啟動活動時,您必須保留使用者預期的導航體驗。輕觸「返回」按鈕必須讓使用者返回應用程式的一般工作流程前往主畫面,並開啟「最近使用」畫面,活動必須以獨立任務的形式顯示。為保留這項導覽體驗,請採取新的工作來啟動活動。

請參閱「建立基本通知」一文,瞭解為通知設定輕觸行為的基本方式。本頁面說明如何為通知動作設定 PendingIntent,以便建立新的工作和返回堆疊。具體方式視您要開始的活動類型而定:

固定活動
此活動會在應用程式正常的使用者體驗流程中發揮作用。當使用者透過通知進入活動時,新工作必須包含完整的返回堆疊,讓使用者輕觸「返回」按鈕可向上瀏覽應用程式階層。
特殊活動
使用者只會看到從通知啟動的活動。基本上,這個活動會提供難以顯示在通知本身中的資訊,藉此擴充通知 UI。這個活動不需要返回堆疊。

設定一般活動 PendingIntent

如要透過通知啟動一般活動,請使用 TaskStackBuilder 設定 PendingIntent,以便按照下列方式建立新的返回堆疊。

定義應用程式的活動階層

在應用程式資訊清單檔案中的每個 <activity> 元素中加入 android:parentActivityName 屬性,藉此定義活動的自然階層。請參閱以下範例:

<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>
<!-- MainActivity is the parent for ResultActivity. -->
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity" />
    ...
</activity>

使用返回堆疊建構 PendingIntent

如要啟動包含活動返回堆疊的活動,請建立 TaskStackBuilder 的執行個體並呼叫 addNextIntentWithParentStack(),針對您要啟動的活動傳遞 Intent

只要您按照上述步驟為每個活動定義父項活動,就可以呼叫 getPendingIntent() 來接收內含整個返回堆疊的 PendingIntent

Kotlin

// Create an Intent for the activity you want to start.
val resultIntent = Intent(this, ResultActivity::class.java)
// Create the TaskStackBuilder.
val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run {
    // Add the intent, which inflates the back stack.
    addNextIntentWithParentStack(resultIntent)
    // Get the PendingIntent containing the entire back stack.
    getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}

Java

// Create an Intent for the activity you want to start.
Intent resultIntent = new Intent(this, ResultActivity.class);
// Create the TaskStackBuilder and add the intent, which inflates the back
// stack.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack.
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

如有需要,您可以呼叫 TaskStackBuilder.editIntentAt(),將引數新增至堆疊中的 Intent 物件。有時,必須確保返回堆疊中的活動在使用者前往活動時能夠顯示有意義的資料。

接著,您可以照常將 PendingIntent 傳遞至通知:

Kotlin

val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
    setContentIntent(resultPendingIntent)
    ...
}
with(NotificationManagerCompat.from(this)) {
    notify(NOTIFICATION_ID, builder.build())
}

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentIntent(resultPendingIntent);
...
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(NOTIFICATION_ID, builder.build());

設定特殊活動 PendingIntent

由於從通知啟動的特殊活動不需要返回堆疊,因此您可以呼叫 getActivity() 來建立 PendingIntent。然而,在資訊清單中定義適當的工作選項。

  1. 在資訊清單中,將下列屬性新增至 <activity> 元素。
    android:taskAffinity=""
    與您在程式碼中使用的 FLAG_ACTIVITY_NEW_TASK 旗標結合,因此請將這項屬性設為空白,確保這項活動不會納入應用程式的預設任務。任何具備應用程式預設相依性的現有工作都不會受到影響。
    android:excludeFromRecents="true"
    從「最近使用」畫面排除新任務,以免使用者意外返回。

    如以下範例所示:

    <activity
        android:name=".ResultActivity"
        android:launchMode="singleTask"
        android:taskAffinity=""
        android:excludeFromRecents="true">
    </activity>
    
  2. 建構並發出通知:
    1. 建立啟動 ActivityIntent
    2. 使用 FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK 標記呼叫 setFlags(),設定 Activity 開始新的空白工作。
    3. 呼叫 getActivity() 來建立 PendingIntent

    如以下範例所示:

    Kotlin

    val notifyIntent = Intent(this, ResultActivity::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    val notifyPendingIntent = PendingIntent.getActivity(
            this, 0, notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )
    

    Java

    Intent notifyIntent = new Intent(this, ResultActivity.class);
    // Set the Activity to start in a new, empty task.
    notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    // Create the PendingIntent.
    PendingIntent notifyPendingIntent = PendingIntent.getActivity(
            this, 0, notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );
    
  3. 照常將 PendingIntent 傳遞至通知:

    Kotlin

    val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
        setContentIntent(notifyPendingIntent)
        ...
    }
    with(NotificationManagerCompat.from(this)) {
        notify(NOTIFICATION_ID, builder.build())
    }
    

    Java

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
    builder.setContentIntent(notifyPendingIntent);
    ...
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    notificationManager.notify(NOTIFICATION_ID, builder.build());
    

如要進一步瞭解各種工作選項和返回堆疊的運作方式,請參閱「工作和返回堆疊」。