码迷,mamicode.com
首页 > 移动开发 > 详细

安卓蓝牙实现即时通讯功能

时间:2016-05-18 19:42:44      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:

安卓蓝牙实现即时通讯功能

本demo是《Android智能穿戴设备开发指南》书中的一块内容,实现了两台手机基于蓝牙进行即时通讯的功能。

demo演示如下:
技术分享

结构图

技术分享

主要代码

技术分享

MainActivity:启动服务器和客户端界面

    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {

            case R.id.startServerBtn:
                //打开服务器
                Intent serverIntent = new Intent(MainActivity.this, ServerActivity.class);
                serverIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(serverIntent);
                break;

            case R.id.startClientBtn:
                //打开客户端
                Intent clientIntent = new Intent(MainActivity.this, ClientActivity.class);
                clientIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(clientIntent);
                break;
        }
    }

ClientActivity

  • 注册广播,开启服务(BluetoothClientService)

    //广播接收器
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
    
            if (BluetoothTools.ACTION_NOT_FOUND_SERVER.equals(action)) {
                //未发现设备
                serversText.append("not found device\r\n");
    
            } else if (BluetoothTools.ACTION_FOUND_DEVICE.equals(action)) {
                //获取到设备对象
                BluetoothDevice device = (BluetoothDevice)intent.getExtras().get(BluetoothTools.DEVICE);
                deviceList.add(device);
                serversText.append(device.getName() + "\r\n");
    
            } else if (BluetoothTools.ACTION_CONNECT_SUCCESS.equals(action)) {
                //连接成功
                serversText.append("连接成功");
                sendBtn.setEnabled(true);
    
            } else if (BluetoothTools.ACTION_DATA_TO_GAME.equals(action)) {
                //接收数据
                TransmitBean data = (TransmitBean)intent.getExtras().getSerializable(BluetoothTools.DATA);
                String msg = "from remote " + new Date().toLocaleString() + " :\r\n" + data.getMsg() + "\r\n";
                chatEditText.append(msg);
    
            }
        }
    };
    

#

    //注册BoradcasrReceiver
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(BluetoothTools.ACTION_NOT_FOUND_SERVER);
    intentFilter.addAction(BluetoothTools.ACTION_FOUND_DEVICE);
    intentFilter.addAction(BluetoothTools.ACTION_DATA_TO_GAME);
    intentFilter.addAction(BluetoothTools.ACTION_CONNECT_SUCCESS);
    registerReceiver(broadcastReceiver, intentFilter);

#

    //开启后台service
    Intent startService = new Intent(ClientActivity.this, BluetoothClientService.class);
    startService(startService);

#

  • 开始搜索蓝牙和连接第一个设备

    startSearchBtn.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                //开始搜索
                Intent startSearchIntent = new Intent(BluetoothTools.ACTION_START_DISCOVERY);
                sendBroadcast(startSearchIntent);
            }
        });
    
    selectDeviceBtn.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                //选择第一个设备
                Intent selectDeviceIntent = new Intent(BluetoothTools.ACTION_SELECTED_DEVICE);
                selectDeviceIntent.putExtra(BluetoothTools.DEVICE, deviceList.get(0));
                sendBroadcast(selectDeviceIntent);
            }
        }); 
    
  • 向服务器发送消息

    sendBtn.setOnClickListener(new OnClickListener() {
    
        @Override
        public void onClick(View v) {
            //发送消息
            if ("".equals(sendEditText.getText().toString().trim())) {
                Toast.makeText(ClientActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show();
            } else {
                //发送消息
                TransmitBean data = new TransmitBean();
                data.setMsg(sendEditText.getText().toString());
                Intent sendDataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_SERVICE);
                sendDataIntent.putExtra(BluetoothTools.DATA, data);
                sendBroadcast(sendDataIntent);
            }
        }
    });
    

