2013-06-28 3 views
5

Ich benutze asmack die neueste Version (asmack-android-8-source-0.8.3) in einem Android-Projekt und Ich habe den folgenden Code :(a) Smacks IQ.toXml() gibt XML ohne benutzerdefinierte Kindelemente zurück

connection.addPacketListener(new PacketListener() 
{ 
    @Override 
    public void processPacket(Packet p) 
    { 
     if(p.getPacketID().equals("v3")) 
     { 
      Log.e("TAG", p.toXML()); 
     } 
    } 
}, new IQTypeFilter(IQ.Type.RESULT)); 


Packet iq = new Packet() 
{ 
    @Override 
    public String toXML() 
    { 
     String str = "<iq type='get' id='v3'><getservertime xmlns='urn:xmpp:mrpresence'/></iq>"; 
     Log.e("TAG", str); 
     return str; 
    } 
}; 

//sends <iq type='get' id='v3'><getservertime xmlns='urn:xmpp:mrpresence'/></iq> 
connection.sendPacket(iq); 

im Debugger die Antwort, es ist ok, und dies erwartet wird:

<iq type="result" id="v3" to="[email protected]/Smack"> 
    <servertime xmlns="urn:xmpp:mrpresence" utc="2013-06-28T11:45:32.380Z" local="2013-06-28T07:45:32.380Z"/> 
</iq> 

aber p.toXML() im Paket listner, das Stichwort "Servertime" es fehlt:

<iq id="v3" to="[email protected]/Smack" type="result"></iq> 

Irgendwelche Vorschläge, was ich falsch mache?

Antwort

3

<servertime/> ist ein benutzerdefiniertes untergeordnetes Element, das Smack nicht bekannt ist. Es wird einfach ignoriert, wenn die Zeilengruppe analysiert wird. Sie müssen Smack auf das Element aufmerksam machen, indem Sie eine neue PacketExtension erstellen, die mit der ProviderManager registriert werden muss.

Sie können mehr darüber in Smacks Dokumentation über die Provider Architecture lesen.

+0

Ich habe einen PacketExtensionProvider mit ProviderManager.getInstance() hinzugefügt. AddExtensionProvider (packetExtensionProvider) wie in diesem Tutorial: http://oneminutedistraction.wordpress.com/2010/08/31/receiving-pep-broadcast-2/ aber mein PacketExtensionProvider wird nie aufgerufen. Benütze ich immer noch connection.addPacketListener()? Danke. –

+0

