我正在尝试通过蓝牙连接两个设备。配对过程是通过android原生的东西完成的,这意味着我只需要获取套接字本身并在此套接字上调用.connect()。
目标是创建一个蓝牙系统来处理主/工关系(几个工人将数据发送给主人)。
到目前为止,这是我的代码:
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
public final class BluetoothLogic {
private final Handler mHandler;
public BluetoothLogic(Handler handler) {
mHandler = handler;
}
@Nullable
public ConnectedThread getMaster() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.cancelDiscovery();
ArrayList<BluetoothDevice> pairedDevices = new ArrayList<>(bluetoothAdapter.getBondedDevices());
if (pairedDevices.size() > 0) {
BluetoothDevice device = pairedDevices.get(0);
BluetoothSocket socket = null;
try {
socket = device.createRfcommSocketToServiceRecord(device.getUuids()[0].getUuid());
socket.connect();
return new ConnectedThread(socket);
} catch (IOException e) {
e.printStackTrace();
try {
if(socket != null) {
socket.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
return null;
} else {
Log.d(BluetoothLogic.class.getName(), "No connected devices");
return null;
}
}
@Nullable
public ArrayList<ConnectedThread> getWorker() {
ArrayList<ConnectedThread> threads = new ArrayList<>();
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.cancelDiscovery();
ArrayList<BluetoothDevice> pairedDevices = new ArrayList<>(bluetoothAdapter.getBondedDevices());
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
BluetoothSocket socket = null;
try {
socket = device.createRfcommSocketToServiceRecord(device.getUuids()[0].getUuid());
socket.connect();
threads.add(new ConnectedThread(socket));
} catch (IOException e) {
e.printStackTrace();
try {
if(socket != null) {
socket.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
if(!threads.isEmpty()) {
return threads;
} else {
return null;
}
} else {
Log.d(BluetoothLogic.class.getName(), "No connected devices");
return null;
}
}
public class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = mmSocket.getInputStream();
tmpOut = mmSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[20]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(0, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
}
我的例外:
04-28 21:29:09.165 11213-11324/com.thm.sensors W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
04-28 21:29:09.342 11213-11236/com.thm.sensors D/OpenGLRenderer: endAllStagingAnimators on 0xaec45800 (RippleDrawable) with handle 0xaee0dfd0
04-28 21:29:09.470 11213-11324/com.thm.sensors W/System.err: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
04-28 21:29:09.471 11213-11324/com.thm.sensors W/System.err: at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:684)
04-28 21:29:09.471 11213-11324/com.thm.sensors W/System.err: at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:643)
04-28 21:29:09.471 11213-11324/com.thm.sensors W/System.err: at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:377)
04-28 21:29:09.471 11213-11324/com.thm.sensors W/System.err: at com.thm.sensors.logic.BluetoothLogic.getMaster(BluetoothLogic.java:37)
04-28 21:29:09.472 11213-11324/com.thm.sensors W/System.err: at com.thm.sensors.activity.WorkerActivity$1.doInBackground(WorkerActivity.java:70)
04-28 21:29:09.472 11213-11324/com.thm.sensors W/System.err: at com.thm.sensors.activity.WorkerActivity$1.doInBackground(WorkerActivity.java:65)
04-28 21:29:09.472 11213-11324/com.thm.sensors W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
04-28 21:29:09.472 11213-11324/com.thm.sensors W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
04-28 21:29:09.472 11213-11324/com.thm.sensors W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
04-28 21:29:09.472 11213-11324/com.thm.sensors W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
04-28 21:29:09.472 11213-11324/com.thm.sensors W/System.err: at java.lang.Thread.run(Thread.java:818)
我还尝试使用以下方法实现经常建议的解决方案:
createMethod = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] { int.class });
sock = (BluetoothSocket)createMethod.invoke(device, 1);
我用于测试的两个设备是Nexus 5和Nexus 5X。我希望有人能帮助我解决我的问题。 :)
更新
根据logcat,套接字在打开之前就已关闭:
.....
04-30 20:53:56.022 4754-4754/? I/BTConnectionReceiver: onReceive(context, Intent { act=android.bluetooth.device.action.ACL_CONNECTED flg=0x4000010 cmp=com.google.android.googlequicksearchbox/com.google.android.search.core.service.BluetoothConnectionReceiver (has extras) }, [BluetoothDevice: address=CC:FA:00:54:17:51, alias=null, name=Nexus 5, majorDeviceClass=512, deviceClass=524]
04-30 20:53:56.025 4754-4754/? I/BluetoothClassifier: Bluetooth Device Name: Nexus 5
04-30 20:53:56.308 5785-5849/? W/bt_rfcomm: port_rfc_closed RFCOMM connection in state 1 closed: Closed (res: 19)
04-30 20:53:56.309 10462-10462/com.thm.sensors W/System.err: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
04-30 20:53:56.309 5785-5853/? E/bt_btif_sock_rfcomm: find_rfc_slot_by_id unable to find RFCOMM slot id: 8
....
这怎么可能?