【问题标题】:Bluetooth printing throws an IOException from the Socket across different devices蓝牙打印从不同设备的 Socket 中抛出 IOException
【发布时间】:2015-06-16 00:30:06
【问题描述】:

我正在尝试通过蓝牙打印到热敏打印机。

我之前能够在 Nexus 7 设备(第一代和第二代)上成功打印。但是,当我将完全相同的代码复制粘贴到不同的应用程序并将其部署到华硕平板电脑上时,我突然收到一个IOException,告诉我我的套接字可能已关闭。

这是我的代码:

public void onPrintReceipt(){

    Toast.makeText(getApplicationContext(), "Printing", Toast.LENGTH_LONG).show();

    try{
        Set<BluetoothDevice> bdevices = bluetoothAdapter.getBondedDevices();
        blueToothDevice = bluetoothAdapter.getRemoteDevice("00:01:90:EE:B2:52");

        simpleComm(1);
    }
    catch(Exception ex){
        Log.e("", "simpleComm() Catch Statement Entered");
    }
}


protected void simpleComm(Integer port){

    //InputStream tmpIn = null;
    byte[] buffer = new byte[3]; //{65,65,53,53,49,52,65,66,67,68};

    buffer[0] = (byte) 0x08;
    buffer[1] = (byte) 0x99;
    buffer[2] = (byte) 0x04;
    OutputStream tmpOut;// = null;

    bluetoothAdapter.cancelDiscovery();

    Log.e(this.toString(), "Port = " + port);
    try {


        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
        Method m = blueToothDevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });

        socket = (BluetoothSocket) m.invoke(blueToothDevice, port);

        // assert (socket != null) : "Socket is Null";
        if(socket.isConnected()){
            socket.close();
        }
        socket.connect();

        try {

            Log.e(this.toString(), "************ CONNECTION SUCCEES! *************");
            try{
                //tmpIn=socket.getInputStream();
                tmpOut = socket.getOutputStream();

                //mmInStream = tmpIn;
                mmOutStream = tmpOut;
                out = new BufferedWriter(new OutputStreamWriter(mmOutStream));

            }
            catch(Exception ex){
                Log.e(this.toString(), "Exception " + ex.getMessage());
            }

            //TODO print sequence starts here

            //....snip snip a LOT of code

        }
        finally{

            mmOutStream.flush();

            mmOutStream.close();
            socket.close();

        }

    }
    catch (IOException ex){
        Log.e(this.toString(), "IOException: " + ex.getMessage());
    }
    catch (NoSuchMethodException ex){
        Log.e(this.toString(), "NoSuchMethodException: " + ex.getMessage());
    }
    catch (IllegalAccessException ex){
        Log.e(this.toString(), "IllegalAccessException: " + ex.getMessage());
    }
    catch (InvocationTargetException ex){
        Log.e(this.toString(), "InvocationTargetException: " + ex.getMessage());
    }

}

这是来自 try-catch 块的错误:

IOException: read failed, socket might closed or timeout, read ret: -1

现在我很困惑,为什么我所做的只是将代码部署在不同的设备上时突然出现错误。

我该如何继续?

【问题讨论】:

  • “现在我很困惑,为什么我所做的只是在不同的设备上部署代码时突然出现错误。” 因为 BT 的编码很糟糕。不同的设备/型号/版本之间可能会有所不同。但是connect() 会发生什么?似乎有些东西没有正确执行。
  • @codeMagic 似乎就是这样。我刚刚将我在 Acer 平板电脑上尝试运行的完全相同的代码运行到我的 Nexus 7 设备上。 Nexus 7 设备通过蓝牙打印到热敏打印机没有问题。看起来有一些较低级别的交互即将到来。
  • Tell me 关于它....Bt is fun!。但它似乎仍然与您的 connect() 方法有关。也许可以更改其中的某些内容以使其正常工作。

标签: java android sockets bluetooth


【解决方案1】:

我看到您使用反射来创建您的 RFCOMM 连接。这很危险,我最近回答了一个这方面的问题:How do Bluetooth SDP and UUIDs work? (specifically for Android)

Tl;dr:您正在绕过 SDP 查找机制,该机制将 UUID 映射到您连接到的设备上的适当蓝牙通道。您的代码始终连接到蓝牙通道 1。这可能在最初/某些情况下有效 - 但也可能是您的问题。这取决于接收设备。

您正在创建一个 UUID。我猜(希望)你从打印机的文档中得到它?但是,如果您检查您的代码,您会发现您没有使用它来连接打印机 - 您绝对应该这样做(请参阅链接的答案,了解整个故事)。使用createRfcommSocketToServiceRecord(uuid) 打开您的套接字。

由于您使用的是 Nexus 7:我使用了两台 Nexus 7、一台 Nexus 4 和 10 台其他设备来测试我写的 bluetooth middleware for android。特别是 Nexus 设备非常敏感,当蓝牙受到许多并发呼叫的压力时,导致蓝牙适配器完全无用,直到我重新启动它们。另外,我想记住,当我使用这个 hacky 反射 sn-p 填充 bt 适配器的通道直到没有人离开导致蓝牙完全故障时,存在一个错误(我无法找到指向相关的官方 android 错误报告,但有一个适用于 Nexus 设备)。

【讨论】:

  • 感谢提供线索,我一定会调查的!
猜你喜欢
  • 2013-09-02
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多