适用于android的XMPP/facebook聊天连接
更改:适用于android的XMPP/facebook聊天连接,android,facebook,xmpp,chat,Android,Facebook,Xmpp,Chat,更改: 02-18 16:06:20.178: ERROR/AndroidRuntime(453): java.lang.IllegalStateException: Not connected to server. 02-18 16:06:20.178: ERROR/AndroidRuntime(453): at org.jivesoftware.smack.XMPPConnection.sendPacket(XMPPConnection.java:665) 02-18 16:06:2
02-18 16:06:20.178: ERROR/AndroidRuntime(453): java.lang.IllegalStateException: Not connected to server.
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at org.jivesoftware.smack.XMPPConnection.sendPacket(XMPPConnection.java:665)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at com.developpez.florentgarin.android.ClientJabberActivity$1.onClick(ClientJabberActivity.java:61)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at android.view.View.performClick(View.java:2485)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at android.view.View$PerformClick.run(View.java:9080)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at android.os.Handler.handleCallback(Handler.java:587)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at android.os.Handler.dispatchMessage(Handler.java:92)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at android.os.Looper.loop(Looper.java:123)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at android.app.ActivityThread.main(ActivityThread.java:3647)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at java.lang.reflect.Method.invokeNative(Native Method)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at java.lang.reflect.Method.invoke(Method.java:507)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-18 16:06:20.178: ERROR/AndroidRuntime(453): at dalvik.system.NativeStart.main(Native Method)
02-18 16:06:43.167: ERROR/installd(35): eof
02-18 16:06:43.167: ERROR/installd(35): failed to read size
02-18 16:07:11.857: ERROR/Zygote(470): setreuid() failed. errno: 17
02-18 16:07:16.408: ERROR/BatteryService(477): usbOnlinePath not found
02-18 16:07:16.408: ERROR/BatteryService(477): batteryVoltagePath not found
02-18 16:07:16.408: ERROR/BatteryService(477): batteryTemperaturePath not found
02-18 16:07:16.477: ERROR/SurfaceFlinger(477): Couldn't open /sys/power/wait_for_fb_sleep or /sys/power/wait_for_fb_wake
02-18 16:07:16.758: ERROR/SensorService(477): couldn't open device for module sensors (Invalid argument)
致:
嗯,不完全是。不过你明白了
facebook的XMPP规范不包括用于登录的@server.here。将其包含在用户名字符串中或完全删除服务器字符串。Facebook登录不同:
private final static String LOGIN = "xxxxx";
package.com.test;
导入java.io.IOException;
导入java.io.UnsupportedEncodingException;
导入java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
导入java.util.GregorianCalendar;
导入java.util.HashMap;
导入java.util.Map;
导入org.apache.harmony.javax.security.auth.callback.CallbackHandler;
导入org.jivesoftware.smack.saslauthentification;
导入org.jivesoftware.smack.XMPPException;
导入org.jivesoftware.smack.sasl.SASLMechanism;
导入org.jivesoftware.smack.util.Base64;
导入de.measite.smack.Sasl;
公共类FacebookConnectSASLMechanism扩展了SASLMechanism
{
私有字符串sessionKey=“”;
私有字符串sessionSecret=“”;
私有字符串apiKey=“”;
公共Facebook连接SASLME机制(SASLAuthentication SASLAuthentication){
超级(saslAuthentication);
}
//受保护的void authenticate()引发IOException,xmppeException{
//字符串[]机制={getName()};
//Map props=newhashmap();
//sc=Sasl.createSaslClient(机制、null、“xmpp”、主机名、道具、,
//这),;
//
//super.authenticate();
// }
受保护的void authenticate()引发IOException,xmppeException{
StringBuilder节=新建StringBuilder();
第节。附加(“”);
第节。附加(“”);
//将身份验证发送到服务器
//getSASLAuthentication().send(节.toString());
}
public void身份验证(字符串apiKeyAndSessionKey、字符串主机、字符串sessionSecret)
抛出IOException,xmppeException{
if(apiKeyAndSessionKey==null | | sessionSecret==null)
抛出新的IllegalStateException(“无效参数!”);
String[]keyArray=apiKeyAndSessionKey.split(“\\\\”);
if(keyArray==null | | keyArray.length!=2)
抛出新的IllegalStateException(“Api密钥或会话密钥不存在!”);
this.apiKey=keyArray[0];
this.sessionKey=keyArray[1];
this.sessionSecret=sessionSecret;
this.authenticationId=会话密钥;
this.password=sessionSecret;
this.hostname=host;
字符串[]机制={“摘要-MD5”};
Map props=newhashmap();
sc=Sasl.createSaslClient(机制,null,“xmpp”,主机,道具,this);
验证();
}
公共无效身份验证(字符串用户名、字符串主机、CallbackHandler cbh)
抛出IOException,xmppeException{
字符串[]机制={“摘要-MD5”};
Map props=newhashmap();
sc=Sasl.createSaslClient(机制,null,“xmpp”,主机,道具,cbh);
验证();
}
受保护的字符串getName(){
返回“X-FACEBOOK-PLATFORM”;
}
public void challengeReceived(字符串质询)引发IOException{
//构建对响应文本进行编码的质询响应节
StringBuilder节=新建StringBuilder();
字节响应[]=null;
if(质询!=null){
String decodedResponse=新字符串(Base64.decode(challenge));
映射参数=getQueryMap(decodedResponse);
字符串version=“1.0”;
字符串nonce=parameters.get(“nonce”);
String方法=parameters.get(“方法”);
Long callId=new gregorianalendar().getTimeInMillis()/1000;
字符串sig=“api_key=“+apiKey
+“call_id=“+callId
+“方法=”+方法
+“nonce=“+nonce
+“会话密钥=”+会话密钥
+“v=”+版本
+会议秘书;
试一试{
sig=MD5(sig);
}捕获(无算法异常){
抛出新的非法状态异常(e);
}
字符串composedResponse=“api_key=“+apiKey+”&”
+“call_id=“+callId+”&”
+“method=“+method+”&”
+“nonce=“+nonce+”&”
+“session_key=“+sessionKey+”&”
+“v=“+版本+”&”
+“sig=“+sig;
response=composedResponse.getBytes();
}
字符串authenticationText=“”;
if(响应!=null){
authenticationText=Base64.encodeBytes(响应,Base64.Don_BREAK_line);
}
第节。附加(“”);
附加节(authenticationText);
第节。附加(“”);
//将身份验证发送到服务器
//getSASLAuthentication().send(节);
}
私有映射getQueryMap(字符串查询){
字符串[]params=query.split(&);
Map Map=newhashmap();
for(字符串参数:params){
字符串名称=参数拆分(“=”[0];
字符串值=参数拆分(“=”[1];
map.put(名称、值);
}
private final static String LOGIN = "xxxxx@chat.facebook.com";
private final static String LOGIN = "xxxxx";
package com.test;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.util.Base64;
import de.measite.smack.Sasl;
public class FacebookConnectSASLMechanism extends SASLMechanism
{
private String sessionKey = "";
private String sessionSecret = "";
private String apiKey = "";
public FacebookConnectSASLMechanism(SASLAuthentication saslAuthentication) {
super(saslAuthentication);
}
// protected void authenticate() throws IOException, XMPPException {
// String[] mechanisms = { getName() };
// Map<String, String> props = new HashMap<String, String>();
// sc = Sasl.createSaslClient(mechanisms, null, "xmpp", hostname, props,
// this);
//
// super.authenticate();
// }
protected void authenticate() throws IOException, XMPPException {
StringBuilder stanza = new StringBuilder();
stanza.append("<auth mechanism=\"").append(getName());
stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
stanza.append("</auth>");
// Send the authentication to the server
//getSASLAuthentication().send(stanza.toString());
}
public void authenticate(String apiKeyAndSessionKey, String host, String sessionSecret)
throws IOException, XMPPException {
if(apiKeyAndSessionKey==null || sessionSecret==null)
throw new IllegalStateException("Invalid parameters!");
String[] keyArray = apiKeyAndSessionKey.split("\\|");
if(keyArray==null || keyArray.length != 2)
throw new IllegalStateException("Api key or session key is not present!");
this.apiKey = keyArray[0];
this.sessionKey = keyArray[1];
this.sessionSecret = sessionSecret;
this.authenticationId = sessionKey;
this.password = sessionSecret;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
authenticate();
}
public void authenticate(String username, String host, CallbackHandler cbh)
throws IOException, XMPPException {
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh);
authenticate();
}
protected String getName() {
return "X-FACEBOOK-PLATFORM";
}
public void challengeReceived(String challenge) throws IOException {
// Build the challenge response stanza encoding the response text
StringBuilder stanza = new StringBuilder();
byte response[] = null;
if (challenge != null) {
String decodedResponse = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedResponse);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
Long callId = new GregorianCalendar().getTimeInMillis()/1000;
String sig = "api_key="+apiKey
+"call_id="+callId
+"method="+method
+"nonce="+nonce
+"session_key="+sessionKey
+"v="+version
+sessionSecret;
try {
sig = MD5(sig);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e);
}
String composedResponse = "api_key="+apiKey+"&"
+"call_id="+callId+"&"
+"method="+method+"&"
+"nonce="+nonce+"&"
+"session_key="+sessionKey+"&"
+"v="+version+"&"
+"sig="+sig;
response = composedResponse.getBytes();
}
String authenticationText="";
if (response != null) {
authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
}
stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
stanza.append(authenticationText);
stanza.append("</response>");
// Send the authentication to the server
//getSASLAuthentication().send(stanza);
}
private Map<String, String> getQueryMap(String query) {
String[] params = query.split("&");
Map<String, String> map = new HashMap<String, String>();
for (String param : params) {
String name = param.split("=")[0];
String value = param.split("=")[1];
map.put(name, value);
}
return map;
}
private String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9))
buf.append((char) ('0' + halfbyte));
else
buf.append((char) ('a' + (halfbyte - 10)));
halfbyte = data[i] & 0x0F;
} while(two_halfs++ < 1);
}
return buf.toString();
}
public String MD5(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md;
md = MessageDigest.getInstance("MD5");
byte[] md5hash = new byte[32];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
md5hash = md.digest();
return convertToHex(md5hash);
}
}