As a follow up to my recent post I tried to program a very basic launcher. The idea is to pass commands from my android phone to my ubuntu laptop. The android side of things was already catered for by SL4A, I used a fixed version of their bluetooth_chat.py program that comes bundled with SL4A python. The ubuntu side of things was surprisingly more difficult. There is a lot of information on the web, but it’s either incomplete or didn’t quite fit what I was trying to do. So this article is pretty much a reminder for myself as well as a hopeful helping hand for anyone else in a similar situation. Here’s what I had to do to get the ubuntu laptop and nexus 5 phone to communicate:
1. Pair the two devices.
If you dont do this, you’ll get a lot of errors like “connection refused”. Pairing is simple enough and is a run of the mill operation. On the ubuntu machine, open the bluetooth applet (I’m using the default one), and make sure that both bluetooth itself and the visibility (or discover-able) is set to on:

Next, do the same on the nexus device and pair to the linux machine. Make sure the phone is visible to all blueooth devices

The devices will ask you to confirm that each one is seeing the other properly by confirming a random PIN number. Once you have successfully paired the devices, you should see them in the “paired devices” section like in the screenshots above.
2. Launch the bluetooth “server” on the phone
It’s a bit counter-intuitive that the phone is going to be our “server” since we’re going to run the commands on the laptop – but this was actually the easier setup. Open SL4A and run the “bluetooth_chat.py” program. When prompted if it should be a server, click “yes”. The SL4A script will make your device visible for the next 300 seconds.
3. Figure out the UUID for the phone
We need to figure out the UUID that the phone is broadcasting so our ubuntu client can search and connect to it in order to receive commands. The easiest way I found to do this is, first scan for the phone MAC address:
hcitool scan
Once you know the mac from the output of the above command, you need to delve a bit deeper and find the specific UUID of the SL4a service. You can do this via:
sdptool records 12:15:00:7B:91:FA
Where 12:15:00:7B:91:FA is the mac address of the pone. You should see something similar to:
Service Name: SL4A
Service RecHandle: 0x1000d
Service Class ID List:
UUID 128: 457807c0-4897-11df-9879-0800200c9a66
Protocol Descriptor List:
“L2CAP” (0x0100)
“RFCOMM” (0x0003)
Channel: 5
Make a note of the UUID in bold above, you’ll be using it next…
4. Launch the blluetooth client on the ubuntu machine
For my bluetooth client, I decided to use the python bluez stack (pybluez). They conveniently have two useful examples (rfcomm server and rfcomm client), which you can find here:
https://code.google.com/p/pybluez/source/browse/trunk/examples/simple/
The actual code follows (it’s just a very ugly modification of the two examples above):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from bluetooth import * | |
import sys | |
from subprocess import call | |
if sys.version < '3': | |
input = raw_input | |
addr = None | |
print("no device specified. Searching all nearby bluetooth devices for") | |
print("the SL4A service") | |
# search for the SL4A service | |
uuid = sys.argv[1] | |
service_matches = find_service( uuid = uuid, address = addr ) | |
if len(service_matches) == 0: | |
print("couldn't find the SL4A service =(") | |
sys.exit(0) | |
first_match = service_matches[0] | |
port = first_match["port"] | |
name = first_match["name"] | |
host = first_match["host"] | |
print("connecting to \"%s\" on %s" % (name, host)) | |
# Create the client socket | |
sock=BluetoothSocket( RFCOMM ) | |
sock.connect((host, port)) | |
print("connected.") | |
try: | |
while True: | |
data = sock.recv(1024) | |
if len(data) == 0: break | |
print("received %s" % data) | |
print('——————–') | |
if (data == 'firefox\n'): | |
call(["firefox",""]) | |
sock.send("recv: %s" % data) | |
except IOError: | |
pass | |
print("disconnected") | |
sock.close() | |
print("all done") |
In the above example the nexus phone actually has to be discover-able since in the script I am searching across all bluetooth devices for the UUID rather than directly connecting to a specific MAC address (which is also possible btw). Also note that I implemented only a single command, “firefox” which would launch the browser. Other commands are possible of course. As soon as the phone detects a connection, it shows a dialog box that you can use to send commands over. The ubuntu side just echos back all commands unless otherwise instructed.
Hopefully in a future post i’ll implement this natively in android rather than over SL4A…
References: