如何在Android(2014)中使用aSmack XMPP库实现Facebook聊天?

时间:2014-01-14 13:53:22

标签: facebook facebook-graph-api chat

我搜索了许多地方,想方设法将Facebook聊天功能整合到Android / Smack中,但没有一个完全有效。有人可以提供适用于最新版本API的实用示例吗?

1 个答案:

答案 0 :(得分:1)

使用 X-FACEBOOK-PLATFORM SASLAuthentication进行身份验证。已于2014年1月14日通过Android 4.2.2验证工作。

jabber ID not username@chat.facebook.com。它被解析为一个数字ID,你可以检查名册。


<强> ChatActivity.java

public void connectToFb() throws XMPPException {        
        ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
        SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM",SASLXFacebookPlatformMechanism.class);
        SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
        config.setSASLAuthenticationEnabled(true);
        config.setSecurityMode(SecurityMode.required);
        config.setSendPresence(false);
        XMPPConnection xmpp = new XMPPConnection(config);
        try {
            xmpp.connect();
            xmpp.login(Session.getActiveSession().getApplicationId(), Session.getActiveSession().getAccessToken(), "Application");

            //send a chat message           
            ChatManager chatmanager = xmpp.getChatManager();
            Chat newChat = chatmanager.createChat("<jabber-id-here>@chat.facebook.com", new MessageListener() {
                @Override
                public void processMessage(Chat chat, Message msg) {
                    Log.d("test", "message sent = "+ msg);
                }
            });
            newChat.sendMessage("Cowdy!");    

            //get roster  
            Roster roster = xmpp.getRoster();
            Collection<RosterEntry> entries = roster.getEntries();
            System.out.println("Connected!");
            System.out.println("\n\n" + entries.size() + " buddy(ies):");
            for (RosterEntry entry : entries) {
                Log.i("test", entry.getName());
                Log.i("test", entry.getUser());
            }
        } catch (XMPPException e) {
            xmpp.disconnect();
            e.printStackTrace();
        }
    }

<强> SASLXFacebookPlatformMechanism.java

public class SASLXFacebookPlatformMechanism extends SASLMechanism {

        public static final String NAME = "X-FACEBOOK-PLATFORM";
        private String apiKey = "";
        private String accessToken = "";


        /**
         * Constructor.
         */
        public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication) {
            super(saslAuthentication);
        }

        @Override
        protected void authenticate() throws IOException, XMPPException {
            // Send the authentication to the server
            getSASLAuthentication().send(new AuthMechanism(getName(), ""));
        }

        @Override
        public void authenticate(String apiKey, String host, String accessToken) throws IOException, XMPPException {
            this.apiKey = apiKey;
            this.accessToken = accessToken;
            this.hostname = host;

            String[] mechanisms = { "DIGEST-MD5" };
            Map<String, String> props = new HashMap<String, String>();
            this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
            authenticate();
        }

        @Override
        protected String getName() {
            return NAME;
        }

        @Override
        public void challengeReceived(String challenge) throws IOException {
            byte[] response = null;

            if (challenge != null) {
                String decodedChallenge = new String(Base64.decode(challenge));
                Map<String, String> parameters = getQueryMap(decodedChallenge);

                String version = "1.0";
                String nonce = parameters.get("nonce");
                String method = parameters.get("method");

                long callId = new GregorianCalendar().getTimeInMillis() / 1000L;

                String composedResponse = "api_key=" + URLEncoder.encode(apiKey, "utf-8")
                        + "&call_id=" + callId
                        + "&method=" + URLEncoder.encode(method, "utf-8")
                        + "&nonce=" + URLEncoder.encode(nonce, "utf-8")
                        + "&access_token=" + URLEncoder.encode(accessToken, "utf-8")
                        + "&v=" + URLEncoder.encode(version, "utf-8");

                response = composedResponse.getBytes("utf-8");
            }

            String authenticationText = "";

            if (response != null){
                authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
            }
            // Send the authentication to the server
            getSASLAuthentication().send(new Response(authenticationText));
        }

        private Map<String, String> getQueryMap(String query) {
            Map<String, String> map = new HashMap<String, String>();
            String[] params = query.split("\\&");

            for (String param : params) {
                String[] fields = param.split("=", 2);
                map.put(fields[0], (fields.length > 1 ? fields[1] : null));
            }
            return map;
        }
    }

使用SASL / Plain的身份验证流程(提供用户名和密码时)

请参阅Android Facebook chat example project