How can I convert android.bluetooth.socket input stream to python string in Kivy?
I am working on a Kivy app.
Since I want to receive data from bluetooth adapter, I used below code.
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.scatter import Scatter
from kivy.properties import ObjectProperty,NumericProperty
from kivy.clock import Clock
from kivy.lang import Builder
from jnius import cast,autoclass
from kivy.logger import Logger
BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
bufferedreader = autoclass('android.bluetooth.BluetoothAdapter')
BluetoothDevice = autoclass('android.bluetooth.BluetoothDevice')
BluetoothSocket = autoclass('android.bluetooth.BluetoothSocket')
InputStreamReader = autoclass('java.io.InputStreamReader')
BufferedReader = autoclass('java.io.BufferedReader')
UUID = autoclass('java.util.UUID')
StringBuilder = autoclass('java.lang.StringBuilder')
Builder.load_string('''
<bluetooth>:
Button:
pos:root.width/3,root.height/2
text: root.data
size: (300,100)
''')
class bluetooth(Scatter):
socket = ObjectProperty(None,allownone = True)
data = ObjectProperty('getting data',allownone = True)
recv = ObjectProperty(None,allownone = True)
counter = NumericProperty(0)
def change_data(self,dt):
Logger.info('Im in the change_data!!')
self.data = 'change_data'
paired_devices = BluetoothAdapter.getDefaultAdapter().getBondedDevices().toArray()
for device in paired_devices:
self.data = str(device.getName())
Logger.info('Im in the loop!!'+str(device))
if device.getName() == 'HC-06':
self.socket = device.createRfcommSocketToServiceRecord(UUID.fromString('00001101-0000-1000-8000-00805F9B34FB'))
bufferedreader = BufferedReader(InputStreamReader(self.socket.getInputStream(),"UTF-8"))
StringBuilder.append(bufferedreader.read())
self.data = StringBuilder.toString()
#if self.socket == None:
# pass
#else:
# self.socket.connect()
class myApp(App):
def build(self):
bt = bluetooth()
Clock.schedule_interval(bt.change_data,1)
return bt
myApp().run()
Maybe I missed some code. I can't seem to figure out how to get the bluetooth.socket input for a python string. Can anyone please help?
I finally found a solution that seems to work. I have a Kivy app communicating with an Arduino based device via bluetooth. On Arduino, I use SerialCommand library to receive custom commands and respond accordingly. Although commands are sent to my Arduino on the main thread, I have a second thread with a loop that reads an InputStream from my bluetooth socket. The answer from Arduino is enclosed in <>, and when I get the correct answer, I extract the text between the brackets and send it to the function in my mainthread. Hope this helps you.
from kivy.clock import mainthread
import threading
import jnius
def get_socket_stream(self, name):
paired_devices = self.BluetoothAdapter.getDefaultAdapter().getBondedDevices().toArray()
socket = None
for device in paired_devices:
if device.getName() == name:
socket = device.createRfcommSocketToServiceRecord(
self.UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
reader = self.InputStreamReader(socket.getInputStream(), 'US-ASCII')
recv_stream = self.BufferedReader(reader)
send_stream = socket.getOutputStream()
break
socket.connect()
return recv_stream, send_stream
def connect(self, *args):
device = self.config.get('bluetooth', 'bt_name')
try:
self.recv_stream, self.send_stream = self.get_socket_stream(device)
except AttributeError as e:
print e.message
return False
except jnius.JavaException as e:
print e.message
return False
except:
print sys.exc_info()[0]
return False
threading.Thread(target=self.stream_reader).start()
def stream_reader(self, *args):
stream = ''
while True:
if self.stop.is_set():
jnius.detach()
return
if self.recv_stream.ready():
try:
stream = self.recv_stream.readLine()
except self.IOException as e:
print "IOException: ", e.message
except jnius.JavaException as e:
print "JavaException: ", e.message
except:
print "Misc error: ", sys.exc_info()[0]
try:
start = stream.rindex("<") + 1
end = stream.rindex(">", start)
self.got_response(stream[start:end])
except ValueError:
pass
@mainthread
def got_response(self, response):
do something...
source to share