অ্যাপ আইকনে নোটিফিকেশন বেজ (Notification Badge/Count) দেখানো
Android 8.0 (Oreo, API 26) থেকে সিস্টেম লঞ্চার স্বয়ংক্রিয়ভাবেই নোটিফিকেশন কাউন্ট (বেজ/ডট) দেখায় যদি অ্যাপে অপরিহিত (unread) নোটিফিকেশন থাকে। এই টিউটোরিয়ালে দেখানো হয়েছে কীভাবে NotificationCompat.Builder.setNumber() এবং setBadgeIconType() ব্যবহার করে এটাকে কন্ট্রোল করা যায়।
বেজ টাইপসমূহ
| BadgeIconType | দৃশ্য |
|---|---|
BADGE_ICON_NONE | কোনো আইকন নেই, শুধু ডট/নাম্বার |
BADGE_ICON_SMALL | স্মল আইকন (setSmallIcon) বেজে দেখাবে |
BADGE_ICON_LARGE | লার্জ আইকন (setLargeIcon) বেজে দেখাবে |
দ্রষ্টব্য: লঞ্চার সাপোর্ট
- স্টক Android (Pixel, Android One) — বেজ সাপোর্ট করে
- Samsung One UI, Xiaomi MIUI, OnePlus OxygenOS — নিজস্ব বেজ সিস্টেম (সেটিংসে এনাবল করতে হয়)
- কিছু লঞ্চার (Nova, Action Launcher) — বেজ সাপোর্ট করে
- সেটিংস → Notifications → App icon badges → On করুন
ধাপ ১: প্রজেক্ট সেটআপ
Package: com.example.notificationbadge
ধাপ ২: লেআউট (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"
android:padding="16dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:text="নোটিফিকেশন বেজ ডেমো"
android:textSize="24sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnNotify"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="createNotification"
android:text="নোটিফিকেশন তৈরি করুন (কাউন্ট বাড়বে)"/>
<Button
android:id="@+id/btnClear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/btnNotify"
android:layout_marginTop="16dp"
android:onClick="clearNotifications"
android:text="সব নোটিফিকেশন ক্লিয়ার করুন"
android:backgroundTint="#F44336"
android:textColor="#FFFFFF"/>
<TextView
android:id="@+id/tvCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btnClear"
android:layout_centerHorizontal="true"
android:layout_marginTop="24dp"
android:text="নোটিফিকেশন কাউন্ট: 0"
android:textSize="18sp"/>
</RelativeLayout>
ধাপ ৩: MainActivity.java
package com.example.notificationbadge;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
public class MainActivity extends AppCompatActivity {
public static final String CHANNEL_ID = "badge_demo_channel";
private static final String DEFAULT_CHANNEL = "default";
private NotificationManagerCompat notificationManager;
private TextView tvCount;
private int notificationCount = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvCount = findViewById(R.id.tvCount);
notificationManager = NotificationManagerCompat.from(this);
createNotificationChannel();
}
@Override
protected void onResume() {
super.onResume();
// অ্যাপ খোলার সময় কাউন্ট রিসেট (ঐচ্ছিক)
notificationCount = 0;
updateCountDisplay();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID, "বেজ ডেমো চ্যানেল",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("নোটিফিকেশন বেজ কাউন্ট ডেমো");
channel.setShowBadge(true); // বেজ দেখানোর অনুমতি
notificationManager.createNotificationChannel(channel);
}
}
public void createNotification(View view) {
notificationCount++;
updateCountDisplay();
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("fromNotification", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, DEFAULT_CHANNEL)
.setContentTitle("নোটিফিকেশন #" + notificationCount)
.setContentText("এটি বেজ কাউন্ট ডেমো নোটিফিকেশন")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setNumber(notificationCount) // কাউন্ট সেট (বেজে দেখাবে)
.setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL) // স্মল আইকন বেজে
.setChannelId(CHANNEL_ID)
.setPriority(NotificationCompat.PRIORITY_HIGH);
// ইউনিক ID দিয়ে নোটিফিকেশন (তाकি একাধিক থাকে)
int notificationId = (int) System.currentTimeMillis();
notificationManager.notify(notificationId, builder.build());
}
public void clearNotifications(View view) {
notificationManager.cancelAll();
notificationCount = 0;
updateCountDisplay();
}
private void updateCountDisplay() {
tvCount.setText("নোটিফিকেশন কাউন্ট: " + notificationCount);
}
}
ধাপ ৪: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.notificationbadge">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<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.NotificationBadge">
<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>
গুরুত্বপূর্ণ: Android 13+ (API 33+) POST_NOTIFICATIONS পারমিশন
Android 13 থেকে নোটিফিকেশন পাঠাতে রানটাইম পারমিশন দরকার। MainActivity-এ যোগ করুন:
private static final int NOTIFICATION_PERMISSION_REQUEST = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.POST_NOTIFICATIONS},
NOTIFICATION_PERMISSION_REQUEST);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == NOTIFICATION_PERMISSION_REQUEST) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// পারমিশন পেলে নোটিফিকেশন পাঠাতে পারবেন
} else {
Toast.makeText(this, "নোটিফিকেশন পারমিশন দরকার", Toast.LENGTH_LONG).show();
}
}
}
অ্যাপ খোলার সময় বেজ ক্লিয়ার করা (Badge Clear on Launch)
অ্যাপ ফোরগ্রাউন্ডে আসলে বেজ ক্লিয়ার করতে চাইলে onResume()-এ কাউন্ট ০ করুন এবং একটি "ক্লিয়ার" নোটিফিকেশন পোস্ট করুন:
@Override
protected void onResume() {
super.onResume();
notificationCount = 0;
updateCountDisplay();
// বেজ ক্লিয়ার করার ট্রিক: ০ কাউন্ট দিয়ে একটি নোটিফিকেশন পোস্ট করুন
NotificationCompat.Builder clearBadge = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setNumber(0) // কাউন্ট ০
.setChannelId(CHANNEL_ID)
.setPriority(NotificationCompat.PRIORITY_MIN); // শব্দ/ভাইব্রেশন নয়
notificationManager.notify(9999, clearBadge.build()); // ফিক্সড ID
}
শর্টকাট বেজ (Static Shortcut Badge) — অ্যাপ শর্টকাটে কাউন্ট
Android 7.1+ (API 25) এ লঞ্চার শর্টকাটেও বেজ দেখানো যায়:
// res/xml/shortcuts.xml
<shortcuts xmlns:android="https://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="messages"
android:enabled="true"
android:icon="@drawable/ic_message"
android:shortcutShortLabel="@string/messages"
android:shortcutLongLabel="@string/messages_long">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.example.notificationbadge"
android:targetClass="com.example.notificationbadge.MessageActivity" />
</shortcut>
</shortcuts>
// MainActivity-এ (কাউন্ট আপডেট)
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "messages")
.setShortLabel("Messages")
.setIcon(Icon.createWithResource(this, R.drawable.ic_message))
.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("myapp://messages")))
.setRank(0)
.build();
shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));
// কাউন্ট আপডেট (API 26+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
shortcutManager.updateShortcuts(Arrays.asList(
new ShortcutInfo.Builder(this, "messages")
.setNumber(5) // বেজ কাউন্ট
.build()
));
}
পরীক্ষা পদ্ধতি
- অ্যাপ ইনস্টল → সেটিংসে "App Icon Badges" অন করুন (সিস্টেম সেটিংস → Notifications)
- অ্যাপ চালু করুন → "নোটিফিকেশন তৈরি করুন" ৩-৪ বার চাপুন
- হোম স্ক্রিনে যান → অ্যাপ আইকনে সংখ্যা বেজ দেখুন (১, ২, ৩...)
- "সব নোটিফিকেশন ক্লিয়ার করুন" চাপুন → বেজ গিয়ে যাবে
সাধারণ সমস্যা ও সমাধান
| সমস্যা | সমাধান |
|---|---|
| বেজ দেখাচ্ছে না | লঞ্চার সেটিংসে "App Icon Badges" অন আছে কিনা, Channel-এ setShowBadge(true) আছে কিনা |
| কাউন্ট আপডেট হচ্ছে না | setNumber() প্রতি নোটিফিকেশনে সেট করুন, একই ID দিয়ে আপডেট করবেন না (তবে আপডেট হয়) |
| Samsung/Xiaomi-এ কাজ করে না | ওই লঞ্চারগুলোর নিজস্ব সেটিংস আছে; সেটিংস → Home Screen → Badges চেক করুন |
| Android 13+ তে নোটিফিকেশন আসছে না | POST_NOTIFICATIONS রানটাইম পারমিশন রিকোয়েস্ট করুন |