之前学习了通过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. STL 优先队列详解

    优先队列是一个保证队列里元素单调的队列,我们可以利用它来维护一个线性结构的单调性. 一般的优先队列: 当然需要加头文件 #include <queue> priority_queue &l ...

  2. poj 3041 Asteroids 最小点覆盖/最大匹配

    Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16242 Accepted: 8833 Descriptio ...

  3. JavaScript Promises

    上篇文章介绍了JavaScript异步机制,请看这里. JavaScript异步机制带来的问题 JavaScript异步机制的主要目的是处理非阻塞,在交互的过程中,会需要一些IO操作(比如Ajax请求 ...

  4. ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE

    http://www.chinaz.com/web/2012/1119/282540.shtml 编码一直是让新手头疼的问题,特别是 GBK.GB2312.UTF-8 这三个比较常见的网页编码的区别, ...

  5. PyQt5 各种菜单实现

    # -*- coding: utf-8 -*- # Created by PCITZDF on 2018/4/8 15:36. # FileName: menuandtools.py import s ...

  6. Using Windows Server 2012 Backup for Hyper-V Virtual Machines. Error 80780176 - The specified component was not reported by the VSS writer.

    https://social.technet.microsoft.com/Forums/windowsserver/en-US/1a1e0066-f421-43d6-970b-1e20e674cdf9 ...

  7. 想要快速上手 Spring Boot?看这些教程就足够了!| 码云周刊第 81 期

    原文:https://blog.gitee.com/2018/08/19/weekly-81/ 想要快速上手 Spring Boot?看这些教程就足够了!| 码云周刊第 81 期 码云周刊 | 201 ...

  8. 【C#高级编程】笔记之核心C#

    Main()方法 每一个C#可执行文件(如控制台程序.Windows程序和Windows服务)都必须有一个入口点——Main()方法(注意M大写). 这个方法必须是类或静态方法,并且返回类型必须是in ...

  9. Android实例剖析笔记(三)

    摘要:点介绍Activity的生命周期,通过一个简单的实验来摸索状态转换的机制 Activity的生命周期 Activity类中有许多onXXX形式的函数可以重载,比如onCreate,onStart ...

  10. c中的static变量

    当一个进程的全局变量被声明为static之后.它的中文名叫静态全局变量.静态全局变量和其它的全局变量的存储地点并没有差别.可是它仅仅在定义它的源文件内有效,其它源文件无法訪问它. static局部变量 ...