Search code examples
androidremoteview

Retrieve text from a RemoteViews Object


I need to retrieve some text from a RemoteViews object. It is possible for me to get the LayoutId, but I have no idea how to retrieve text from a TextView that is in this RemoteView (namely a notification).

Also the RemoteView only contains setters, but no getters, so I guess I have to use the LayoutId (somehow).

Can you help me with that? Thanks!

/edit: The reason why I am asking this, is because I have an AccessibilityService that retrieves the notification. Therefore this is the only way of retrieving the value.

/edit2: I use this code for receiving the notification:

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

    }
}

With the notification object I have access to a RemoteViews (notification.contentView) and to a PendingIntent (notification.contentIntent). To get the layoutId, I can call contentView.getLayoutId()


Solution

  • Taken from Extract notification text from parcelable, contentView or contentIntent :

    Notification notification = (Notification) event.getParcelableData();
    RemoteViews views = notification.contentView;
    Class secretClass = views.getClass();
    
    try {
        Map<Integer, String> text = new HashMap<Integer, String>();
    
        Field outerFields[] = secretClass.getDeclaredFields();
        for (int i = 0; i < outerFields.length; i++) {
            if (!outerFields[i].getName().equals("mActions")) continue;
    
            outerFields[i].setAccessible(true);
    
            ArrayList<Object> actions = (ArrayList<Object>) outerFields[i]
            .get(views);
            for (Object action : actions) {
                Field innerFields[] = action.getClass().getDeclaredFields();
    
                Object value = null;
                Integer type = null;
                Integer viewId = null;
                for (Field field : innerFields) {
                    field.setAccessible(true);
                    if (field.getName().equals("value")) {
                        value = field.get(action);
                    } else if (field.getName().equals("type")) {
                        type = field.getInt(action);
                    } else if (field.getName().equals("viewId")) {
                        viewId = field.getInt(action);
                    }
                }
    
                if (type == 9 || type == 10) {
                    text.put(viewId, value.toString());
                }
            }
    
            System.out.println("title is: " + text.get(16908310));
            System.out.println("info is: " + text.get(16909082));
            System.out.println("text is: " + text.get(16908358));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }