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

Cách tạo thông báo cục bộ (Local Notification) trong Android

Giới thiệu

Thông báo cục bộ do ứng dụng tự tạo và hiển thị, không cần server push. Phù hợp cho: nhắc nhở, alarm, kết quả download, hoàn thành task nền.

So sánh Local vs Push Notification

Đặc điểmLocal NotificationPush Notification (FCM)
NguồnApp tự tạoServer gửi qua FCM
Yêu cầu mạngKhông cầnCần internet
Độ trễNgay lập tức / theo lịchTùy network, FCM
Chi phíMiễn phí hoàn toànMiễn phí (FCM) nhưng cần backend
App đóng vẫn hoạt độngCần Service/WorkManager/AlarmLuôn hoạt động (FCM wake up)

3 Cách tạo Local Notification phổ biến

1. Ngay lập tức (Instant) - Demo ở bài trước

Gọi NotificationManager.notify() trực tiếp trong Activity/Fragment.

2. Đặt lịch một lần (AlarmManager + BroadcastReceiver)

Xem chi tiết bài "How to schedule local notifications in Android" (ID 1003061557).

3. Định kỳ (WorkManager - Khuyên dùng cho API 23+)

// Worker class
public class NotificationWorker extends Worker {
    public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        showNotification("Đồng bộ định kỳ", "Đã kiểm tra cập nhật lúc " + new Date());
        return Result.success();
    }

    private void showNotification(String title, String text) {
        NotificationManager manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), "work_channel")
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle(title)
                .setContentText(text)
                .setAutoCancel(true);
        // Channel setup...
        manager.notify((int) System.currentTimeMillis(), builder.build());
    }
}

// Đăng ký chạy mỗi 15 phút (tối thiểu)
PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(NotificationWorker.class, 15, TimeUnit.MINUTES)
        .build();
WorkManager.getInstance(context).enqueue(request);

Code mẫu hoàn chỉnh (Instant Local Notification)

Giống bài 1003061554, nhưng bổ sung xin quyền runtime cho Android 13+:

MainActivity.java (có xin quyền)

package com.example.localnotificationfull;

import android.Manifest;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final String CHANNEL_ID = "local_full_channel";
    private static final int REQ_POST_NOTIF = 1001;

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

        Button btn = findViewById(R.id.btnCreateNotification);
        btn.setOnClickListener(v -> {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // API 33
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) 
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, 
                            new String[]{Manifest.permission.POST_NOTIFICATIONS}, REQ_POST_NOTIF);
                    return;
                }
            }
            sendNotification();
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQ_POST_NOTIF && grantResults.length > 0 
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            sendNotification();
        } else {
            Toast.makeText(this, "Cần quyền gửi thông báo", Toast.LENGTH_SHORT).show();
        }
    }

    private void sendNotification() {
        NotificationManager manager = getSystemService(NotificationManager.class);
        
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle("Local Notification")
                .setContentText("Đã xin quyền runtime cho Android 13+")
                .setAutoCancel(true)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    CHANNEL_ID, "Local Full", NotificationManager.IMPORTANCE_DEFAULT);
            manager.createNotificationChannel(channel);
        }

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

Tóm tắt checklist

  • [ ] Tạo Notification Channel (API 26+)
  • [ ] setSmallIcon() - bắt buộc
  • [ ] setContentTitle() + setContentText()
  • [ ] setAutoCancel(true) cho thông báo tương tác
  • [ ] Xin quyền POST_NOTIFICATIONS runtime (API 33+)
  • [ ] Dùng WorkManager cho tác vụ định kỳ/lặp lại
  • [ ] Dùng AlarmManager.setExact() cho báo thức chính xác