Keeping Java Bluetooth connection alive
Asked Answered
R

1

8

I’m building a simple Java Bluetooth server for my computer using the Bluecove API. I’m building an Android client side app as well but the problem seems to be stemming from the server side app.

I’m sure someone has posted any answer already somewhere and I’ve tried different solutions rigorously for the past several days and looked at every possible forum but I can’t seem to keep the connection on the socket thread alive.

I can exchange a message across after a connection is established from android to computer and vice versa from computer to android but immediately after the bytes are exchanged, the Bluecove stack shuts down and closes the socket connection even when I don’t explicitly tell it to connection.close().

I’ve tried to use a while(some statement is true) loop to keep the connection alive and it no longer shuts down the socket after receiving the first message but it can’t receive any subsequent messages I send from my smartphone to my computer either. While it is essentially alive, it can’t receive any new messages when I try to send them from the smartphone. Not sure why.

I'm sorry, this is my first time posting and I'm not sure why the first part of the code does not display properly on the page.

Code making connection:

public BluetoothServer() {
    try {
        service = (StreamConnectionNotifier) 
            Connector.open("btspp://localhost:" + new UUID(0x1101).toString() + 
                                ";name=SampleServer");
        
        System.out.println("open connection");

        while (runState == true) {
        
            connection = (StreamConnection) service.acceptAndOpen();
                
            //send a greeting across to android
            outputStream = connection.openOutputStream();
            String greeting = "JSR-82 RFCOMM server says hello";
            outputStream.write(greeting.getBytes());
            
            //run thread that listens for incoming bytes through socket connection
            Thread t = new Thread(new ConnectedThread(connection));
            t.start();                
        }
            
    } catch(IOException e) {}
}

THREAD CODE FOR LISTENING TO INCOMING DATA

public void run() {
    try {    
        //open input stream to listen to data
        inputStream = connection.openInputStream();              
                                      
        byte buffer[] = new byte[1024];
        int bytes_read = inputStream.read(buffer);

        String received = new String(buffer, 0, bytes_read);
        System.out.println("received: " + received);
            
    } catch(IOException e) {}
}
Redroot answered 11/2, 2013 at 20:2 Comment(3)
You can't send more than one message from Client to Server, but can you Send multiple messages from Server to Client? Which loop calls your run() method? Can you provide this code calling run() aswell?Embank
In the past I face very similar issue. But in my case, connection was not closed, only IO speed was slowing down(on the Android side). After debugging, we discovered, after some period of inactivity, it happens on the Android side after specific timeout(Android switches power safe mode) and this timeout can't be changed. To keep connection alive, we just periodically sent empty packet(one byte). Hope it will help.Mahican
Don't just use blank try/catch blocks. Log the exception when it is thrown , it will help you to get real reason. Otherwise you are guessing.Waybill
L
1

Unfortunately I can't try your code on my machine in real, but I think I saw your error: in your run()-Method you read from the input stream, print it to the console and then it is over. After your last line

        System.out.println("received: " + received);

your run()-Method is over and the thread is discarded by the runtime. You would need to put the receiving in a while(true) or while(running) loop.

I modified your code and here it is, however please keep in mind what I said before: I could not test-run it, so it comes totally untested!

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;


public class BluetoothServer {

    private boolean runState = true;

    public BluetoothServer(){

        try {
            StreamConnectionNotifier service = (StreamConnectionNotifier) Connector.open("btspp://localhost:" + new UUID(0x1101).toString() + ";name=SampleServer");
            System.out.println("open connection");

            while(runState == true){
                StreamConnection connection = (StreamConnection) service.acceptAndOpen();
                new Listener(connection).start();
            }

        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    private class Listener extends Thread{

        private OutputStream os;
        private InputStream is;

        public Listener(StreamConnection connection){
            try {
                this.os = connection.openOutputStream();
                os.flush();
                this.is = connection.openInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void run(){
            StringBuilder builder;
            try{
                String greeting = "JSR-82 RFCOMM server says hello";
                os.write(greeting.getBytes());

                while(true){
                    builder = new StringBuilder();
                    int tmp = 0;
                    while((tmp = is.read()) != -1){
                        builder.append((char) tmp);
                    }
                    System.out.println("received: " + builder.toString());
                }
            } 
            catch(IOException e){
                e.printStackTrace();
            }
        }
    }
}

Here a few general points and thoughts about mine and your code:

  • As you can see, in the main thread I only accept a new connection. As soon as a client connected, I give the connection object to the thread. It then starts to communicate with the client
  • In Java, we normally put opening brackets on the same line as the statement which asks for it, but this is just a detail and not a must.
  • ALLWAYS do something with exceptions or do not catch them. So the minimum is a printStacktrace() or to declare your method with "throws xException" but do not catch and ignore them.

For the next time you're posting something here, I'd recommend to include all your import statements etc., it can help the people who are trying to help you. (sometimes, an import can be the cause of all trouble, for example when someone imported java.awt.List instead of java.util.List)

I hope that I helped you!

Leschen answered 17/3, 2015 at 21:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.