Bắt đầu một hoạt động trên thông báo

Khi bắt đầu một hoạt động từ một thông báo, bạn phải duy trì trải nghiệm điều hướng dự kiến của người dùng. Việc nhấn vào nút Quay lại sẽ đưa người dùng quay lại Màn hình chính thông qua quy trình làm việc thông thường của ứng dụng. Việc mở màn hình Gần đây phải hiển thị hoạt động dưới dạng một tác vụ riêng biệt. Để duy trì trải nghiệm điều hướng này, 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 phần Tạo thông báo cơ bản. Trang này mô tả cách thiết lập PendingIntent cho thao tác của thông báo để tạo một tác vụ và ngăn xếp lui mới. Cách thực hiện việc này tuỳ thuộc vào loại hoạt động bạn đang bắt đầu:

Hoạt động thông thường
Đây là một 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. Khi người dùng đến hoạt động từ thông báo, nhiệm 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 để di chuyển lên hệ phân cấp ứng dụng.
Hoạt động đặc biệt
Người dùng chỉ thấy hoạt động này nếu hoạt động bắt đầu từ thông báo. Về phía, hoạt động này mở rộng giao diện người dùng thông báo bằng cách cung cấp thông tin khó hiển thị trong chính thông báo. Hoạt động này không cần ngăn xếp lui.

Thiết lập một PendingIntent 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 bằng cách 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 thông thường cho các hoạt động bằng cách thêm thuộc tính android:parentActivityName vào từng phần tử <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 một PendingIntent bằng ngăn xếp lui

Để bắt đầu một hoạt động bao gồm ngăn xếp lui của các hoạt động, hãy tạo một thực thể của TaskStackBuilder và gọi addNextIntentWithParentStack(), chuyển Intent cho hoạt động bạn muốn bắt đầu.

Chỉ cần xác định hoạt động gốc cho mỗi hoạt động như được mô tả trước đó, bạn có thể gọi getPendingIntent() để nhận 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 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 hoạt động đó.

Sau đó, bạn có thể truyề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 PendingIntent hoạt động đặc biệt

Vì một hoạt động đặc biệt bắt đầu từ thông báo không cần ngăn xếp lui, nên 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.

  1. 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 cờ FLAG_ACTIVITY_NEW_TASK 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 đi vào tác vụ mặc định của ứng dụng. Mọi nhiệm vụ hiện tại có đối tượng tương đồng mặc định của ứng dụng sẽ 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 tác vụ đó.

    Lệnh này được minh hoạ trong ví dụ sau:

    <activity
        android:name=".ResultActivity"
        android:launchMode="singleTask"
        android:taskAffinity=""
        android:excludeFromRecents="true">
    </activity>
    
  2. Tạo và gửi thông báo:
    1. Tạo một Intent để khởi động Activity.
    2. Đặt Activity để bắt đầu trong một tác vụ mới, trống bằng cách gọi setFlags() với các cờ FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK.
    3. 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
    );
    
  3. 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 hoạt động của ngăn xếp lui, hãy xem phần Tác vụ và ngăn xếp lui.