Как использовать pyjnius для чтения и записи аргументов для Bluetooth getInputStream и getOutputStream? - PullRequest
1 голос
/ 21 октября 2019

Я возился с получением данных из конвертера bluetooth RS232, используя библиотеку python for android jnius. Я думал, что это будет так же просто, как библиотека PySerial, но, поскольку я все еще новичок в Java, реализация совсем другая.
Я довольно легко создал соединение Bluetooth, но как только я пытаюсь прочитать или записать данные, я получаю jnius.jnius.JavaException, No methods matching your arguments, и методы, доступные для read: '()I', '([B)I', '([BII)I' и write являются '(I)V', '([B)V', '([BII)V'. Я пытался найти это в документации для разработчиков Android, а также DuckDuck, но без какой-либо ясности.
Я также попробовал пример BufferedReader ( Здесь ), используя метод readLine(), но постоянно получаю сообщение об ошибке: 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 внутри моего Eventloop, чтобы не создавать заново объект сокета. Приходится тестировать больше, чтобы увидеть, где была главная проблема. До сих пор не знаю, каковы аргументы метода read и write. Метод readLine() возвращает строку с перебоями или не возвращает ее вообще, и кажется, что моя eventloop не работает с методом readLine().

Обновление при обновлении:

Цикл обработки событий снова работает. Мой плохой, я неправильно вызвал триггерный объект. У метода readLine() есть странный паттерн: при первом чтении он дает мне JavaException: JVM exception occurred: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference, при последующих чтениях - части ожидаемой или пустой строки. У меня были похожие строки и кусочки, возвращенные, когда я получил данные через жесткую линию, используя PySerial. Решение было сбросить входной буфер. Есть ли что-то похожее в вышеупомянутых библиотеках Java?

Наконец-то взломаны исключения:

Да, это захватывающе! Через много часов я заметил, что больше не могу получать входные данные, кроме исключений. Я попробовал библиотеку BufferedInputStream и получил тот же результат, больше не было прерывистого чтения. Почему? Итак, я повторно отправил файл main прошлой ночи, и прерывистый ввод читался еще раз.
Причина была в том, что, если я создаю java-объекты, когда объект rfsocket Bluetooth не подключен к указанному порту, Null объекты были инициализированы на другом порту, который по какой-то причине не был замечен блоками ifself.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, это 2-й аргумент для размера чанка, который вы хотите прочитать, или в языке java defaultCharBufferSize.

...