Android NotificationListenerService onNotificationPosted fire twice

I listen to notifications such as WhatsApp messages.

But every time a notification comes into the fire NotificationListenerService twice.

Does anyone know this problem?

This is a snippet from AndroidManifest.xml:

<service android:name=".NotifyService" android:label="WhatsNotify" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService"></action> </intent-filter> </service> 

And inside the class NotificationListenerService:

 public class NotifyService extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn) { Log.i("NotifyService", "got notification"); } } 

Edit : Properties of both StatusBarNotification s:

First notice:

0|com.whatsapp|1| xxxxxxxxxx@s.whatsapp.net |10073

Second notice:

0|com.whatsapp|1|null|10073

+5
source share
4 answers

I do not know why this is happening. Perhaps the notification flags may run it twice.

You can try to omit duplicate execution yourself:

 public class NotifyService extends NotificationListenerService { private String mPreviousNotificationKey; @Override public void onNotificationPosted(StatusBarNotification sbn) { if(TextUtils.isEmpty(mPreviousNotification) || !TextUtils.isEmpty(mPreviousNotification) && !sbn.getKey().equals(mPreviousNotificationKey)){ Log.i("NotifyService", "got notification"); } } 

Each StatusBarNotification has a unique key that is generated:

 private String key() { return user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid; } 

Holding each previous key can distinguish the last notification for this package.

+3
source

Collision with the same issue for WhatsApp notification

I just solve this problem by creating a new key using statusBarNotification.key + statusBarNotification.title

Now save this key in my SQLiteDatabase

code written in Kotlin

  override fun onNotificationPosted(sbn: StatusBarNotification?) { if(sbn?.tag!=null) { var key = sbn?.key ?: null var id = sbn?.id var postTime = sbn?.postTime var packageName = sbn?.packageName ?: null var tikerText = sbn?.notification?.tickerText ?: null var extraBundle: Bundle? = sbn?.notification?.extras ?: null var notificationTitle = extraBundle?.get(Notification.EXTRA_TITLE) var text = extraBundle?.getCharSequence(Notification.EXTRA_TEXT).toString() var modifiyedUniq = key + notificationTitle //check key present in database or not if (!databaseHandler.checkNotification(modifiyedUniq!!)) { Log.e(TAG, "Notification Key :: ${key}") Log.e(TAG, "Notification Id :: ${id}") Log.e(TAG, "Notification postTime :: ${postTime}") Log.e(TAG, "Notification From :: ${packageName}") Log.e(TAG, "Notification TikerText :: ${tikerText}") Log.e(TAG, "Notification Title :: ${notificationTitle}") Log.e(TAG, "Notification Text :: ${text}") //now add this record in database databaseHandler.addNotification(notificationData) } } } 

this databaseHandler.checkNotification(modifiyedUniq!!) method returns true if the record is present with this key, otherwise it returns false

each time a key is checked, if there is no record, it means a new notification

 fun checkNotification(key: String): Boolean { var isPresent: Boolean = false val db = readableDatabase val selectALLQuery = "SELECT * FROM $TABLE_NAME WHERE $KEY='${key}'" val cursor = db.rawQuery(selectALLQuery, null) if (cursor != null) { if (cursor.count > 0) { cursor.close() db.close() Log.e("","====================================RECORD PRESEBNT=======================") return true } } cursor.close() db.close() Log.e("","===*******=======********=====RECORD NOT PRESENT===*******=======********=====") return isPresent } 

Notification 0 | 0|com.whatsapp|1| XX2X606878@s.whatsapp.net |10171

tag = 91XX06X78@s.whatsapp.net

 Notification Id :: 1 Notification postTime :: 15464X794103 Notification From :: com.whatsapp Notification TikerText :: null Notification Title :: XXX X Bca (2 messages): ​Notification Text :: XXXXX(last new Message) 
0
source

This problem happened to me too. My workaround is to use notification time + (notification title + notification text) as two keys.

If the time is not older than 1 second and the same heading + text, ignore.

 if (Calendar.getInstance().getTimeInMillis() - lastMessageTime < 1000 && lastMessageContent.equalsIgnoreCase(title + text)) { // Ignore return; } else { lastMessageContent = title + text; lastMessageTime = Calendar.getInstance().getTimeInMillis(); } 

I worked for me, but I think this may miss some notifications.

0
source

Using Split, you can achieve this goal.

  String[] separated = Your Notification key.split("\\|"); if (!separated[3].equalsIgnoreCase("null")){//Add Your Data in list or DB } 
-1
source

Source: https://habr.com/ru/post/1246473/


All Articles