之前学习了通过Openfire+spark+smack的模式来完成我们的即时通讯软件,上次我们已经完成了Openfire的安装和配置,这次我们继续完成我们的客户端部分。

  1.首先我们通过百度smack来下载我们所需要的jar包,将下载好的jar包导入到我们的工程中,创建一个工具类XmppTool:

package com.xmpp.client.util;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.json.JSONArray; public class XmppTool { private static XMPPConnection con = null; private static void openConnection(String url, String pcName) {
try {
// url、端口,也可以设置连接的服务器名字,地址,端口,用户。
ConnectionConfiguration connConfig = new ConnectionConfiguration(
"192.168.2.113", 5222, "JEREHEDU"); con = new XMPPConnection(connConfig);
con.connect();
} catch (XMPPException xe) {
xe.printStackTrace();
}
} private static void openOffConnection(String url, String pcName) {
try {
ConnectionConfiguration connConfig = new ConnectionConfiguration(
url, 5222, pcName);
connConfig.setSendPresence(false);
con = new XMPPConnection(connConfig);
con.connect();
} catch (XMPPException xe) {
xe.printStackTrace();
}
} public static XMPPConnection getOffConnection(String url, String pcName) {
if (con == null) { openOffConnection(url, pcName);
}
return con;
} public static XMPPConnection getConnection(String url, String pcName) {
if (con == null) {
openConnection(url, pcName);
}
return con;
} public static void closeConnection() {
con.disconnect();
con = null;
}
}

工具类XmppTool

  主要还是通过ConnectionConfiguration来连接服务器,传入三个参数(地址,端口,用户名)

  2.登陆界面

package com.xmpp.client;

import java.util.Iterator;

import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.OfflineMessageManager; import com.xmpp.client.util.XmppTool;
import com.xmpp.client.R; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast; public class FormLogin extends Activity implements OnClickListener { private EditText useridText, pwdText, urlText, pcnameText;;
private LinearLayout layout1, layout2; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.formlogin); // 获取用户和密码
this.useridText = (EditText) findViewById(R.id.formlogin_userid);
this.pwdText = (EditText) findViewById(R.id.formlogin_pwd);
this.urlText = (EditText) findViewById(R.id.formlogin_url);
this.pcnameText = (EditText) findViewById(R.id.formlogin_pcname);
// 正在登录
this.layout1 = (LinearLayout) findViewById(R.id.formlogin_layout1);
// 登录界面
this.layout2 = (LinearLayout) findViewById(R.id.formlogin_layout2); Button btsave = (Button) findViewById(R.id.formlogin_btsubmit);
btsave.setOnClickListener(this);
Button btcancel = (Button) findViewById(R.id.formlogin_btcancel);
btcancel.setOnClickListener(this);
} @Override
public void onClick(View v) {
// 根据ID来进行提交或者取消
switch (v.getId()) {
case R.id.formlogin_btsubmit:
// 取得填入的用户和密码
// 取得填入的用户和密码
final String USERID = this.useridText.getText().toString();
final String PWD = this.pwdText.getText().toString();
final String URL = this.urlText.getText().toString();
final String PCNAME = this.pcnameText.getText().toString(); Thread t = new Thread(new Runnable() {
public void run() {
// sendEmptyMessage:发送一条消息
handler.sendEmptyMessage(1);
try {
// 连接
XmppTool.getOffConnection(URL, PCNAME).login(USERID,
PWD);
getOfflineMessage();
// 状态
Presence presence = new Presence(
Presence.Type.available);
XmppTool.getConnection(URL, PCNAME)
.sendPacket(presence); Intent intent = new Intent();
intent.setClass(FormLogin.this, FormClient.class);
intent.putExtra("USERID", USERID);
intent.putExtra("URL", URL);
intent.putExtra("PCNAME", PCNAME);
FormLogin.this.startActivity(intent);
FormLogin.this.finish();
} catch (XMPPException e) {
XmppTool.closeConnection(); handler.sendEmptyMessage(2);
}
}
});
t.start();
break;
case R.id.formlogin_btcancel:
finish();
break;
}
} /**
* 获取离线消息
*/
private void getOfflineMessage() { OfflineMessageManager offlineManager = new OfflineMessageManager(
XmppTool.getConnection(this.urlText.getText().toString(),
this.pcnameText.getText().toString()));
Iterator<org.jivesoftware.smack.packet.Message> it;
try {
it = offlineManager.getMessages();
while (it.hasNext()) {
org.jivesoftware.smack.packet.Message message = it.next();
Log.i("离线消息", "收到离线消息, Received from 【" + message.getFrom()
+ "】 message: " + message.getBody());
}
// 删除离线消息
offlineManager.deleteMessages(); } catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) { if (msg.what == 1) {
layout1.setVisibility(View.VISIBLE);
layout2.setVisibility(View.GONE);
} else if (msg.what == 2) {
layout1.setVisibility(View.GONE);
layout2.setVisibility(View.VISIBLE);
Toast.makeText(FormLogin.this, "登录失败!", Toast.LENGTH_SHORT)
.show();
}
};
};
}

