简体   繁体   中英

Android Bluetooth Inputstream.read never receiving data

I am making a game for Android, in which two devices connect and then trade a small amount of data, then disconnect and use that data. I started with the Bluetooth Chat example. At this point, I have it mostly working, but some (most) times, one of the devices never receives any data. This is the same app on both devices, so the send and receive code for both is the same. I am connecting like this:

    public BluetoothClientThread(BluetoothDevice get_device,boolean secure){
        BluetoothSocket temp=null;
        device=get_device;
        socket_type=secure?"Secure":"Insecure";

        try{
            if(secure){
                temp=device.createRfcommSocketToServiceRecord(UUID_SECURE);
            }
            else{
                temp=device.createRfcommSocketToServiceRecord(UUID_INSECURE);
            }
        }
        catch(IOException e){
            StorageManager.error_log_add(context,TAG,"create() on "+socket_type+" client socket failed.",e);
        }

        socket=temp;
    }

    public void run(){
        bluetooth_adapter.cancelDiscovery();

        try{
            socket.connect();
        }
        catch(IOException e){
            StorageManager.error_log_add(context,TAG,"Connection failed.",e);

            try{
                socket.close();
            }
            catch(IOException ioe){
                StorageManager.error_log_add(context,TAG,"close() on "+socket_type+" client socket failed during connection failure.",ioe);
            }

            connection_failed();

            return;
        }

        synchronized(BluetoothService.this){
            bluetooth_client_thread=null;
        }

        connected(socket,device,socket_type,false);
    }

Once connected, I grab the socket's getInputStream() and getOutputStream(). I then use the following code to read input on the socket:

    public void run(){
        String packet="";

        while(true){
            try{
                int get_byte=input.read();
                char get_char=(char)get_byte;

                if(get_char!='\u0003'){
                    StorageManager.error_log_add(context,"BluetoothService","Adding packet raw data: \""+get_char+"\"",null);
                    packet+=get_char;
                }
                else{
                    StorageManager.error_log_add(context,"BluetoothService","Packet received:\n"+packet,null);
                    handler.obtainMessage(Activity_Battle_Menu.HANDLER_READ,packet).sendToTarget();
                    packet="";
                }

                if(done && they_done){
                    handler.obtainMessage(Activity_Battle_Menu.HANDLER_READY).sendToTarget();
                }
            }
            catch(IOException e){
                StorageManager.error_log_add(context,TAG,"Connection lost.",e);

                connection_lost();

                break;
            }
        }
    }

It reads data one byte at a time, appending the bytes to a packet String. When the ETX character is reached (which I stick on the end of everything when I send it), a complete packet has been received, and is passed to the activity via handler, where it is acted upon. Here is my writing code:

    public void write(byte[] buffer){
        try{
            StorageManager.error_log_add(context,"BluetoothService","Writing data:\n"+new String(buffer),null);

            output.write(buffer);
        }
        catch(IOException e){
            StorageManager.error_log_add(context,TAG,"write() on "+socket_type+" connected socket failed.",e);
        }
    }

As you can see, I write to a log when a data "packet" is sent, when a byte is received, and when a whole "packet" has been received.

I'm not sure if any of this is relevant, but: I am testing this with a Nook Color with Cyanogenmod 7.1 (Android 2.3.7) and Android x86 running in VirtualBox (Android 2.3.5). My app's minSdkVersion is 8 (Android 2.2). For the Android running on my computer, I'm using a Rocketfish USB Bluetooth adapter.

There are supposed to be two packets of data sent by each instance. First, a data packet holding all of the needed game data is sent. When the other instance's game data is received, the app sets its own boolean done to true. It also sends a "done" packet to the other instance. Thus, once both instances are done, and know the other is done, we know all data has been sent and received, and they both disconnect/stop their Bluetooth threads and act on the data.

Since I have it logging on both devices when data is sent and received, the logs tell me a story of what is going on.

-First, I start both games and go to the Bluetooth activity (obviously).

-Next, I connect to the Nook instance from the emulated instance.

-The emulated instance sends its game data packet.

-The Nook instance receives the emulated instance's game data, and sends its own (sometimes these two are switched in order, just because they happen asynchronously).

-Since it received a game data packet, the Nook instance now sends its "done" packet.

-That is it. The emulated instance never receives either packet. It never even receives a single byte, and the input.read() just blocks, waiting for input that never arrives (like it should).

So that is my problem. It seems that one of two things is happening:

  1. The data never gets sent by output.write() on the Nook instance, even though it does not throw any exception, and the log verifies that it gets called.

  2. The data never gets received by input.read() on the emulated instance. Maybe it gets lost in transmission?

As far as I can tell, my code is rock solid. The problem seems to be Bluetooth-related. Maybe one or both Android instance has a screwy Bluetooth setup?

I also want to add that every rare once in a while (maybe 1/15 times), all of the packets are sent and received properly, and the game proceeds as it should. So whatever is wrong only USUALLY happens, but not always.

I got access to another Android device with Bluetooth. I've since tested my game, and it connects and the devices trade data correctly. I've found several other bugs with my program that occur after the Bluetooth stuff, but that is neither here nor there!

The Nook Color from before and an HTC Status are what worked together. I'm officially concluding, then, that I have a faulty Bluetooth adapter on my computer. The code posted above works nicely enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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