断开Android中的蓝牙套接字
我正在开发一个程序,其中,从Android手机,我必须作为客户端连接到蓝牙医疗传感器。 我正在使用官方蓝牙API,连接时没有问题(SPPconfiguration文件),但是当我结束套接字时,传感器仍然连接到我的手机(虽然我已经closures了连接)。
有什么办法让蓝牙断线? 我认为有一个名为ACTION_ACL_CONNECTED的意图,这样做。 任何人都可以解释我如何使用这个?
提前致谢。
编辑:这是代码,如果任何人需要额外的信息,这是一个Nonin 4100医疗传感器。
Set<BluetoothDevice> pairedDevices = Activa.myBluetoothAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { // Add the name and address to an array adapter to show in a ListView String name = device.getName(); if (name.contains("Nonin")) { try { found = true; // socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); // handler.sendEmptyMessage(5); // Activa.myBluetoothAdapter.cancelDiscovery(); // socket.connect(); BluetoothDevice hxm = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress()); Method m; try { m = hxm.getClass().getMethod("createRfcommSocket", new Class[]{int.class}); socket = (BluetoothSocket)m.invoke(hxm, Integer.valueOf(1)); handler.sendEmptyMessage(5); socket.connect(); } catch (Exception e) { handler.sendEmptyMessage(7); e.printStackTrace(); break; } handler.sendEmptyMessage(6); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); byte[] retrieve = { 0x44, 0x31}; out.write(retrieve); byte [] ack = new byte [1]; in.read(ack); if (ack[0] == 0x15) { cancelMeasurement(); return; } byte [] data = new byte [3]; long timeStart = System.currentTimeMillis(); this.timePassed = System.currentTimeMillis() - timeStart; while ((this.timePassed < (this.time))&&(this.finished)) { try { in.read(data); processData(data); Thread.sleep(1000); this.timePassed = System.currentTimeMillis() - timeStart; } catch (Exception e) { e.printStackTrace(); } } in.close(); out.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
请记得先closuresinput/输出stream,然后closures套接字。
通过closuresstream,您启动断开连接过程。 closures套接字后,连接应完全分解。
如果在stream之前closures套接字,则可能会绕过某些closures步骤,例如(正确)closures物理层连接。
这是我用它来分解连接的方法。
/** * Reset input and output streams and make sure socket is closed. * This method will be used during shutdown() to ensure that the connection is properly closed during a shutdown. * @return */ private void resetConnection() { if (mBTInputStream != null) { try {mBTInputStream.close();} catch (Exception e) {} mBTInputStream = null; } if (mBTOutputStream != null) { try {mBTOutputStream.close();} catch (Exception e) {} mBTOutputStream = null; } if (mBTSocket != null) { try {mBTSocket.close();} catch (Exception e) {} mBTSocket = null; } }
编辑:添加连接()的代码:
// bluetooth adapter which provides access to bluetooth functionality. BluetoothAdapter mBTAdapter = null; // socket represents the open connection. BluetoothSocket mBTSocket = null; // device represents the peer BluetoothDevice mBTDevice = null; // streams InputStream mBTInputStream = null; OutputStream mBTOutputStream = null; static final UUID UUID_RFCOMM_GENERIC = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); /** * Try to establish a connection with the peer. * This method runs synchronously and blocks for one or more seconds while it does its thing * SO CALL IT FROM A NON-UI THREAD! * @return - returns true if the connection has been established and is ready for use. False otherwise. */ private boolean connect() { // Reset all streams and socket. resetConnection(); // make sure peer is defined as a valid device based on their MAC. If not then do it. if (mBTDevice == null) mBTDevice = mBTAdapter.getRemoteDevice(mPeerMAC); // Make an RFCOMM binding. try {mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(UUID_RFCOMM_GENERIC); } catch (Exception e1) { msg ("connect(): Failed to bind to RFCOMM by UUID. msg=" + e1.getMessage()); return false; } msg ("connect(): Trying to connect."); try { mBTSocket.connect(); } catch (Exception e) { msg ("connect(): Exception thrown during connect: " + e.getMessage()); return false; } msg ("connect(): CONNECTED!"); try { mBTOutputStream = mBTSocket.getOutputStream(); mBTInputStream = mBTSocket.getInputStream(); } catch (Exception e) { msg ("connect(): Error attaching i/o streams to socket. msg=" + e.getMessage()); return false; } return true; }
我发现如果在通过OutputStream进行最近一次通信后过早地调用socket.close(),那么closures失败,我无法重新连接。 我在close()调用之前添加了一个Thread.sleep(1000),这似乎解决了这个问题。
HI,
我见过完全相同的问题(HTC Desire)。 尽pipeclosures了本书的套接字(就像Brad所说的那样),但下一个connect()会永远封锁 – 直到被另一个线程closures()结束。
我通过在连接之前始终调用BluetoothAdapter.disable()/。enable()来规避问题。 可怕的,不友好的黑客,我知道…
我怀疑目前的一些BT问题是制造商特定的,因为一些应用程序的实现者似乎愉快地与createRfcommSocketToServiceRecord(),我的HTC Desire(Android 2.1更新1)失败。
我已经看到了HTC Desire的BT堆栈与Nexus One不同的迹象(对不起,没有参考),虽然他们似乎是非常相似的设备…
BR Per
(另外)这是一个非常简单的活动来重现问题(没有我的禁用/启用'治愈'):
package com.care2wear.BtTest; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.os.Bundle; import android.util.Log; import android.widget.TextView; public class BtTestActivity extends Activity { private static final String TAG="BtTest"; BluetoothAdapter mBtAdapter = null; BluetoothDevice mBtDev = null; BluetoothSocket mBtSocket = null; InputStream isBt; OutputStream osBt; String mAddress = "00:18:E4:1C:A4:66"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); connect(); // ok disconnect(); // ok connect(); // this invariably fails - blocked until BT is switched off by someone else, or the peer device turns off/goes out of range disconnect(); } private void init() { Log.d(TAG, "initializing"); mBtAdapter = BluetoothAdapter.getDefaultAdapter(); mBtDev = mBtAdapter.getRemoteDevice(mAddress); Log.d(TAG, "initialized"); } private void connect() { try { Log.d(TAG, "connecting"); Method m = mBtDev.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); mBtSocket = (BluetoothSocket) m.invoke(mBtDev, 1); mBtSocket.connect(); Log.d(TAG, "connected"); } catch (SecurityException e) { Log.e(TAG, "SecEx", e); } catch (NoSuchMethodException e) { Log.e(TAG, "NsmEx", e); } catch (IllegalArgumentException e) { Log.e(TAG, "IArgEx", e); } catch (IllegalAccessException e) { Log.e(TAG, "IAccEx", e); } catch (InvocationTargetException e) { Log.e(TAG, "ItEx", e); } catch (IOException e) { Log.e(TAG, "IOEx", e); } } private void disconnect() { Log.d(TAG, "closing"); if (isBt != null) { try { isBt.close(); } catch (IOException e) { Log.e(TAG, "isBt IOE", e); } isBt = null; } if (osBt != null) { try { osBt.close(); } catch (IOException e) { Log.e(TAG, "osBt IOE", e); } osBt = null; } if (mBtSocket != null) { try { mBtSocket.close(); } catch (IOException e) { Log.e(TAG, "socket IOE", e); } mBtSocket = null; } Log.d(TAG, "closed"); } }
如果任何人可以发现,如果我做错了,随时评论:)
(另外2)我想我现在开始工作:
- 目前正式的连接RFCOMM(通过SDP)的方法实际上似乎工作(HTC Desire,2.1更新1), 但我不得不删除和重新配对的BT设备。 去搞清楚..
- 重新连接可能仍然失败(服务发现失败),如果我“重新连接太快”(退出应用程序,然后立即重新启动)。 猜猜连接还没有完全closures..
- 如果我总是不仅用finish()结束(最后)活动,而且用Runtime.getRuntime()。exit(0)结束(最后)活动,效果会好很多。 再次去图…
如果有人能解释这一点,我会很高兴地学习。 /每
(另外3)终于得到了我的欲望Froyo(2.2)更新,据我所知,SPP现在工作:) /每
我正在开发一个适用于BT设备的应用程序。 您的代码在HTC Wildfire中正常工作,但Samsung Galaxy I5700无法正常工作。 这两个操作系统是2.1更新,但…..
例外是“InvocationTargetException”
我唯一需要修改的是disconnect()。
private void disconnect() { if(Conectado){ try { ***mBtSocket.close();*** texto.setText(texto.getText()+"\nDesconectado"); Conectado = false; } catch (IOException e1) { // TODO Auto-generated catch block texto.setText(texto.getText()+"\n"+e1.getMessage()); } catch (Exception e2) { // TODO Auto-generated catch block texto.setText(texto.getText()+"\n"+e2.getMessage()); } }
嘿所以我一直在使用Android开发网站的蓝牙聊天应用程序,他们在BluetoothChatService类中提供了一个stop()
方法。 所以我只是在我的主类中创build了一个实例,并从断开连接button中调用了停止function。
这是我在我的主课堂中如何调用它
//聊天服务的成员对象
private BluetoothManager mChatService = null; case R.id.disconnect: mChatService.stop(); break;
BluetoothChatService中的stop()方法
private AcceptThread mAcceptThread; private ConnectThread mConnectThread; public synchronized void stop() { if (mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; } if (mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; } if (mAcceptThread != null) { mAcceptThread.cancel(); mAcceptThread = null; } }
我有同样的问题。 这是蓝牙模块CSR BC417的问题,出现在许多设备中,与SPPconfiguration文件串行到蓝牙适配器。 与另一个蓝牙模块的Android设备工作正常,并且蓝牙在socketsclosures后释放连接,但与此CSR芯片的设备不是。 基于CSR BC417的SPP蓝牙到串行适配器的testing以及来自Actisys的蓝牙模块。 与Android 4.0设备。 我不知道为什么,但是是硬件之间的兼容性问题,尝试改变另一个核心的另一个串行适配器。 我尝试编程寻找解决scheme,甚至禁用蓝牙,但是不可能,麻烦源于CSR模块。