Android中的蓝牙套接字超时。 HCI_STATUS = 36错误

时间:2013-10-01 21:59:29

标签: android sockets bluetooth

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

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

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

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

在我的ConnectedThread的run()方法中,我有一个while(true)循环,我正在使用这个readWrite方法。然后我得到String响应,并根据响应我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的Nexus 7,内部版本号为JWR66V。我在另一台设备上使用android 2.3.3测试了这款应用。日志是不同的,但我想这是同一种错误。

请帮忙!

1 个答案:

答案 0 :(得分:2)

我有同样的问题,我通过创建一个Keep Alive Thread来解决它,每隔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;
}

}