Android:BluetoothSocket 连接抛出 IOException

Posted

技术标签:

【中文标题】Android:BluetoothSocket 连接抛出 IOException【英文标题】:Android: BluetoothSocket connect throws IOException 【发布时间】:2014-03-31 17:15:32 【问题描述】:

我正在编写一个应用程序,它将接收来自另一台设备的串行数据(不是 android,如果重要的话,它将是 Bluesmirf Silver 模块,但现在我只在我的笔记本电脑蓝牙适配器上尝试)。这是我正在使用的代码:

public class ListenThread extends Thread 
    private BluetoothSocket socket;
    private InputStream istream;
    private Handler handler;
    private BluetoothAdapter adapter;

    public ListenThread(BluetoothAdapter adapter, Handler handler) 
        Log.v(TAG, "creating ListenThread");
        this.adapter = adapter;
        this.handler = handler;

        if (adapter.isDiscovering()) 
            adapter.cancelDiscovery();
        
    

    public void run() 
        if (running == false) 
            // Thread is cancelled
            Log.v(TAG, "run(): running == false");
            return;
        

        if (adapter == null) 
            // No BT adapter supplied
            Log.v(TAG, "run(): adapter == null");
            return;
        

        if (btDevice == null) 
            // No btDevice is paired
            Log.v(TAG, "run(): btDevice == null");
            return;
        

        try 

            socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));     
            adapter.cancelDiscovery();
            socket.connect();
            Log.v(TAG, "run(): socket connected");
         catch (IOException e) 
            Log.v(TAG, "run(): socket not connected");
            Log.v(TAG, "IOException: " + e.toString());
            e.printStackTrace();
            socket = null;
         

        if (socket == null) 
            // Connection to device failed
            Log.v(TAG, "run(): socket is null");
            return;
        

        InputStream tmpIn = null;
        try 
            tmpIn = socket.getInputStream();
         catch (IOException e) 
            // getInputStream always returns InputStream
            // but operations will throw IOException until
            // the stream is ready
        
        istream = tmpIn;

        StringBuffer sb = new StringBuffer();
        byte[] buffer = new byte[1024]; // buffer store for the stream
        int bytes;  // bytes returned from the read();
        String message;
        int idx;
        HashMap<String, String> hm;
        String[] chunks;

        Log.v(TAG, "run(): listening loop starting");
        while (true) 
            try 
                // Read from the InputStream
                bytes = istream.read();
                sb.append(new String(buffer, 0, bytes));
                while ((idx = sb.indexOf("\r\n\r\n")) > -1) 
                    message = sb.substring(0, idx);
                    sb.replace(0, idx + 4, "");
                    hm = new HashMap<String, String>();
                    for (String line : message.split("\n")) 
                        chunks = line.trim().split("=", 2);
                        if (chunks.length != 2) continue;
                        hm.put(chunks[0], chunks[1]);
                    
                    handler.obtainMessage(0x2a, hm).sendToTarget();
                
             catch (IOException e) 
                break;
            
        
    

我总是在 socket.connect() 行得到一个 IOException。我尝试了几种建立连接的方法,但都没有成功,但每种方法都抛出了不同的 IO 异常:

方法一:

socket=BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress()).createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

方法二:

socket = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

方法3:

socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

我也试过这样:

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] int.class);
socket = (BluetoothSocket) m.invoke(device, 1);

我总是遇到服务发现失败或连接被拒绝。这就是我管理 ListenThread 的方式:

public void startListening() 
    Log.v(TAG, "starting to listen");
    running = true;     


public void stopListening() 
    Log.v(TAG, "stoping listening");
    running = false;

我搜索了谷歌,但我发现的只是连接套接字的不同方法,但正如我所说,它们都不起作用。任何的想法?非常感谢!

编辑:

这就是 Log.v(TAG, "IOException: " + e.toString());和 e.printStackTrace();打印:

    IOException: java.io.IOException: Service discovery failed
    java.io.IOException: Service discovery failed
    W/System.err(8604):     at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:397)
    W/System.err(8604):     at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:207)
    W/System.err(8604):     at com.ginger.kanarci_android.communication.BluetoothService$ListenThread.run(BluetoothService.java:133)

【问题讨论】:

你能贴一下logcat文件吗? IOException: java.io.IOException: 服务发现失败 java.io.IOException: 服务发现失败 W/System.err(8604): at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket. java:397) W/System.err(8604): 在 android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:207) W/System.err(8604): 在 com.ginger.kanarci_android.communication.BluetoothService$ListenThread。运行(BluetoothService.java:133) 对您的原始问题进行编辑并发布完整的堆栈跟踪 (logcat) :) 我做了 :) 但我不知道我是否发布了与此异常相关的整个日志。我打印了e.toString()和e.printStackTrace(),不知道还有什么。我也觉得有点短…… 您是否尝试过在清单文件中将蓝牙添加到您的权限中? 【参考方案1】:

所以我终于能够做到这一点。唯一的问题是 UUID。在我发布的代码中,我使用了众所周知的 SPP UUID,但我笔记本电脑的蓝牙适配器的 UUID 不同,这就是我认为两者无法连接的原因。

当我配置 Bluesmirf 模块(默认具有 SSP UUID)并尝试从应用程序连接时,它运行良好。

【讨论】:

本周早些时候我遇到了同样的问题,使用的是 en-41。显然,他们有一个专用于 android 的特定 UUID。即使在通过它的串行端口自定义 UUID 之后,与我写的我的 android 地址相同也没有修复它。我不得不接受他们在数据表中的建议。

以上是关于Android:BluetoothSocket 连接抛出 IOException的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中的 BluetoothSocket inputstream.read() 中实现超时

如何在 Android 中实例化 L2Cap 套接字?

Android怎么检测蓝牙的连接状态?如果一段断开,我这边怎么检测得到?

捕获 BluetoothSocket InputStream.read() 超时的线程

为什么BluetoothSocket ConnectAsync会阻止UI线程? [重复]

如何通过蓝牙将 iPhone 连接到本地 Python 客户端?