我一直在摸索使用python for android jnius库从蓝牙RS232转换器获取数据。我原以为它会像 PySerial 库一样简单,但由于我还是 java 新手,所以实现是完全不同的。
我很容易地创建了蓝牙连接,但是一旦我尝试读取或写入数据,我就会得到一个jnius.jnius.JavaException
可用No methods matching your arguments,
的方法read
是: '()I', '([B)I', '([BII)I'
和 for write
are '(I)V', '([B)V', '([BII)V'
。我尝试在开发人员 android 文档以及 DuckDuckGoing 中找到它,但不清楚。我也使用该方法
尝试了BufferedReader
示例(HerereadLine()
) ,但我不断收到错误: 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
对象不返回任何数据?
我调用的 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 和上面的链接获得):
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()
读写代码(来源:与上面的链接相同):
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()
不返回错误并返回字符串的方法获得了输入。我清理了一下,但代码差别不大。主要的事情是我检查了是否在我的事件循环device != None
中if rfsocket.connected:
创建 getInputStream 之前,以免重新创建套接字对象。必须进行更多测试才能看到主要问题在哪里。仍然不知道和的论点是read
什么write
方法的论点是什么。该readLine()
方法间歇地或根本不返回字符串,我的事件循环似乎不适用于该readLine()
方法。
更新更新:
事件循环再次工作。我的错,我没有正确调用触发对象。这readLine()
方法有一个奇怪的模式,在第一次读取时它给了我JavaException: JVM exception occurred: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
,随后的读取给了我预期的字符串片段或空字符串。当我使用 PySerial 通过硬线接收数据时,我返回了类似的字符串位和片段。解决方案是重置输入缓冲区。上面的java库中是否有类似的东西?
终于破解了异常:
是的,这很令人兴奋!几个小时后,我注意到我无法再获得输入,只有例外。我尝试了BufferedInputStream
图书馆并得到了相同的结果,没有更多的间歇阅读。为什么?所以我重新 Apk'd 昨晚的main
文件并再次读取间歇输入。
原因是,如果我在rfsocket
蓝牙对象未连接到指定端口时创建 java 对象,则Null
对象在不同的端口上初始化,由于某种原因,if
块self.recv_stream is not None
和self.recv_stream != None
. 可能是因为它们不是Null
对象,而是Null
我指定的后续端口 1 套接字连接。我的例子中
的工作,需要三个参数readline()
read()
bytes(), int offset, int len(bytes()
jnius.jnius.exception
从象形文字的信息中不清楚。还在摸索write
方法。您可以在该方法中指定的一件事是BufferedReader
您要读取的块大小的第二个参数或在 java speakdefaultCharBufferSize
中。