Android Open Source - blue-chat Chat Manager






From Project

Back to project page blue-chat.

License

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.

Java Source Code

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();
                    }

                });
            }
        }

    }

}




Java Source Code List

com.alexkang.bluechat.ApplicationTest.java
com.alexkang.bluechat.ChatManager.java
com.alexkang.bluechat.ClientActivity.java
com.alexkang.bluechat.HostActivity.java
com.alexkang.bluechat.MainActivity.java
com.alexkang.bluechat.MessageBox.java
com.alexkang.bluechat.MessageFeedAdapter.java