Как получить текст Stacked Notifications в Android

Вопрос в том, как получить поле ТЕКСТ (не заголовок) всех входящих уведомлений, когда они складываются (как в Whatsapp).

введите здесь описание изображения

public class NLService extends NotificationListenerService {
public void onNotificationPosted(StatusBarNotification sbn) {

    Log.v(Constants.TAG_notifs,
            "------------------------- in onNotificationPosted(), Notification Text = "
                    + sbn.getNotification().tickerText);


    Bundle extras = sbn.getNotification().extras;

    if (extras.containsKey("android.text")) {
        if (extras.getCharSequence("android.text") != null) {
            String text = extras.getCharSequence("android.text").toString();
            Log.v(Constants.TAG_notifs,
                    "------------------------- in onNotificationPosted(), Bundle.text != NULL, so here it is = "
                            + text);
        } 
    }

    if (extras.containsKey("android.title")) {
        Log.v(Constants.TAG_notifs,
                "------------------------- in onNotificationPosted(), Bundle android.title = "
                        + extras.getString("android.title"));
    }

}

@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
    //super.onNotificationRemoved(sbn);
}

} В первый раз, когда приходит уведомление Whatsapp от одного пользователя, эта строка (String text = extras.getCharSequence("android.text").toString();) может быть успешно прочитана text, но после этого, когда приходит больше сообщений и уведомления накапливаются (как на картинке выше), переменная text всегда равна NULL.

Это должно быть возможно, поскольку это приложение выполняет это, протестировал. Он получает текст каждого приложения.

Добавленное поощрение: если вы знаете ответ или что можно попробовать, есть еще один вопрос, похожий на вопрос здесь.


person user1406716    schedule 31.03.2015    source источник


Ответы (4)


Приложение WhatsApp имеет такую ​​структуру для отправки уведомлений:

        Case                                 Notification

Message comes from A : Hi                   Title : A    Text: Hi

Message comes from A : How are you          Title : A    Text: How are you

                                            Title : A    Text: 2 new messages


Message comes from B : Hello                Title : B    Text: Hello

                                            Title : B    Text: 1 new message

                                            Title : A    Text: 2 new messages

                     Title : WhatsApp  Text: 3 new messages from 2 conversation
---- Here comes the stacking ----

Message comes from C : Good work            Title : C    Text: Good work

                                            Title : C    Text: 1 new message

                                            Title : B    Text: 1 new message

                                            Title : A    Text: 2 new messages

                     Title : WhatsApp  Text: 4 new messages from 3 conversation


 ---- This way when new sender message comes, previoud notifications also comes and we get callback in NotificationListener ----

Последнее уведомление приходит с заголовком в виде имени пакета: WhatsApp и текстом в виде: X сообщений из Y беседы

Чтобы получить текст:

sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString();

Чтобы получить титул:

sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TITLE).toString();

Чтобы работать с этой структурой стека, нам нужно разобрать этот стек уведомлений и отображать в нашем приложении только выборочную информацию.

Я надеюсь, что мой ответ поможет и решит ваш вопрос

person Kushal    schedule 31.03.2015
comment
Когда второе уведомление (скажем, от A в вашем примере) приходит в 'sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString();' NULL, там ничего нет. Вы тоже не видите NULL? Я пытаюсь в Kitkat, API=19 - person user1406716; 31.03.2015
comment
Я не уверен, так ли это, не могли бы вы уточнить, как также получить предыдущие уведомления?: Таким образом, когда приходит новое сообщение отправителя, также приходят предыдущие уведомления, и мы получаем обратный вызов в NotificationListener - person user1406716; 31.03.2015
comment
Для KitKat он должен нормально работать с AccessibilityService. Попробуйте использовать этот обратный вызов службы. В моем случае AccessibilityService работал нормально до (‹= KitKat), поэтому, пожалуйста, проверьте его использование. - person Kushal; 31.03.2015
comment
Для получения предыдущих уведомлений вы можете поддерживать структуру данных, сохранять в нее входящие уведомления, анализировать и отображать из нее выборочное уведомление вашему приложению. - person Kushal; 31.03.2015
comment
Итак, вы пробовали только с AccessibilityService, а не с NotificationListenerService??? При использовании NotificationListenerService читается только ТЕКСТ первого уведомления, после чего все поля ТЕКСТА имеют значение NULL, поэтому я также не могу сохранить их в своей собственной структуре данных. Будет ли метод AccessibilityService не работать в Lollipop?? - person user1406716; 31.03.2015
comment
Нет, специальные возможности не работают с пакетом WhatsApp.. там выдается нуль.. - person Kushal; 31.03.2015
comment
Я так понимаю, вы правы, что тогда невозможно получить ТЕКСТ каждого уведомления от Whatsapp? - person user1406716; 31.03.2015
comment
Используйте службу специальных возможностей для ‹= KitKat и используйте службу NotificationListener для › Kitkat. Тогда вы сможете получать текст - person Kushal; 31.03.2015

Если вы работаете с Android 7.0+, WhatsApp использует расширенные уведомления MessageStyle. Здесь — https://developer.android.com/training/notify-user/expanded.html#message-style

Чтобы получить все 5 сообщений из уведомления, например

MyFriend (5 messages)
testt

Сделай это:

Bundle extras = mysbn.getNotification().extras;
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)){
        Parcelable b[] = (Parcelable[]) extras.get(Notification.EXTRA_MESSAGES);

        if(b != null){
            content = "";
            for (Parcelable tmp : b){

                Bundle msgBundle = (Bundle) tmp;
                content = content + msgBundle.getString("text") + "\n";

                /*Set<String> io = msgBundle.keySet(); // To get the keys available for this bundle*/

            }
        }
    }

То же, что и мой ответ здесь.

person Balamurugan    schedule 08.03.2018

Я думаю, что это может помочь вам:

CharSequence[] lines = 
extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES);
if(lines != null && lines.length > 0) {
   StringBuilder sb = new StringBuilder();
   for (CharSequence msg : lines)
      if (!TextUtils.isEmpty(msg)) {
         sb.append(msg.toString());
         sb.append('\n');
      }
   return sb.toString().trim();
}
CharSequence chars = 
extras.getCharSequence(Notification.EXTRA_BIG_TEXT);
if(!TextUtils.isEmpty(chars))
   return chars.toString();
person Ismael Duzi    schedule 09.02.2017

Исследовал только WhatsApp с разрешением службы специальных возможностей. все входящие уведомления, когда они складываются (например, в Whatsapp), вы можете использовать метод AccessibilityEvent getRecord() для извлечения контекста в стеке. Контент содержит [отправитель, кому, время, контекст, индекс], проверенный на Android 5.1 на MOTO G.

person Fan Li    schedule 05.12.2016