我在使用不安全的RFCOMM連接配接連接配接到WML-C46 AH Bluetooth Chip時遇到問題。我用相關的代碼寫了一個android應用程式來向你展示我的問題。Android滞後/不穩定的藍牙連接配接
應用程式
該應用程式隻有一個按鈕。如果你點選這個按鈕,就開始藍牙裝置發現。發現完成後,應用程式連接配接到藍牙裝置(我隻使用一個藍牙裝置進行測試,是以無法找到任何其他裝置)。然後打開一個輸入流來讀取這個裝置的資料。如果連接配接中斷(引發ioexception)或再次單擊該按鈕,則關閉連接配接(關閉所有線程,套接字和流)。如果你點選一次按鈕新的裝置發現啟動等等......
的問題
連接配接不能正常工作。資料輸入流似乎有點滞後,有時連接配接斷開而沒有任何可觀察的原因(IOException:軟體導緻連接配接中止或IOException:請再試一次)。這幾乎是Android藍牙聊天示例的簡化版本,它使用裝置發現而不是配對的裝置,僅使用一項活動。
守則
public class MainActivity extends Activity implements View.OnClickListener {
BluetoothDevice btDevice;
BluetoothSocket btSocket;
InputStream inStream;
OutputStream outStream;
Object lock = new Object();
boolean connected = false;
boolean canceled = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(this);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
getApplicationContext().registerReceiver(btReceiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
getApplicationContext().registerReceiver(btReceiver, filter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View arg0) {
if (!connected) {
connected = true;
canceled = false;
new Thread(new Runnable() {
@Override
public void run() {
BluetoothAdapter btAdapter = BluetoothAdapter
.getDefaultAdapter();
try {
if (btAdapter.isDiscovering())
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
// block until device discovery has finished
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
Log.d("EXCEPTION", "", e);
}
}
btSocket = btDevice.createInsecureRfcommSocketToServiceRecord(UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB"));
btSocket.connect();
inStream = btSocket.getInputStream();
outStream = btSocket.getOutputStream();
new Thread(new Runnable() {
@Override
public void run() {
while (!canceled) {
try {
int in;
while ((in = inStream.read()) != -1) {
Log.d("Received new byte: ", in
+ "");
}
} catch (IOException e) {
Log.d("EXCEPTION IN LISTENER", "", e);
disconnect();
}
}
}
}).start();
} catch (IOException e) {
Log.d("", "", e);
}
}
}).start();
} else {
disconnect();
}
}
private void disconnect() {
connected = false;
canceled = true;
try {
btSocket.close();
} catch (Exception e) {
Log.d("EXCEPTION DISCONNECTING", "", e);
}
try {
inStream.close();
} catch (Exception e) {
Log.d("EXCEPTION DISCONNECTING", "", e);
}
try {
outStream.close();
} catch (Exception e) {
Log.d("EXCEPTION DISCONNECTING", "", e);
}
btDevice = null;
btSocket = null;
inStream = null;
outStream = null;
}
private final BroadcastReceiver btReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
try {
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
synchronized (lock) {
lock.notifyAll();
}
}
} catch (Exception e) {
Log.d(this.getClass().getName(), "", e);
}
}
};
}
我隻使用屏蔽方法或自己做的阻塞。是以連接配接建立工作非常程式化。當我改編它時,我可能已經失去了android示例的連接配接流程,但我找不到問題。
輸出
建立連接配接:
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketNative
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): ...fd 47 created (RFCOMM, lm = 0)
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketFromFdNative
01-16 16:52:46.257: D/BluetoothUtils(6961): isSocketAllowedBySecurityPolicy start : device null
01-16 16:52:47.171: V/BluetoothSocket.cpp(6961): connectNative
01-16 16:52:47.570: V/BluetoothSocket.cpp(6961): ...connect(47, RFCOMM) = 0 (errno 115)
連接配接中斷:
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): java.io.IOException: Software caused connection abort
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): at android.bluetooth.BluetoothSocket.readNative(Native Method)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:388)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:60)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): at com.example.bttest.MainActivity$2$1.run(MainActivity.java:100)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): at java.lang.Thread.run(Thread.java:856)
謝謝!