关闭

Android即时聊天系统-随聊App之接口实现

标签: openfirexmppandroid即时聊天
918人阅读 评论(0) 收藏 举报
分类:

接口定义请参考上篇,实现接口采用的是成熟的第三方asmack包,asmack是smack的android版,而smack是一个已经相对成熟的封装xmpp协议的第三方jar包。服务器端安装openfire服务器,通过调用asmack的相关接口可以进行用户间通信。

在写代码之前先简单介绍几个常用类

1:ConnectionConfiguration  这是一个xmpp连接的配置类 可以通过 ConnectionConfiguration  imConfig = new ConnectionConfiguration(IMConfig.IMSERVER, IMConfig.IMPORT); 配置服务器的ip和接口。

2:  XMPPConnection xmpp连接管理类,通过ConnectionConfiguration 配置好相关设置后,通过imConnection = new XMPPConnection(imConfig);创建一个新的连接。

3: Roster roster相当于联系人列表,里面存储了联系人相关信息。

4:Preference  状态:分为:在线,离线,等。(4种状态)。


具体接口实现代码如下:

public class IMChat implements IMChatImpl {

	protected static final String TAG = "IMChat";
	private Context iContext;
	private static IMChat chatInstance = null;
	private ConnectionConfiguration imConfig;
	private XMPPConnection imConnection;
	private Roster roster;
	private FileTransferManager fileTransferManager;
	private ArrayList<FriendRoster> friendList;

	private RecentDao recentDao;
	private MessageDao messageDao;

	/**
	 * 保持自动重连
	 */
	static {
		try {
			Class.forName("org.jivesoftware.smack.ReconnectionManager");
		} catch (ClassNotFoundException ex) {
			// problem loading reconnection manager
		}
	}

	private IMChat(Context context) {
		iContext = context.getApplicationContext();
		initIMConnection();
	}

	private void initIMConnection() {
		recentDao = new RecentDao(iContext);
		messageDao = new MessageDao(iContext);
		imConfig = new ConnectionConfiguration(IMConfig.IMSERVER,
				IMConfig.IMPORT);
		imConfig.setCompressionEnabled(false);
		imConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
		imConfig.setReconnectionAllowed(true);
		imConfig.setSendPresence(true);
		imConfig.setDebuggerEnabled(false);
		chatConfig();
		imConnection = new XMPPConnection(imConfig);
	}

