美文网首页Android
Android基于蓝牙串口编程实现HC-05通讯

Android基于蓝牙串口编程实现HC-05通讯

作者: heyrenly | 来源:发表于2019-02-24 16:00 被阅读77次

    Android基于蓝牙串口编程实现HC-05通讯

    最近接了个工程自动化的项目,需求是实时接收从单片机传过来的数据,并进行数据分析处理再进行显示,在查阅大量的相关博客和自己踩了不少的坑后,想说把自己的一些经验分享出来给后来人做个参考www

    先介绍下蓝牙串口的定义

    蓝牙串口是基于SPP协议(Serial Port Profile),能在蓝牙设备之间创建串口进行数据传输的一种设备。蓝牙串口的目的是针对如何在两个不同设备(通信的两端)上的应用之间保证一条完整的通信路径。

    目前应用商店可以下载到的蓝牙串口app就是基于SPP协议,而有一些蓝牙搜索app搜索不到HC-05就是由于没有实现蓝牙串口服务。要想要在自己的app内实现SPP协议需要服务对应的UUID,蓝牙串口服务的UUID为:

    SerialPortServiceClass_UUID = '{00001101-0000-1000-8000-00805F9B34FB}' 
    

    更多的手机蓝牙各类服务对应的UUID,可以通过下面这个网站进行查询:
    https://www.douban.com/group/topic/20009323/

    顺便讲下蓝牙串口app的使用,首先需要在系统设置里,连接上HC-05的蓝牙,默认配对密码为1234,默认波特率为9600,默认名为HC-05。最好在连接后再看一下对应的MAC地址,因为我做的是单一连接,单片机同一时间只能接入一个蓝牙设备,所以需求对更改连接蓝牙模块需求要求不大,如果用户不在创建项目时更改设备MAC地址,则使用的就是默认的MAC地址,所以也没有做选择蓝牙设备的模块。

    博客附本项目截图以及项目源码地址。

    需要的权限

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- 6.0以上需要加的额外权限 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    

    获取蓝牙适配器

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    

    不支持蓝牙时

    // If the adapter is null, then Bluetooth is not supported
    if (mBluetoothAdapter == null) {
        Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
        finish();
    }
    

    绑定蓝牙设备

    // String MACAddr = "xx:xx:xx:xx:xx:xx";
    BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(MACAddr);
    

    *如果检测到蓝牙没打开,调用系统蓝牙设置(可选)

    Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
    startActivity(intent);
    

    连接设备,开启蓝牙连接线程

    public void connect(BluetoothDevice device) {
            printLog("connect to: " + device);
            // Start the thread to connect with the given device
            mConnectThread = new ConnectThread(device);
            mConnectThread.start();
        }
    

    连接线程

    /**
         * This thread runs while attempting to make an outgoing connection with a
         * device. It runs straight through; the connection either succeeds or
         * fails.
         */
        private class ConnectThread extends Thread {
            private final BluetoothSocket mmSocket;
            private final BluetoothDevice mmDevice;
    
            public ConnectThread(BluetoothDevice device) {
                mmDevice = device;
                BluetoothSocket tmp = null;
    
                // Get a BluetoothSocket for a connection with the
                // given BluetoothDevice
                try {
                    tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(App.SPP_UUID));
                } catch (IOException e) {
                    printLog("create() failed" + e);
                }
                mmSocket = tmp;
            }
    
            public void run() {
                if (Thread.interrupted())
                    return;
                setName("ConnectThread");
    
                // Always cancel discovery because it will slow down a connection
                mBluetoothAdapter.cancelDiscovery();
    
                // Make a connection to the BluetoothSocket
                try {
                    // This is a blocking call and will only return on a
                    // successful connection or an exception
                    isBlueToothConnected = true;
                    mmSocket.connect();
                } catch (IOException e) {
    
                    printLog("unable to connect() socket " + e);
                    handler.sendEmptyMessage(NOT_CONNECT);
                    isBlueToothConnected = false;
                    // Close the socket
                    try {
                        mmSocket.close();
                    } catch (IOException e2) {
                        printLog("unable to close() socket during connection failure" + e2);
                    }
                    return;
                }
    
                mConnectThread = null;
    
                isBlueToothConnected = true;
    
                // Start the connected thread
                // Start the thread to manage the connection and perform
                // transmissions
                handler.sendEmptyMessage(CONNECT_SUCCESS);
    
                mConnectedThread = new ConnectedThread(mmSocket);
            }
    
            public void cancel() {
                try {
                    mmSocket.close();
                } catch (IOException e) {
                    printLog("close() of connect socket failed" + e);
                }
            }
        }
    

    数据传输线程(可读可写,需求只用读取)

    **
         * This thread runs during a connection with a remote device. It handles all
         * incoming and outgoing transmissions.
         */
        private class ConnectedThread extends Thread {
            private final BluetoothSocket mmSocket;
            private final InputStream mmInStream;
            private final OutputStream mmOutStream;
    
            public ConnectedThread(BluetoothSocket socket) {
                printLog("create ConnectedThread");
                mmSocket = socket;
                InputStream tmpIn = null;
                OutputStream tmpOut = null;
    
                // Get the BluetoothSocket input and output streams
                try {
                    tmpIn = socket.getInputStream();
                    tmpOut = socket.getOutputStream();
                } catch (IOException e) {
                    printLog("temp sockets not created" + e);
                }
    
                mmInStream = tmpIn;
                mmOutStream = tmpOut;
            }
    
            public void run() {
                if (Thread.interrupted()) {
                    printLog("return");
                    return;
                }
                printLog("BEGIN mConnectedThread");
                byte[] buffer = new byte[256];
                int bytes;
    
                // Keep listening to the InputStream while connected
                while (true) {
                    synchronized (this) {
                        try {
                            // Read from the InputStream
                            bytes = mmInStream.read(buffer);
                            
                            Message msg = new Message();
                            msg.what = GET_DATA;
                            Bundle bundle = new Bundle();
                            bundle.putInt("data", buffer[0]);
                            msg.setData(bundle);
                            
                            handler.sendMessage(msg);
                        } catch (IOException e) {
                            printLog("disconnected " + e);
    //                        handler.sendEmptyMessage(OUT_OF_CONNECTED);
                            break;
                        }
                    }
                }
            }
    
            /**
             * Write to the connected OutStream.
             *
             * @param buffer The bytes to write
             */
            public void write(byte[] buffer) {
                try {
                    mmOutStream.write(buffer);
                } catch (IOException e) {
                    Log.e(TAG, "Exception during write", e);
                }
            }
    
            public void cancel() {
                try {
                    mmSocket.close();
                } catch (IOException e) {
                    Log.e(TAG, "close() of connect socket failed", e);
                }
            }
        }
    

    停止蓝牙连接

    private void stopBlutoothThread() {
            if (mConnectThread != null) {
                mConnectThread.cancel();
                mConnectThread = null;
            }
            if (mConnectedThread != null) {
                mConnectedThread.cancel();
                mConnectedThread = null;
            }
        }
    

    项目截图

    01 02 03
    源码可以在我的Github上看到
    项目地址:https://github.com/WithLei/DistanceMeasure

    相关文章

      网友评论

        本文标题:Android基于蓝牙串口编程实现HC-05通讯

        本文链接:https://www.haomeiwen.com/subject/vmtmyqtx.html