如何在 Android 中获取 Stacked Notifications 的文本

Posted

技术标签:

【中文标题】如何在 Android 中获取 Stacked Notifications 的文本【英文标题】:How to get text of Stacked Notifications in Android 【发布时间】:2015-03-31 08:14:40 【问题描述】:

问题是如何在所有传入通知堆叠时获取 TEXT(不是标题)字段(如在 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。

这一定是可能的,因为this app 正在这样做,并对其进行了测试。它正在获取每个应用程序的文本。

添加激励:如果您知道答案或尝试的事情,还有另一个问题与here 类似的问题。

【问题讨论】:

【参考方案1】:

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 和文本作为:来自 Y 对话的 X 条消息

获取文本:

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

获取标题:

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

要使用这种堆栈结构,我们需要解析这个通知堆栈并在我们的应用程序中仅显示选择性信息

希望我的回答能帮助解决您的疑问

【讨论】:

当第二个通知(假设在你的例子中来自 A)进入 'sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString();'是NULL,那里什么都没有。你也没有看到它为NULL吗?我正在尝试使用 Kitkat,API=19 我不确定这是不是真的,您能否详细说明如何获取以前的通知? NotificationListener 中的回调" 对于 KitKat,它应该与 AccessibilityService 一起正常工作。尝试使用此服务回调。在我的情况下,AccessibilityService 在 ( 为了获取以前的通知,您可以维护数据结构,将传入的通知保存到其中,解析并从中向您的应用程序显示选择性通知 为 Kitkat 使用 NotificationListener 服务。然后您将能够获取文本【参考方案2】:

如果您使用的是 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*/

            
        
    

和我的回答一样here。

【讨论】:

【参考方案3】:

我认为这可以帮助你:

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();

【讨论】:

【参考方案4】:

仅在具有辅助功能服务权限的 WhatsApp 上进行了研究。 所有传入的通知在堆叠时(如在 Whatsapp 中),您可以使用 AccessibilityEvent getRecord() 方法在堆栈中提取上下文。 内容包含 [sender, to, time, context, index] 在 MOTO G 上的 Android 5.1 上测试

【讨论】:

以上是关于如何在 Android 中获取 Stacked Notifications 的文本的主要内容,如果未能解决你的问题,请参考以下文章

qt stacked widget界面中如何用按钮实现换页

在android中每n分钟获取当前位置

如何在为 Android 共享提供的消息中获取换行符

正确训练 Stacked Autoencoder

R绘制堆叠的密度图(Stacked Area Chart)

Firebase Android - 如何随机获取一些项目[重复]