Работа с unicode , как избавиться? Android / Java

Я использую библиотеку эмуляторов терминала для создания терминала, а затем я использую его для отправки данных, введенных через последовательный порт на последовательное устройство. Здесь можно увидеть библиотеку.

Когда я ввожу данные в терминал, посылается / принимается странная серия символов. Я думаю, что символ замены Юникода отправляется через последовательный порт, серийное устройство не знает, что это такое, и возвращает ~ 0.

Снимок экрана о том, что появляется в терминале, когда я пишу «тест»: Введите описание изображения здесь

И журнал показывает переданные строки и полученные данные. http://i.imgur.com/x79aPzv.png

Я создаю EmulatorView, это терминал. Здесь упоминаются алмазы.

private void sendText(CharSequence text) { int n = text.length(); char c; try { for(int i = 0; i < n; i++) { c = text.charAt(i); if (Character.isHighSurrogate(c)) { int codePoint; if (++i < n) { codePoint = Character.toCodePoint(c, text.charAt(i)); } else { // Unicode Replacement Glyph, aka white question mark in black diamond. codePoint = '\ufffd'; } mapAndSend(codePoint); } else { mapAndSend(c); } } } catch (IOException e) { Log.e(TAG, "error writing ", e); } } 

Есть ли способ исправить это? Может ли кто-нибудь увидеть в классе библиотеки, почему это происходит? Как я могу ссылаться на в java, чтобы даже разобрать его, если захочу? Я не могу сказать, если (! Str.contains (" ") я его принимаю.

Когда я набираю терминал, это запускается:

 public void write(byte[] bytes, int offset, int count) { String str; try { str = new String(bytes, "UTF-8"); Log.d(TAG, "data received in write: " +str ); GraphicsTerminalActivity.sendOverSerial(str.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { Log.d(TAG, "exception" ); e.printStackTrace(); } // appendToEmulator(bytes, 0, bytes.length); return; } 

Это то, что я вызываю для отправки данных. SendData (Byte [] data) – это метод библиотеки.

 public static void sendOverSerial(byte[] data) { String str; try { str = new String(data,"UTF-8"); if(mSelectedAdapter !=null && data !=null){ Log.d(TAG, "send over serial string==== " + str); mSelectedAdapter.sendData(str.getBytes("UTF-8")); } } catch (UnsupportedEncodingException e) { Log.d(TAG, "exception"); e.printStackTrace(); } } 

После отправки данных ответ получен здесь:

 public void onDataReceived(int id, byte[] data) { try { dataReceived = new String(data, "UTF-8"); } catch (UnsupportedEncodingException e) { Log.d(TAG, "exception"); e.printStackTrace(); } try { dataReceivedByte = dataReceived.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { Log.d(TAG, "exception"); e.printStackTrace(); } statusBool = true; Log.d(TAG, "in data received " + dataReceived); ((MyBAIsWrapper) bis).renew(data); runOnUiThread(new Runnable(){ @Override public void run() { mSession.appendToEmulator(dataReceivedByte, 0, dataReceivedByte.length); }}); viewHandler.post(updateView); } 

Соответствующий раздел класса библиотеки, где написаны символы:

Соответствующий раздел класса:

 private void sendText(CharSequence text) { int n = text.length(); char c; try { for(int i = 0; i < n; i++) { c = text.charAt(i); if (Character.isHighSurrogate(c)) { int codePoint; if (++i < n) { codePoint = Character.toCodePoint(c, text.charAt(i)); } else { // Unicode Replacement Glyph, aka white question mark in black diamond. codePoint = '\ufffd'; } mapAndSend(codePoint); } else { mapAndSend(c); } } } catch (IOException e) { Log.e(TAG, "error writing ", e); } } private void mapAndSend(int c) throws IOException { int result = mKeyListener.mapControlChar(c); if (result < TermKeyListener.KEYCODE_OFFSET) { mTermSession.write(result); } else { mKeyListener.handleKeyCode(result - TermKeyListener.KEYCODE_OFFSET, getKeypadApplicationMode()); } clearSpecialKeyStatus(); } элемент private void sendText(CharSequence text) { int n = text.length(); char c; try { for(int i = 0; i < n; i++) { c = text.charAt(i); if (Character.isHighSurrogate(c)) { int codePoint; if (++i < n) { codePoint = Character.toCodePoint(c, text.charAt(i)); } else { // Unicode Replacement Glyph, aka white question mark in black diamond. codePoint = '\ufffd'; } mapAndSend(codePoint); } else { mapAndSend(c); } } } catch (IOException e) { Log.e(TAG, "error writing ", e); } } private void mapAndSend(int c) throws IOException { int result = mKeyListener.mapControlChar(c); if (result < TermKeyListener.KEYCODE_OFFSET) { mTermSession.write(result); } else { mKeyListener.handleKeyCode(result - TermKeyListener.KEYCODE_OFFSET, getKeypadApplicationMode()); } clearSpecialKeyStatus(); } 

Java хранит текст внутри как Unencode Unencode. Используется для 16 бит, теперь я предполагаю, что это 32 на основе того факта, что вы получаете четыре символа вывода на своем терминале для каждого символа юникода, который вы пытаетесь вывести.

То, что вы, вероятно, хотите сделать, это использовать что-то вроде string.getBytes («ASCII»), чтобы преобразовать строку в unicode в прямое однобайтное ascii. Если ваш эмулятор терминала обрабатывает другие наборы символов (например, Latin-1), используйте вместо «ASCII».

Затем передайте байты в эмулятор терминала вместо строки.

Примечания: Я не уверен, что «ASCII» – точное имя набора символов; Вы захотите исследовать это самостоятельно. Кроме того, я не знаю, что getBytes () будет делать с символами Юникода, которые не могут быть переведены на ascii, поэтому вы тоже захотите изучить это.

ETA: У меня возникли проблемы с вашей логикой кода из выписок, которые вы опубликовали. Кто называет write (), откуда взялись данные, и куда он идет? Те же вопросы относятся к sendOverSerial () и onDataReceived ().

В любом случае, я почти уверен, что где-то , необработанные 32-разрядные данные Unicode были преобразованы в байты без кодирования. С этого момента, отправляя его как есть или перекодируя его, как UTF-8, вы получите эффект, который вы видите. Я не понимаю, как это могло произойти в любом из кода, который вы опубликовали, поэтому я предполагаю, что это произошло где-то еще до того, как вызываются какие-либо функции, которые вы нам показывали.

Я решил эту проблему, отредактировав библиотеку, которую я использую. Они использовали метод, который преобразовывал байт в int, он принимал codePoint и преобразовывал его. Поэтому для каждого нажатия клавиши используются 4 байта. Я изменил это так, чтобы вместо байта использовался байт. Больше лишних байтов. Формат кодировки не имеет никакого отношения.

Похоже, что библиотека, которую вы используете, отправляет кодовые точки в виде int (32 бит), и ваш код предполагает, что он закодирован как utf-8, который неправильно обрабатывает 4 байта. Это не связано с тем, как Java хранит текст внутри. Btw Java хранит текст внутри, как кодированный UTF-16, а не unencoded unicode. Опять же, это не причина этой проблемы. Это то, как вы взаимодействуете с библиотекой, которую используете.