Android - 蓝牙打印会在不同设备上从Socket抛出IOException吗?

时间:2015-06-16 00:30:06

标签: java android sockets bluetooth

美好的一天。我正试图通过蓝牙打印到蓝牙热敏打印机。

我之前能够在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

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

任何人都可以帮助我解决我遇到的问题吗?很感谢任何形式的帮助。谢谢。

1 个答案:

答案 0 :(得分: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反射片段填充bt-adapter的频道直到没有人留下导致完全蓝牙失败(我无法找到)的情况下有一个错误相关官方机器人bug报告的链接,但Nexus设备有一个。)