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

Tạo thông báo Android không hiển thị icon trên status bar

Giới thiệu

Ví dụ này minh họa cách tạo thông báo không hiển thị icon trên status bar (thanh trạng thái trên cùng) nhưng vẫn xuất hiện trong khu vực kéo xuống (notification shade). Sử dụng NotificationCompat.VISIBILITY_SECRET và custom layout.

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 chính (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="Tạo thông báo ẩn icon status bar" />

</RelativeLayout>

Bước 3: Custom Layout không có ImageView (res/layout/custom_notification_layout.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="96dp"
    android:padding="10dp">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Thông báo ẩn icon"
        android:textColor="#000"
        android:textSize="18sp" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:layout_marginTop="8dp"
        android:hint="Chúng ta test không có icon"
        android:inputType="text"
        android:textSize="14sp" />

</RelativeLayout>

Bước 4: MainActivity (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.RemoteViews;

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);
    }

    public void createNotification(View view) {
        RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);

        NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            MainActivity.this, default_notification_channel_id);

        mBuilder.setContent(contentView);
        
        // VẪN BẮT BUỘC PHẢI CÓ SMALL ICON (dù không hiển thị)
        mBuilder.setSmallIcon(R.drawable.ic_launcher_foreground);
        mBuilder.setAutoCancel(true);
        
        // QUAN TRỌNG: ẨN TỪ STATUS BAR
        mBuilder.setVisibility(NotificationCompat.VISIBILITY_SECRET);

        // Priority thấp để không hiện heads-up
        mBuilder.setPriority(NotificationCompat.PRIORITY_MIN);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            int importance = NotificationManager.IMPORTANCE_LOW; // Low importance
            NotificationChannel notificationChannel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID, "Kênh ẩn icon", importance);
            // Không set light/vibration
            mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
            assert mNotificationManager != null;
            mNotificationManager.createNotificationChannel(notificationChannel);
        }

        assert mNotificationManager != null;
        mNotificationManager.notify((int) System.currentTimeMillis(), mBuilder.build());
    }
}

Bước 5: 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>

Giải thích kỹ thuật

1. VISIBILITY_SECRET

mBuilder.setVisibility(NotificationCompat.VISIBILITY_SECRET);
  • Ẩn nội dung trên lock screen
  • Giảm khả năng hiển thị trên status bar
  • Vẫn hiển thị đầy đủ trong notification shade

2. PRIORITY_MIN + IMPORTANCE_LOW

mBuilder.setPriority(NotificationCompat.PRIORITY_MIN);
// Channel importance
notificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
  • Không hiện heads-up (popup)
  • Không phát âm thanh/rung
  • Icon status bar có thể ẩn (tùy OEM)

3. Custom Layout không ImageView

Layout tùy chỉnh không chứa ImageView → không hiển thị large icon → trông như "không icon".

Lưu ý quan trọng

⚠️ Không thể ẩn hoàn toàn icon status bar

  • Android yêu cầu setSmallIcon() bắt buộc (crash nếu thiếu)
  • Hệ thống quyết định hiển thị status bar icon dựa trên importance/priority
  • Một số OEM (Samsung, Xiaomi) vẫn hiện icon dù PRIORITY_MIN
  • Cách duy nhất "ẩn hẳn": không post notification, dùng overlay/window manager (cần quyền đặc biệt)

Use case thực tế

  • Thông báo nền (background sync, backup hoàn tất)
  • Thông báo không quan trọng, không muốn làm phiền
  • App tracker, analytics ping

Chạy thử nghiệm

Chạy app → Tạo thông báo → Quan sát status bar (có thể không có icon) → Kéo thanh thông báo xuống → Thấy thông báo đầy đủ trong shade.