Back to project page blue-chat.
The source code is released under:
MIT License
If you think the Android project blue-chat listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.alexkang.bluechat; /*from w ww. j a va 2s. co m*/ import android.app.Activity; import android.app.ProgressDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothSocket; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.os.Message; import android.preference.PreferenceManager; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ListView; import android.widget.Toast; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; public class ChatManager { public static final int BODY_LENGTH_END = 255; public static final int BODY_LENGTH_END_SIGNED = -1; public static final int MESSAGE_ID = 1; public static final int MESSAGE_NAME = 2; public static final int MESSAGE_SEND = 3; public static final int MESSAGE_RECEIVE = 4; public static final int MESSAGE_SEND_IMAGE = 5; public static final int MESSAGE_RECEIVE_IMAGE = 6; private boolean isHost; private boolean isInitialized = false; private ArrayList<ConnectedThread> connections; private int id; private ArrayList<MessageBox> mMessageList; private MessageFeedAdapter mFeedAdapter; private ListView mMessageFeed; private Activity mActivity; private ProgressDialog mProgressDialog; private ConnectedThread mConnectedThread; private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { byte[] packet = (byte[]) msg.obj; int senderLength = msg.arg1; int senderId = msg.arg2; String sender = new String(Arrays.copyOfRange(packet, 0, senderLength)); byte[] body = Arrays.copyOfRange(packet, senderLength, packet.length); boolean isSelf = senderId == id; switch (msg.what) { case MESSAGE_ID: id = body[0]; case MESSAGE_NAME: if (!isHost && !isInitialized) { String chatRoomName = new String(body); if (mActivity.getActionBar() != null) { mActivity.getActionBar().setTitle(chatRoomName); } BluetoothAdapter.getDefaultAdapter().cancelDiscovery(); mProgressDialog.dismiss(); Toast.makeText(mActivity, "Connected!", Toast.LENGTH_SHORT).show(); isInitialized = true; } break; case MESSAGE_SEND: if (isHost) { byte[] sendPacket = buildPacket(MESSAGE_SEND, senderId, sender, body); writeMessage(sendPacket, senderId); } break; case MESSAGE_RECEIVE: MessageBox messageBox = new MessageBox(sender, new String(body), new Date(), isSelf); addMessage(messageBox); break; case MESSAGE_SEND_IMAGE: if (isHost) { byte[] sendImagePacket = buildPacket(MESSAGE_SEND_IMAGE, senderId, sender, body); writeMessage(sendImagePacket, senderId); } break; case MESSAGE_RECEIVE_IMAGE: Bitmap bitmap = BitmapFactory.decodeByteArray(body, 0, body.length); MessageBox imageBox = new MessageBox(sender, bitmap, new Date(), isSelf); addMessage(imageBox); } } }; public ChatManager(Activity activity, boolean isHost) { mActivity = activity; mMessageFeed = (ListView) mActivity.findViewById(R.id.message_feed); this.isHost = isHost; if (isHost) { id = 0; connections = new ArrayList<ConnectedThread>(); } mMessageList = new ArrayList<MessageBox>(); mFeedAdapter = new MessageFeedAdapter(mActivity, mMessageList); mMessageFeed.setAdapter(mFeedAdapter); View footer = new View(mActivity); footer.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 250)); footer.setBackgroundColor(mActivity.getResources().getColor(android.R.color.transparent)); mMessageFeed.addFooterView(footer, null, false); } public void startConnection(BluetoothSocket socket) { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mActivity); String username = sharedPref.getString("username", BluetoothAdapter.getDefaultAdapter().getName()); mConnectedThread = new ConnectedThread(socket); mConnectedThread.start(); if (isHost) { connections.add(mConnectedThread); byte[] idAssignmentPacket = buildPacket( MESSAGE_ID, username, new byte[] { (byte) connections.size() } ); mConnectedThread.write(idAssignmentPacket); } } public void startConnection(BluetoothSocket socket, ProgressDialog progressDialog) { startConnection(socket); mProgressDialog = progressDialog; } public byte[] buildPacket(int type, int senderId, String sender, byte[] body) { ByteArrayOutputStream output = new ByteArrayOutputStream(); output.write(type); output.write(sender.length()); int bodyLength = body.length; do { output.write(bodyLength % 10); bodyLength = bodyLength / 10; } while (bodyLength > 0); try { output.write(BODY_LENGTH_END); output.write(senderId); output.write(sender.getBytes()); output.write(body); } catch (IOException e) { System.err.println("Error in building packet."); return null; } return output.toByteArray(); } public byte[] buildPacket(int type, String sender, byte[] body) { return buildPacket(type, id, sender, body); } public void writeChatRoomName(byte[] byteArray) { connections.get(connections.size() - 1).write(byteArray); } public void writeMessage(byte[] byteArray, int senderId) { int type = byteArray[0]; int receiveType = 0; if (type == MESSAGE_SEND) { receiveType = MESSAGE_RECEIVE; } else if (type == MESSAGE_SEND_IMAGE) { receiveType = MESSAGE_RECEIVE_IMAGE; } int senderLength = byteArray[1]; int currIndex = 2; do { currIndex++; } while (byteArray[currIndex] != BODY_LENGTH_END_SIGNED); mHandler.obtainMessage(receiveType, senderLength, senderId, Arrays.copyOfRange(byteArray, currIndex + 2, byteArray.length)) .sendToTarget(); if (isHost) { new DistributeThread(receiveType, senderId, byteArray).start(); } else { mConnectedThread.write(byteArray); } } public void writeMessage(byte[] byteArray) { writeMessage(byteArray, id); } private void addMessage(MessageBox message) { mMessageList.add(message); mMessageFeed.invalidateViews(); mFeedAdapter.notifyDataSetChanged(); mMessageFeed.setSelection(mFeedAdapter.getCount()-1); } private class DistributeThread extends Thread { int mReceiveType; int mSenderId; private byte[] mByteArray; public DistributeThread(int receiveType, int senderId, byte[] byteArray) { mReceiveType = receiveType; mSenderId = senderId; mByteArray = byteArray; } public void run() { mByteArray[0] = (byte) mReceiveType; for (int i = 0; i < connections.size(); i++) { if (i + 1 != mSenderId) { connections.get(i).write(mByteArray); } } } } private class ConnectedThread extends Thread { private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { InputStream tmpIn = null; OutputStream tmpOut = null; try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) { Toast.makeText(mActivity, "Could not connect to ChatRoom, now exiting", Toast.LENGTH_SHORT).show(); Intent i = new Intent(mActivity, MainActivity.class); mActivity.startActivity(i); mActivity.finish(); } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { while (true) { try { int type = mmInStream.read(); int senderLength = mmInStream.read(); /* * Calculate the length of the body in bytes. Each byte read is a digit * in the body length in order of least to most significant digit. * * i.e. Body length of 247 would be read in the form {7, 4, 2}. */ int bodyLength = 0; int currPlace = 1; int currDigit = mmInStream.read(); do { bodyLength += (currDigit * currPlace); currPlace *= 10; currDigit = mmInStream.read(); } while (currDigit != BODY_LENGTH_END); int senderId = mmInStream.read(); ByteArrayOutputStream packetStream = new ByteArrayOutputStream(); for (int i = 0; i < senderLength + bodyLength; i++) { packetStream.write(mmInStream.read()); } byte[] packet = packetStream.toByteArray(); mHandler.obtainMessage(type, senderLength, senderId, packet) .sendToTarget(); } catch (IOException e) { System.err.println("Error in receiving packets"); e.printStackTrace(); endActivity(); break; } } } public void write(byte[] byteArray) { try { mmOutStream.write(byteArray); mmOutStream.flush(); } catch (IOException e) { String byteArrayString = ""; for (byte b : byteArray) { byteArrayString += b + ", "; } System.err.println("Failed to write bytes: " + byteArrayString); System.err.println(e.toString()); endActivity(); } } private void endActivity() { if (!isHost) { mActivity.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(mActivity, "ChatRoom closed", Toast.LENGTH_SHORT).show(); mActivity.finish(); } }); } } } }