java - 安卓 & 蓝牙 & Arduino

标签 java android bluetooth arduino byte

我正在尝试在我的 Android 手机(目标 4.3)上显示从传输 arduino 类型设备接收的传感器数据。传输通过蓝牙进行。我能够连接到 arduino 类型的设备,甚至共享数据,但是由于某种原因我遇到了同步问题。

arduino现在的设置方式,在成功连接后,它等待从我的手机接收一个字节(无符号字节值255),当它收到这个字节时,它通过发送一个数据包(3个字节)来响应,其中包含来自三个不同传感器的信息,即

packet:
byte 1: temperature data
byte 2: cadence data
byte 3: speed data

我所要做的就是重复显示这些数据(正在实时更新),直到用户终止 Android 手机上的连接。

这是我的代码,我觉得我在逻辑中的某个地方犯了一个小错误。

消息处理程序

Handler mHandler = new Handler(){           
            public void handleMessage(Message msg){
                super.handleMessage(msg);
                switch(msg.what){
                    case SUCCESS_CONNECT:
                        // Do Something;
                        ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
                        Toast.makeText(getActivity(),"CONNECTED",Toast.LENGTH_SHORT).show();
                        /*
                         * Could send test string here
                         */
                        /*
                         * String connect_string = "test";
                         * connectedThread.write(connect_string.getBytes());
                         */
                        connectedThread.start();
                        break;
                    case MESSAGE_READ:
                        byte[] readBuf = (byte[])msg.obj;
                        int tempInt = byteToInt(readBuf[0]);
                        int cadenceInt = byteToInt(readBuf[1]);
                        int speedInt = byteToInt(readBuf[2]);
                        EditText temperatureData = (EditText)getActivity().findViewById(R.id.temperatureData);
                        temperatureData.setText(Integer.toString(tempInt));
                        EditText cadenceData = (EditText)getActivity().findViewById(R.id.cadence);
                        cadenceData.setText(Integer.toString(cadenceInt));
                        EditText speedData = (EditText)getActivity().findViewById(R.id.speed_data);
                        speedData.setText(Integer.toString(speedInt));

                }
            }       
        };

连接线程

public class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;
    public ConnectThread(BluetoothDevice device) {

        /*
         *  Use a temporary object that is later assigned to mmSocket,
         *  because mmSocket is final                
         */

        BluetoothSocket tmp = null;

        mmDevice = device;

        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }

    public void run() {
        // Cancel discovery because it will slow down the connection
        mBluetoothAdapter.cancelDiscovery();

        try {
        // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and get out
            try {
                mmSocket.close();
            } catch (IOException closeException) {
                Toast.makeText(getActivity(), "Connecting to device failed!", Toast.LENGTH_LONG).show();
            }
                return;
        }

            // Do work to manage the connection (in a separate thread)
            mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
    }

    /** Will cancel an in-progress connection, and close the socket */
    public void cancel() {
        try {
            mmSocket.close();
           } catch (IOException e) { }
    }

}

连接线程

private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        byte[] buffer; // buffer store for the stream
        int bytes; // bytes returned from read()
        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                buffer = new byte[3];
                byte maxByte = (byte) 1;
                mmOutStream.write(255);
                bytes = mmInStream.read(buffer,0,buffer.length);
                // Send the obtained bytes to the message handler

                mHandler.obtainMessage(MESSAGE_READ,buffer).sendToTarget();
                }
             catch (IOException e) {
                 break;
             }
        }
     }

    /* Call this from the main activity to send data to the remote device */
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) { }
    }
}

字节转整数方法

public static int byteToInt(byte b){
    int value;
    value = b & 0xFF;
    return  value;
}

我收到的数据正在显示,但通常最终会出错,主要是因为字节数组序列关闭,导致显示错误的值。我已经尝试解决这个问题有一段时间了,任何意见都会有所帮助。

最佳答案

检查是否可以在消息中向处理程序发送克隆数组。 它应该类似于“buffer.clone”或“buffer.clone()”,而不是简单的“buffer”。 如果是这样,则意味着未克隆的缓冲区被复制为处理程序的引用。当处理程序执行其操作时,连接的线程可能会重新定义数组并为其重新分配不同的值。 要测试这一点,您还可以定义缓冲区 ad Byte[] 而不是 byte[]。 通过这种方式,我在我的应用程序中解决了类似的问题。

关于java - 安卓 & 蓝牙 & Arduino,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22291049/

相关文章:

java - 使用 HttpServletRequest 捕获重复的请求 header

android - 使用 OkHttp 覆盖 SocketFactory 后的问题

java - 将 uri 转换为位图时出现 "No content provider execution "错误

linux - 有没有办法增加 BlueZ 中的 BLE 广告频率?

python - 除了 blueZ (Pybluez),还有其他方法可以获得 RSSI 值吗?

java - 无法将蓝牙键盘连接到 Android 设备

java - Android DecimalFormat 格式不正确

java - @Embeddable 类中的 JPA @Version

java - 从 bluemix 上的 Boilerplates Java DB Web Starter 示例代码更改表

android - HttpResponse 无法解析