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

Thêm thông báo mới khi nhận Push Notification Android

Giới thiệu

Ví dụ này minh họa cách tạo thêm một thông báo cục bộ (local notification) khi ứng dụng nhận được Push Notification từ server (FCM). Thường dùng để: hiển thị khác giao diện, thêm action buttons, hoặc xử lý logic local trước khi hiện.

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

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

Tạo project Android Studio mới.

Bước 2: Layout (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:onClick="createNotification"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_margin="16dp"
        android:text="Mô phỏng nhận Push → Tạo thông báo local" />

</RelativeLayout>

Bước 3: MainActivity - Xử lý Push và tạo Notification (src/MainActivity.java)

package app.tutorialspoint.com.notifyme;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    public static final String NOTIFICATION_CHANNEL_ID = "10001";
    private final static String default_notification_channel_id = "default";

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

    // GIẢ LẬP NHẬN PUSH NOTIFICATION TỪ FCM
    public void simulatePushReceived(String title, String body, String data) {
        // Xử lý data từ push
        Log.d("PUSH_RECEIVED", "Title: " + title + ", Body: " + body + ", Data: " + data);
        
        // TẠO THÔNG BÁO LOCAL TÙY CHỈNH
        createLocalNotification(title, body, data);
    }

    public void createNotification(View view) {
        // Mô phỏng nhận push
        simulatePushReceived("Push từ Server", "Nội dung push notification", "{\"orderId\":12345}");
    }

    private void createLocalNotification(String title, String body, String data) {
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            MainActivity.this, default_notification_channel_id);

        mBuilder.setContentTitle(title);
        mBuilder.setContentText(body);
        mBuilder.setSmallIcon(R.drawable.ic_launcher_foreground);
        mBuilder.setAutoCancel(true);
        mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);

        // THÊM ACTION BUTTONS TÙY CHỈNH
        Intent viewIntent = new Intent(this, MainActivity.class);
        viewIntent.putExtra("push_data", data);
        viewIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent viewPendingIntent = PendingIntent.getActivity(
            this, 0, viewIntent, PendingIntent.FLAG_IMMUTABLE);
        mBuilder.setContentIntent(viewPendingIntent);
        mBuilder.addAction(R.drawable.ic_action, "Xem chi tiết", viewPendingIntent);
        mBuilder.addAction(R.drawable.ic_action, "Đóng", viewPendingIntent);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel notificationChannel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID, "Kênh Push Local", importance);
            mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
            assert mNotificationManager != null;
            mNotificationManager.createNotificationChannel(notificationChannel);
        }

        assert mNotificationManager != null;
        int notificationId = (int) System.currentTimeMillis();
        mNotificationManager.notify(notificationId, mBuilder.build());
        
        Toast.makeText(this, "Đã tạo thông báo local từ Push", Toast.LENGTH_SHORT).show();
    }
}

Bước 4: AndroidManifest.xml

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

    <uses-permission android:name="android.permission.VIBRATE" />

    <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/AppTheme">

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

    </application>
</manifest>

Triển khai thực tế với FirebaseMessagingService

// src/MyFirebaseMessagingService.java
public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        // 1. Lấy data từ push
        String title = remoteMessage.getNotification() != null 
            ? remoteMessage.getNotification().getTitle() : "Thông báo mới";
        String body = remoteMessage.getNotification() != null 
            ? remoteMessage.getNotification().getBody() : "";
        Map data = remoteMessage.getData();

        // 2. Tạo local notification tùy chỉnh
        createCustomNotification(title, body, data);
    }

    private void createCustomNotification(String title, String body, Map data) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "push_channel");

        builder.setContentTitle(title)
               .setContentText(body)
               .setSmallIcon(R.drawable.ic_notification)
               .setAutoCancel(true)
               .setPriority(NotificationCompat.PRIORITY_HIGH);

        // Intent mở app với data
        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra("push_data", new Gson().toJson(data));
        PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
        builder.setContentIntent(pendingIntent);

        // Action buttons
        builder.addAction(R.drawable.ic_view, "Xem", pendingIntent);
        builder.addAction(R.drawable.ic_dismiss, "Bỏ qua", 
            PendingIntent.getBroadcast(this, 0, new Intent("DISMISS"), PendingIntent.FLAG_IMMUTABLE));

        // Channel
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                "push_channel", "Push Notifications", NotificationManager.IMPORTANCE_HIGH);
            manager.createNotificationChannel(channel);
            builder.setChannelId("push_channel");
        }

        manager.notify((int) System.currentTimeMillis(), builder.build());
    }
}

Manifest cho FCM Service

<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Luồng xử lý Push → Local Notification

  1. Server gửi FCM message (data payload khuyến nghị)
  2. FirebaseMessagingService.onMessageReceived() được gọi (app foreground/background)
  3. Parse data, quyết định hiển thị như thế nào
  4. Tạo NotificationCompat.Builder tùy chỉnh
  5. Add actions, styles, intents phù hợp
  6. NotificationManager.notify() hiển thị

Lợi ích tạo Local Notification từ Push

    Tùy chỉnh UI hoàn toàn (BigTextStyle, InboxStyle, BigPictureStyle, Custom Layout)
  • Thêm Action Buttons (Trả lời, Xem, Mua, Hủy...)
  • Xử lý logic local: lưu DB, cập nhật badge, sync data
  • Nhóm thông báo (Notification Grouping)
  • Kiểm soát visibility, priority, category
  • Offline support: queue notification khi offline

Chạy thử nghiệm

Chạy app → Nhấn nút mô phỏng → Kéo shade → Thấy thông báo với 2 action buttons "Xem chi tiết" và "Đóng".