登陆界面

  3.聊天客户端

package com.xmpp.client;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List; import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smackx.filetransfer.FileTransfer;
import org.jivesoftware.smackx.filetransfer.FileTransfer.Status;
import org.jivesoftware.smackx.filetransfer.FileTransferListener;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.FileTransferRequest;
import org.jivesoftware.smackx.filetransfer.IncomingFileTransfer;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.packet.DelayInformation; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast; import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest.HttpMethod; import com.xmpp.client.util.ScreenShot;
import com.xmpp.client.util.TimeRender;
import com.xmpp.client.util.XmppTool; public class FormClient extends Activity { private MyAdapter adapter;
private List<Msg> listMsg = new ArrayList<Msg>();
private String pUSERID;
private EditText msgText, toText;
private ProgressBar pb; private Button btsend; private TextView waitpb; private String URL;
private String PCNAME;
private String PERSON; private Chat mychat;
private ChatManager cm; public class Msg {
String userid;
String msg;
String date;
String from; public Msg(String userid, String msg, String date, String from) {
this.userid = userid;
this.msg = msg;
this.date = date;
this.from = from;
}
} @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.formclient); // 获取Intent传过来的用户名,url,pcname
this.pUSERID = getIntent().getStringExtra("USERID");
this.URL = getIntent().getStringExtra("URL");
this.PCNAME = getIntent().getStringExtra("PCNAME"); ListView listview = (ListView) findViewById(R.id.formclient_listview);
listview.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); this.adapter = new MyAdapter(this);
listview.setAdapter(adapter); // 获取文本信息
this.msgText = (EditText) findViewById(R.id.formclient_text);
// 获取聊天对象
this.toText = (EditText) findViewById(R.id.formclient_to); // 发送消息给water-pc服务器water(获取自己的服务器,和好友)
// 消息监听
cm = XmppTool.getConnection(URL, PCNAME).getChatManager();
chatListener(); // 发送消息
btsend = (Button) findViewById(R.id.formclient_btsend);
sendChatMessage(); } /**
* send chat message
*
*/
private void sendChatMessage() {
btsend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 获取text文本
String msg = msgText.getText().toString();
PERSON = toText.getText().toString();
mychat = cm.createChat(PERSON + "@" + PCNAME, null);
if (msg.length() > 0) {
// 发送消息
listMsg.add(new Msg(pUSERID, msg, TimeRender.getDate(),
"OUT"));
// 刷新适配器
adapter.notifyDataSetChanged();
try {
// 发送消息给指定人
mychat.sendMessage(msg); } catch (XMPPException e) {
e.printStackTrace();
}
} else {
Toast.makeText(FormClient.this, "请输入信息", Toast.LENGTH_SHORT)
.show();
}
// 清空text
msgText.setText("");
}
});
} /**
* 监听单人消息
*/
private void chatListener() {
cm.addChatListener(new ChatManagerListener() {
@Override
public void chatCreated(Chat chat, boolean able) {
chat.addMessageListener(new MessageListener() {
@Override
public void processMessage(Chat chat2, Message message) {
Log.v("--tags--", "--tags-form--" + message.getFrom());
Log.v("--tags--",
"--tags-message--" + message.getBody()); // 收到来自water-pc服务器water的消息(获取自己的服务器,和好友)
if (message.getFrom().contains(pUSERID + "@keyi-pc")) {
// 获取用户、消息、时间、IN
String[] args = new String[] { pUSERID,
message.getBody(), TimeRender.getDate(),
"IN" };
android.os.Message msg = handler.obtainMessage();
msg.what = 1;
msg.obj = args;
msg.sendToTarget();
} else { } Log.i("json", "b " + message.getBody());
String amsg = message.getBody();
String[] args = null; args = new String[] { message.getFrom(), amsg,
TimeRender.getDate(), "IN" };
android.os.Message msg = handler
.obtainMessage();
msg.what = 1;
msg.obj = args;
msg.sendToTarget(); } });
}
});
} private OutgoingFileTransfer fileTransfer; Handler outHandler = new Handler();
Runnable outrunnable = new Runnable() {
@Override
public void run() {
if (fileTransfer.getProgress() == 1) {
pb.setVisibility(View.GONE);
outHandler.removeCallbacks(outrunnable);
}
outHandler.postDelayed(outrunnable, 100); }
}; private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) { switch (msg.what) {
case 1:
// 获取消息并显示
String[] args = (String[]) msg.obj;
listMsg.add(new Msg(args[0], args[1], args[2], args[3]));
// 刷新适配器
adapter.notifyDataSetChanged();
break;
case 2:
// 附件进度条
if (pb.getVisibility() == View.GONE) { pb.setVisibility(View.VISIBLE);
waitpb.setVisibility(View.VISIBLE);
}
break;
case 3:
pb.setProgress(msg.arg1);
break;
case 4:
pb.setVisibility(View.GONE);
waitpb.setVisibility(View.GONE);
break; default:
break;
}
};
}; // 退出
@Override
public void onBackPressed() {
super.onBackPressed();
XmppTool.closeConnection();
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
} class MyAdapter extends BaseAdapter { private Context cxt;
private LayoutInflater inflater; public MyAdapter(FormClient formClient) {
this.cxt = formClient;
} @Override
public int getCount() {
return listMsg.size();
} @Override
public Object getItem(int position) {
return listMsg.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
// 显示消息的布局:内容、背景、用户、时间
this.inflater = (LayoutInflater) this.cxt
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // IN,OUT的图片
if (listMsg.get(position).from.equals("IN")) {
convertView = this.inflater.inflate(
R.layout.formclient_chat_in, null);
} else {
convertView = this.inflater.inflate(
R.layout.formclient_chat_out, null);
} TextView useridView = (TextView) convertView
.findViewById(R.id.formclient_row_userid);
TextView dateView = (TextView) convertView
.findViewById(R.id.formclient_row_date);
TextView msgView = (TextView) convertView
.findViewById(R.id.formclient_row_msg); useridView.setText(listMsg.get(position).userid);
dateView.setText(listMsg.get(position).date);
msgView.setText(listMsg.get(position).msg); return convertView;
}
} }

