一些看smack时的笔记东西,和实现基本功能的源码,包括添加好友,创建群,接受邀请,聊天等,业务逻辑和UI分离
一、注册
Registration reg = new Registration();
reg.setType(IQ.Type.SET);
reg.setTo(ConnectionUtils.getConnection()
.getServiceName());
reg.setUsername(phoneCode.getText().toString());
reg.setPassword(passwd);
reg.addAttribute("android", "geolo_createUser_android");
PacketFilter filter = new AndFilter(new PacketIDFilter(
reg.getPacketID()), new PacketTypeFilter(
IQ.class));
PacketCollector collector = ConnectionUtils.getConnection().
createPacketCollector(filter);
ConnectionUtils.getConnection().sendPacket(reg);
result = (IQ) collector.nextResult(SmackConfiguration
.getPacketReplyTimeout());
// Stop queuing results
collector.cancel();// 停止请求results(是否成功的结果)
if (result == null) {
Toast.makeText(getApplicationContext(), "服务器没有返回结果", Toast.LENGTH_SHORT).show();
} else if (result.getType() == IQ.Type.ERROR) {
if (result.getError().toString()
.equalsIgnoreCase("conflict(409)")) {
Toast.makeText(getApplicationContext(), "这个账号已经存在", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "注册失败",
Toast.LENGTH_SHORT).show();
}
} else if (result.getType() == IQ.Type.RESULT) {
Toast.makeText(getApplicationContext(), "恭喜你注册成功", Toast.LENGTH_SHORT).show();
}
二、登陆
// 无连接
if (!ConnectionUtils.getConnection().isConnected())
return false;
if (ConnectionUtils.getConnection().isAuthenticated()) {
return true;
} else {
// 用户登录
ConnectionUtils.getConnection().login(
util.getString("userCode", ""),util.getString("passwd", ""));
return ConnectionUtils.getConnection().isAuthenticated();
}
三、发送用户状态
Presence presence = new Presence(Presence.Type.available);
presence.setStatus("Gone fishing");
ConnectionUtils.getConnection().sendPacket(presence);
四、检索信息
Smack提供以下两种方法阅读收到的信息包:PacketListener和PacketCollector。它们都使用PacketFilter的实例来决定应该处理哪个信息包。信息包*********(packet listener)用于事件类型的设计,而信息包收集器(packet collector)有一个信息包的结果队列,你可以对其实施polling和blocking操作。所以,信息包*********在你收到任何一个信息包,且你想对其进行操作时是有用的,而信息包收集器在你想等待某个特殊的信息包时是有用的。信息包收集器和*********可以通过XMPPConnection的实例来创建。
、PacketListener
PacketFilter packetFilter = new AndFilter(new PacketIDFilter(
jp.getPacketID()), new PacketTypeFilter(IQ.class));
// 监听所有的包
con.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
if (packet instanceof MyIQ) {
MyIQ iq = (MyIQ) packet;
if (iq.getType() == IQ.Type.RESULT) {
System.out.println("返回内容: "
+ iq.toXML());
}
} else {
System.out.println("其他消息:"+packet.toXML());
}
}
}, packetFilter);
、PacketCollector
PacketFilter filter = new AndFilter(new PacketIDFilter(
reg.getPacketID()), new PacketTypeFilter(
IQ.class));
PacketCollector collector = ConnectionUtils
.getConnection().createPacketCollector(filter);
ConnectionUtils.getConnection().sendPacket(reg);
result = (IQ) collector.nextResult(SmackConfiguration
.getPacketReplyTimeout());
五、添加一个好友
/**
* The user and subscriber have no interest in each other's presence.
*/
none,
none:是用户和自己roster中的好友彼此不关心,既不想把自己的presence状态告诉对方,也不愿意收到对方presence更新消息
/**
* The user is interested in receiving presence updates from the subscriber.
*/
to,
to:是关心roster中好友的presence状态消息,而不将自己的消息告诉对方
/**
* The subscriber is interested in receiving presence updates from the user.
*/
from,
from:是只关心,接受对方的状态消息,而不将自己的消息告诉对方
/**
* The user and subscriber have a mutual interest in each other's presence.
*/
both,
both:即收取对方状态更新,又将自己的更新告知对方
/**
* The user wishes to stop receiving presence updates from the subscriber.
*/
remove
Remove :将对方干掉,不再关心他的任何信息。
在申请添加一个好友,当对方Roster.setDefaultSubscriptionMode(SubscriptionMode.manual)时,此时添加的好友为“挂起”状态。对方设置监听PacketFilter filter = new PacketFilter() {
@Override
public boolean accept(Packet packet) {
if (packet instanceof Presence) {
Presence presence = (Presence) packet;
if (presence.getType().equals(Presence.Type.subscribe)) {
return true;
}
}
return false;
}
};
允许添加好友则回复消息Presence presence = new Presence(Presence.Type.subscribed);
presence.setTo(packet.getFrom());
ConnectionUtils.getConnection().sendPacket(presence);
此时邀请人的好友状态为to。而被添加的user的subscription状态为from。如果要改为both。Both users need to subscribe to each other and accept the subscription request they received.
被邀请人应当也发送一个邀请请求。
Presence subscription = new Presence(Presence.Type.subscribe);
subscription.setTo(packet.getFrom());
ConnectionUtils.getConnection().sendPacket(subscription);
六、设置昵称nickname
RosterEntry entry = connection.getRoster().getEntry(user.getJID());
entry.setName(nickname);这个方法会设置昵称自动发送给服务器,服务器修改后会发布一个update操作。
七、组添加或删除成员
添加一个好友到组,当组存在时,添加到当前存在组,不存在时则先创建一个组,再将好友添加进去,如果从组中删除一个好友,如果当前好友是组成员最后一个,则同时删除组。
/**
* 把一个好友添加到一个组中
*
* @param user
* @param groupName
*/
public static void addUserToGroup(final User user, final String groupName,
final XMPPConnection connection) {
if (groupName == null || user == null)
return;
// 将一个rosterEntry添加到group中是PacketCollector,会阻塞线程
new Thread() {
public void run() {
RosterGroup group = connection.getRoster().getGroup(groupName);
// 这个组已经存在就添加到这个组,不存在创建一个组
RosterEntry entry = connection.getRoster().getEntry(
user.getJID());
try {
if (group != null) {
if (entry != null)
group.addEntry(entry);
} else {
RosterGroup newGroup = connection.getRoster()
.createGroup(groupName);
if (entry != null)
newGroup.addEntry(entry);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 把一个好友从组中删除
*
* @param user
* @param groupName
*/
public static void removeUserFromGroup(final User user,
final String groupName, final XMPPConnection connection) {
if (groupName == null || user == null)
return;
new Thread() {
public void run() {
RosterGroup group = connection.getRoster().getGroup(groupName);
if (group != null) {
try {
RosterEntry entry = connection.getRoster().getEntry(
user.getJID());
if (entry != null)
group.removeEntry(entry);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
}.start();
}
八、申请创建联系人
public void createEntry(String user, String name, String[] groups)
发送一个Presence.Type.subscribe邀请请求。
九、删除联系人
public void removeEntry(RosterEntry entry)
十、创建chat
每个chat对应一个线程,所有的线程都保存在ChatManager.threadChats中。Chat在ChatManager.jidChats中以jid为key保存,在ChatManager.baseJidChats中以Jid的@前半部分保存。
获得chat的方法:
public Chat getThreadChat(String thread)
packetfilter 是个interface ,主要的实现类有AndFilter, FromContainsFilter, FromMatchesFilter, IQTypeFilter, MessageTypeFilter, NotFilter, OrFilter, PacketExtensionFilter, PacketIDFilter, PacketTypeFilter, ThreadFilter, ToContainsFilter