Bắt đầu một hoạt động trên thông báo
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Khi bắt đầu một hoạt động trên một thông báo, bạn phải giữ nguyên thông tin
trải nghiệm điều hướng dự kiến. Thao tác nhấn vào nút Quay lại sẽ đưa người dùng quay lại
qua quy trình công việc thông thường của ứng dụng đến Màn hình chính và mở mục Gần đây
màn hình phải hiển thị hoạt động dưới dạng một tác vụ riêng biệt. Để duy trì lộ trình di chuyển này
trải nghiệm, hãy bắt đầu hoạt động trong một tác vụ mới.
Phương pháp cơ bản để thiết lập hành vi nhấn cho thông báo được mô tả trong
Tạo một quy tắc cơ bản
thông báo.
Trang này mô tả cách thiết lập
PendingIntent
cho
hành động của thông báo để tạo một tác vụ và thao tác quay lại mới
ngăn xếp. Cách thực hiện
phụ thuộc vào loại hoạt động bạn đang bắt đầu:
- Hoạt động thông thường
- Đây là hoạt động nằm trong quy trình trải nghiệm người dùng thông thường của ứng dụng. Thời gian
người dùng truy cập vào hoạt động từ thông báo, thì tác vụ mới phải
bao gồm một ngăn xếp lui hoàn chỉnh, cho phép người dùng nhấn vào nút Quay lại để điều hướng
lên hệ thống phân cấp ứng dụng.
- Hoạt động đặc biệt
- Người dùng chỉ nhìn thấy hoạt động này nếu hoạt động bắt đầu từ một thông báo. Trong một
hoạt động này mở rộng giao diện người dùng của thông báo bằng cách cung cấp thông tin
rất khó để hiển thị trong thông báo. Hoạt động này không cần có
ngăn xếp lui.
Thiết lập một PendingIntent hoạt động thông thường
Để bắt đầu một hoạt động thông thường từ thông báo của bạn, hãy thiết lập PendingIntent
sử dụng TaskStackBuilder
để tạo một ngăn xếp lui mới như sau.
Xác định Hệ phân cấp hoạt động của ứng dụng
Xác định hệ phân cấp tự nhiên cho các hoạt động của bạn bằng cách thêm phương thức
android:parentActivityName
cho mỗi <activity>
trong tệp kê khai ứng dụng. Hãy xem ví dụ sau:
<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>
Tạo PendingIntent bằng ngăn xếp lui
Để bắt đầu một hoạt động bao gồm một ngăn xếp lui gồm các hoạt động, hãy tạo một
thực thể của TaskStackBuilder
và gọi
addNextIntentWithParentStack()
,
truyền phương thức này Intent
cho
mà bạn muốn bắt đầu.
Miễn là bạn xác định hoạt động gốc cho từng hoạt động như mô tả
sớm hơn, bạn có thể gọi
getPendingIntent()
để nhận một PendingIntent
bao gồm toàn bộ ngăn xếp lui.
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);
Nếu cần, bạn có thể thêm đối số vào đối tượng Intent
trong ngăn xếp bằng cách gọi
TaskStackBuilder.editIntentAt()
.
Điều này đôi khi cần thiết để đảm bảo rằng một hoạt động trong ngăn xếp lui
hiển thị dữ liệu có ý nghĩa khi người dùng chuyển đến đó.
Sau đó, bạn có thể chuyển PendingIntent
đến thông báo như bình thường:
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());
Thiết lập một hoạt động đặc biệt PendingIntent
Vì hoạt động đặc biệt bắt đầu từ thông báo không cần quay lại
ngăn xếp, bạn có thể tạo PendingIntent
bằng cách gọi
getActivity()
.
Tuy nhiên, hãy xác định các tuỳ chọn tác vụ thích hợp trong tệp kê khai.
-
Trong tệp kê khai, hãy thêm các thuộc tính sau vào
Phần tử
<activity>
.
-
android:taskAffinity=""
-
Kết hợp với
FLAG_ACTIVITY_NEW_TASK
cờ mà bạn sử dụng trong mã, hãy đặt thuộc tính này trống để đảm bảo
hoạt động này không nằm trong tác vụ mặc định của ứng dụng. Bất kỳ hạng nào
các công việc hiện tại có đối tượng tương đồng mặc định của ứng dụng không
bị ảnh hưởng.
-
android:excludeFromRecents="true"
-
Loại trừ tác vụ mới khỏi màn hình Gần đây để người dùng
không thể vô tình quay lại đó.
Lệnh này được minh hoạ trong ví dụ sau:
<activity
android:name=".ResultActivity"
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>
-
Tạo và đưa ra thông báo:
-
Tạo một
Intent
để khởi động
Activity
-
Đặt
Activity
để bắt đầu trong một tác vụ mới, trống bằng cách
đang gọi
setFlags()
với các cờ FLAG_ACTIVITY_NEW_TASK
và
FLAG_ACTIVITY_CLEAR_TASK
.
-
Tạo
PendingIntent
bằng cách gọi
getActivity()
Lệnh này được minh hoạ trong ví dụ sau:
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
);
- Truyền
PendingIntent
vào thông báo như bình thường:
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());
Để biết thêm thông tin về các tuỳ chọn tác vụ và cách ngăn xếp lui
hoạt động, xem phần Tác vụ và ngăn xếp lui.
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-07-27 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-07-27 UTC."],[],[],null,["# Start an Activity from a Notification\n\nWhen you start an activity from a notification, you must preserve the user's\nexpected navigation experience. Tapping the Back button must take the user back\nthrough the app's normal work flow to the Home screen, and opening the Recents\nscreen must show the activity as a separate task. To preserve this navigation\nexperience, start the activity in a fresh task.\n\nThe basic approach to set the tap behavior for your notification is described in\n[Create a basic\nnotification](/develop/ui/views/notifications/build-notification#SimpleNotification).\nThis page describes how to set up a\n[`PendingIntent`](/reference/android/app/PendingIntent) for your\nnotification's action so it creates a fresh [task and back\nstack](/guide/components/activities/tasks-and-back-stack). How you do this\ndepends on which type of activity you're starting:\n\nRegular activity\n: This is an activity that exists as a part of your app's normal UX flow. When\n the user arrives in the activity from the notification, the new task must\n include a complete back stack, letting the user tap the Back button to navigate\n up the app hierarchy.\n\nSpecial activity\n: The user only sees this activity if it's started from a notification. In a\n sense, this activity extends the notification UI by providing information that\n is difficult to display in the notification itself. This activity doesn't need a\n back stack.\n\nSet up a regular activity PendingIntent\n---------------------------------------\n\nTo start a regular activity from your notification, set up the `PendingIntent`\nusing [`TaskStackBuilder`](/reference/androidx/core/app/TaskStackBuilder)\nso that it creates a new back stack as follows.\n\n### Define your app's Activity hierarchy\n\nDefine the natural hierarchy for your activities by adding the\n[`android:parentActivityName`](/guide/topics/manifest/activity-element#parent)\nattribute to each [`\u003cactivity\u003e`](/guide/topics/manifest/activity-element)\nelement in your app manifest file. See the following example: \n\n```xml\n\u003cactivity\n android:name=\".MainActivity\"\n android:label=\"@string/app_name\" \u003e\n \u003cintent-filter\u003e\n \u003caction android:name=\"android.intent.action.MAIN\" /\u003e\n \u003ccategory android:name=\"android.intent.category.LAUNCHER\" /\u003e\n \u003c/intent-filter\u003e\n\u003c/activity\u003e\n\u003c!-- MainActivity is the parent for ResultActivity. --\u003e\n\u003cactivity\n android:name=\".ResultActivity\"\n android:parentActivityName=\".MainActivity\" /\u003e\n ...\n\u003c/activity\u003e\n```\n\n### Build a PendingIntent with a back stack\n\nTo start an activity that includes a back stack of activities, create an\ninstance of `TaskStackBuilder` and call\n[`addNextIntentWithParentStack()`](/reference/androidx/core/app/TaskStackBuilder#addNextIntentWithParentStack(android.content.Intent)),\npassing it the [`Intent`](/reference/android/content/Intent) for the\nactivity you want to start.\n\nAs long as you define the parent activity for each activity as described\nearlier, you can call\n[`getPendingIntent()`](/reference/androidx/core/app/TaskStackBuilder#getPendingIntent(int,int))\nto receive a `PendingIntent` that includes the entire back stack. \n\n### Kotlin\n\n```kotlin\n// Create an Intent for the activity you want to start.\nval resultIntent = Intent(this, ResultActivity::class.java)\n// Create the TaskStackBuilder.\nval resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run {\n // Add the intent, which inflates the back stack.\n addNextIntentWithParentStack(resultIntent)\n // Get the PendingIntent containing the entire back stack.\n getPendingIntent(0,\n PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)\n}\n```\n\n### Java\n\n```java\n// Create an Intent for the activity you want to start.\nIntent resultIntent = new Intent(this, ResultActivity.class);\n// Create the TaskStackBuilder and add the intent, which inflates the back\n// stack.\nTaskStackBuilder stackBuilder = TaskStackBuilder.create(this);\nstackBuilder.addNextIntentWithParentStack(resultIntent);\n// Get the PendingIntent containing the entire back stack.\nPendingIntent resultPendingIntent =\n stackBuilder.getPendingIntent(0,\n PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);\n```\n\nIf necessary, you can add arguments to `Intent` objects in the stack by calling\n[`TaskStackBuilder.editIntentAt()`](/reference/androidx/core/app/TaskStackBuilder#editIntentAt(int)).\nThis is sometimes necessary to ensure that an activity in the back stack\ndisplays meaningful data when the user navigates to it.\n\nThen you can pass the `PendingIntent` to the notification as usual: \n\n### Kotlin\n\n```kotlin\nval builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {\n setContentIntent(resultPendingIntent)\n ...\n}\nwith(NotificationManagerCompat.from(this)) {\n notify(NOTIFICATION_ID, builder.build())\n}\n```\n\n### Java\n\n```java\nNotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);\nbuilder.setContentIntent(resultPendingIntent);\n...\nNotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);\nnotificationManager.notify(NOTIFICATION_ID, builder.build());\n```\n\nSet up a special activity PendingIntent\n---------------------------------------\n\nBecause a special activity that starts from a notification doesn't need a back\nstack, you can create the `PendingIntent` by calling\n[`getActivity()`](/reference/android/app/PendingIntent#getActivity(android.content.Context,%20int,%20android.content.Intent,%20int)).\nHowever, define the appropriate task options in the manifest.\n\n1. In your manifest, add the following attributes to the `\u003cactivity\u003e` element.\n\n\n [android:taskAffinity](/guide/topics/manifest/activity-element#aff)`=\"\"`\n :\n Combined with the\n [FLAG_ACTIVITY_NEW_TASK](/reference/android/content/Intent#FLAG_ACTIVITY_NEW_TASK)\n flag that you use in code, set this attribute blank to ensure\n this activity doesn't go into the app's default task. Any\n existing tasks that have the app's default affinity aren't\n affected.\n\n\n [android:excludeFromRecents](/guide/topics/manifest/activity-element#exclude)`=\"true\"`\n :\n Excludes the new task from the Recents screen so that the user\n can't accidentally navigate back to it.\n\n\n This is shown in the following example: \n\n ```xml\n \u003cactivity\n android:name=\".ResultActivity\"\n android:launchMode=\"singleTask\"\n android:taskAffinity=\"\"\n android:excludeFromRecents=\"true\"\u003e\n \u003c/activity\u003e\n ```\n2. Build and issue the notification:\n 1. Create an `Intent` that starts the [Activity](/reference/android/app/Activity).\n 2. Set the `Activity` to start in a new, empty task by calling [setFlags()](/reference/android/content/Intent#setFlags(int)) with the flags `FLAG_ACTIVITY_NEW_TASK` and [FLAG_ACTIVITY_CLEAR_TASK](/reference/android/content/Intent#FLAG_ACTIVITY_CLEAR_TASK).\n 3. Create a `PendingIntent` by calling `getActivity()`.\n\n\n This is shown in the following example: \n\n ### Kotlin\n\n ```kotlin\n val notifyIntent = Intent(this, ResultActivity::class.java).apply {\n flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK\n }\n val notifyPendingIntent = PendingIntent.getActivity(\n this, 0, notifyIntent,\n PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\n )\n ```\n\n ### Java\n\n ```java\n Intent notifyIntent = new Intent(this, ResultActivity.class);\n // Set the Activity to start in a new, empty task.\n notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK\n | Intent.FLAG_ACTIVITY_CLEAR_TASK);\n // Create the PendingIntent.\n PendingIntent notifyPendingIntent = PendingIntent.getActivity(\n this, 0, notifyIntent,\n PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE\n );\n ```\n3. Pass the `PendingIntent` to the notification as usual: \n\n ### Kotlin\n\n ```kotlin\n val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {\n setContentIntent(notifyPendingIntent)\n ...\n }\n with(NotificationManagerCompat.from(this)) {\n notify(NOTIFICATION_ID, builder.build())\n }\n ```\n\n ### Java\n\n ```java\n NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);\n builder.setContentIntent(notifyPendingIntent);\n ...\n NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);\n notificationManager.notify(NOTIFICATION_ID, builder.build());\n ```\n\nFor more information about the various task options and how the back stack\nworks, see [Tasks and the back stack](/guide/components/activities/tasks-and-back-stack)."]]