我需要从RemoteViews对象中检索一些文本。我可以获取LayoutId,但是我不知道如何从该TextView中的RemoteView(即通知)中检索文本。

另外RemoteView仅包含setter,但没有getter,因此我想我必须使用LayoutId(以某种方式)。

你能帮我吗?谢谢!

/edit:之所以问这个原因,是因为我有一个检索通知的AccessibilityService。因此,这是获取值的唯一方法。

/edit2:我使用以下代码来接收通知:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
        List<CharSequence> notificationList = event.getText();
        for (int i = 0; i < notificationList.size(); i++) {
            Toast.makeText(this.getApplicationContext(), notificationList.get(i), 1).show();
        }
        if (!(parcel instanceof Notification)) {
            return;
        }
        final Notification notification = (Notification) parcel;
        doMoreStuff();

    }
}

使用notification对象,我可以访问RemoteViews(notification.contentView)和PendingIntent(notification.contentIntent)。
要获取layoutId,我可以调用contentView.getLayoutId()

最佳答案

我提出了一个类似的解决方案here,它也使用反射来解决问题,但是方式更加平易近人。这是我的解决方案。在这种情况下,RemoteViews来自Notification,因此如果您已经可以访问RemoteViews对象,则前三行可能会被忽略。页面上的链接提供了有关实际情况的详细说明。我希望这将对任何有类似问题的人有所帮助。

public static List<String> getText(Notification notification)
{
    // We have to extract the information from the view
    RemoteViews        views = notification.bigContentView;
    if (views == null) views = notification.contentView;
    if (views == null) return null;

    // Use reflection to examine the m_actions member of the given RemoteViews object.
    // It's not pretty, but it works.
    List<String> text = new ArrayList<String>();
    try
    {
        Field field = views.getClass().getDeclaredField("mActions");
        field.setAccessible(true);

        @SuppressWarnings("unchecked")
        ArrayList<Parcelable> actions = (ArrayList<Parcelable>) field.get(views);

        // Find the setText() and setTime() reflection actions
        for (Parcelable p : actions)
        {
            Parcel parcel = Parcel.obtain();
            p.writeToParcel(parcel, 0);
            parcel.setDataPosition(0);

            // The tag tells which type of action it is (2 is ReflectionAction, from the source)
            int tag = parcel.readInt();
            if (tag != 2) continue;

            // View ID
            parcel.readInt();

            String methodName = parcel.readString();
            if (methodName == null) continue;

            // Save strings
            else if (methodName.equals("setText"))
            {
                // Parameter type (10 = Character Sequence)
                parcel.readInt();

                // Store the actual string
                String t = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel).toString().trim();
                text.add(t);
            }

            // Save times. Comment this section out if the notification time isn't important
            else if (methodName.equals("setTime"))
            {
                // Parameter type (5 = Long)
                parcel.readInt();

                String t = new SimpleDateFormat("h:mm a").format(new Date(parcel.readLong()));
                text.add(t);
            }

            parcel.recycle();
        }
    }

    // It's not usually good style to do this, but then again, neither is the use of reflection...
    catch (Exception e)
    {
        Log.e("NotificationClassifier", e.toString());
    }

    return text;
}

关于android - 从RemoteViews对象检索文本,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9293617/

10-11 19:59