Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách mở Activity khi người dùng bấm vào thông báo Android

Giới thiệu

Hướng dẫn cơ bản: gán PendingIntent vào thông báo qua setContentIntent() để mở một Activity khi người dùng chạm vào thông báo.

Các bước thực hiện

Bước 1: Tạo dự án

File → New Project → Empty Activity → đặt tên package (ví dụ: com.example.notificationclick).

Bước 2: Giao diện đơn giản

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnNotify"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Gửi thông báo"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Bước 3: MainActivity.java - Xử lý click mở Activity

package com.example.notificationclick;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private static final String CHANNEL_ID = "click_channel";
    private static final String DEFAULT_CHANNEL = "default";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = findViewById(R.id.btnNotify);
        btn.setOnClickListener(v -> sendNotification());
    }

    private void sendNotification() {
        // 1. Intent đích: Mở MainActivity (hoặc Activity khác)
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        // Quan trọng: FLAG_IMMUTABLE (API 31+) hoặc FLAG_MUTABLE
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

        // 2. Xây dựng Notification
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, DEFAULT_CHANNEL)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle("Có tin nhắn mới")
                .setContentText("Bấm để mở ứng dụng")
                .setContentIntent(pendingIntent) // ==== GÁN PENDINGINTENT ====
                .setAutoCancel(true); // Tự xóa sau khi bấm

        // 3. NotificationManager & Channel
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    CHANNEL_ID, "Kênh click", NotificationManager.IMPORTANCE_DEFAULT);
            manager.createNotificationChannel(channel);
            builder.setChannelId(CHANNEL_ID);
        }

        // 4. Hiển thị
        int notifyId = (int) System.currentTimeMillis();
        manager.notify(notifyId, builder.build());
    }
}

Bước 4: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.notificationclick">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.NotificationClick">

        <activity android:name=".MainActivity" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

Giải thích các flag quan trọng

FlagChức năng
FLAG_ACTIVITY_CLEAR_TOPNếu Activity đã tồn tại trong back stack, xóa các Activity phía trên nó
FLAG_ACTIVITY_SINGLE_TOPKhông tạo instance mới nếu Activity đã ở đỉnh stack
PendingIntent.FLAG_IMMUTABLEBắt buộc từ Android 12, PendingIntent không thể sửa đổi sau khi tạo
PendingIntent.FLAG_UPDATE_CURRENTCập nhật extra data nếu PendingIntent đã tồn tại

Mở Activity khác (không phải MainActivity)

Chỉ cần thay MainActivity.class bằng DetailActivity.class trong Intent. Đảm bảo Activity đích đã khai báo trong Manifest.

Truyền dữ liệu qua Intent

intent.putExtra("notification_id", notifyId);
intent.putExtra("message", "Nội dung chi tiết từ server");
// Trong Activity đích:
String msg = getIntent().getStringExtra("message");