यह गाइड **NotificationListenerService** का उपयोग करके अन्य ऐप्स से नई नोटिफिकेशन का पता लगाने का तरीका बताता है। यह नोटिफिकेशन मॉनिटरिंग ऐप्स, ऑटो-उत्तर बॉट्स, अभिभावकीय नियंत्रण, या उत्पादकता उपकरण बनाने के लिए आवश्यक है।
अवलोकन
NotificationListenerService एक सिस्टम सेवा है जो आपके ऐप को स्टेटस बार में पोस्ट की गई **सभी नोटिफिकेशन** (आपके अपने ऐप की नहीं, बल्कि सभी ऐप्स की) पर इवेंट प्राप्त करने की अनुमति देती है। इसके लिए उपयोगकर्ता की स्पष्ट सहमति की आवश्यकता होती है।
चरण 1: NotificationListenerService कार्यान्वयन
package com.example.notificationdetector;
import android.content.Context;
import android.content.Intent;
android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
public class NotificationDetectorService extends NotificationListenerService {
private static final String TAG = "NotificationDetector";
// UI अपडेट के लिए वैकल्पिक कॉलबैक इंटरफेस
public interface NotificationCallback {
void onNotificationPosted(StatusBarNotification sbn);
void onNotificationRemoved(StatusBarNotification sbn);
}
private static NotificationCallback callback;
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "नोटिफिकेशन डिटेक्टर सर्विस शुरू हुई");
}
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
String packageName = sbn.getPackageName();
String tag = sbn.getTag();
int id = sbn.getId();
long postTime = sbn.getPostTime();
// नोटिफिकेशन विवरण निकालें
String title = "";
String text = "";
String bigText = "";
if (sbn.getNotification().extras != null) {
android.os.Bundle extras = sbn.getNotification().extras;
title = extras.getString(android.app.Notification.EXTRA_TITLE, "");
text = extras.getCharSequence(android.app.Notification.EXTRA_TEXT, "").toString();
bigText = extras.getCharSequence(android.app.Notification.EXTRA_BIG_TEXT, "").toString();
}
Log.i(TAG, String.format("पोस्ट किया गया: pkg=%s, id=%d, title=%s, text=%s",
packageName, id, title, text));
// कॉलबैक के माध्यम से UI को सूचित करें
if (callback != null) {
callback.onNotificationPosted(sbn);
}
// ब्रॉडकास्ट के माध्यम से अन्य घटकों को सूचित करें (यदि ऐप पृष्ठभूमि में है)
Intent broadcast = new Intent("com.example.NOTIFICATION_POSTED");
broadcast.putExtra("package", packageName);
broadcast.putExtra("title", title);
broadcast.putExtra("text", text);
broadcast.putExtra("id", id);
sendBroadcast(broadcast);
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
String packageName = sbn.getPackageName();
int id = sbn.getId();
Log.i(TAG, "हटाया गया: pkg=" + packageName + ", id=" + id);
if (callback != null) {
callback.onNotificationRemoved(sbn);
}
Intent broadcast = new Intent("com.example.NOTIFICATION_REMOVED");
broadcast.putExtra("package", packageName);
broadcast.putExtra("id", id);
sendBroadcast(broadcast);
}
@Override
public void onNotificationRankingUpdate(RankingMap rankingMap) {
super.onNotificationRankingUpdate(rankingMap);
// नोटिफिकेशन रैंकिंग/प्राथमिकता बदली
}
public static void setCallback(NotificationCallback callback) {
NotificationDetectorService.callback = callback;
}
}
चरण 2: MainActivity - UI और अनुमति संचालन
package com.example.notificationdetector;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements NotificationDetectorService.NotificationCallback {
private TextView tvLog;
private ScrollView scrollView;
private static final int PERMISSION_REQUEST_CODE = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLog = findViewById(R.id.tvLog);
scrollView = findViewById(R.id.scrollView);
Button btnTest = findViewById(R.id.btnTestNotification);
Button btnSettings = findViewById(R.id.btnOpenSettings);
btnTest.setOnClickListener(v -> createTestNotification());
btnSettings.setOnClickListener(v -> openNotificationAccessSettings());
// कॉलबैक पंजीकृत करें
NotificationDetectorService.setCallback(this);
// नोटिफिकेशन अनुमति जांचें (Android 13+)
checkNotificationPermission();
}
private void checkNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.POST_NOTIFICATIONS}, PERMISSION_REQUEST_CODE);
}
}
}
private void createTestNotification() {
// टेस्ट नोटिफिकेशन बनाएँ जो हमारी अपनी सर्विस द्वारा पता लगाया जाएगा
String channelId = "test_channel";
android.app.NotificationManager manager = getSystemService(android.app.NotificationManager.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (manager.getNotificationChannel(channelId) == null) {
android.app.NotificationChannel channel = new android.app.NotificationChannel(
channelId, "टेस्ट चैनल", android.app.NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
}
}
androidx.core.app.NotificationCompat.Builder builder =
new androidx.core.app.NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("टेस्ट नोटिफिकेशन")
.setContentText("यह NotificationListenerService द्वारा पता लगाया जाएगा")
.setPriority(androidx.core.app.NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true);
manager.notify((int) System.currentTimeMillis(), builder.build());
}
private void openNotificationAccessSettings() {
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivity(intent);
}
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
runOnUiThread(() -> appendLog(formatNotification(sbn, "पोस्ट किया गया")));
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
runOnUiThread(() -> appendLog(formatNotification(sbn, "हटाया गया")));
}
private String formatNotification(StatusBarNotification sbn, String event) {
StringBuilder sb = new StringBuilder();
sb.append("[").append(event).append("] ");
sb.append(sbn.getPackageName());
sb.append(" | ID: ").append(sbn.getId());
if (sbn.getNotification().extras != null) {
String title = sbn.getNotification().extras.getString(
android.app.Notification.EXTRA_TITLE, "");
String text = sbn.getNotification().extras.getCharSequence(
android.app.Notification.EXTRA_TEXT, "").toString();
if (!title.isEmpty()) sb.append(" | ").append(title);
if (!text.isEmpty()) sb.append(": ").append(text);
}
sb.append("\n");
return sb.toString();
}
private void appendLog(String message) {
tvLog.append(message);
// ऑटो-स्क्रॉल नीचे
scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));
}
@Override
protected void onDestroy() {
super.onDestroy();
NotificationDetectorService.setCallback(null);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "नोटिफिकेशन अनुमति दी गई", Toast.LENGTH_SHORT).show();
}
}
}
}
चरण 3: लेआउट (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<Button
android:id="@+id/btnTestNotification"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="टेस्ट नोटिफिकेशन बनाएँ"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/btnOpenSettings"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="नोटिफिकेशन एक्सेस सेटिंग्स खोलें"
android:layout_marginTop="12dp"
app:layout_constraintTop_toBottomOf="@id/btnTestNotification"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="12dp"
app:layout_constraintTop_toBottomOf="@id/btnOpenSettings"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:id="@+id/tvLog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="नोटिफिकेशन इवेंट यहाँ दिखाई देंगे...\n(नोटिफिकेशन एक्सेस सक्षम करने के बाद अन्य ऐप्स से नोटिफिकेशन ट्रिगर करें)"
android:textSize="13sp"
android:background="#1E1E1E"
android:textColor="#00FF00"
android:padding="12dp"
android:fontFamily="monospace" />
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
चरण 4: AndroidManifest.xml - महत्वपूर्ण अनुमति
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.notificationdetector">
<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.NotificationDetector">
<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>
<!-- NotificationListenerService घोषणा - आवश्यक! -->
<service
android:name=".NotificationDetectorService"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
</application>
</manifest>
चरण 5: उपयोगकर्ता सक्षम करना (अनिवार्य)
- ऐप इंस्टॉल करें
- सेटिंग्स → ऐप्स और नोटिफिकेशन → विशेष ऐप एक्सेस → **नोटिफिकेशन एक्सेस** खोलें
- सूची में "NotificationDetector" ढूंढें
- टॉगल **चालू** करें → पुष्टि संवाद में "अनुमति दें" पर टैप करें
- ऐप पर वापस आएँ → "टेस्ट नोटिफिकेशन बनाएँ" दबाएँ → लॉग में इवेंट देखें
प्राप्त डेटा
प्रत्येक StatusBarNotification प्रदान करता है:
| विधि | विवरण |
|---|---|
getPackageName() | नोटिफिकेशन पोस्ट करने वाले ऐप का पैकेज नाम |
getId() | ऐप द्वारा निर्दिष्ट नोटिफिकेशन आईडी |
getTag() | वैकल्पिक टैग स्ट्रिंग |
getPostTime() | पोस्ट समय (मिलीसेकंड) |
getNotification() | पूर्ण Notification ऑब्जेक्ट (extras, actions, आदि) |
getKey() | इस नोटिफिकेशन के लिए अद्वितीय कुंजी |
Notification extras से समृद्ध सामग्री निकालना
Bundle extras = sbn.getNotification().extras; String title = extras.getString(Notification.EXTRA_TITLE); String text = extras.getCharSequence(Notification.EXTRA_TEXT, "").toString(); String bigText = extras.getCharSequence(Notification.EXTRA_BIG_TEXT, "").toString(); String subText = extras.getString(Notification.EXTRA_SUB_TEXT); CharSequence[] lines = extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES); Bitmap largeIcon = extras.getParcelable(Notification.EXTRA_LARGE_ICON); Bitmap picture = extras.getParcelable(Notification.EXTRA_PICTURE); // क्रियाएँ Notification.Action[] actions = sbn.getNotification().actions; // लोग/वार्तालाप (Android 11+) Person[] people = extras.getParcelableArray(Notification.EXTRA_PEOPLE);
फ़िल्टरिंग उदाहरण
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
String pkg = sbn.getPackageName();
// केवल विशिष्ट ऐप्स के लिए
if (!pkg.equals("com.whatsapp") && !pkg.equals("com.google.android.gm")) {
return; // अनदेखा करें
}
// सिस्टम नोटिफिकेशन अनदेखा करें
if (pkg.startsWith("android.") || pkg.startsWith("com.android.")) {
return;
}
// प्रक्रिया करें...
}
महत्वपूर्ण विचार
- गोपनीयता: उपयोगकर्ता को स्पष्ट रूप से सहमति देनी होगी; डेटा को जिम्मेदारी से संभालें, अनावश्यक लॉगिंग न करें
- प्रदर्शन:
onNotificationPostedमें भारी कार्य न करें; कार्य को वर्कर थ्रेड/WorkManager पर भेजें - जीवनचक्र: सर्विस सिस्टम द्वारा प्रबंधित होती है; मैन्युअल रूप से शुरू/रोकें नहीं
- Android 12+: कुछ नोटिफिकेशन सामग्री के लिए अतिरिक्त अनुमतियों की आवश्यकता हो सकती है
- बैटरी: लगातार निगरानी का बैटरी पर न्यूनतम प्रभाव पड़ता है
उपयोग के मामले
- अभिभावकीय नियंत्रण / माता-पिता निगरानी
- ऑटो-उत्तर बॉट (WhatsApp, Telegram - नीति जांचें)
- नोटिफिकेशन इतिहास/बैकअप ऐप्स
- उत्पादकता: ध्यान भटकाने वाली ऐप्स से नोटिफिकेशन फ़िल्टर करें
- स्मार्ट होम ट्रिगर (उदाहरण के लिए, सुरक्षा कैमरा अलर्ट पर लाइट चालू करें)