【问题标题】:Android NotificationListenerService onNotificationPosted fire twiceAndroid NotificationListenerService onNotificationPosted 触发两次
【发布时间】:2015-10-29 10:46:48
【问题描述】:

我会收听诸如 WhatsApp 消息之类的通知。

但每次通知进入 NotificationListenerService 时都会触发两次。

有人知道这个问题吗?

这是来自 AndroidManifest.xml 的 sn-p:

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

编辑StatusBarNotifications 的两个属性:

第一次通知:

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

第二次通知:

0|com.whatsapp|1|null|10073

【问题讨论】:

  • 你有这个prob的解决方案吗
  • @BhanuSharma 不。我的解决方案是创建一个新的 android 项目,然后它就可以工作了。
  • 是指你在新项目中写的相同代码,它会自动正常运行吗?
  • 你解决了这个问题吗,因为我收到这个错误直到日期
  • 您的问题与群组摘要通知有关。见:stackoverflow.com/a/55365244/1658621

标签: android android-notifications android-notification-bar


【解决方案1】:

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

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

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;

}

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

【讨论】:

  • 第二次触发通知时,所有属性都与第一次相同。标签除外。标签为空。
  • @gravmatt 第一个有标签? key 属性呢?
  • 是的,它有一个标签。 第一次: 0|com.whatsapp|1|xxxxxxxxxx@s.whatsapp.net|10073 第二次: 0|com.whatsapp|1|null|10073跨度>
  • @gravmatt 尝试持有具有标签的引用,并在第二个到达时执行您的代码。我对此没有任何其他想法。
  • Google Allo 应用程序来了两次,并且两次都标记为 null 现在的答案是什么?请帮忙
【解决方案2】:

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|XX2X606878@s.whatsapp.net|10171

标签 = 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)

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        使用Split你可以做到这一点。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多