4

我想为 Android 创建一个应用程序,使我能够获取用户的地理位置。这必须作为客户端-服务器应用程序制作,而对于服务器端,我使用的是 OpenFire。为了获取用户的位置,我必须使用 XEP-0080,对吗?还有 SmackAPI 吗?我对 XMPP 和 Smack 完全陌生,所以如果有人能给我一些指示或示例或任何类型的文档,我将非常感激。

提前感谢您的帮助。

4

2 回答 2

3

我目前正在处理的一个 Android 项目需要使用 aSmack 和 XEP-0080 定期将用户的位置发布给他们的 XMPP 名册朋友。

结果比我想要的更棘手,所以我在这里记录了我的解决方案:http ://www.dbotha.com/2014/11/02/xep-0080-user-location-on-android-using-pep-with-咂嘴/

为了完整起见,我将在这里介绍重要部分。为简洁起见,我将介绍的 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);
    }
}

用于保存 UserLocation PEPItem 的大部分样板 PEPEvent:

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
        }
    }
};
于 2014-11-03T17:03:50.697 回答
2

我相信这与您要完成的工作很接近。

XEP-0080 Smack 库中的用户位置

于 2010-04-27T22:16:13.300 回答