【发布时间】:2018-09-22 09:44:58
【问题描述】:
我有一个应用程序,它通过蓝牙连接到 RaspberryPi,并在接收一些数据时将相同的数据循环给它。
我在连接时遇到了一些问题,因此需要使用此解决方法将我的 Android 手机连接到 RaspberryPi:IOException: read failed, socket might be closed - Bluetooth on Android 4.3
由于某种原因,android 手机正在接收自己的输出。 字符串 "Hello Raspberry. It's me, AndroidPhone" 以永无止境的循环发送到输出。传入的数据(来自 RaspberryPi)也在一个永无止境的循环中被读取。
但不知何故,我不仅接收来自 RaspberryPi 的数据,还接收通过智能手机发送的字符串。这是我的代码:
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter bluetoothAdapter;
UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
@Override
protected void onCreate(Bundle savedInstanceState) {
// (...)
// Only GUI-stuff until this point
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice raspberryPi = bluetoothAdapter.getRemoteDevice("B8:27:EB:56:DC:B2");
BluetoothSocket btSocket;
try {
btSocket = raspberryPi.createRfcommSocketToServiceRecord(SERIAL_UUID);
btSocket.connect();
} catch (IOException e) {
Log.e("BTError", e.getMessage());
// Workaround, found on: https://stackoverflow.com/questions/18657427/ioexception-read-failed-socket-might-closed-bluetooth-on-android-4-3
try {
Log.e("BTError", "Trying fallback...");
btSocket = (BluetoothSocket) raspberryPi.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(raspberryPi, 1);
btSocket.connect();
(new Thread(new SendingThread(btSocket))).start();
(new Thread(new ReceivingThread(btSocket))).start();
} catch (Exception e2) {
Log.e("BTError", e2.getMessage());
Log.e("BTError", "Couldn't establish Bluetooth connection!");
}
}
}
private class SendingThread extends Thread {
private OutputStream out;
public SendingThread(BluetoothSocket btSocket) {
try {
out = btSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
int delay = 100000000;
while (true) {
if (delay == 0) {
Log.i("WRT", "Written to RaspberryPi");
out.write("Hello Raspberry. It's me, AndroidPhone".getBytes());
delay = 100000000;
}
delay--;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ReceivingThread extends Thread {
private InputStream in;
public ReceivingThread(BluetoothSocket btSocket) {
try {
in = btSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
int data = 0;
while (true) {
try {
data = in.read();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("RCV", String.valueOf((char) data));
}
}
}
在 RaspberryPi 端,一切看起来都很正常。一个简单的 java 程序启动 Linux 命令rfcomm listen /dev/rfcomm0 并使用FileReader 和FileWriter 读取/写入文件/dev/rfcomm0。唯一相关的行是:
run {
// Inside writer-thread
bluetoothWriter = new BufferedWriter(new FileWriter("/dev/rfcomm0"));
while(true) {
bluetoothWriter.write("This is RaspPi");
bluetoothWriter.flush();
}
}
和
run {
// Inside reader-thread
bluetoothReader = new BufferedReader(new FileReader("/dev/rfcomm0"));
while(true) {
int incData = bluetoothReader.read();
System.out.print((char) incData);
}
}
感谢您的帮助!
编辑: 仍然没有解决这个问题。我怀疑 RaspberryPi 以某种方式发回了它收到的东西。但是当我禁用它发送任何东西时,智能手机仍然直接接收它发送的东西。
【问题讨论】:
-
你有没有尝试改变调用
createRfcommSocket的反射方法的参数?它应该改变蓝牙套接字的通道,也许这就是问题所在。 -
是的,我已经尝试更改 android 应用程序中使用的频道以及(只是为了完全确定)在 RaspberryPi 上运行的程序使用的频道。遗憾的是它并没有解决问题。
-
您是否尝试过以 30 秒的间隔大幅减少发送,以便真正分析调试器内部的输出和输入?似乎有什么东西在回响。您是否尝试过在来自 rasberry pi 的输出写入消息中添加“我的 rasberry pi 前缀”前缀,以查看您是否在 rasberry pi 上有完整的消息?您还检查了输出和接收的字节十进制值,以比较到达 Rasberri Pi 的内容。我会对到达 rasberry pi 的内容以及“确切发送”的内容更感兴趣。
-
我想说的是,您是否 100% 肯定您已经检查了离开 rasberri pi 的字节并确认它们不包含您的消息。因为如果他们这样做了,那么你的问题就不是 rasberri 方面,也不是 Android。
标签: java android bluetooth android-bluetooth