0

我看到很多关于蓝牙问题/蓝牙超时的问题,但没有一个对我有帮助。

我正在开发一个向/从另一个蓝牙设备发送和接收数据的应用程序。我每秒发送大约 3 次。我知道响应应该是什么样子(一个字节数组,如 [FC ... FF])。

我正在基于 BluetoothChat 演示构建我的应用程序,并且我主要更改了 BluetoothChatService 类中的代码。

我所做的是实现一个返回布尔值的新方法(我称之为布尔值 readWrite(byte[] data))。在这种方法中,我首先写入输出流,然后从输入流中读取。如果写入正常,我将布尔值设置为 true,如果读取正常,我将另一个布尔值设置为 true,并将响应字节数组转换为字符串并将此字符串设置为响应。如果写/读出错,我的方法将返回 false;

在我的 ConnectedThread 的 run() 方法中,我有一个 while(true) 循环,我正在使用这个 readWrite 方法。然后我得到字符串响应,并根据响应我 readWrite() 另一个数据。

我将在此处发布一些代码,以便您了解我的实际操作。通过这种方式,我试图摆脱套接字超时并在读/写出错时重置连接。我收到如下所示的一些错误,但它可能是我的设备?

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

    public ConnectedThread(BluetoothSocket socket) {
        Log.d(TAG, "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) {
            Log.e(TAG, "temp sockets not created", e);
        }
        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    private boolean readWrite(byte[] data) {
        byte[] read = null;
        int bytes = 0;
        String bc;
        String packet;
        boolean readPacket = false;
        boolean writing = false
        boolean reading = false; 

        try {
            // Log.d(TAG, "write to the device");
            mmOutStream.write(data);
            writing = true; 
        } catch (IOException e) {
            Log.e(TAG, "Exception occurred during write: " + e.getMessage());
            setState(STATE_NONE);
            writing = false; 
        }
        // if writing goes ok 
        if(writing){
            read = new byte[64];
            // the response packet should be a byte array like [FC ... FF]
            while(!readPacket)
            try {
                // Read from the InputStream
                bytes = mmInStream.read();
                bc = String.format("%02x", (0xFF & bytes)).toUpperCase();
                    if(bc.equalsIgnoreCase("fc"))
                    {
                        packet = "";
                        packet += bc;
                    }
                    else if(bc.equalsIgnoreCase("ff"))
                    {
                        readPacket = true;
                        packet += bc; // finish the response packet
                        Log.d(TAG, "read packet -> to UI: " + packet);
                        reading = true;
                        read = null;
                        myBluetoothService.this.setReceivedMessage(packet);
                        packet = "";
                    }
                    else{
                        packet += bc;
                    }
            }
            catch (IOException e) {
                reading = false;
                connectionLost();
                break;
            }
        }
        else return false;
        return (reading&&writing);
    }

    public void run() {
        setName("ConnectedThread");         
        byte[] buffer = new byte[64];
        String globalString = "";
        String requestCommand = "request";          
        buffer = requestCommand.getBytes();

        // Keep listening to the InputStream until an exception occurs
        while (true) {              
            Log.d(TAG, "in the LOOP");
            if(readWrite(buffer))
            {
                // get response from the remoteDevice
                globalString = getReceivedMessage();
                String key = globalString.substring(18, 20); //substract the key pressed on the device
                int keyNum = HexString2Int(key); // convert the string to int
                switch (keyNum) {
                    case 1:
                        // code here
                        break;
                    case 2:
                        // code here
                        break;
                    default:
                        break;
                }
            }else {
                try {
                    Log.d(TAG, "else JOIN - in the LOOP");
                    resetConnection();
                    Thread.currentThread().join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }               
            // pause between the loops
            try {Thread.sleep(300);Log.d(TAG, "300 sleeping time");} catch (InterruptedException e) {e.printStackTrace();}
        } // out of while loop
        try {
            resetConnection();
            Thread.currentThread().join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    } // end run()

    private void resetConnection() {
        setState(STATE_NONE);
        Log.d(TAG, "reset connection");
        if (mmInStream != null) {
            try {mmInStream.close();} catch (Exception e) {Log.d(TAG,"exception in closing inputstream - "  + e.getMessage());}
        }
        if (mmOutStream != null) {
            try {mmOutStream.close();} catch (Exception e) {Log.d(TAG,"exception in closing outputstream - " + e.getMessage());}
        }
        if (mmSocket != null) {
            try {mmSocket.close();} catch (Exception e) {Log.d(TAG,"exception in closing socket - " + e.getMessage());}
        }
    }

    public void cancel() {
        try {
            // close connection socket
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed - ConnectedThread cancel()", e);
        }
    }
}

所有这些工作正常,但有时几分钟后(最多 30 分钟)我收到以下错误:

09-20 10:44:31.270: W/bt-btif(883): dm_pm_timer expires
09-20 10:44:31.270: W/bt-btif(883): dm_pm_timer expires 0
09-20 10:44:31.290: W/bt-btif(883): proc dm_pm_timer expires
09-20 10:44:31.310: E/bt-btif(883): bta_dm_pm_btm_status  hci_status=36

有人知道为什么会这样吗?这真的很令人沮丧。我的设备是带有 Android 4.3、内部版本号 JWR66V 的 Nexus 7。我在另一台装有 android 2.3.3 的设备上测试了这个应用程序。日志是不同的,但我想这是同一种错误。

请帮忙!

4

1 回答 1

2

我遇到了同样的问题,我通过创建一个 Keep Alive 线程来解决它,该线程每 0.3 秒在套接字上传输一个字节的数据。我相信问题出在新的 Android 4.3 上,因为我在更新之前没有遇到这个问题。

public class KeepAlive extends Thread{
private ConnectedThread connectedThread;
private final String TAG = "KeepAlive";
private volatile boolean running = true;

public KeepAlive(ConnectedThread connectedThread) {
    this.connectedThread = connectedThread;
    running = true;
}

public synchronized void run() {
    Log.d(TAG,"KeepAlive Thread starting");
    while(running) {

        try {
            wait(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        connectedThread.write('!');
    }
    Log.d(TAG,"KeepAlive Thread closing");
}

public void setRunning(boolean running) {
    this.running = running;
}

}

于 2013-10-02T00:18:23.497 回答