简体   繁体   English

使用InputStream.read()后蓝牙传输应用程序停止,没有错误

[英]Bluetooth transfer App stops after using InputStream.read() with no error

I am trying to make a file transfer Bluetooth app work using these sources: 我正在尝试使用以下来源制作文件传输蓝牙应用程序:

http://developer.android.com/guide/topics/connectivity/bluetooth.html http://developer.android.com/guide/topics/connectivity/bluetooth.html

https://android.googlesource.com/platform/development/+/25b6aed7b2e01ce7bdc0dfa1a79eaf009ad178fe/samples/BluetoothChat/ https://android.googlesource.com/platform/development/+/25b6aed7b2e01ce7b​​dc0dfa1a79eaf009ad178fe/samples/BluetoothChat/

When I attempt to get the InputStream bytes using InputStream.read() method this way: 当我尝试使用InputStream.read()方法以这种方式获取InputStream字节时:

public class ConnectedThread extends Thread {

...(some code here)

public void run(){

        byte[] buffer = new byte[1024];
        int bytes = -1;

        //Keep listening to the InputStream while connected
        while (true){

            try {

                bytes = this.mmInStream.read(buffer);

                //* this part is not reached
                if (bytes==-1){
                    Log.d("NoData:","-1");  
                }

            }
            catch(Exception e){
                Log.d("inStream exception:",e.getMessage());
                break;
            }

        }

    }

...(some code here)

}

The next part of the code ( "if" part in this case) is never reached, nor a Log.D debug output or whatever else I put in following. 永远不会到达代码的下一部分(在这种情况下为"if"部分),也不会出现Log.D调试输出或我放入的其他任何内容。 I just get this message from LogCat: 我刚从LogCat收到此消息:

BluetoothSocket read in: android.net.LocalStocketImpl$SocketInputStream@f7e
                b08 len: 1024

To transfer the data from the Client to the Server I am doing this: 要将数据从客户端传输到服务器,我这样做:

public class MainActivity extends Activity {

...(some code here)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    clientConnect();
    //serverConnect();

}

...(some code here)

public void clientConnect(){

        Set<BluetoothDevice> devices;

        devices = bConfig.getPairedDevices(); 

        if (devices == null){                   
            return;
        }

        if (devices.size() > 0) {           

            BluetoothDevice device = devices.iterator().next();

            ConnectThread connectTransmit = new ConnectThread(device,bConfig.getBluetoothAdapter(),BluetoothConfig.mUUID);
            connectTransmit.start();

            Toast.makeText(this, "connected", Toast.LENGTH_SHORT).show();

            socket = connectTransmit.mmSocket;
            ConnectedThread connectedThread = new ConnectedThread(socket);

            //write file bytes to the connected thread, so the thread can receive its own input written bytes later
            File file_to_transfer = new File(Environment.getExternalStorageDirectory() + "/txtTransfer.txt");           

            //get bytes from our File
            int size = (int) file_to_transfer.length();
            byte[] bytes = new byte[size];

            try {

                //14b are read succesfully, the whole text file 
                BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file_to_transfer));
                buf.read(bytes,0,bytes.length);
                buf.close();                

            }catch (FileNotFoundException e){
                Log.d("FileNotFoundException:",e.getMessage());
            }catch (IOException e){ 
                Log.d("IOException:",e.getMessage());
            }

            //send the data to the server
            connectedThread.start();
            connectedThread.write(bytes);
            //connectedThread.cancel();

        }

    }

...(some code here)

}

The AcceptThread (Server part of the implementation) works, because when I run the client part to connect and then transfer the data, while debuging in the device the LogCat on the Server part activates and reaches the run method of the thread, where I call the ConnectedThread implementation but then after it "apparently" reads the bytes but it gets stuck on LogCat with no error. AcceptThread (实现的服务器部分)工作,因为当我运行客户端部分连接然后传输数据时,在设备中进行调试时,服务器部分上的LogCat激活并到达线程的run方法,我调用ConnectedThread实现,但之后“显然”读取字节但它在LogCat上卡住而没有错误。

