Java 如何为Bluetooth getInputStream和getOutputStream使用pyjnius读写参数?

Java 如何为Bluetooth getInputStream和getOutputStream使用pyjnius读写参数?,java,android,python-3.x,bluetooth,pyjnius,Java,Android,Python 3.x,Bluetooth,Pyjnius,我一直在摸索使用python for android jnius库从蓝牙RS232转换器获取数据。我原以为它会像PySerial库一样简单,但由于我还不熟悉java,所以实现就完全不同了我很容易创建了蓝牙连接,但只要我尝试读取或写入数据,我就会得到一个jnius.jnius.JavaException,即没有与参数匹配的方法,,并且读取可用的方法是:'()I'、'([B)I'、'([BII)I'和写入的方法是'(I)V'、([B)V'、'([BII)V'。我试着在开发者android文档中找到它

我一直在摸索使用python for android jnius库从蓝牙RS232转换器获取数据。我原以为它会像PySerial库一样简单,但由于我还不熟悉java,所以实现就完全不同了
我很容易创建了蓝牙连接,但只要我尝试读取或写入数据,我就会得到一个
jnius.jnius.JavaException
,即
没有与参数匹配的方法,
,并且
读取可用的方法是:
'()I'、'([B)I'、'([BII)I'
写入
的方法是
'(I)V'、([B)V'、'([BII)V'
。我试着在开发者android文档中找到它,但没有明确说明。
我还试着使用
readLine()的
BufferedReader
示例()
method,但我经常收到一个错误:
JavaException:JVM异常发生:尝试在空对象引用上调用虚拟方法“int java.io.InputStream.read(byte[],int,int)”

有人能给我指一下文档来理解上面的读写参数吗?
另外,请帮助我理解为什么
读取、读取行()和写入
对象不返回任何数据

我称之为Java库:

BluetoothAdapter = 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')
System = autoclass('java.lang.System')
连接代码(从Github和上面的链接获得):

更新: 因此,我最终使用
readLine()获得了输入
方法不返回错误,也返回字符串。我清理了一些东西,但代码没有太大区别。但主要的是我检查了
设备!=None
如果rfsocket.connected:
在我的eventloop中创建getInputStream之前,以免重新创建套接字对象。必须测试进一步了解主要问题在哪里。仍然不知道
read
write
方法的参数是什么。
readLine()
方法间歇返回字符串,或者根本不返回字符串,我的eventloop似乎无法与
readLine()
方法一起工作

更新内容: 事件循环再次工作。糟糕,我没有正确调用触发器对象。
readLine()
方法有一个奇怪的模式,在第一次读取时,它给了我
JavaException:JVM异常发生:尝试调用虚拟方法'int java.io.InputStream.available()'在空对象引用上
,后续读取会给我预期的字符串片段或空字符串。当我使用PySerial通过硬线接收数据时,返回了类似的字符串位和片段。解决方案是重置输入缓冲区。上述java库中是否有类似的内容

终于破解了例外: 是的,这很令人兴奋!几个小时后,我注意到我再也无法获得输入,只有异常。我尝试了
BufferedInputStream
库,得到了相同的结果,没有更多的间歇读取。为什么?所以我重新调用了昨晚的
main
文件,再次启动间歇输入读取。
原因是,如果我在
rfsocket
蓝牙对象未连接到指定端口时创建java对象,
Null
对象在另一个端口上初始化,由于某种原因,
if
self.recv_流不是None
self.recv_流!=None
因为它们不是
Null
对象,而是我指定的后续端口1套接字连接的
Null


readline()
的工作原理与我的示例相同,
read()
有三个参数
bytes()、int offset、int len(bytes())
这在
jnius.jnius.exception
Hieraoglyphics'消息中不清楚。仍然在弄清楚
write
方法。您可以在
BufferedReader
方法中指定的一件事是您想要读取的块大小的第二个参数,或者在java speak
defaultCharBufferSize

中指定的块大小我的答案已经全部解决了。
为了连接到蓝牙,我根据上的建议构建。在创建
getOutputStream
getInputStream
java对象之前,我必须明确设置自己的套接字,否则连接端口和对象将不相同。您只需调用
GetBSerial()
连接

    def get_socket_stream(self, name):
        defaultCharBufferSize = 8192
        try:
            blueAdapt = BluetoothAdapter.getDefaultAdapter()
            if self.rfsocket is not None:
                if self.rfsocket.connected:
                    reader = InputStreamReader(self.rfsocket.getInputStream(), getEncode)
                    recv_stream = BufferedReader(reader)
                    send_stream = self.rfsocket.getOutputStream()
                else:
                    self.rfsocket = self.device.createRfcommSocketToServiceRecord(UUID.fromString(getUuid))
                    if self.get_port_connect():
                        reader = InputStreamReader(self.rfsocket.getInputStream(), getEncode)
                        recv_stream = BufferedReader(reader, defaultCharBufferSize)
                        send_stream = self.rfsocket.getOutputStream()
            else:
                if blueAdapt is not None:
                    if blueAdapt.isEnabled():
                        paired_devices = blueAdapt.getBondedDevices().toArray()
                        self.rfsocket = None
                        for self.device in paired_devices:
                            if self.device.getName() == name:
                                if self.device.bluetoothEnabled:
                                    self.rfsocket = self.device.createRfcommSocketToServiceRecord(
                                        UUID.fromString(getUuid))
                                    if self.rfsocket is not None:
                                        if self.get_port_connect(): #connect and set the port before creating java objects
                                            reader = InputStreamReader(self.rfsocket.getInputStream(), getEncode)
                                            recv_stream = BufferedReader(reader, defaultCharBufferSize)
                                            send_stream = self.rfsocket.getOutputStream()
                                            break
                    else:
                        self.ids.bluet_info.text = '[b]Bluetooth not enabled[/b]'
            if recv_stream is not None and send_stream is not None:
                return recv_stream, send_stream
            else:
                return False, False
        except UnboundLocalError as e:
            return False, False
        except TypeError as e:
            return False, False
    def get_port_connect(self):
        try:
            if self.rfsocket.port <= 0:
                self.rfsocket = self.device.createRfcommSocket(1) #set the port explicitly
                if not self.rfsocket.connected:
                    self.rfsocket.connect()
            else:
                if not self.rfsocket.connected:
                    self.rfsocket.connect()
            if self.rfsocket.connected:
                self.ids.bluet_info.text = '[b]Connected[/b]'
            return True
        except jnius.jnius.JavaException as e:
            self.ids.bluet_info.text = '[b]Cannot connect to socket[/b]'
    def GetBSerial(self):
        try:
            getDevname = self.the.config.get('bluetoothsettings', 'stringbluetdevname')
            self.recv_stream, self.send_stream = self.get_socket_stream(getDevname)
        except jnius.jnius.JavaException as e:
            self.ids.bluet_info.text = '[b]Not Connected[/b]'
外部:

if self.recv_stream.ready() != None:
    r = self.recv_stream.read()
    theChar = CharBuilder.toChars(r) #gives a tuple of which the first element is a character
    self.read += theChar[0]
您必须反复构建字符串,才能知道字符串必须从何处开始。

write()
方法的第一件事是它接受一个bytes对象。因此,您可以构建一个
bytearray()
并将其用作参数。使用ESC/POS打印机初始化命令和字符串的示例:

i = [27,64] #ASCII escape integer and at sign integer
pre = bytearray(i)
cmd = 'Hello You\n'.encode('UTF-8')
#extend bytearray
pre.extend(cmd)
self.send_stream.write(pre)
self.send_stream.flush()

还不知道如何一次性创建bytearray整数和字符串。

所以我在发布我的答案,因为我已经解决了所有问题。
为了连接到蓝牙,我根据上的建议构建。在创建
getOutputStream
getInputStream
java对象之前,我必须明确设置自己的套接字,否则连接端口和对象将不相同。您只需调用
GetBSerial()
连接

    def get_socket_stream(self, name):
        defaultCharBufferSize = 8192
        try:
            blueAdapt = BluetoothAdapter.getDefaultAdapter()
            if self.rfsocket is not None:
                if self.rfsocket.connected:
                    reader = InputStreamReader(self.rfsocket.getInputStream(), getEncode)
                    recv_stream = BufferedReader(reader)
                    send_stream = self.rfsocket.getOutputStream()
                else:
                    self.rfsocket = self.device.createRfcommSocketToServiceRecord(UUID.fromString(getUuid))
                    if self.get_port_connect():
                        reader = InputStreamReader(self.rfsocket.getInputStream(), getEncode)
                        recv_stream = BufferedReader(reader, defaultCharBufferSize)
                        send_stream = self.rfsocket.getOutputStream()
            else:
                if blueAdapt is not None:
                    if blueAdapt.isEnabled():
                        paired_devices = blueAdapt.getBondedDevices().toArray()
                        self.rfsocket = None
                        for self.device in paired_devices:
                            if self.device.getName() == name:
                                if self.device.bluetoothEnabled:
                                    self.rfsocket = self.device.createRfcommSocketToServiceRecord(
                                        UUID.fromString(getUuid))
                                    if self.rfsocket is not None:
                                        if self.get_port_connect(): #connect and set the port before creating java objects
                                            reader = InputStreamReader(self.rfsocket.getInputStream(), getEncode)
                                            recv_stream = BufferedReader(reader, defaultCharBufferSize)
                                            send_stream = self.rfsocket.getOutputStream()
                                            break
                    else:
                        self.ids.bluet_info.text = '[b]Bluetooth not enabled[/b]'
            if recv_stream is not None and send_stream is not None:
                return recv_stream, send_stream
            else:
                return False, False
        except UnboundLocalError as e:
            return False, False
        except TypeError as e:
            return False, False
    def get_port_connect(self):
        try:
            if self.rfsocket.port <= 0:
                self.rfsocket = self.device.createRfcommSocket(1) #set the port explicitly
                if not self.rfsocket.connected:
                    self.rfsocket.connect()
            else:
                if not self.rfsocket.connected:
                    self.rfsocket.connect()
            if self.rfsocket.connected:
                self.ids.bluet_info.text = '[b]Connected[/b]'
            return True
        except jnius.jnius.JavaException as e:
            self.ids.bluet_info.text = '[b]Cannot connect to socket[/b]'
    def GetBSerial(self):
        try:
            getDevname = self.the.config.get('bluetoothsettings', 'stringbluetdevname')
            self.recv_stream, self.send_stream = self.get_socket_stream(getDevname)
        except jnius.jnius.JavaException as e:
            self.ids.bluet_info.text = '[b]Not Connected[/b]'
外部:

if self.recv_stream.ready() != None:
    r = self.recv_stream.read()
    theChar = CharBuilder.toChars(r) #gives a tuple of which the first element is a character
    self.read += theChar[0]
您必须反复构建字符串,才能知道字符串必须从何处开始。

write()
方法的第一件事是它接受一个bytes对象。因此,您可以构建一个
bytearray()
并将其用作参数。使用ESC/POS打印机初始化命令和字符串的示例:

i = [27,64] #ASCII escape integer and at sign integer
pre = bytearray(i)
cmd = 'Hello You\n'.encode('UTF-8')
#extend bytearray
pre.extend(cmd)
self.send_stream.write(pre)
self.send_stream.flush()

还不知道如何一次性创建bytearray整数和字符串。

您在上面所做的工作做得很好。我刚刚遇到了
CreateRfcomSocket()
的问题,它给出了
JVM异常:读取失败,套接字可能关闭或超时,读取ret