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

接口定义请参考上篇,实现接口采用的是成熟的第三方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;
	}

}
如有疑问可在下面回复,一一作答,因本人太懒,实在懒得写文字描述了。。。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章