Ich habe mir auch diesen Quellcode angeschaut: github.com/rumblem/jfexmpp und diesen einen GitHub.com/redsolution/xabber-android aber kein Erfolg :( –

+0

@Flow können Sie bitte erarbeiten, wie Sie eine neue PacketExtension erstellen und registrieren Sie sie mit ProviderManager. – Sushant

3

ich dieses Problem gelöst durch IQ und IQProvider Klassen erstrecken:

ServerTime_IQProvider.java

public class ServerTime_IQProvider implements IQProvider 
{ 
    public static final String NAMESPACE = "urn:xmpp:mrpresence"; 
    public static final String ELEMENT_NAME = "servertime"; 
    public static final String UTC = "utc"; 
    public static final String LOCAL = "local"; 
    private Map<String, String> list = new HashMap<String, String>(); 

    @Override 
    public IQ parseIQ(XmlPullParser parser) throws Exception 
    { 
     boolean stop = false; 
     String name = parser.getName(); 

     while(false == stop) 
     { 
      switch (parser.getEventType()) 
      { 
       case XmlPullParser.START_TAG: 
       { 
        if(ELEMENT_NAME.equals(name)) 
        { 
         list.put(UTC, parser.getAttributeValue("", UTC)); 
         list.put(LOCAL, parser.getAttributeValue("", LOCAL)); 
        } 

        break; 
       } 
       case XmlPullParser.END_TAG: 
       { 
        stop = ELEMENT_NAME.equals(name); 
        break; 
       } 
      } 
     } 

     name = null; 
     return new ServerTime_IQ(list); 
    } 
} 

ServerTime_IQ.java

public class ServerTime_IQ extends IQ 
{ 
    public static final String ID = "servertime"; 
    private Map<String, String> list; 

    public ServerTime_IQ(Map<String, String> l) 
    { 
     list = l; 
    } 

    @Override 
    public String getChildElementXML() 
    { 
     return null; 
    } 

    public String getServerTime_UTC() 
    { 
     return list.get(ServerTime_IQProvider.UTC); 
    } 

    public String getServerTime_Local() 
    { 
     return list.get(ServerTime_IQProvider.LOCAL); 
    } 
} 

Dann habe ich den Serveranbieter die Liste der IQProvider:

ProviderManager.getInstance().addIQProvider(ServerTime_IQProvider.ELEMENT_NAME, ServerTime_IQProvider.NAMESPACE, new ServerTime_IQProvider()); 

Dadurch wird sichergestellt, dass die XML-Antwort vom Server mit meinem benutzerdefinierten Parser (ServerTime_IQProvider) analysiert wird, der die benutzerdefinierten Tags kennt und nicht mit dem Standard-Parser von Asmack.

2

Dies funktioniert für mich

ServerTime_IQProvider.class

public class ServerTime_IQProvider implements IQProvider{ 
    public static final String NAMESPACE = "urn:xmpp:mrpresence"; 
    public static final String ELEMENT_NAME = "servertime"; 
    public static final String UTC = "utc"; 
    public static final String LOCAL = "local"; 
    private Map<String, String> list = new HashMap<String, String>(); 

    @Override 
    public IQ parseIQ(XmlPullParser parser) throws Exception 
    { 
     boolean stop = false; 
     String name = parser.getName(); 

     while(false == stop) 
     { 
      int i = parser.getEventType(); 

      switch (i) 
      { 
      case XmlPullParser.START_TAG: 
      { 
       if(ELEMENT_NAME.equals(name)) 
       { 
        list.put(UTC, parser.getAttributeValue("", UTC)); 
        list.put(LOCAL, parser.getAttributeValue("", LOCAL)); 
       } 
       parser.next(); 

       break; 
      } 
      case XmlPullParser.END_TAG: 
      { 
       stop = ELEMENT_NAME.equals(name); 
       break; 
      } 
      } 
     } 

     name = null; 
     return new ServerTime_IQ(list); 
    } 
} 

WebServiceIQ.class

public class ServerTime_IQ extends IQ{ 
    public static final String ID = "servertime"; 
    private Map<String, String> list; 

    public ServerTime_IQ(Map<String, String> l) 
    { 
     list = l; 
    } 

    @Override 
    public String getChildElementXML() 
    { 
     StringBuilder builder = new StringBuilder("<"+ServerTime_IQProvider.ELEMENT_NAME+" xmlns=\""+ServerTime_IQProvider.NAMESPACE+"\" "); 
     builder.append(ServerTime_IQProvider.UTC+"=\""+getServerTime_UTC()+"\" "); 
     builder.append(ServerTime_IQProvider.LOCAL+"=\""+getServerTime_Local()+"\" "); 
     builder.append("/>"); 
     return builder.toString(); 
    } 

    public String getServerTime_UTC() 
    { 
     return list.get(ServerTime_IQProvider.UTC); 
    } 

    public String getServerTime_Local() 
    { 
     return list.get(ServerTime_IQProvider.LOCAL); 
    } 
} 

dann den Serveranbieter die Liste der IQProvider hinzufügen

ProviderManager.addIQProvider(ServerTime_IQProvider.ELEMENT_NAME,ServerTime_IQProvider.NAMESPACE, new ServerTime_IQProvider()); 

Paketfilter für ServerTime_IQ Paket

connection.addPacketListener(new PacketListener() { 
     @Override 
     public void processPacket(Packet packet) { 
      System.out.println("################# Custom packet received"); 

      ServerTime_IQ IQ = (ServerTime_IQ)packet; 
      //Do your stuff 

     } 
    }, new PacketTypeFilter(ServerTime_IQ.class)); 

Dies ist die erste Antwort von mir eingereichten hier, Senioren bitte Änderungen, wenn erforderlich machen.

Verwandte Themen