how to convert android.bluetooth.socket inputstream to python string in Kivy?

亡梦爱人 提交于 2020-05-13 07:53:04

问题


I'm working on Kivy app.

Since I want to get data from bluetooth adapter, I used code below.

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 find out how to get bluetooth.socket inputstream to python string. Can someone please help?


回答1:


I have finally find a solution that seems to work. I have a Kivy app communicating with an Arduino based device over Bluetooth. On the Arduino I use the SerialCommand library to recieve custom commands and respond accordingly. While the commands is send to my Arduino in the main thread, I have a second thread with a loop that reads the InputStream from my Bluetooth socket. The response from Arduino is enclosed with <>, and when I get a proper response I extract the text between the brackets and send it to a function in my mainthread. I hope this is helpful for 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...


来源:https://stackoverflow.com/questions/29719898/how-to-convert-android-bluetooth-socket-inputstream-to-python-string-in-kivy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!