ServerActivity

  • 注册广播接收器

    //广播接收器
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            String action = intent.getAction();
    
            if (BluetoothTools.ACTION_DATA_TO_GAME.equals(action)) {
                //接收数据
                TransmitBean data = (TransmitBean) intent.getExtras().getSerializable(BluetoothTools.DATA);
                String msg = "from remote " + new Date().toLocaleString() + " :\r\n" + data.getMsg() + "\r\n";
                msgEditText.append(msg);
    
            } else if (BluetoothTools.ACTION_CONNECT_SUCCESS.equals(action)) {
                //连接成功
                serverStateTextView.setText("连接成功");
                sendBtn.setEnabled(true);
            }
    
        }
    };
    
    
    //注册BoradcasrReceiver
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(BluetoothTools.ACTION_DATA_TO_GAME);
    intentFilter.addAction(BluetoothTools.ACTION_CONNECT_SUCCESS);
    
    registerReceiver(broadcastReceiver, intentFilter);
    
  • 开启后台服务

    //开启后台service
    Intent startService = new Intent(ServerActivity.this, BluetoothServerService.class);
    startService(startService);
    
  • 向客户端发送消息

    sendBtn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if ("".equals(sendMsgEditText.getText().toString().trim())) {
                Toast.makeText(ServerActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show();
            } else {
                //发送消息
                TransmitBean data = new TransmitBean();
                data.setMsg(sendMsgEditText.getText().toString());
                Intent sendDataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_SERVICE);
                sendDataIntent.putExtra(BluetoothTools.DATA, data);
                sendBroadcast(sendDataIntent);
            }
        }
    });
    

BluetoothClientService

    /**
     * 蓝牙模块客户端主控制Service
     */
    public class BluetoothClientService extends Service {

        //搜索到的远程设备集合
        private List<BluetoothDevice> discoveredDevices = new ArrayList<BluetoothDevice>();

        //蓝牙适配器
        private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        //蓝牙通讯线程
        private BluetoothCommunThread communThread;

        //控制信息广播的接收器
        private BroadcastReceiver controlReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();

                if (BluetoothTools.ACTION_START_DISCOVERY.equals(action)) {
                    //开始搜索
                    discoveredDevices.clear();  //清空存放设备的集合
                    bluetoothAdapter.enable();  //打开蓝牙
                    bluetoothAdapter.startDiscovery();  //开始搜索

                } else if (BluetoothTools.ACTION_SELECTED_DEVICE.equals(action)) {
                    //选择了连接的服务器设备
                    BluetoothDevice device = (BluetoothDevice)intent.getExtras().get(BluetoothTools.DEVICE);

                    //开启设备连接线程
                    new BluetoothClientConnThread(handler, device).start();

                } else if (BluetoothTools.ACTION_STOP_SERVICE.equals(action)) {
                    //停止后台服务
                    if (communThread != null) {
                        communThread.isRun = false;
                    }
                    stopSelf();

                } else if (BluetoothTools.ACTION_DATA_TO_SERVICE.equals(action)) {
                    //获取数据
                    Object data = intent.getSerializableExtra(BluetoothTools.DATA);
                    if (communThread != null) {
                        communThread.writeObject(data);
                    }

                }
            }
        };

        //蓝牙搜索广播的接收器
        private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                //获取广播的Action
                String action = intent.getAction();

                if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                    //开始搜索
                } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    //发现远程蓝牙设备
                    //获取设备
                    BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    discoveredDevices.add(bluetoothDevice);

                    //发送发现设备广播
                    Intent deviceListIntent = new Intent(BluetoothTools.ACTION_FOUND_DEVICE);
                    deviceListIntent.putExtra(BluetoothTools.DEVICE, bluetoothDevice);
                    sendBroadcast(deviceListIntent);

                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    //搜索结束
                    if (discoveredDevices.isEmpty()) {
                        //若未找到设备,则发动未发现设备广播
                        Intent foundIntent = new Intent(BluetoothTools.ACTION_NOT_FOUND_SERVER);
                        sendBroadcast(foundIntent);
                    }
                }
            }
        };

        //接收其他线程消息的Handler
        Handler handler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                //处理消息
                switch (msg.what) {
                    case BluetoothTools.MESSAGE_CONNECT_ERROR:
                        //连接错误
                        //发送连接错误广播
                        Intent errorIntent = new Intent(BluetoothTools.ACTION_CONNECT_ERROR);
                        sendBroadcast(errorIntent);
                        break;
                    case BluetoothTools.MESSAGE_CONNECT_SUCCESS:
                        //连接成功

                        //开启通讯线程
                        communThread = new BluetoothCommunThread(handler, (BluetoothSocket)msg.obj);
                        communThread.start();

                        //发送连接成功广播
                        Intent succIntent = new Intent(BluetoothTools.ACTION_CONNECT_SUCCESS);
                        sendBroadcast(succIntent);
                        break;
                    case BluetoothTools.MESSAGE_READ_OBJECT:
                        //读取到对象
                        //发送数据广播(包含数据对象)
                        Intent dataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_GAME);
                        dataIntent.putExtra(BluetoothTools.DATA, (Serializable)msg.obj);
                        sendBroadcast(dataIntent);
                        break;
                }
                super.handleMessage(msg);
            }

        };

        /**
         * 获取通讯线程
         * @return
         */
        public BluetoothCommunThread getBluetoothCommunThread() {
            return communThread;
        }

        @Override
        public void onStart(Intent intent, int startId) {

            super.onStart(intent, startId);
        }

        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }

        /**
         * Service创建时的回调函数
         */
        @Override
        public void onCreate() {
            //discoveryReceiver的IntentFilter
            IntentFilter discoveryFilter = new IntentFilter();
            discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);

            //controlReceiver的IntentFilter
            IntentFilter controlFilter = new IntentFilter();
            controlFilter.addAction(BluetoothTools.ACTION_START_DISCOVERY);
            controlFilter.addAction(BluetoothTools.ACTION_SELECTED_DEVICE);
            controlFilter.addAction(BluetoothTools.ACTION_STOP_SERVICE);
            controlFilter.addAction(BluetoothTools.ACTION_DATA_TO_SERVICE);

            //注册BroadcastReceiver
            registerReceiver(discoveryReceiver, discoveryFilter);
            registerReceiver(controlReceiver, controlFilter);
            super.onCreate();
        }

        /**
         * Service销毁时的回调函数
         */
        @Override
        public void onDestroy() {
            if (communThread != null) {
                communThread.isRun = false;
            }
            //解除绑定
            unregisterReceiver(discoveryReceiver);
            super.onDestroy();
        }

    }

