Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing bluetooth connection android(client) to python(server) on pc

I am trying to send a "helloWorld" (just a string) from my android phone(samsung galaxy s2) to a python script on my pc running linux. But I cant get it to work. Below are the code for the android app(client) and the python script(server). The bluetooth are working fine on the pc and phone(e.g. I can send photos from the phone via BT). When I call btSocket.connect(); in the java code below it just wont connect. Do I have to specify a port to connect to, since I have specified a port for the serverSocket? Any help would be very appreciated.

public class BlueTooth_testActivity extends Activity {
    TextView header;
    Button discoverDevicesBtn;
    Button sendMsgBtn;
    Button closeBtn;
    EditText sendTxt;
    BluetoothAdapter btAdapter;
    BluetoothSocket btSocket;
    private static String btAdress = "00:10:60:D1:95:CD";
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private OutputStream out;
    public BluetoothDevice device;
    private Boolean CONNECTED = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //init layout parameters        
        header = (TextView) findViewById(R.id.text1);
        discoverDevicesBtn = (Button) findViewById(R.id.discBtn);
        sendMsgBtn = (Button) findViewById(R.id.sendButton);
        closeBtn = (Button) findViewById(R.id.closeButton);
        sendTxt = (EditText) findViewById(R.id.editText1);
        discoverDevicesBtn.setOnClickListener(discoverDeviceListener);
        sendMsgBtn.setOnClickListener(sendMsgListener);
        closeBtn.setOnClickListener(closeBtnListener);
        //init bluetooth
        btAdapter = BluetoothAdapter.getDefaultAdapter();
        if (btAdapter.isEnabled()) {
            Toast.makeText(this, "Bluetooth state:" + btAdapter.getState() + " Ok!", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Bluetooth state:" + btAdapter.getState() + " Not ok!", Toast.LENGTH_LONG).show();
        }

    }

    private Button.OnClickListener discoverDeviceListener = new Button.OnClickListener() {@Override
        public void onClick(View v) {
            if (!CONNECTED) {
                device = btAdapter.getRemoteDevice(btAdress);
                header.append("\nRemote device: " + device.getName());
                try {
                    btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
                } catch (Exception e) {
                                    }
                header.append("\n createRfcommsockettoservice! ");
                btAdapter.cancelDiscovery();
                try {
                    btSocket.connect();
                    CONNECTED = true;
                    header.append("\n btSocket Created!");
                } catch (IOException e) {
                    Toast.makeText(getApplicationContext(), "Could not connect to socket", Toast.LENGTH_LONG);
                    try {
                        btSocket.close();
                    } catch (Exception b) {}
                }
            }

        }
    };


    private Button.OnClickListener sendMsgListener = new Button.OnClickListener() {@Override
        public void onClick(View v) {
            if (CONNECTED) {
                try {
                    out = btSocket.getOutputStream();
                    String msg = sendTxt.getText().toString();
                    byte[] msgBffr = msg.getBytes();
                    out.write(msgBffr);
                    Toast.makeText(getApplicationContext(), "Message sent", Toast.LENGTH_LONG).show();
                } catch (Exception a) {
                    Toast.makeText(getApplicationContext(), "Could not send msg", Toast.LENGTH_LONG).show();
                }
            } else {
                Toast.makeText(getApplicationContext(), "cant send msg, not connected", Toast.LENGTH_LONG).show();
            }

        }
    };


}  

(I havnt bothered to include the rest of the java code as the problem is somewhere in the connection setup)

import bluetooth

name="bt_server"
target_name="siggen"
uuid="00001101-0000-1000-8000-00805F9B34FB"

def runServer():
serverSocket=bluetooth.BluetoothSocket(bluetooth.RFCOMM )
    port=bluetooth.PORT_ANY
    serverSocket.bind(("",port))
    print "Listening for connections on port: ", port   
    serverSocket.listen(1)
    port=serverSocket.getsockname()[1]
    inputSocket, address=serverSocket.accept()
    print "Got connection with" , address
    data=inputSocket.recv("1024")
    print "received [%s] \n " % data    
    inputSocket.close()
    serverSocket.close()  

runServer()  

.

like image 785
Simen Andresen Avatar asked Jun 06 '12 21:06

Simen Andresen


People also ask

What is GATT service on Android?

