gpt4 book ai didi

android-bluetooth - Bluetooth ServerSocket accept() 在 HTC Desire 上不返回

转载 作者:行者123 更新时间:2023-11-30 03:22:24 28 4
gpt4 key购买 nike

我正在基于著名的 BluetoothChat 示例开发具有蓝牙功能的应用程序。基本上,使用此应用程序,客户端可以向服务器发送一些数据包。

我已经使用两部 Xperia 智能手机(Xperia X8 和 Xperia Sola,android 2.1 和 4.0)测试了该应用程序,一切正常:它们都可以充当客户端或服务器。

不幸的是,如果我使用 HTC Desire (android 2.3) 作为服务器,它将无法接受来自 Xperia 客户端之一的传入连接。似乎客户端 connect() 返回时一切正常,但服务器却在其 accept() 上被阻塞,就好像什么都没发生一样。

相关代码 fragment :

<强>1。 “接受话题”

private class BluetoothAcceptThread extends Thread
{
private final BluetoothServerSocket serverSocket;

public BluetoothAcceptThread()
{
BluetoothServerSocket tmpSocket = null;

try
{
Method m = bluetoothAdapter.getClass().getMethod("listenUsingRfcommOn", new Class[] {int.class});
tmpSocket = (BluetoothServerSocket) m.invoke(bluetoothAdapter, APP_BT_CHANNEL);
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothAcceptThread listen() (with reflection) failed", e);
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}

serverSocket = tmpSocket;
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread ServerSocket created");
}

@Override
public void run()
{
BluetoothSocket socket = null;

try
{
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread calling accept()...");
socket = serverSocket.accept();
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread accept() returned");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothAcceptThread accept() failed: " + e.getMessage());
}

if (socket != null)
{
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread accept() successfully");

synchronized (BluetoothManager.this)
{
if (currentState == SocketState.LISTENING || currentState == SocketState.CONNECTING)
startBluetoothConnection(socket); // all is ok, it can proceed

else if (currentState == SocketState.INACTIVE || currentState == SocketState.CONNECTED)
cancel(socket);
}
}
}

@Override
public void cancel()
{
try
{
serverSocket.close();
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread ServerSocket closed");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothAcceptThread close() failed", e);
}
}

private void cancel(BluetoothSocket newSocket)
{
try
{
newSocket.close();
Log.d(MainActivity.DEBUG_TAG, "BluetoothAcceptThread client socket closed");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothAcceptThread client socket close() failed", e);
}
}
}

<强>2。 “连接线程”

private class BluetoothConnectThread extends Thread
{
private final BluetoothSocket socket;
private final BluetoothDevice device;

public BluetoothConnectThread(BluetoothDevice d)
{
device = d;
BluetoothSocket tmpSocket = null;

try
{
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmpSocket = (BluetoothSocket) m.invoke(device, APP_BT_CHANNEL);
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothConnectThread create() (with reflection) failed", e);
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}

socket = tmpSocket;
Log.d(MainActivity.DEBUG_TAG, "BluetoothConnectThread client socket created");
}

@Override
public void run()
{
stopBluetoothDiscovery(); // otherwise it will slow down the connection

try
{
socket.connect();
Log.d(MainActivity.DEBUG_TAG, "BluetoothConnectThread connect() successfully");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothConnectThread connect() failed", e);
String deviceName = device != null ? device.getName() : "none";
connectionFailed(deviceName); // notify UI thread
return;
}

synchronized (BluetoothManager.this)
{
bluetoothConnectThread = null;
}

startBluetoothConnection(socket); // create the "Communication" Thread
}

@Override
public void cancel()
{
try
{
socket.close();
Log.d(MainActivity.DEBUG_TAG, "BluetoothConnectThread client socket closed");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothConnectThread close() failed", e);
}
}
}

<强>3。 “通信线程”(在 BluetoothChat 示例中又称为 ConnectedThread)

