如何为蓝牙getInputStream和getOutputStream使用pyjnius读写参数? [英] How to use the pyjnius read and write arguments for Bluetooth getInputStream and getOutputStream?

查看:208
本文介绍了如何为蓝牙getInputStream和getOutputStream使用pyjnius读写参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用python for android jnius库从蓝牙RS232转换器获取数据.我曾以为它会像PySerial库一样简单,但是由于我还是java的新手,其实现却大不相同.
我很容易地创建了蓝牙连接,但是当我尝试读取或写入数据时,我得到一个jnius.jnius.JavaException,该No methods matching your arguments,以及read可用的方法是:'()I', '([B)I', '([BII)I''(I)V', '([B)V', '([BII)V'.我试图在开发人员的android文档以及DuckDuckGoing中找到它,但不清楚.
我还尝试了BufferedReader示例(

I have been fumbling with getting data from a bluetooth RS232 converter using the python for android jnius library. I had thought that it would be as simple as the PySerial library, but as I am still new to java the implementation is quite different.
I created the bluetooth connection quite easily, but as soon as I try to read or write data I get a jnius.jnius.JavaException that No methods matching your arguments, and that the methods available for read are: '()I', '([B)I', '([BII)I' and for write are '(I)V', '([B)V', '([BII)V'. I tried finding this in the developer android docs as well as DuckDuckGoing it but with no clarity.
I also tried the BufferedReader example (Here) using the readLine() method, but I am constantly getting an error: JavaException: JVM exception occurred: Attempt to invoke virtual method 'int java.io.InputStream.read(byte[], int, int)' on a null object reference.

有人可以指出我的文档以理解上述读写参数吗?
另外,请帮助我理解为什么read, readLine() and write对象为什么不返回任何数据?

Can someone please point me to the documentation to understand the above read and write arguments?
Also, please help me to understand why the read, readLine() and write objects does not return any data?

我称之为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和以上链接获得此信息):

