Android蓝牙不安全Rfcomm的"服务发现失败"

Mat*_*att 13 android bluetooth insecure-connection

有没有人知道如何在API级别2.3.3的2个Android设备之间创建不安全的RFCOMM连接,同时使用任意声明的服务名称?(不是随机或更改服务名称,只是我自己定义的服务名称)

细节

我试图在2个Android设备之间创建一个不安全的Rfcomm连接:Droid X2和华硕Transformer.我假设这两款设备都具有Android 2.3.3级别的功能,实际上可以使用不安全的Rfcomm.

当我尝试按照此处所述创建蓝牙连接时,使用now public createInsecureRfcommSocketToServiceRecord()和listenUsingInsecureRfcommWithServiceRecord(SERVICE,UUID),我得到一个报告:

java.io.IOException: Service discovery failed
at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:377)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:201)
at com.s4d.bluenomad.DeviceConnections$ClientThread.run(DeviceConnections.java:406)
Run Code Online (Sandbox Code Playgroud)

我发现了一个相关的问题,即有人创建正常连接时会收到此错误并使用反射来调用私有方法.但是,我不知道现在的私有方法会对应于启动"不安全"连接.我尝试使用相关问题中提出的解决方案,但Android要求我配对设备,这正是我需要避免的.我确实需要不安全的方法.

我甚至尝试了这里概述的官方和黑客解决方案的组合

相关代码片段

创建ServerThread以侦听连接

Log.i(TAG, "Constructing a ServerThread");
// Use a temporary object that is later assigned to serverSocket,
// because serverSocket is final
BluetoothServerSocket tmp = null;
try {
    // MY_UUID is the app's UUID string, also used by the client code
    tmp = btAdapter.listenUsingInsecureRfcommWithServiceRecord(SERVICE_NAME, SERVICE_UUID);
    Log.i(TAG,"Started listening on insecure RFCOMM channel for service requests for: " + SERVICE_NAME);
} catch (IOException e) { }
serverSocket = tmp;
Run Code Online (Sandbox Code Playgroud)

ServerThread侦听连接

BluetoothSocket socket;
while(true)
{
    try
    {
        socket = serverSocket.accept();
    }
    catch( IOException e)
    {
        break;
    }

    if( socket != null )
    {
        Log.i(TAG, "Received new socket connection requesting service: " + SERVICE_NAME);
    }
    else
    {
        Log.i(TAG, "Socket connection attempted, but socket received is NULL.");
    }
}
Run Code Online (Sandbox Code Playgroud)

创建ClientThread以启动连接

Log.i(TAG, "Constructing a ClientThread");
BluetoothSocket tmp = null;
try {
    // MY_UUID is the app's UUID string, also used by the server code
    tmp = device.createInsecureRfcommSocketToServiceRecord(SERVICE_UUID);
    Log.i(TAG,"Created client socket on insecure RFCOMM channel for service requests for: " + SERVICE_NAME);
} 
catch (IOException e) 
{ 
    Log.i(TAG, "Failed to createInsecureRfcommSocket() against MAC: " + device.getAddress());
}
clientSocket = tmp;
Run Code Online (Sandbox Code Playgroud)

ClientThread连接到服务器

try
{
    clientSocket.connect();
}
catch( final IOException e)
{
    DeviceConnections.this.runOnUiThread(new Runnable()
    {

        @Override
        public void run() 
        {
            console.append("Client unable to connect to service.");
            Log.i(TAG, "Client socket unable to connect() to: " + clientSocket.getRemoteDevice().getAddress());
            e.printStackTrace();
        }

    });

}
Run Code Online (Sandbox Code Playgroud)

我得到日志输出"客户端套接字无法连接()到:[MY_MAC_ADDRESS]",然后我得到"服务发现失败"异常的堆栈跟踪.

Mat*_*att 15

看来问题是在我打电话之前

clientSocket.connect()
Run Code Online (Sandbox Code Playgroud)

我需要打电话

btAdapter.cancelDiscovery()
Run Code Online (Sandbox Code Playgroud)

我在文档中看过这个,但它被列为"性能"问题 - 在我看来,这实际上是一个"功能"问题.添加取消发现调用后,套接字连接立即生效.

  • 我也有同样的问题,我尝试在`sockect.connect()`之前调用`btAdapter.cancelDiscovery()`,但不幸的是它在我的情况下不起作用.我仍然遇到同样的问题.任何的想法? (6认同)

Den*_*ews 5

要检查的一些事情

  • 在客户端和服务器上使用相同且唯一的UUID.
  • 有BLUETOOTH许可
  • 尝试使用标准的着名SPP UUID 00001101-0000-1000-8000-00805F9B34FB

如果您可以将完整日志粘贴到客户端和服务器端打印API错误代码(如果有的话),它也会有所帮助.