3

I am extending Android TagHandler class to handle custom html tags within a TextField. So far so good, I am able to intercept the tags and assing custom functionality to the "onClick()" for these. However - I am not able to capture any attributes for these custom tags, for example:

"This is an example of a custom mark-up tag embedded in text that a text field would handle <custom id='1233' uri='0023'> CUSTOM </custom>and that I need to capture."

I am able to capture the occurrence of the custom tag but not the attributes with the following:

public class SpecialTagHandler implements TagHandler
{
    @Override
    public void handleTag(
      boolean opening,
      String tag,
      Editable output,
      XMLReader xmlReader)
    {
        if(tag.equalsIgnoreCase("custom")) {

            // handle the custom tag
            if(opening) {

                Log.e(TAG, "found custom tag OPENING");
                try {
                    Field elementField = xmlReader.getClass().getDeclaredField("theNewElement");
                    elementField.setAccessible(true);

                    try {
                        Object element = elementField.get(xmlReader);
                        Field attsField = element.getClass().getDeclaredField("theAtts");
                        attsField.setAccessible(true);

                        Object atts = attsField.get(element);
                        Field dataField = atts.getClass().getDeclaredField("data");
                        dataField.setAccessible(true);

                        String[] data = (String[])dataField.get(atts);
                        Field lengthField = atts.getClass().getDeclaredField("length");
                        lengthField.setAccessible(true);

                        int length = (Integer)lengthField.get(atts);
                        String mIdAttribute = null;
                        String mUrlAttribute = null;

                        for(int i = 0; i < length; i++) {
                            if("id".equals(data[i*5 + 1])) {
                                mIdAttribute = data[i*5 + 4];
                            } else if("uri".equals(data[i*5 + 1])) {
                                mUrlAttribute = data[i*5 + 4];
                            }
                        }
                        Log.e(TAG, "id: " + mIdAttribute + " url: " + mUrlAttribute);
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } catch (NoSuchFieldException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
}

Any suggestions on how to read the id and uri attributes as well? There was a discussion about using XMLReader that is passed to this function. Thanks in advance!

-------- HAVE AN ANSWER! ---------

Well - some more digging and Voila! YES - you do have access to your custom attributes in your tag in marked-up html text. I have to include what appears to me dark magic from @rekire using reflection to access xmlReader attributes. (none of these elements are "visible" to a "naked" eye). The link is here: link. No need to resort to duplicate java classes or funky tag names that actually include id in it's designation! Thanks again - @rekire Added the code paraphrased from linked post that will do the trick.

Community
  • 1
  • 1
narkis
  • 335
  • 1
  • 7
  • 17
  • they dont pass Attributes so probably you cannot do that – pskink Dec 26 '13 at 17:48
  • @pskink - It is attempted here - using reflection. [link](http://stackoverflow.com/questions/6952243/how-to-get-an-attribute-from-an-xmlreader) - not sure how this is implementable in my case - I can only parse Fields that are declared by the xmlReader - not anything "custom" – narkis Dec 26 '13 at 17:57
  • if you really need to access atteibutes in custom tags copy/paste Html class and pass Attributes instead of XmlReader as a third parameter – pskink Dec 26 '13 at 18:19
  • after tracing what is available, i.e. Fields while iterating through xmlReader in this case, I appear to have a handle to the following: HEADER_SIZES, mImageGetter, mReader, mSource, mSpannableStringBuilder, mTagHandler. Could any of these be of any use before I go cut'n'pastin' ? – narkis Dec 26 '13 at 19:18
  • see https://github.com/android/platform_frameworks_base/blob/master/core/java/android/text/Html.java, method handleStartTag, you need its second parameter not any class field, – pskink Dec 26 '13 at 19:30
  • checked that - thanks- now trying to figure out if there is a more elegant way to get to that without the cut'n'paste – narkis Dec 26 '13 at 19:34

1 Answers1

0

It is possible to hook into XMLReader and get access attributes by replacing xmlReader ContentHandler with your own ContentHandler. This method does not work for the first html tag, thus a fake tag has to be added at the start. See detailed answer.

Community
  • 1
  • 1
Juozas Kontvainis
  • 9,461
  • 6
  • 55
  • 66