Connecting code (got this from Github and above link):

    def get_socket_stream(self, name):
        paired_devices = BluetoothAdapter.getDefaultAdapter().getBondedDevices().toArray()
        self.rfsocket == None
        for device in paired_devices:
            if device.getName() == name:
                if device.bluetoothEnabled:
                    if not device.connected:
                        self.rfsocket = device.createInsecureRfcommSocketToServiceRecord(
                            UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"))
                        self.reader = InputStreamReader(self.rfsocket.getInputStream(), 'LATIN-1')
                        recv_stream = BufferedReader(self.reader)
                        send_stream = self.rfsocket.getOutputStream()
                        break
        print(self.rfsocket.getRemoteDevice().getName())
        if self.rfsocket.port <= 0:
            self.rfsocket = device.createRfcommSocket(1)
            if not self.rfsocket.connected:
                print('port two: ',self.rfsocket.port)
                self.rfsocket.connect()

读写代码(来源:与上面的链接相同):

Read and write code (source: same as above link):

    def GetBSerial(self):
        self.messager('Trying Serial')
        self.recv_stream, self.send_stream = self.get_socket_stream(devicename)
        if  not self.rfsocket.connected and self.recv_stream == None:
            print("Get paired device failed")
        else:
            print('Initiating trigger')
            self.weight_ticker()
    def GetInput(self):
        self.send_stream.write("Hallo\r\n")
        self.send_stream.flush
        if self.rfsocket.connected and self.recv_stream != None:
            if self.weigh_tme > 0:
                while self.recv_stream.ready != None:
                    try:
                        self.scale_output = self.recv_stream.readLine()
                    except jnius.jnius.JavaException as e:
                        print("JavaException: ", e, self.rfsocket.connected)
                    except ValueError as e:
                        print("Misc error: ", e)

                    try:
                        self.show_input(self.scale_output)
                    except ValueError:
                        pass

更新:

所以我最终使用readLine()方法获得了Input,不返回错误,也返回了字符串.我整理了一下,但是代码并没有太大的区别.不过,主要的事情是我在eventloop中创建getInputStream之前检查了device != Noneif rfsocket.connected:是否,以免重新创建套接字对象.必须进行更多测试以查看主要问题在哪里.仍然不要不理解readwrite方法的参数. readLine()方法间歇性返回字符串或根本不返回该字符串,并且我的eventloop似乎不适用于readLine()方法.

Update:

So I finally got the Input using the readLine() method to not return an error and also return the string. I cleaned things up a bit, but the code does not differ much. Main thing though is I checked whether the device != None and if rfsocket.connected: before creating getInputStream within my eventloop, so as not to re-create the socket object. Have to test more to see where was the main problem. Still do not no what the arguments are of the read and write method. The readLine() method returns the string intermitantly or not at all and my eventloop seems to not work with the readLine() method.

事件循环再次起作用.不好,我没有正确调用触发器对象. readLine()方法有一个奇怪的模式,在第一次读取时,它会给我JavaException: JVM exception occurred: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference,随后的读取时,会给我一些期望的字符串或空字符串.当我使用PySerial通过硬线接收数据时,我返回了相似的字符串片段.解决方案是重置输入缓冲区.上面的Java库中有类似的东西吗?

The event loop works again. My bad, I did not call the trigger object correctly. The readLine() method has a strange pattern in that on the first read it gives me JavaException: JVM exception occurred: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference, subsequent reads gives me pieces of the expected string or an empty string. I had similar string bits and pieces returned when I received the data via a hardline using PySerial. The solution was resetting the input buffer. Is there something similar in the above java libraries?

是的,这很令人兴奋!很多小时后,我注意到我再也无法获得输入了,只有例外.我尝试了BufferedInputStream库,并得到了相同的结果,没有更多的间断性读取.为什么?因此,我重新批准了昨晚的main文件,并再次读取了繁荣的间歇输入.
原因是如果rfsocket蓝牙对象未连接到指定端口时我创建了Java对象,则Null对象被初始化在另一个端口上,由于某些原因,ifself.recv_stream is not None无法看到该对象.和self.recv_stream != None.可能是因为它们不是我指定的后续端口1套接字连接的Null对象,而是Null.
readline()的工作方式与我的示例相同,read()带有三个参数bytes(), int offset, int len(bytes(),这在jnius.jnius.exception象形文字的消息中并不清楚.仍在弄清楚write方法.您可以在BufferedReader方法中指定的一件事是要读取的块大小的第二个参数,或者用Java语言说defaultCharBufferSize.

Yes, this is exciting! After many hours I had noticed that I could not get the Input anymore only exceptions. I tried the BufferedInputStream library and got the same result, there was no more intermittant read. Why? So I re-Apk'd the main file of last night and boom intermittant Input read once again.
The reason was if I create the java objects when the rfsocket Bluetooth object is not connected to the specified port, Null objects was initialised on a different port which for some reason was not seen by the if blocks self.recv_stream is not None and self.recv_stream != None. Probably because they are not Null objects but Null for the subsequent port 1 socket connection I specified.
The readline() work as is in my example, the read() takes three arguments bytes(), int offset, int len(bytes() which is not clear from the jnius.jnius.exception hieroglyphics' message. Still figuring out the write method. One thing that you can specify in the BufferedReader method is a 2nd argument for the chunk size you want to read or in java speak defaultCharBufferSize.

推荐答案

因此,我在解决所有问题后都会发布我的答案.
要连接到蓝牙,我在
GitHub示例的基础上,遵循了 Android开发人员网站.在创建getOutputStreamgetInputStream java对象之前,我必须显式设置自己的套接字,否则连接和对象的端口将不同.您只需调用GetBSerial()进行连接

So I am posting my answers as I have solved them all.
To connect to bluetooth I built on the GitHub example by following the suggestions on the android developers site. I had to set my own socket explicitly before creating the getOutputStream and getInputStream java objects otherwise the ports of the connection and objects will not be the same. You only need to call the GetBSerial() to connect

    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]'

我使用了readLine()方法,但是要使用read()方法,有两种方法来构建字符串.在外部(我只尝试过此操作)或在数组中.
导入:

I used the readLine() method, but to use the read() method, there are two ways to build a string. Either externally (I only tried this one) or in an Array.
Import:

CharBuilder = autoclass('java.lang.Character')

外部:

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()方法的第一件事是它需要一个字节对象.因此,您构建一个bytearray()并将其用作参数.使用ESC/POS打印机初始化命令和字符串的示例:

You have to play around with building your string to know where the string must start.

The first thing about the write() method is it takes a bytes object. So you build a bytearray() and use it as an argument. Example using ESC/POS printer initialise command and a string:

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()

还不知道如何一次性创建字节数组整数和字符串.

Could not figure out how to create a bytearray integer and string in one go, yet.

这篇关于如何为蓝牙getInputStream和getOutputStream使用pyjnius读写参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