Please let me know what can I do to finish reading the bytes to move to the next part of the flow. 请让我知道如何完成读取字节以移动到流程的下一部分。

Thank you 谢谢

You're blocked waiting for more input. 您被阻止等待更多输入。

The part labelled ... (some code here) should be inside the read loop, after the test for end of stream. 在流结束测试之后,标记为... (some code here)的部分... (some code here)应该在读取循环内 NB If read() returns -1 it doesn't mean 'no data', it means end of stream, and you should close the socket and break out of the read loop. 注意如果read()返回-1并不表示“没有数据”,则表示流结束,您应该关闭套接字并中断读取循环。 Otherwise you should then go on to process the data you've just read. 否则,您应该继续处理您刚读过的数据。 At present you just read and ignore all input until end of stream, which is pointless. 目前你只是读取并忽略所有输入,直到流结束,这是没有意义的。 At best you can only process the last partial buffer, and you won't know how long it was. 充其量只能处理最后一个部分缓冲区,你不知道它有多长。

In your client code you should probably keep the connectedThread object alive a while longer. 在您的客户端代码中,您应该让connectedThread对象保持活动一段时间。 Might be that once the if clause closes and it goes out of scope (not quite sure what happens with GC and all) the write just doesn't happen and your connection is not closed but not used either. 可能是一旦if子句关闭并且它超出了范围(不太确定GC和所有事情发生了什么),写入就不会发生并且您的连接没有关闭但也没有使用。

Calling flush() on the mmOutStream inside the connectedThread after the write might help also. 在写入之后在connectedThread内的mmOutStream上调用flush()也可能有所帮助。

Like @EJP suggested, you should put something inside your read loop. 就像@EJP建议的那样,你应该把一些东西放在你的阅读循环中。

Edit: For the sake of debugging you could add this.wait(1000); 编辑:为了调试你可以添加this.wait(1000); immediately after your write in the client code. 在您写入客户端代码后立即。

In my opinion You should verify if something is in buffer before reading. 在我看来你应该在阅读之前验证某些东西是否在缓冲区中。 reading from stream is blocking operation so aplication will hang until somehing data appear. 从流中读取是阻止操作,因此应用程序将挂起,直到出现某些数据。 How can I check if an InputStream is empty without reading from it? 如何在不读取的情况下检查InputStream是否为空?

Try changing your run method to this: 尝试将run方法更改为:

public void run(){
    byte[] buffer = new byte[1024];
    int bytesRead = 0;
    final int shortSleepTime = 1000;
    final int longSleepTime = 5000;
    int emptyReadCounter = 0;
    int sleepCounter = 0;
    int currentSleepTime = shortSleepTime;

    //Keep listening to the InputStream while connected
    while (bytesRead >= 0){
        try {

            // if available() returns 0, there is nothing to read yet
            if (this.mmInStream.available() != 0){
                bytesRead = this.mmInStream.read(buffer);

                // Check if we need to reset the sleep counters
                if (emptyReadCounter != 0){
                    emptyReadCounter = 0;
                    sleepCounter = 0;
                    currentSleepTime = shortSleepTime;

                    // We can also do anything else dependent on just waking up
                    // from a sleep cycle in this block
                }


                // Do something with my now full buffer
                // Remember not to process more than 
                // 'bytesRead' bytes from my buffer because the
                // rest could be filled with crap left over from
                // the last iteration
            } else {                
                // Three consecutive empty reads means sleep
                if (emptyReadCounter++ >= 3){                       
                    if (currentSleepTime != longSleepTime && sleepCounter++ >= 3){
                        currentSleepTime = longSleepTime;
                    }
                    Thread.sleep(currentSleepTime);
                }
            }
        }
        catch(Exception e){
            Log.d("inStream exception:",e.getMessage());
            break;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM