使用 `xmpp` 和 `smack` 从 `vcard` 获取自定义元素
Posted
技术标签:
【中文标题】使用 `xmpp` 和 `smack` 从 `vcard` 获取自定义元素【英文标题】:Get customized element from `vcard` using `xmpp` and `smack` 【发布时间】:2019-03-05 16:39:21 【问题描述】:我创建了一个带有自定义元素的vcard
:
<vCard xmlns='vcard-temp'><NICKNAME>nickname</NICKNAME><elementName xmlns='xmlns:custom'><avatar>elementName_avatar_3.png</avatar></elementName></vCard>
当我问这个vcard
时,我的结果是:
<iq xmlns='jabber:client' to='602157@peropenfire101.per.local/3r6td85ng7' from='271087@peropenfire101.per.local' id='jA5pI-33' type='result'><vCard xmlns='vcard-temp'><JABBERID>271087@peropenfire101.per.local/4usgw7j7u</JABBERID><NICKNAME>nickname</NICKNAME></vCard></iq>
如您所见,缺少自定义元素。 这是我的要求:
try
connection.sendStanzaWithResponseCallback(
new cdcd(from),
new StanzaFilter()
@Override
public boolean accept(Stanza stanza)
return false;
,
new StanzaListener()
@Override
public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException, SmackException.NotLoggedInException
);
catch (Exception e)
e.printStackTrace();
private class cdcd extends Stanza
private final Jid from;
public cdcd(Jid from)
this.from = from;
@Override
public String toString()
return null;
@Override
public CharSequence toXML(String enclosingNamespace)
return "<iq from=\'"+ from +"\' id='v1' type='get'><vCard xmlns='vcard-temp'/></iq>";
我不知道如何解决这个问题。
【问题讨论】:
【参考方案1】:根据XEP-054不支持vCard DTD的非标准元素的特性,所以你的XMPP服务器忽略它们。
很遗憾,Dawson 的提案并未在 IETF 的标准流程中取得进展。由于现在在时间的迷雾中迷失的原因,Jabber 项目继续使用来自 draft-dawson-vcard-xml-dtd-01 的 DTD,进行了两项小的修改以使其适用于 Jabber 社区(添加 JABBERID 和 DESC元素),但也指定所有大写而不是小写的元素名称,如 Draft-dawson-vcard-xml-dtd-01 中定义的那样。此外,Jabber 社区遵循该草案中关于版本信息的用法(但不是 DTD),包括它作为 vCard 元素的属性而不是子元素。这种格式是在 Jabber 社区中的“vcard-temp”命名空间下实现的。
你可以看到here所有支持的元素。 另见讨论here
【讨论】:
@thorny84 ,我很高兴知道您是如何解决这个问题的。【参考方案2】:解决了...
我创建了一个扩展 VCardProvider
的新类,并在重写方法 parse 中解析了我的自定义标记
public class CustomVCardProvider extends VCardProvider
private static final String[] TEL = new String[]
"VOICE",
"FAX",
"PAGER",
"MSG",
"CELL",
"VIDEO",
"BBS",
"MODEM",
"ISDN",
"PCS",
"PREF",
;
private static final String[] ADR = new String[]
"POSTAL",
"PARCEL",
"DOM",
"INTL",
"PREF",
"POBOX",
"EXTADR",
"STREET",
"LOCALITY",
"REGION",
"PCODE",
"CTRY",
"FF",
;
@Override
public VCard parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException
VCard vCard = new VCard();
String name = null;
outerloop:
while (true)
int eventType = parser.next();
switch (eventType)
case XmlPullParser.START_TAG:
name = parser.getName();
switch (name)
case CUSTOM_TAG:
parseCustomTag(parser, vCard);
break;
case "N":
parseName(parser, vCard);
break;
case "ORG":
parseOrg(parser, vCard);
break;
case "TEL":
parseTel(parser, vCard);
break;
case "ADR":
parseAddress(parser, vCard);
break;
case "EMAIL":
parseEmail(parser, vCard);
break;
case "NICKNAME":
vCard.setNickName(parser.nextText());
break;
case "JABBERID":
vCard.setJabberId(parser.nextText());
break;
case "PHOTO":
parsePhoto(parser, vCard);
break;
default:
break;
break;
case XmlPullParser.TEXT:
if (initialDepth + 1 == parser.getDepth())
vCard.setField(name, parser.getText());
break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth)
break outerloop;
break;
default:
break;
return vCard;
别忘了从原始提供者那里复制所有解析器,并在认证后添加ProviderManager.addIQProvider("vCard", "vcard-temp", new CustomVCardProvider());
【讨论】:
以上是关于使用 `xmpp` 和 `smack` 从 `vcard` 获取自定义元素的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 Smack 4.1 从 Android 连接 apache vysper XMPP 服务器
使用 Smack Android 将字符串转换为 XMPP 节