我想为android创建一个应用程序,使我能够获得用户的地理位置。这必须作为一个客户端-服务器应用程序,对于服务器端,我使用openfire。
为了得到用户的位置,我必须使用xep-0080,对吗?还有Smackapi?
我对xmpp和smack是完全陌生的,所以如果有人能给我一些指针或者示例,或者任何关于这个的文档,我会非常感激。
提前谢谢你的帮助。

最佳答案

我目前正在做的一个android项目需要定期使用asmack&xep-0080将用户的位置发布给他们的xmpp花名册朋友。
结果比我想要的要复杂,所以我在这里记录了我的解决方案:http://www.dbotha.com/2014/11/02/xep-0080-user-location-on-android-using-pep-with-smack/
为了完整起见,我将在这里介绍重要的部分。为了简洁起见,我将介绍xep-0080规范中唯一的xml子元素是那些与纬度和经度相关的元素。
用于保存用户位置并将其转换为适当XML的pepitem:

public class UserLocation extends PEPItem {

    public static final String NODE =
        "http://jabber.org/protocol/geoloc";

    public final double latitude, longitude;

    public UserLocation(double latitude, double longitude) {
        this(StringUtils.randomString(16), latitude, longitude);
    }

    public UserLocation(double latitude, double longitude,
            String id) {
        super(id);
        this.latitude = latitude;
        this.longitude = longitude;
    }

    @Override
    java.lang.String getNode() {
        return NODE;
    }

    // return an XML element approximately inline
    // with the XEP-0080 spec
    @Override
    java.lang.String getItemDetailsXML() {
        return String.format(
            "<geoloc xmlns='%s'><lat>%f</lat>" +
            "<lon>%f</lon></geoloc>",
            NODE, latitude, longitude);
    }
}

一个主要用于保存用户位置pepitem的样板pepitem:
public class UserLocationEvent extends PEPEvent {

    private final UserLocation location;

    public UserLocationEvent(UserLocation location) {
        this.location = location;
    }

    public UserLocation getLocation() {
        return location;
    }

    @Override
    public String getNamespace() {
        return "http://jabber.org/protocol/pubsub#event";
    }

    @Override
    public String toXML() {
        return String.format("<event xmlns=" +
            "'http://jabber.org/protocol/pubsub#event' >" +
            "<items node='%s' >%s</items></event>",
            UserLocation.NODE, location.toXML());
    }
}

一个自定义packetextensionprovider,用于从存在的传入数据包中分析出userlocationevent。
public class UserLocationProvider
        implements PacketExtensionProvider {

    // This method will get called whenever aSmack discovers a
    // packet extension containing a publish element with the
    // attribute node='http://jabber.org/protocol/geoloc'
    @Override
    public PacketExtension parseExtension(XmlPullParser parser)
            throws Exception {

        boolean stop = false;
        String id = null;
        double latitude = 0;
        double longitude = 0;
        String openTag = null;

        while (!stop) {
            int eventType = parser.next();

            switch (eventType) {
                case XmlPullParser.START_TAG:
                    openTag = parser.getName();
                    if ("item".equals(openTag)) {
                        id = parser.getAttributeValue("", "id");
                    }

                    break;

                case XmlPullParser.TEXT:
                    if ("lat".equals(openTag)) {
                        try {
                            latitude = Double.parseDouble(
                                parser.getText());
                        } catch (NumberFormatException ex) {
                            /* ignore */
                        }
                    } else if ("lon".equals(openTag)) {
                        try {
                            longitude = Double.parseDouble(
                                parser.getText());
                        } catch (NumberFormatException ex) {
                            /* ignore */
                        }
                    }

                    break;

                case XmlPullParser.END_TAG:
                    // Stop parsing when we hit </item>
                    stop = "item".equals(parser.getName());
                    openTag = null;
                    break;
            }
        }

        return new UserLocationEvent(
            new UserLocation(id, latitude, longitude));
    }
}

现在把这些联系在一起:
XMPPTCPConnection connection = new XMPPTCPConnection();

ServiceDiscoveryManager sdm = ServiceDiscoveryManager
    .getInstanceFor(connection);
sdm.addFeature("http://jabber.org/protocol/geoloc");
sdm.addFeature("http://jabber.org/protocol/geoloc+notify");

EntityCapsManager capsManager = EntityCapsManager
    .getInstanceFor(connection);
capsManager.enableEntityCaps();

PEPProvider pepProvider = new PEPProvider();
pepProvider.registerPEPParserExtension(
    "http://jabber.org/protocol/geoloc",
    new UserLocationProvider());
ProviderManager.addExtensionProvider("event",
    "http://jabber.org/protocol/pubsub#event", pepProvider);
PEPManager pepManager = new PEPManager(connection);
pepManager.addPEPListener(PEP_LISTENER);

connection.connect();
connection.login(username, password);

最后是传入locationevent的侦听器:
PEPListener PEP_LISTENER = new PEPListener() {
    @Override
    public void eventReceived(String from, PEPEvent event) {
        if (event instanceof UserLocationEvent) {
            // do something interesting
        }
    }
};

10-07 19:14
查看更多