	private void chatConfig() {
		ProviderManager pm = ProviderManager.getInstance();
		// 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());
		// 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());
		pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
		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());
	}

	public static IMChat getInstace(Context context) {
		if (chatInstance == null)
			chatInstance = new IMChat(context);
		return chatInstance;
	}

	/**
	 * 通过Roster获取联系人列表
	 * 
	 * @return 联系人的ArrayList
	 */
	public ArrayList<FriendRoster> getFriends() {
		friendList = new ArrayList<FriendRoster>();
		FriendRoster friendRoster;
		Collection<RosterEntry> rosterEntries = roster.getEntries();
		for (RosterEntry friendEntry : rosterEntries) {
			String friendJid = friendEntry.getUser();
			String friendAlias = friendEntry.getName();
			friendRoster = new FriendRoster(friendJid, friendAlias);
			friendList.add(friendRoster);
		}
		return friendList;
	}

	@Override
	public boolean login(String account, String password) {
		if (imConnection.isConnected())
			imConnection.disconnect();
		try {
			imConnection.connect();
			imConnection.login(account, password);
		} catch (XMPPException e) {
			e.printStackTrace();
			return false;
		}
		if (imConnection.isAuthenticated()) {
			roster = imConnection.getRoster();
			roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);
			initMessageListener();
			initFileListener();
			return true;
		}
		return false;
	}

	/**
	 * 注册消息的监听器
	 */
	private void initMessageListener() {
		imConnection.getChatManager().addChatListener(
				new ChatManagerListener() {
					@Override
					public void chatCreated(Chat chat, boolean createdLocally) {
						chat.addMessageListener(messageListener);
					}
				});
	}

	/**
	 * 创建文本消息的监听器(new)
	 */
	private MessageListener messageListener = new MessageListener() {
		@Override
		public void processMessage(Chat chat, Message message) {
			if (message.getType() == Message.Type.chat) {
				String fromId = message.getFrom();
				System.out.println(fromId);
				fromId = fromId.split("@")[0];
				String friendAlias = getFriendName(fromId);
				String msgContent = message.getBody();
				String msgTime = DateTime.getSimpleTime();
				addRecentMessageDao(fromId, friendAlias, msgTime, msgContent,
						ChatMessage.MSG_TYPE_TXT_IN);
			}
		}
	};

	/**
	 * 数据库内添加最近聊天文字信息
	 * 
	 * @param chatAccount
	 * @param chatUser
	 * @param msgTime
	 * @param msgContent
	 */
	private void addRecentMessageDao(String chatAccount, String chatUser,
			String msgTime, String msgContent, int msgType) {
		ChatMessage chatMessage = new ChatMessage();
		chatMessage.setMsgAccount(chatAccount);
		chatMessage.setMsgUser(chatUser);
		chatMessage.setMsgTime(msgTime);
		chatMessage.setMsgContent(msgContent);
		chatMessage.setMsgType(msgType);
		messageDao.insert(chatMessage);
		if (msgType == ChatMessage.MSG_TYPE_IMG_IN) {
			msgContent = "[图片]";
		} else if (msgType == ChatMessage.MSG_TYPE_VOICE_IN) {
			msgContent = "[语音]";
		}
		RecentChat recentChat = new RecentChat(chatAccount, null, chatUser,
				msgTime, msgContent);
		recentDao.insert(recentChat);

		Intent intent = new Intent(IMConfig.MSG_ACTION);
		intent.putExtra(IMConfig.CHAT_ACCOUNT, chatAccount);
		intent.putExtra(IMConfig.CHAT_USERNAME, chatUser);
		intent.putExtra(IMConfig.CHAT_CONTENT,msgContent);
		iContext.sendBroadcast(intent);
	}

	/**
	 * 注册接收文件的监听器
	 */
	private void initFileListener() {
		fileTransferManager = new FileTransferManager(imConnection);
		fileTransferManager.addFileTransferListener(new FileTransferListener() {

			@Override
			public void fileTransferRequest(FileTransferRequest request) {
				String fromId = request.getRequestor();
				if (fromId != null && !"".equals(fromId)) {
					String descript = request.getDescription();
					IncomingFileTransfer inTransfer = request.accept();
					String subName = ".img";
					int msgType = IMConfig.MSG_TYPE_IMAGE;
					if (descript.equals("voice")) {
						subName = ".arm";
						msgType = IMConfig.MSG_TYPE_VOICE;
					}
					String fileName = System.currentTimeMillis() + subName;
					File path;
					if (Environment.MEDIA_MOUNTED.equals(Environment
							.getExternalStorageState())) {
						path = iContext.getExternalFilesDir(fromId.split("@")[0]);
					} else {
						path = iContext.getFilesDir();
					}
					String absolutePath = path.getAbsolutePath() + "/"
							+ fileName;
					File file = new File(absolutePath);
					try {
						inTransfer.recieveFile(file);
					} catch (XMPPException e) {
						e.printStackTrace();
					}
					if (msgType == IMConfig.MSG_TYPE_IMAGE) {
						fromId = fromId.split("@")[0];
						String friendAlias = getFriendName(fromId);
						String msgContent = absolutePath;
						String msgTime = DateTime.getSimpleTime();
						addRecentMessageDao(fromId, friendAlias, msgTime,
								msgContent, ChatMessage.MSG_TYPE_IMG_IN);
						Log.v(TAG, "img receive success");

					} else if (msgType == IMConfig.MSG_TYPE_VOICE) {
						fromId = fromId.split("@")[0];
						String friendAlias = getFriendName(fromId);
						String msgContent = absolutePath;
						String msgTime = DateTime.getSimpleTime();
						addRecentMessageDao(fromId, friendAlias, msgTime,
								msgContent, ChatMessage.MSG_TYPE_VOICE_IN);
						Log.v(TAG, "amr receive success");
					}
				}
			}
		});
	}

	@Override
	public String getFriendName(String userAccount) {
		if (roster.getEntry(userAccount) == null) {
			addFriend(userAccount, userAccount, null);
		}
		String friendName = roster.getEntry(userAccount).getName();
		return friendName;
	}

	@Override
	public boolean addFriend(String userAccount, String alias,
			String[] groupName) {
		try {
			roster.createEntry(userAccount, alias, groupName);
		} catch (XMPPException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public boolean removeFriend(String userAccount) {
		try {
			RosterEntry rosterEntry = roster.getEntry(userAccount);
			roster.removeEntry(rosterEntry);
		} catch (XMPPException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public boolean setAlias(String userAccount, String alias) {
		RosterEntry rosterEntry = roster.getEntry(userAccount);
		rosterEntry.setName(alias);
		return true;
	}

	@Override
	public boolean sendMessage(String userAccount, String message) {
		try {
			imConnection.getChatManager().createChat(userAccount, null)
					.sendMessage(message);
		} catch (XMPPException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public boolean sendFile(String userAccount, String filePath, String type) {
		try {
			File file = new File(filePath);
			OutgoingFileTransfer outTransfer = fileTransferManager
					.createOutgoingFileTransfer(userAccount);
			outTransfer.sendFile(file, type);
		} catch (XMPPException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public boolean logout() {
		if (imConnection.isConnected())
			imConnection.disconnect();
		return true;
	}

}
如有疑问可在下面回复,一一作答,因本人太懒,实在懒得写文字描述了。。。

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Android基于环信SDK开发IM即时聊天

版权声明:本文为博主原创文章,转载请注明出处。 目录(?)[+] 目前市面上我了解的做第三方即时聊天SDK的有两家:环信、融云,这里我使用环信SDK来完成即时聊...
  • qq_35114086
  • qq_35114086
  • 2016-08-07 11:13
  • 1963

winform中socket实现即时通讯(仿qq聊天)

c# winform socket实现即时通讯(仿qq)
  • gmandlyh
  • gmandlyh
  • 2015-10-13 18:58
  • 2612

环信SDK调用实现即时聊天功能

最近在做个项目,需要用到即时通信的功能,选定了环信的IM云来实现,关于环信IM的SDK接口,自己研究了一天,基本的功能实现了一下,这里PO出来demo。 因为只是为了验证sdk的实现,所以界面设计的比...
  • sinat_22013331
  • sinat_22013331
  • 2016-03-24 16:05
  • 4036

Android即时聊天系统--随聊APP之接口定义

接口定义大约包括了登陆、添加联系人、设置联系人备注、删除联系人、发送文字消息、发送文件(用作发送语音和图片)、退出等接口。因当时想实现AIDL接口,让聊天服务在另一个新的线程中,为了方便,就没有设置获...
  • jav_imba
  • jav_imba
  • 2015-06-13 15:17
  • 912

Android即时聊天系统--随聊APP之前序

我的毕业设计项目,做完之后一直想总结一下,不过话说一直没时间啊,今天总算是抽出空来了。 随聊APP,自己命名的,取自随时随地,想聊就聊。通过第三方openfire开源客户端以及asmack开源api...
  • jav_imba
  • jav_imba
  • 2015-06-01 18:12
  • 471

Android即时聊天App

  • 2017-05-25 10:49
  • 4.42MB
  • 下载

Whoere即时聊天App(四)客户端实现+服务部署 续

Screenshot
  • xxx_qz
  • xxx_qz
  • 2017-02-21 22:30
  • 488

Whoere即时聊天App(三)客户端实现+服务部署

服务云端部署、android app实现客户端 在完成本地开发和测试以后,接下来实现客户端app,同时将服务部署在阿里云linux服务器
  • xxx_qz
  • xxx_qz
  • 2017-02-21 22:10
  • 332

基于百度推送的第三方服务器android即时聊天系统

本系统采用百度云推送,结合z'jian
  • writerpan
  • writerpan
  • 2014-06-12 22:36
  • 776

Android 源码系列之<十五>,深入浅出WebSocket,打造自己的即时聊天交互系统<上>

做Java开发的小伙伴们应该对Socket比较熟悉,在J2SE的Socket编程这一章节中专门对Socket通信做了详细介绍,当时自学完该章节后只知道Socket是端到端通信的,Server端根据指定...
  • llew2011
  • llew2011
  • 2017-06-07 09:24
  • 2762
    个人资料
    • 访问:72974次
    • 积分:1305
    • 等级:
    • 排名:千里之外
    • 原创:58篇
    • 转载:11篇
    • 译文:1篇
    • 评论:32条
    最新评论