используя XMPP для определения местоположения пользователя - PullRequest
4 голосов
/ 28 апреля 2010

Я хочу создать приложение для Android, которое позволит мне получить геолокацию пользователя. Это должно быть сделано как клиент-серверное приложение, а для серверной части я использую OpenFire. Для получения местоположения пользователя я должен был бы использовать XEP-0080, верно? И SmackAPI тоже? Я совершенно новичок в XMPP и Smack, так что если кто-нибудь может дать мне несколько указателей или, возможно, примеры или любую документацию по этому поводу, я был бы очень благодарен.

Заранее спасибо за любую помощь.

Ответы [ 2 ]

3 голосов
/ 03 ноября 2014

Android-проект, над которым я сейчас работаю, требует периодической публикации местоположения пользователя его друзьям из списка XMPP с помощью aSmack & XEP-0080.

Это оказалось сложнее, чем мне бы хотелось, поэтому я задокументировал свое решение здесь: http://www.dbotha.com/2014/11/02/xep-0080-user-location-on-android-using-pep-with-smack/

Для полноты я расскажу здесь о важных частях. В интересах краткости единственные дочерние элементы XML из спецификации XEP-0080, которые я рассмотрю, - это элементы, относящиеся к широте и долготе.

PEPItem для хранения местоположения пользователя и преобразования его в соответствующий XML:

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);
    }
}

В основном шаблонный PEPEvent для хранения пользовательского местоположения 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's:

PEPListener PEP_LISTENER = new PEPListener() {
    @Override
    public void eventReceived(String from, PEPEvent event) {
        if (event instanceof UserLocationEvent) {
            // do something interesting
        }
    }
};
2 голосов
/ 28 апреля 2010

Я считаю, что это близко к тому, что вы пытаетесь достичь.

Расположение пользователя XEP-0080 в библиотеке Smack

...