GATT Service A collection of characteristics (data fields) that describes a feature of a device, e.g. the Device Information service can contain a characteristic representing the serial number of the device, and another characteristic representing the battery level of the device.

How Bluetooth can be made available through program?

In order to enable the Bluetooth of your device, call the intent with the following Bluetooth constant ACTION_REQUEST_ENABLE. Its syntax is. Intent turnOn = new Intent(BluetoothAdapter. ACTION_REQUEST_ENABLE); startActivityForResult(turnOn, 0);


3 Answers

You don't need to specify a port, it should just connect you to the first open RFComm channel. One thing I found for the Bluetooth app I've made is that in order for it to work on my phone, I have to manually connect to the computer that the server is running on BEFORE trying to connect in the app. That is, I go through Settings -> Wireless/Networks -> Bluetooth Settings -> <Find/Pair to Computer> and do all of that until the notification pops up in my system tray. Then, when I try to make the socket connection through my app it works. I find this strange because I only have to jump through these hoops on my phone and not tablet, so maybe it depends on the device.

Also, you are going to want to do the connection stuff in a separate Thread.

like image 87
telkins Avatar answered Sep 22 '22 03:09

telkins


The Server Piece

I'm out of my depth when it comes to python, but it looks like your python snippet doesn't use the uuid anywhere. For example, the pybluez repo has an example server where they use the uuid when calling advertise_service, which you don't appear to have in your snippet. If you were to do something similar, your snippit might look like:

import bluetooth

name="bt_server"
target_name="siggen"
uuid="00001101-0000-1000-8000-00805F9B34FB"

def runServer():
serverSocket=bluetooth.BluetoothSocket(bluetooth.RFCOMM )
    port=bluetooth.PORT_ANY
    serverSocket.bind(("",port))
    print "Listening for connections on port: ", port   
    serverSocket.listen(1)
    port=serverSocket.getsockname()[1]

    #the missing piece
    advertise_service( server_sock, "SampleServer",
                       service_id = uuid,
                       service_classes = [ uuid, bluetooth.SERIAL_PORT_CLASS ],
                       profiles = [ bluetooth.SERIAL_PORT_PROFILE ] 
                        )

    inputSocket, address=serverSocket.accept()
    print "Got connection with" , address
    data=inputSocket.recv("1024")
    print "received [%s] \n " % data    
    inputSocket.close()
    serverSocket.close()  

runServer()  

The Client

BluetoothDevice.createRfcommSocketToServiceRecord() is for creating "secure communication sockets". Is this what your server is doing? If not, perhaps BluetoothDevice.createInsecureRfcommSocketToServiceRecord() is the appropriate call?

like image 37
NobodyMan Avatar answered Sep 24 '22 03:09

NobodyMan


Following the recommendations already posted, here is how I was able to get your code working as I expect you wanted it to:

   

import bluetooth
    
    name="bt_server"
    target_name="test"
    # some random uuid, generated by https://www.famkruithof.net/uuid/uuidgen
    uuid="0fee0450-e95f-11e5-a837-0800200c9a66"
    
    def runServer():
        # you had indentation problems on this line:
        serverSocket=bluetooth.BluetoothSocket(bluetooth.RFCOMM )
        port=bluetooth.PORT_ANY
        serverSocket.bind(("",port))
        print "Listening for connections on port: ", port   

        # wait for a message to be sent to this socket only once
        serverSocket.listen(1)
        port=serverSocket.getsockname()[1]
    
        # you were 90% there, just needed to use the pyBluez command:
        bluetooth.advertise_service( serverSocket, "SampleServer",
                           service_id = uuid,
                           service_classes = [ uuid, bluetooth.SERIAL_PORT_CLASS ],
                           profiles = [ bluetooth.SERIAL_PORT_PROFILE ] 
                            )
    
        inputSocket, address=serverSocket.accept()
        print "Got connection with" , address
        data=inputSocket.recv(1024)
        print "received [%s] \n " % data    
        inputSocket.close()
        serverSocket.close()  
    
    runServer()  

Run from the command line, that code will wait forever until a message is sent via bluetooth. So, with that code running, all you have to do is connect your Android device via bluetooth, and then have the device send data (with reference to the same uuid as above) via either the Android app method you were developing or something like this gist (that I used): https://gist.github.com/tito/7432757

like image 43
ecoe Avatar answered Sep 25 '22 03:09

ecoe