AndroidNotificationListenerService onNotificationPosted 触发两次

问题描述 投票:0回答:6

我收听 WhatsApp 消息等通知。

但是每次通知传入NotificationListenerService 都会触发两次。

有人知道这个问题吗?

这是 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>

在NotificationListenerService类中:

public class NotifyService extends NotificationListenerService {

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

编辑: 两个

StatusBarNotification
的属性:

第一次通知:

0|com.whatsapp|1|[email protected]|10073

第二次通知:

0|com.whatsapp|1|null|10073

android android-notifications android-notification-bar
6个回答
5
投票

我不确定为什么会发生这种情况。也许通知标志可能会触发它两次。

您可以尝试自己省略重复执行:

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

每个

StatusBarNotification
都有唯一生成的密钥:

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

}

按住前一个键可以区分给定包裹的后一个通知。


1
投票

Whatsapp 通知面临同样的问题

我只是通过使用

statusBarNotification.key + statusBarNotification.title

生成新密钥来解决这个问题

现在将此密钥存储在我的

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

此方法

databaseHandler.checkNotification(modifiyedUniq!!)
如果使用此键记录存在,则返回 true 否则返回 false

每次检查密钥如果没有记录就意味着它新通知

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
}

通知

0|com.whatsapp|1|[email protected]|10171

标签=

[email protected]

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
投票

这个问题也发生在我身上。我的解决方法是使用通知的时间+(通知的标题+通知的文本)作为两个键。

如果时间不超过 1 秒且类似标题 + 文本,则忽略。

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

我为我工作,但我认为它可能错过了一些通知。


0
投票

我发现了一些东西,第二个通知总是带有空标签,所以这就是我所做的。

if (sbn.tag != null) {
   // Do something
} else {
   cancelNotification(statusBarNotification.key)
}

0
投票

我通过注册活动通知键解决了这个问题,如下所示:

class NotificationsListenerService : NotificationListenerService() {

    private var activeHandledNotificationKeys: MutableSet<String> = mutableSetOf()
        
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        if (activeHandledNotificationKeys.contains(sbn.key)) return
        
        /* Handle unique StatusBarNotification */
        
        activeHandledNotificationKeys.add(sbn.key)
    }
    
    override fun onNotificationRemoved(sbn: StatusBarNotification) {
        activeHandledNotificationKeys.remove(sbn.key)
    }
}

-1
投票

使用 Split 你可以实现这个目标。

 String[] separated = Your Notification key.split("\\|");
    if (!separated[3].equalsIgnoreCase("null")){//Add Your Data in list or DB }
© www.soinside.com 2019 - 2024. All rights reserved.