聊天客户端

  其中有好多类都是自带的我们只需要实现它就可以了。

作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

即时通讯之smack客户端配置的更多相关文章

  1. nodejs+expressjs+ws实现了websocket即时通讯,服务器和客户端互相通信

    nodejs代码 // 导入WebSocket模块: const WebSocket = require('ws'); // 引用Server类: const WebSocketServer = We ...

  2. layim即时通讯实例各功能整合

    一.系统演示1.1 聊天窗体主界面演示 1.2 模拟两人在线聊天(点击图片查看演示视频) 1.3 在线演示> 在线演示,点击进入系统到这里,若是您想要的,接下来听我娓娓道来二.开发工具开发软件: ...

  3. XMPP之ios即时通讯客户端开发-配置XMPP基本信息之工程代码(五)

    登录功能完成以后包含以下代码文件: AppDelegate.h AppDelegate.m LoginViewController.h LoginViewController.m LoginUser. ...

  4. 用smack+openfire做即时通讯

    首发:个人博客 必须说明:smack最新的4.1.1,相对之前版本变化很大,而且资料缺乏,官方文档也不好,所以还是用老版本3.2.2吧.这篇博文中的代码是4.1.1版的,但不推荐用它.用openfir ...

  5. openfire+spark+smack实现即时通讯

    近公司项目需要用到即时通讯功能,经过调研发现openfire+spark+smack可以实现.在网上找了很久,资料都十分有限,即使有些朋友实现了也说的不清不楚.于是决定自己研究,耗时一周的时间实现了文 ...

  6. openfire+smack 实现即时通讯基本框架

    smack jar下载地址 http://www.igniterealtime.org/downloads/download-landing.jsp?file=smack/smack_3_2_2.zi ...

  7. XMPP openfire Smack 即时通讯

    重新整理下这篇文章. 这篇文章的主要任务是使用AndroidStudio,通过Openfire,利用XMPP协议完成一个可以即时通讯.拥有好友系统的聊天软件. 一.服务器配置与相关库 理论不多说,只谈 ...

  8. Openfire XMPP Smack RTC IM 即时通讯 聊天 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. 基于openfire+smack即时通讯instant message开发

    前言 Java领域的即时通信的解决方案可以考虑openfire+spark+smack.当然也有其他的选择. Openfire 是基于Jabber协议(XMPP)实现的即时通信服务器端版本,目前建议使 ...

