982013-05-03 22:01:25| 分类: 默认分类 | 标签:android xmpp xmpp登陆 即时聊天 安卓即时聊天 |字号 订阅
登陆这里着实走了很多弯路,由于没有系统的资料介绍,只能各种百度谷歌,我这里大概写一下一些常识。PS:没有专业的名词和术语,都是根据我自己的理解写的,如有错误的地方欢迎指正。
登陆的三要素:IP地址、端口、结点标识符;IP地址自然是服务器的IP,端口号一般都是5222,节点标识符一般是域名,但是这是正式部署服务器的时候的结点标识符,平时测试的时候应该不是真实的域名而是服务器上配置的,这个可以根据服务器配置来确定。
下面是网上常见的登陆代码,但是我是用不成功:
XMPPConnection connection = null;
ConnectionConfiguration connectionConfig = new ConnectionConfiguration(host, 5222, "");
connConfig.setReconnectionAllowed(true);
connConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
connConfig.setSASLAuthenticationEnabled(true);
connConfig .setTruststorePath("/system/etc/security/cacerts.bks");
connConfig.setTruststorePassword("changeit");
connConfig.setTruststoreType("bks");
connection = new XMPPConnection(connConfig); 还有一些比较简单的登录方式:
ConnectionConfiguration config = new ConnectionConfiguration("jabber.org", 5222);
XMPPConnection conn = new XMPPConnection(config); 这些我是一律没有登陆成功,我的登陆代码如下:
ConnectionConfiguration connConfig = new ConnectionConfiguration("46.55.63.125", 5222, "yiqiwan.com");
xmppConnection = new XMPPConnection(connConfig);
xmppConnection.connect();
// 此登陆代码后面会继续完善 个人感觉asmack既然作为开源的支持包,应该封装了一些通用的操作,像第一个那样的设置至少在Android的asmack上可以省略。上面的三个参数分别就是刚才说的三个要素了,不过为了在全程序中使用一个实例,建议使用单例模式。
这里要说一下Android在使用asmack的时候经常出现的一些监听器明明注册了但是却不触发或者一些类型转换异常的情况,原因我不清楚,看了好多资料大概是因为Android不允许预读取asmack里面的一个叫META-INF里面的文件?这个搞不清,但是至少我按照以下代码设置基本所有的监听器都可以使用了(我的OfflineMessageManager还是用不了,那是因为ejabberd服务器暂时还不支持此服务)。
贴出来我的XMPP初始化的源码吧,这里只是初始化,没有登录。
package com.dbw.travel.net;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.provider.PrivacyProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smackx.GroupChatInvitation;
import org.jivesoftware.smackx.PrivateDataManager;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.bytestreams.socks5.provider.BytestreamsProvider;
import org.jivesoftware.smackx.packet.ChatStateExtension;
import org.jivesoftware.smackx.packet.LastActivity;
import org.jivesoftware.smackx.packet.OfflineMessageInfo;
import org.jivesoftware.smackx.packet.OfflineMessageRequest;
import org.jivesoftware.smackx.packet.SharedGroupsInfo;
import org.jivesoftware.smackx.provider.AdHocCommandDataProvider;
import org.jivesoftware.smackx.provider.DataFormProvider;
import org.jivesoftware.smackx.provider.DelayInformationProvider;
import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
import org.jivesoftware.smackx.provider.MUCAdminProvider;
import org.jivesoftware.smackx.provider.MUCOwnerProvider;
import org.jivesoftware.smackx.provider.MUCUserProvider;
import org.jivesoftware.smackx.provider.MessageEventProvider;
import org.jivesoftware.smackx.provider.MultipleAddressesProvider;
import org.jivesoftware.smackx.provider.RosterExchangeProvider;
import org.jivesoftware.smackx.provider.StreamInitiationProvider;
import org.jivesoftware.smackx.provider.VCardProvider;
import org.jivesoftware.smackx.provider.XHTMLExtensionProvider;
import org.jivesoftware.smackx.search.UserSearch;
import android.util.Log;
import com.dbw.travel.utils.AppConfig;
import com.dbw.travel.utils.LogUtil;
/**
*
* @author WuMeng
* @version 1.0
* @date 2012-12-03
* @Description XMPP实例处理类
*
*/
public class BaseXmpp {
/** XMPP实例 单例模式 */
private static XMPPConnection xmppConnection = null;
/**
* 单例模式
*
* @return
*/
public static XMPPConnection getConnection() {
if (xmppConnection == null) {
createConnection();
}
return xmppConnection;
}
/**
* 关闭连接
*/
public static void closeConnection() {
if (xmppConnection != null && xmppConnection.isConnected()) {
xmppConnection.disconnect();
}
xmppConnection = null;
}
/**
* 创建连接
*/
private static void createConnection() {
try {
configure(ProviderManager.getInstance());
// 这三个参数自行修改为自己的真实数值
ConnectionConfiguration connConfig = new ConnectionConfiguration(
ServerConfig.XMPP_SERVER_IP, ServerConfig.XMPP_SERVER_PORT,
ServerConfig.XMPP_SERVICE_NAME);
xmppConnection = new XMPPConnection(connConfig);
xmppConnection.connect();
initFeatures(xmppConnection);
} catch (XMPPException e) {
LogUtil.doException(e);
}
}
private static void initFeatures(XMPPConnection xmppConnection) {
ServiceDiscoveryManager.setIdentityName("Android_IM");
ServiceDiscoveryManager.setIdentityType("phone");
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(xmppConnection);
if (sdm == null) {
sdm = new ServiceDiscoveryManager(xmppConnection);
}
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("http://jabber.org/protocol/caps");
sdm.addFeature("urn:xmpp:avatar:metadata");
sdm.addFeature("urn:xmpp:avatar:metadata+notify");
sdm.addFeature("urn:xmpp:avatar:data");
sdm.addFeature("http://jabber.org/protocol/nick");
sdm.addFeature("http://jabber.org/protocol/nick+notify");
sdm.addFeature("http://jabber.org/protocol/xhtml-im");
sdm.addFeature("http://jabber.org/protocol/muc");
sdm.addFeature("http://jabber.org/protocol/commands");
sdm.addFeature("http://jabber.org/protocol/si/profile/file-transfer");
sdm.addFeature("http://jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/bytestreams");
sdm.addFeature("http://jabber.org/protocol/ibb");
sdm.addFeature("http://jabber.org/protocol/feature-neg");
sdm.addFeature("jabber:iq:privacy");
}
public static void configure(ProviderManager pm) {
// Private Data Storage
pm.addIQProvider("query", "jabber:iq:private",
new PrivateDataManager.PrivateDataIQProvider());
// Time
try {
pm.addIQProvider("query", "jabber:iq:time",
Class.forName("org.jivesoftware.smackx.packet.Time"));
} catch (ClassNotFoundException e) {
Log.w("TesTCLient",
"Cant load class for org.jivesoftware.smackx.packet.Time");
}
// Roster Exchange
pm.addExtensionProvider("x", "jabber:x:roster",
new RosterExchangeProvider());
// Message Events
pm.addExtensionProvider("x", "jabber:x:event",
new MessageEventProvider());
// Chat State
pm.addExtensionProvider("active",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
pm.addExtensionProvider("composing",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
pm.addExtensionProvider("paused",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
pm.addExtensionProvider("inactive",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
pm.addExtensionProvider("gone",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
// XHTML
pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im",
new XHTMLExtensionProvider());
// Group Chat Invitations
pm.addExtensionProvider("x", "jabber:x:conference",
new GroupChatInvitation.Provider());
// Service Discovery # Items
pm.addIQProvider("query", "http://jabber.org/protocol/disco#items",
new DiscoverItemsProvider());
// Service Discovery # Info
pm.addIQProvider("query", "http://jabber.org/protocol/disco#info",
new DiscoverInfoProvider());
// Data Forms
pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
// MUC User
pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user",
new MUCUserProvider());
// MUC Admin
pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin",
new MUCAdminProvider());
// MUC Owner
pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner",
new MUCOwnerProvider());
// Delayed Delivery
pm.addExtensionProvider("x", "jabber:x:delay",
new DelayInformationProvider());
// Version
try {
pm.addIQProvider("query", "jabber:iq:version",
Class.forName("org.jivesoftware.smackx.packet.Version"));
} catch (ClassNotFoundException e) {
// Not sure whats happening here.
}
// VCard
pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
// Offline Message Requests
pm.addIQProvider("offline", "http://jabber.org/protocol/offline",
new OfflineMessageRequest.Provider());
// Offline Message Indicator
pm.addExtensionProvider("offline",
"http://jabber.org/protocol/offline",
new OfflineMessageInfo.Provider());
// Last Activity
pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());
// User Search
pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
// SharedGroupsInfo
pm.addIQProvider("sharedgroup",
"http://www.jivesoftware.org/protocol/sharedgroup",
new SharedGroupsInfo.Provider());
// JEP-33: Extended Stanza Addressing
pm.addExtensionProvider("addresses",
"http://jabber.org/protocol/address",
new MultipleAddressesProvider());
// FileTransfer
pm.addIQProvider("si", "http://jabber.org/protocol/si",
new StreamInitiationProvider());
pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams",
new BytestreamsProvider());
// Privacy
pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
pm.addIQProvider("command", "http://jabber.org/protocol/commands",
new AdHocCommandDataProvider());
pm.addExtensionProvider("malformed-action",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.MalformedActionError());
pm.addExtensionProvider("bad-locale",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.BadLocaleError());
pm.addExtensionProvider("bad-payload",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.BadPayloadError());
pm.addExtensionProvider("bad-sessionid",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.BadSessionIDError());
pm.addExtensionProvider("session-expired",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.SessionExpiredError());
}
} 这段代码中的initFeatures(XMPPConnection xmppConnection)和configure(ProviderManager pm)就是为了解决asmack的各种奇葩的问题,别问我为什么,我也不知道,这是百度谷歌几十页的来的结果。代码整个粘贴过去改下包名和配置,应该就可以直接使用了,当然,这里只是初始化连接,并没有真正的登陆,可以通过xmppConnection.isConnected()方法判断是不是已经初始化成功,若成功,可以继续看下一篇登陆了。