BluetoothServerService

    /**
     * 蓝牙模块服务器端主控制Service
     */
    public class BluetoothServerService extends Service {

        //蓝牙适配器
        private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        //蓝牙通讯线程
        private BluetoothCommunThread communThread;

        //控制信息广播接收器
        private BroadcastReceiver controlReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();

                if (BluetoothTools.ACTION_STOP_SERVICE.equals(action)) {
                    //停止后台服务
                    if (communThread != null) {
                        communThread.isRun = false;
                    }
                    stopSelf();

                } else if (BluetoothTools.ACTION_DATA_TO_SERVICE.equals(action)) {
                    //发送数据
                    Object data = intent.getSerializableExtra(BluetoothTools.DATA);
                    if (communThread != null) {
                        communThread.writeObject(data);
                    }

                }
            }
        };

        //接收其他线程消息的Handler
        private Handler serviceHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {

                switch (msg.what) {
                    case BluetoothTools.MESSAGE_CONNECT_SUCCESS:
                        //连接成功
                        //开启通讯线程
                        communThread = new BluetoothCommunThread(serviceHandler, (BluetoothSocket)msg.obj);
                        communThread.start();

                        //发送连接成功消息
                        Intent connSuccIntent = new Intent(BluetoothTools.ACTION_CONNECT_SUCCESS);
                        sendBroadcast(connSuccIntent);
                        break;

                    case BluetoothTools.MESSAGE_CONNECT_ERROR:
                        //连接错误
                        //发送连接错误广播
                        Intent errorIntent = new Intent(BluetoothTools.ACTION_CONNECT_ERROR);
                        sendBroadcast(errorIntent);
                        break;

                    case BluetoothTools.MESSAGE_READ_OBJECT:
                        //读取到数据
                        //发送数据广播(包含数据对象)
                        Intent dataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_GAME);
                        dataIntent.putExtra(BluetoothTools.DATA, (Serializable)msg.obj);
                        sendBroadcast(dataIntent);

                        break;
                }

                super.handleMessage(msg);
            }

        };

        /**
         * 获取通讯线程
         * @return
         */
        public BluetoothCommunThread getBluetoothCommunThread() {
            return communThread;
        }

        @Override
        public void onCreate() {
            //ControlReceiver的IntentFilter
            IntentFilter controlFilter = new IntentFilter();
            controlFilter.addAction(BluetoothTools.ACTION_START_SERVER);
            controlFilter.addAction(BluetoothTools.ACTION_STOP_SERVICE);
            controlFilter.addAction(BluetoothTools.ACTION_DATA_TO_SERVICE);

            //注册BroadcastReceiver
            registerReceiver(controlReceiver, controlFilter);

            //开启服务器
            bluetoothAdapter.enable();  //打开蓝牙
            //开启蓝牙发现功能(300秒)
            Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
            discoveryIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(discoveryIntent);
            //开启后台连接线程
            new BluetoothServerConnThread(serviceHandler).start();

            super.onCreate();
        }

        @Override
        public void onDestroy() {
            if (communThread != null) {
                communThread.isRun = false;
            }
            unregisterReceiver(controlReceiver);
            super.onDestroy();
        }

        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }

    }

