我看到很多关于蓝牙问题/蓝牙超时的问题,但没有一个帮助我。
我正在开发一个应用程序,用于向/从另一个蓝牙设备发送和接收数据。我每秒发送约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测试了这款应用。日志是不同的,但我想这是同一种错误。
请帮忙!
答案 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;
}
}