android - 来自 Android 蓝牙不安全 Rfcomm 的 "Service discovery failed"

标签 android bluetooth insecure-connection

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

详情

我正在尝试在 2 个 Android 设备之间创建不安全的 Rfcomm 连接:Droid X2 和 Asus Transformer。我假设这两种设备都具有 Android 2.3.3 级别的功能,以实际获得使用不安全 Rfcomm 的能力。

当我尝试按照描述创建蓝牙连接时 here ,使用现在公开的 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)

我找到了一个 related question创建普通连接的人收到此错误并使用反射调用私有(private)方法。但是,我不知道什么私有(private)方法现在对应于启动“不安全”连接。我尝试使用该相关问题中提出的解决方案,但 Android 要求我配对设备,这正是我需要避免的。我确实需要不安全的方法。

我什至尝试了概述的官方和黑客解决方案的组合 here

相关代码 fragment

创建 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;

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.");
    }
}

创建 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;

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();
        }

    });

}

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

最佳答案

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

clientSocket.connect()

我需要打电话

btAdapter.cancelDiscovery()

我曾在文档中看到过此问题,但它被列为“性能”问题 - 在我的案例中,这似乎实际上是一个“功能”问题。添加取消发现调用后,套接字连接立即生效。

关于android - 来自 Android 蓝牙不安全 Rfcomm 的 "Service discovery failed",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8515572/

相关文章:

vb.net - 有没有一种安全的方法可以从 Internet 连接到 Active Directory?

带 https 的 SSL 证书

android - 无法恢复 Activity

android - NavigationView 底部有黑条

iphone - 一个可以在wi-fi和蓝牙之间进行选择的项目

ios - 将数据发送到蓝牙模块以供 arduino rom iOS swift 3 读取

Android 蓝牙 IOException :connection refused

android - 如何在创建的 Activity 上再次重新启动线程

android - Activity 布局 : Fragment class: vs android:name attributes