BluetoothClientConnThread

    /**
     * 蓝牙客户端连接线程
     */
    public class BluetoothClientConnThread extends Thread{

        private Handler serviceHandler;     //用于向客户端Service回传消息的handler
        private BluetoothDevice serverDevice;   //服务器设备
        private BluetoothSocket socket;     //通信Socket

        /**
         * 构造函数
         * @param handler
         * @param serverDevice
         */
        public BluetoothClientConnThread(Handler handler, BluetoothDevice serverDevice) {
            this.serviceHandler = handler;
            this.serverDevice = serverDevice;
        }

        @Override
        public void run() {
            BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
            try {
                socket = serverDevice.createRfcommSocketToServiceRecord(BluetoothTools.PRIVATE_UUID);
                BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
                socket.connect();

            } catch (Exception ex) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //发送连接失败消息
                serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
                return;
            }

            //发送连接成功消息,消息的obj参数为连接的socket
            Message msg = serviceHandler.obtainMessage();
            msg.what = BluetoothTools.MESSAGE_CONNECT_SUCCESS;
            msg.obj = socket;
            msg.sendToTarget();
        }
    }

BluetoothServerConnThread

    /**
     * 服务器连接线程
     */
    public class BluetoothServerConnThread extends Thread {

        private Handler serviceHandler;     //用于同Service通信的Handler
        private BluetoothAdapter adapter;
        private BluetoothSocket socket;     //用于通信的Socket
        private BluetoothServerSocket serverSocket;

        /**
         * 构造函数
         * @param handler
         */
        public BluetoothServerConnThread(Handler handler) {
            this.serviceHandler = handler;
            adapter = BluetoothAdapter.getDefaultAdapter();
        }

        @Override
        public void run() {

            try {
                serverSocket = adapter.listenUsingRfcommWithServiceRecord("Server", BluetoothTools.PRIVATE_UUID);
                socket = serverSocket.accept();
            } catch (Exception e) {
                //发送连接失败消息
                serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
                e.printStackTrace();
                return;
            } finally {
                try {
                    serverSocket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (socket != null) {
                //发送连接成功消息,消息的obj字段为连接的socket
                Message msg = serviceHandler.obtainMessage();
                msg.what = BluetoothTools.MESSAGE_CONNECT_SUCCESS;
                msg.obj = socket;
                msg.sendToTarget();
            } else {
                //发送连接失败消息
                serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
                return;
            }
        }
    }

BluetoothCommunThread

    /**
     * 蓝牙通讯线程
     */
    public class BluetoothCommunThread extends Thread {

        private Handler serviceHandler;        //与Service通信的Handler
        private BluetoothSocket socket;
        private ObjectInputStream inStream;        //对象输入流
        private ObjectOutputStream outStream;    //对象输出流
        public volatile boolean isRun = true;    //运行标志位

        /**
         * 构造函数
         *
         * @param handler 用于接收消息
         * @param socket
         */
        public BluetoothCommunThread(Handler handler, BluetoothSocket socket) {
            this.serviceHandler = handler;
            this.socket = socket;
            try {
                this.outStream = new ObjectOutputStream(socket.getOutputStream());
                this.inStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
            } catch (Exception e) {
                try {
                    socket.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                //发送连接失败消息
                serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            while (true) {
                if (!isRun) {
                    break;
                }
                try {
                    Object obj = inStream.readObject();
                    //发送成功读取到对象的消息,消息的obj参数为读取到的对象
                    Message msg = serviceHandler.obtainMessage();
                    msg.what = BluetoothTools.MESSAGE_READ_OBJECT;
                    msg.obj = obj;
                    msg.sendToTarget();
                } catch (Exception ex) {
                    //发送连接失败消息
                    serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
                    ex.printStackTrace();
                    return;
                }
            }

            //关闭流
            if (inStream != null) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outStream != null) {
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 写入一个可序列化的对象
         *
         * @param obj
         */
        public void writeObject(Object obj) {
            try {
                outStream.flush();
                outStream.writeObject(obj);
                outStream.flush();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
  • 最后还有一个蓝牙工具类(BluetoothTools)和用于传输的数据类(TransmitBean)代码就不粘了,直接把源码地址发出来

源码地址:
http://download.csdn.net/detail/benhuo931115/9519599

安卓蓝牙实现即时通讯功能

标签:

原文地址:http://blog.csdn.net/benhuo931115/article/details/51398681

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!