随机推荐

  1. Linux-数据库4

    存储引擎 什么是存储引擎? mysql中建的库是文件夹,建的表是文件.文件有不同的类型,数据库中的表也有不同的类型,表的类型不同,会对应mysql不同的存取机制,表类型又称为存储引擎. 存储引擎说白了 ...

  2. [BZOJ4487][JSOI2015]染色问题(容斥)

    一开始写了7个DP方程,然后意识到这种DP应该都会有一个通式. 三个条件:有色行数为n,有色列数为m,颜色数p,三维容斥原理仍然成立. 于是就是求:$\sum_{i=0}^{n}\sum_{j=0}^ ...

  3. 洛谷.4252.[NOI2006]聪明的导游(提答 直径 随机化)

    题目链接 随机化 暴力: 随便从一个点开始DFS,每次从之前得到的f[i]最大的子节点开始DFS.f[i]为从i开始(之前)能得到的最大答案. 要注意的是f[i]应当有机会从更小的答案更新, 9.10 ...

  4. 和程序有关的一个游戏<<mu complex>> 攻略

    最速打法: 1 - login, brucedayton 2 - login, allomoto 3 - login, m3g4pa55word 4 - unlock, 03/18/34 5 - ss ...

  5. NOIP 2008 传纸条 NOIP 2000 方块取数 多线程DP

    思路都是一样,建立一个四维dp然后跑一发就完了 当然,也可以像我这么帅的人,降成三维再傻傻的跑一发啦啦啦~ #include<iostream> #include<stdio.h&g ...

  6. Xcode 中的IOS工程模板

    1.IOS模板主要分为: Application .Framework.Other application 分为:Master-Detail Application 可以构建树形导航模式引用,生成的代 ...

  7. offsetLeft && left

    /* function getCss(obj,attr){ return window.getComputedStyle ? window.getComputedStyle(obj,null)[att ...

  8. 重温PHP之快速排序

    基本原理:选出当前数组中任一元素(通常为第一个)作为标准,新建两个空数组分别置于当前数组前后,然后遍历当前数组,如果数组中元素值小于等于第一个元素值就放到前边空数组,否则放到后边空数组. //快速排序 ...

  9. cocos2d-x3.0 Slider

    .h #include "cocos2d.h" #include "cocos-ext.h" #include "ui/CocosGUI.h" ...

  10. 解决Oracle11g空表无法导出的问题

    Oracle11g 新增參数deferred_segment_creation  ,建库的时候默认值为true,意思是延时载入,当表中不存在数据的时候,不为这个表创建空间,当你导出的时候会发现非常多表 ...