Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 安卓藍牙實現即時通訊功能

安卓藍牙實現即時通訊功能

編輯:關於Android編程

本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 discoveredDevices = new ArrayList();

        //藍牙適配器
        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)代碼就不粘了,直接把源碼地址發出來
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved