簡體   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