Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
http://blog.csdn.net/h7870181/article/details/8653865
以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后台服务器代码就比较复杂,对于我这新手来讲就比较难了。后来在网上看到用openfire做服务器,利用强大的Smack API库来实现IM聊天就简单多了。
网上也有很多关于这方面的资料,我就在这里把网上的资料和自己的理解总结一下和大家一起交流学习。
需要用到以下几个工具:
Openfire 最新版本(openfire 3.8.1)
下载地址:http://www.igniterealtime.org/downloads/index.jsp
安装配置可参考:http://www.cnblogs.com/hoojo/archive/2012/05/17/2506769.html
Spark 最新版本(Spark 2.6.3)
下载地址:http://www.igniterealtime.org/downloads/index.jsp
ASmack 最新版本 (asmack-jse-buddycloud-2010.12.11.jar)
由于在Android平台下开发 所以我们用到的是 aSmack,与Smack没有很大的区别
下载地址1:http://download.csdn.net/detail/h7870181/6372585 (现在用的就是这个,修改了一些BUG)
下载地址2:http://code.google.com/p/asmack/downloads/list
需要安装的安装好,需要下载的下载好(这里就不多作介绍)。创建项目工程,导入ASmack jar包,OK,下面就一起去学习怎么实现 用户注册、登录、修改密码和注销等一些功能!
首先第一、与服务器建立好连接
关键代码:127.0.0.1为服务器IP,5222为服务器端口号
- /**
- * 连接服务器
- *
- * @return
- */
- public boolean conServer() {
- ConnectionConfiguration config = new ConnectionConfiguration(
- 127.0.0.1, 5222);
- /** 是否启用安全验证 */
- config.setSASLAuthenticationEnabled(false);
- /** 是否启用调试 */
- // config.setDebuggerEnabled(true);
- /** 创建connection链接 */
- try {
- connection = new XMPPConnection(config);
- /** 建立连接 */
- connection.connect();
- return true;
- } catch (XMPPException e) {
- e.printStackTrace();
- }
- return false;
- }
/**
* 连接服务器
*
* @return
*/
public boolean conServer() {
ConnectionConfiguration config = new ConnectionConfiguration(
127.0.0.1, 5222);
/** 是否启用安全验证 */
config.setSASLAuthenticationEnabled(false);
/** 是否启用调试 */
// config.setDebuggerEnabled(true);
/** 创建connection链接 */
try {
connection = new XMPPConnection(config);
/** 建立连接 */
connection.connect();
return true;
} catch (XMPPException e) {
e.printStackTrace();
}
return false;
}
第二、实现注册
关键代码:
以下代码注释都很清楚了,如有不懂的地方可以留言,这里就不多做解释了。
- /**
- * 注册
- *
- * @param account 注册帐号
- * @param password 注册密码
- * @return 1、注册成功 0、服务器没有返回结果2、这个账号已经存在3、注册失败
- */
- public String regist(String account, String password) {
- if (connection == null)
- return "0";
- Registration reg = new Registration();
- reg.setType(IQ.Type.SET);
- reg.setTo(ClientConServer.connection.getServiceName());
- reg.setUsername(account);// 注意这里createAccount注册时,参数是username,不是jid,是“@”前面的部分。
- reg.setPassword(password);
- reg.addAttribute("android", "geolo_createUser_android");// 这边addAttribute不能为空,否则出错。所以做个标志是android手机创建的吧!!!!!
- PacketFilter filter = new AndFilter(new PacketIDFilter(
- reg.getPacketID()), new PacketTypeFilter(IQ.class));
- PacketCollector collector = ClientConServer.connection
- .createPacketCollector(filter);
- ClientConServer.connection.sendPacket(reg);
- IQ result = (IQ) collector.nextResult(SmackConfiguration
- .getPacketReplyTimeout());
- // Stop queuing results
- collector.cancel();// 停止请求results(是否成功的结果)
- if (result == null) {
- Log.e("RegistActivity", "No response from server.");
- return "0";
- } else if (result.getType() == IQ.Type.RESULT) {
- return "1";
- } else { // if (result.getType() == IQ.Type.ERROR)
- if (result.getError().toString().equalsIgnoreCase("conflict(409)")) {
- Log.e("RegistActivity", "IQ.Type.ERROR: "
- + result.getError().toString());
- return "2";
- } else {
- Log.e("RegistActivity", "IQ.Type.ERROR: "
- + result.getError().toString());
- return "3";
- }
- }
- }
/**
* 注册
*
* @param account 注册帐号
* @param password 注册密码
* @return 1、注册成功 0、服务器没有返回结果2、这个账号已经存在3、注册失败
*/
public String regist(String account, String password) {
if (connection == null)
return "0";
Registration reg = new Registration();
reg.setType(IQ.Type.SET);
reg.setTo(ClientConServer.connection.getServiceName());
reg.setUsername(account);// 注意这里createAccount注册时,参数是username,不是jid,是“@”前面的部分。
reg.setPassword(password);
reg.addAttribute("android", "geolo_createUser_android");// 这边addAttribute不能为空,否则出错。所以做个标志是android手机创建的吧!!!!!
PacketFilter filter = new AndFilter(new PacketIDFilter(
reg.getPacketID()), new PacketTypeFilter(IQ.class));
PacketCollector collector = ClientConServer.connection
.createPacketCollector(filter);
ClientConServer.connection.sendPacket(reg);
IQ result = (IQ) collector.nextResult(SmackConfiguration
.getPacketReplyTimeout());
// Stop queuing results
collector.cancel();// 停止请求results(是否成功的结果)
if (result == null) {
Log.e("RegistActivity", "No response from server.");
return "0";
} else if (result.getType() == IQ.Type.RESULT) {
return "1";
} else { // if (result.getType() == IQ.Type.ERROR)
if (result.getError().toString().equalsIgnoreCase("conflict(409)")) {
Log.e("RegistActivity", "IQ.Type.ERROR: "
+ result.getError().toString());
return "2";
} else {
Log.e("RegistActivity", "IQ.Type.ERROR: "
+ result.getError().toString());
return "3";
}
}
}
第三、实现登录
关键代码: 代码很简单不做太多解释
- /**
- * 登录
- *
- * @param a 登录帐号
- * @param p 登录密码
- * @return
- */
- public boolean login(String a, String p) {
- try {
- if (connection == null)
- return false;
- /** 登录 */
- connection.login(a, p);
- return true;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return false;
- }
/**
* 登录
*
* @param a 登录帐号
* @param p 登录密码
* @return
*/
public boolean login(String a, String p) {
try {
if (connection == null)
return false;
/** 登录 */
connection.login(a, p);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
第四、修改密码
关键代码:同样很简单
- /**
- * 修改密码
- * @param connection
- * @return
- */
- public static boolean changePassword(XMPPConnection connection,String pwd)
- {
- try {
- connection.getAccountManager().changePassword(pwd);
- return true;
- } catch (Exception e) {
- return false;
- }
- }
/**
* 修改密码
* @param connection
* @return
*/
public static boolean changePassword(XMPPConnection connection,String pwd)
{
try {
connection.getAccountManager().changePassword(pwd);
return true;
} catch (Exception e) {
return false;
}
}
第五、更改用户状态
关键代码:好吧,代码有点多,不过很清晰
- /**
- * 更改用户状态
- */
- public void setPresence(int code) {
- if (connection == null)
- return;
- Presence presence;
- switch (code) {
- case 0:
- presence = new Presence(Presence.Type.available);
- connection.sendPacket(presence);
- Log.v("state", "设置在线");
- break;
- case 1:
- presence = new Presence(Presence.Type.available);
- presence.setMode(Presence.Mode.chat);
- connection.sendPacket(presence);
- Log.v("state", "设置Q我吧");
- System.out.println(presence.toXML());
- break;
- case 2:
- presence = new Presence(Presence.Type.available);
- presence.setMode(Presence.Mode.dnd);
- connection.sendPacket(presence);
- Log.v("state", "设置忙碌");
- System.out.println(presence.toXML());
- break;
- case 3:
- presence = new Presence(Presence.Type.available);
- presence.setMode(Presence.Mode.away);
- connection.sendPacket(presence);
- Log.v("state", "设置离开");
- System.out.println(presence.toXML());
- break;
- case 4:
- Roster roster = connection.getRoster();
- Collection<RosterEntry> entries = roster.getEntries();
- for (RosterEntry entry : entries) {
- presence = new Presence(Presence.Type.unavailable);
- presence.setPacketID(Packet.ID_NOT_AVAILABLE);
- presence.setFrom(connection.getUser());
- presence.setTo(entry.getUser());
- connection.sendPacket(presence);
- System.out.println(presence.toXML());
- }
- // 向同一用户的其他客户端发送隐身状态
- presence = new Presence(Presence.Type.unavailable);
- presence.setPacketID(Packet.ID_NOT_AVAILABLE);
- presence.setFrom(connection.getUser());
- presence.setTo(StringUtils.parseBareAddress(connection.getUser()));
- connection.sendPacket(presence);
- Log.v("state", "设置隐身");
- break;
- case 5:
- presence = new Presence(Presence.Type.unavailable);
- connection.sendPacket(presence);
- Log.v("state", "设置离线");
- break;
- default:
- break;
- }
- }
/**
* 更改用户状态
*/
public void setPresence(int code) {
if (connection == null)
return;
Presence presence;
switch (code) {
case 0:
presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
Log.v("state", "设置在线");
break;
case 1:
presence = new Presence(Presence.Type.available);
presence.setMode(Presence.Mode.chat);
connection.sendPacket(presence);
Log.v("state", "设置Q我吧");
System.out.println(presence.toXML());
break;
case 2:
presence = new Presence(Presence.Type.available);
presence.setMode(Presence.Mode.dnd);
connection.sendPacket(presence);
Log.v("state", "设置忙碌");
System.out.println(presence.toXML());
break;
case 3:
presence = new Presence(Presence.Type.available);
presence.setMode(Presence.Mode.away);
connection.sendPacket(presence);
Log.v("state", "设置离开");
System.out.println(presence.toXML());
break;
case 4:
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
for (RosterEntry entry : entries) {
presence = new Presence(Presence.Type.unavailable);
presence.setPacketID(Packet.ID_NOT_AVAILABLE);
presence.setFrom(connection.getUser());
presence.setTo(entry.getUser());
connection.sendPacket(presence);
System.out.println(presence.toXML());
}
// 向同一用户的其他客户端发送隐身状态
presence = new Presence(Presence.Type.unavailable);
presence.setPacketID(Packet.ID_NOT_AVAILABLE);
presence.setFrom(connection.getUser());
presence.setTo(StringUtils.parseBareAddress(connection.getUser()));
connection.sendPacket(presence);
Log.v("state", "设置隐身");
break;
case 5:
presence = new Presence(Presence.Type.unavailable);
connection.sendPacket(presence);
Log.v("state", "设置离线");
break;
default:
break;
}
}
第六:注销
关键代码:很简单吧!
- /**
- * 删除当前用户
- * @param connection
- * @return
- */
- public static boolean deleteAccount(XMPPConnection connection)
- {
- try {
- connection.getAccountManager().deleteAccount();
- return true;
- } catch (Exception e) {
- return false;
- }
- }
/**
* 删除当前用户
* @param connection
* @return
*/
public static boolean deleteAccount(XMPPConnection connection)
{
try {
connection.getAccountManager().deleteAccount();
return true;
} catch (Exception e) {
return false;
}
}
好吧,这篇就先介绍到这!
Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等的更多相关文章
- Android基于XMPP Smack Openfire下学习开发IM(六)总结
不管学习什么都应该总结 这里我把关于Xmpp的一些方法整理到一个工具类中了 我就分享给大家 XmppConnection.java package com.techrare.utils; import ...
- Android基于XMPP Smack Openfire下学习开发IM(五)连接断开重连
学习过程中大家都碰到过连接被断开的问题给困扰吧,下面教大家如何做到连接断开后,重新连接 首先要创建连接监听器,用来监听连接状态,这里我写了一个类 继承了ConnectionListener,重写了里面 ...
- Android基于XMPP Smack openfire 开发的聊天室
Android基于XMPP Smack openfire 开发的聊天室(一)[会议服务.聊天室列表.加入] http://blog.csdn.net/lnb333666/article/details ...
- Android基于XMPP Smack及Openfire学习笔记(1)
之前开发的项目中实用到IM聊天功能.可是这块功能公司有专门的IM团队来开发,由他们开发好后.直接接入到我们APP中.我參与写IM相关功能非常地少,所以也一直想学习相关知识 . 眼下Android主要用 ...
- openfire Android学习(一)----实现用户注册、登录、修改密码和注销等
以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后台服务器代码就比较复杂,对于我这新手来讲就比较难了.后来在网上看到用openfire做服务器,利用强大的Sm ...
- Android基于XMPP的即时通讯2-文件传输
本文是在上一篇博文Android基于XMPP的即时通讯1-基本对话的基础上,添加新的功能,文件传输 1.初始化文件传输管理类 public static FileTransferManager get ...
- Android基于XMPP的即时通讯3-表情发送
这篇博文主要讲表情发送的一些东西. 参考:Android基于XMPP的即时通讯1-基本对话 1.准备好资源文件 采用的是emoji的表情,我打包好了,下载地址:http://files.cnblogs ...
- MVC5 网站开发之六 管理员 1、登录、验证和注销
上次业务逻辑和展示层的架构都写了,可以开始进行具体功能的实现,这次先实现管理员的登录.验证和注销功能. 目录 奔跑吧,代码小哥! MVC5网站开发之一 总体概述 MVC5 网站开发之二 创建项目 MV ...
- mysql5.7 mysql库下面的user表没有password字段无法修改密码
如题所述,mysql5.7 mysql库下面的user表没有password字段无法修改密码, 5.7版本已经不再使用password来作为密码的字段了 而改成了authentication_st ...
随机推荐
- 51nod 1376 最长上升子序列的数量 | DP | vector怒刷存在感!
51nod 1376 最长上升子序列的数量 题解 我们设lis[i]为以位置i结尾的最长上升子序列长度,dp[i]为以位置i结尾的最长上升子序列数量. 显然,dp[i]要从前面的一些位置(设为位置j) ...
- uoj35 后缀排序
题目链接:http://uoj.ac/problem/35 这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第 ...
- linux内核分析 第五周 扒开系统调用的三层皮(下)
rm menu -rf 强制删除原menu文件 git clone http://github.com/mengning/menu.git 从github中克隆 cd menu 在test.c中增加上 ...
- Java类编译、加载、和执行机制
Java类编译.加载.和执行机制 标签: java 类加载 类编译 类执行 机制 0.前言 个人认为,对于JVM的理解,主要是两大方面内容: Java类的编译.加载和执行. JVM的内存管理和垃圾回收 ...
- 解题:POI 2010 Beads
题面 正反各做一遍哈希来判断,然后在两个哈希值里取一个$max/min$做哈希值,然后每次把子串们的哈希插进$set$里,最后统计集合大小,就可以优秀地在$O(nlog^2$ $n)$中出解了 然后我 ...
- bzoj2758【scoi2012】Blinker的的噩梦
题目描述 一天Blinker醒来,发现自己成为了一个二维世界的点,而且被标记上了一个奇怪的值. 这个世界是由N个边界互不相交(且不相切)的图形组成,这里图形仅包括圆和凸多边形.每个图形还有一个权值.每 ...
- 使用kafka消息队列解决分布式事务(可靠消息最终一致性方案-本地消息服务)
微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务 本文转自:http://skaka.me/blog/2016/04/21/springcloud1/ 不同于单一 ...
- pandas读csv、数据处理
.caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...
- linux命令总结之traceroute命令
通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一 ...
- css overflow用法
1. overflow-y: auto 侧边栏滚动效果:overflow-y:auto 2. overflow-y: scroll 如果使用overflow:scroll的话,滚动条就一直都在,页面不 ...