private class BluetoothCommunicationThread extends Thread
{
private final BluetoothSocket socket;
private final InputStream inputStream;
private final OutputStream outputStream;

public BluetoothCommunicationThread(BluetoothSocket s)
{
socket = s;
InputStream in = null;
OutputStream out = null;

try
{
in = socket.getInputStream();
out = socket.getOutputStream();
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothCommunicationThread failed to get streams", e);
}

inputStream = in;
outputStream = out;
}

@Override
public void run()
{
byte[] buffer = new byte[BT_BUFF_SIZE];
int readBytes;

while (true)
{
try
{
readBytes = inputStream.read(buffer, 0, buffer.length);

if (readBytes != -1)
{
Message message = messageHandler.obtainMessage(DATA_MSG, readBytes, -1, buffer);
message.sendToTarget(); // notify to UI thread the bytes counter
}
else
{
BluetoothDevice device = socket.getRemoteDevice();
String deviceName = device != null ? device.getName() : "none";
connectionLost(deviceName);
break;
}
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothCommunicationThread read() failed", e);
BluetoothDevice device = socket.getRemoteDevice();
String deviceName = device != null ? device.getName() : "none";
connectionLost(deviceName);
break;
}
}
}

public void write(byte[] buffer)
{
try
{
outputStream.write(buffer);
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothCommunicationThread write() failed", e);
}
}

@Override
public void cancel()
{
try
{
socket.close();
Log.d(MainActivity.DEBUG_TAG, "BluetoothCommunicationThread socket closed");
}
catch (IOException e)
{
Log.e(MainActivity.ERROR_TAG, "BluetoothCommunicationThread close() failed", e);
}
}
}

所以问题的步骤如下:

  1. HTC Desire 服务器调用 accept()
  2. Xperia 客户端调用 connect()
  3. connect 返回,就像连接已建立一样
  4. HTC 上没有发生任何事情,总是在 accept()
  5. 上被阻塞
  6. Xperia 客户端认为它已连接,因此它创建 CommunicationThread 并调用阻塞 read();此函数抛出 java.io.IOException: Software caused connection abort,可能是因为套接字未连接。

最后这些是相关的 logcats:

Xperia 客户端:

09-20 00:44:23.562    9106-9106/com.powertester D/[PowerTester Debug]﹕ BluetoothConnectThread client socket created
09-20 00:44:25.704 9106-9579/com.powertester D/[PowerTester Debug]﹕ BluetoothConnectThread connect() successfully
09-20 00:44:25.734 9106-9579/com.powertester D/[PowerTester Debug]﹕ BluetoothCommunicationThread started and I/O streams ready
09-20 00:44:25.764 9106-9589/com.powertester E/[PowerTester Error]﹕ BluetoothCommunicationThread read() failed
java.io.IOException: Software caused connection abort
at android.bluetooth.BluetoothSocket.readNative(Native Method)
at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:333)
at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)
at com.powertester.net.BluetoothManager$BluetoothCommunicationThread.run(BluetoothManager.java:518)
09-20 00:44:25.844 9106-9106/com.powertester D/[PowerTester Debug]﹕ BluetoothCommunicationThread socket closed

HTC 服务器:

09-19 15:47:07.591    2422-2422/com.powertester D/[PowerTester Debug]﹕ BluetoothAcceptThread ServerSocket created
09-19 15:47:07.591 2422-2484/com.powertester D/[PowerTester Debug]﹕ BluetoothAcceptThread calling accept()...

真正奇怪的是,HTC Desire 工作如果用作客户端,其中一台 Xperia 用作服务器。

那么,是我的应用程序有问题还是 HTC Desire 蓝牙堆栈有问题?

最佳答案

经过一些麻烦后,我意识到问题出在反射本身和蓝牙 channel 的显式使用上。

使用正常方式(即 the not-hidden bluetooth methods )我的应用程序运行完美。

关于android-bluetooth - Bluetooth ServerSocket accept() 在 HTC Desire 上不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18905973/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com