In this example, we’re going to configure Android device with BT to act as a Serial Port Profile Server, and Linux Phyton app as Serial Port Profile Client
Android
Somewhere withing MainActivity.kt file place this function, and then call it with Context.
@SuppressLint("MissingPermission")
fun startBluetoothServer(ctx: Context) {
val bm = ctx.getSystemService(BluetoothManager::class.java)
val ba = bm.adapter
val bss = ba.listenUsingRfcommWithServiceRecord("CM1", UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666"))
val t = Thread {
val socket = bss.accept()
Log.i("BT", "Socket accepted")
while (true) {
val b = socket.inputStream.read()
socket.outputStream.write(b)
Log.i("BT", "read/write $b")
}
}
t.name = "BluetoothSocket"
t.start()
}
Android Manifest permissions
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
Linux
Here is the complete source of Python client communicating with the Android device.
This assumes that pairing has already been performed.
import socket
from time import sleep
def exchange_spp_bytes(mac_addr, port):
print(f'Connecting to bluetooth dev {mac_addr}, port {port}')
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.connect((mac_addr, port))
while True:
s.sendall(b"baba\n")
print( s.recv(5) )
sleep(0.5)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
# Here we assume that we know what is port (BT channel)
# Use SDP to identify which port is it
# sdptool browse mac::address
exchange_spp_bytes('REPLACE::WITH::BT::MAC:ADDRESS', 13)