My goal is : send via bluetooth certain string comand from my Android app to a Raspberry Pi device so it can runs a script,and after it is done, send back the message to my Android app
My approach:
- Used this python code(from my Pi3) for tryn to connect as a client on my server class
import socket
serverMACAddress = 'F8:8F:07:3D:7A:7B'
port = 2
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.connect((serverMACAddress,port))
while 1:
text = input()
if text == "quit":
break
s.send(bytes(text, 'UTF-8'))
s.close()
The problem: Rpi3 connects just at the level of my phone os bluetooth, but the server client that i wrote in my android app doesnt accept it, also, can't send/receive data from one to another (ofc)
I tried a lot of things in this app for a lot of time,changed a lot of libraries for the client app in python, nothing worked, i spent at least 5 weeks on this part.
I will provide you my kotlin code(note: i dont use ClientClass but maybe it will help posting it, ofc that i want that android client class that i dont use, somehow be translated to python to work on my pi) and also pics with what i have achieved:
class TrackYourWorkoutFragment : Fragment() { private lateinit var binding: FragmentTrackYourWorkoutDataBinding var MAC_ADDRESS = "E4:5F:01:0A:7D:20" var MAC_ADDRESS_SAMSUNG = "F8:8F:07:3D:7A:7B" val DEVICE_NAME = "raspberrypi" var bluetoothSocket: BluetoothSocket? = null var isConnected: Boolean = false private lateinit var bluetoothAdapter: BluetoothAdapter private lateinit var sendReceive: SendReceive companion object { private const val APP_NAME: String = "RealStats" var SHARED_UUID: UUID = UUID.fromString("f4b18e71-c048-43a0-99cc-06f99eb6b654") private const val STATE_LISTENING = 1 private const val STATE_CONNECTING = 2 private const val STATE_CONNECTED = 3 private const val STATE_CONNECTION_FAILED = 4 private const val STATE_MESSAGE_RECEIVED = 5 } private val viewModel: TrackYourWorkoutFragmentViewModel by lazy { ViewModelProvider(this, viewModelFactory { TrackYourWorkoutFragmentViewModel( onConnectToPiClick = { startServerSoPiConnects() }, onStartWorkoutClick = { startWorkout() } ) })[TrackYourWorkoutFragmentViewModel::class.java] } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = DataBindingUtil.inflate( inflater, R.layout.fragment_track_your_workout, container, false ) binding.viewModel = viewModel binding.lifecycleOwner = viewLifecycleOwner return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) (requireActivity() as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.toolbar_track_your_workout) bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() enableBluetooth() } var handler = Handler { msg -> when (msg.what) { STATE_LISTENING -> binding.tvInfoConnection.text = "Listening" STATE_CONNECTING -> binding.tvInfoConnection.text = "Connecting" STATE_CONNECTED -> binding.tvInfoConnection.text = "Connected" STATE_CONNECTION_FAILED -> binding.tvInfoConnection.text = "Connection Failed" STATE_MESSAGE_RECEIVED -> { val readBuff = msg.obj as ByteArray val tempMsg = String(readBuff, 0, msg.arg1) binding.tvInfo.text = tempMsg } } true } @SuppressLint("MissingPermission") private fun startServerSoPiConnects() { //val piDevice: BluetoothDevice = bluetoothAdapter.getRemoteDevice(MAC_ADDRESS) val serverClass = ServerClass() serverClass.start() } private fun startWorkout() { val startMessageForPi = "s" sendReceive.write(startMessageForPi.toByteArray()) } private fun enableBluetooth() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { requestMultiplePermissions.launch( arrayOf( Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT ) ) } } @SuppressLint("MissingPermission") private val requestMultiplePermissions = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { if (!bluetoothAdapter.isEnabled) { bluetoothAdapter.enable() Toast.makeText(this.context, "Bluetooth enabled", Toast.LENGTH_SHORT).show() } } private inner class ServerClass @SuppressLint("MissingPermission") constructor() : Thread() { private lateinit var serverSocket: BluetoothServerSocket init { try { serverSocket = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord( APP_NAME, SHARED_UUID ) } catch (e: IOException) { e.printStackTrace() } } override fun run() { var socket: BluetoothSocket? = null while (socket == null) { try { val message: Message = Message.obtain() message.what = STATE_CONNECTING handler.sendMessage(message) socket = serverSocket.accept() } catch (e: IOException) { e.printStackTrace() val message: Message = Message.obtain() message.what = STATE_CONNECTION_FAILED handler.sendMessage(message) } if (socket != null) { val message: Message = Message.obtain() message.what = STATE_CONNECTED handler.sendMessage(message) sendReceive = SendReceive(socket) sendReceive.start() break } } } } private inner class ClientClass @SuppressLint("MissingPermission") constructor(deviceR: BluetoothDevice) : Thread() { private var device: BluetoothDevice private lateinit var socket: BluetoothSocket init { device = deviceR try { socket = device.createRfcommSocketToServiceRecord(SHARED_UUID) } catch (e: IOException) { e.printStackTrace() } } @SuppressLint("MissingPermission") override fun run() { try { socket.connect() val message = Message.obtain() message.what = STATE_CONNECTED handler.sendMessage(message) sendReceive = SendReceive(socket) sendReceive.start() } catch (e: IOException) { e.printStackTrace() val message = Message.obtain() message.what = STATE_CONNECTION_FAILED handler.sendMessage(message) } } } private inner class SendReceive(socket: BluetoothSocket) : Thread() { private var bluetoothSocket: BluetoothSocket private lateinit var inputStream: InputStream private lateinit var outputStream: OutputStream init { bluetoothSocket = socket var tempIn: InputStream? = null var tempOut: OutputStream? = null try { tempIn = bluetoothSocket.inputStream tempOut = bluetoothSocket.outputStream } catch (e: IOException) { e.printStackTrace() } if (tempIn != null) { inputStream = tempIn } if (tempOut != null) { outputStream = tempOut } } override fun run() { val buffer = ByteArray(1024) var bytes: Int while (true) { try { bytes = inputStream.read(buffer) handler.obtainMessage(STATE_MESSAGE_RECEIVED, bytes, -1, buffer).sendToTarget() } catch (e: IOException) { e.printStackTrace() } } } fun write(bytes: ByteArray) { try { outputStream.write(bytes) } catch (e: IOException) { e.printStackTrace() } } }
}
after starting the server, by clicking connect to pi
If someone manages to solve this somehow, or provide me some usefull notes at least, please, i want to send you a NICE(i hope) gift.
FINALLY FOUND IT, THIS IS THE ANSWER import bluetooth import threading import time import random import sys