繁体   English   中英

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

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

我正在尝试使用以下来源制作文件传输蓝牙应用程序:

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

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

当我尝试使用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)

}

永远不会到达代码的下一部分(在这种情况下为"if"部分),也不会出现Log.D调试输出或我放入的其他任何内容。 我刚从LogCat收到此消息:

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

要将数据从客户端传输到服务器,我这样做:

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)

}

AcceptThread (实现的服务器部分)工作,因为当我运行客户端部分连接然后传输数据时,在设备中进行调试时,服务器部分上的LogCat激活并到达线程的run方法,我调用ConnectedThread实现,但之后“显然”读取字节但它在LogCat上卡住而没有错误。

请让我知道如何完成读取字节以移动到流程的下一部分。

谢谢

您被阻止等待更多输入。

在流结束测试之后,标记为... (some code here)的部分... (some code here)应该在读取循环内 注意如果read()返回-1并不表示“没有数据”,则表示流结束,您应该关闭套接字并中断读取循环。 否则,您应该继续处理您刚读过的数据。 目前你只是读取并忽略所有输入,直到流结束,这是没有意义的。 充其量只能处理最后一个部分缓冲区,你不知道它有多长。

在您的客户端代码中,您应该让connectedThread对象保持活动一段时间。 可能是一旦if子句关闭并且它超出了范围(不太确定GC和所有事情发生了什么),写入就不会发生并且您的连接没有关闭但也没有使用。

在写入之后在connectedThread内的mmOutStream上调用flush()也可能有所帮助。

就像@EJP建议的那样,你应该把一些东西放在你的阅读循环中。

编辑:为了调试你可以添加this.wait(1000); 在您写入客户端代码后立即。

在我看来你应该在阅读之前验证某些东西是否在缓冲区中。 从流中读取是阻止操作,因此应用程序将挂起,直到出现某些数据。 如何在不读取的情况下检查InputStream是否为空?

尝试将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