Traiter avec unicode , comment se débarrasser? Android / java

J'utilise une bibliothèque d'émulateurs de terminal pour créer un terminal puis je l'utilise pour envoyer les données saisies sur une série à un périphérique série. La bibliothèque peut être vue ici .

Lorsque je saisis des données dans le terminal, une étrange série de caractères est envoyée / reçue. Je pense que le personnage de remplacement Unicode est envoyé sur série, le périphérique série ne sait pas ce qu'il est et renvoie ~ 0.

  • Erreur: (23, 17) Impossible de résoudre: junit: junit: 4.12
  • Comment utiliser manuellement le package AAR externe en utilisant le nouveau système de compilation Android Gradle
  • Comment configurer Appium sur Mac OS pour exécuter des tests automatisés à partir de classes JAVA sur les appareils Android et iOS
  • Android 4.3: comment se connecter à plusieurs périphériques Bluetooth Low Energy
  • Envoyer et recevoir IQ XMPP ASMACK Android
  • Aucune erreur "Seul le fil d'origine créé par une hiérarchie de vue peut toucher ses vues" lorsque la vue est mise à jour sans délai
  • Capture d'écran de ce qui apparaît dans le terminal lorsque j'écris "test": Entrez la description de l'image ici

    Et le journal indiquant les chaînes envoyées et les données reçues. Http://i.imgur.com/x79aPzv.png

    Je crée un EmulatorView, c'est la vue de terminal. Il mentionne les diamants ici .

    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); } } 

    Y a-t-il un moyen de réparer ça? Quelqu'un peut-il voir dans la classe de la bibliothèque pourquoi cela se produit ?, Comment puis-je me référer à dans java pour analyser si je le voulais? Je ne peux pas dire si (! Str.contains (" ") Je le prends.

    Lorsque je tape dans le terminal, cela s'exécute:

     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; } 

    C'est ce que j'appelle pour envoyer des données. SendData (Byte [] data) est une méthode de bibliothèque.

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

    Une fois les données envoyées, la réponse est reçue ici:

     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); } 

    Section pertinente de la classe de bibliothèque où les caractères sont écrits:

    Section pertinente de la classe:

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

  • À propos du champ "_id" dans Android SQLite
  • Comment obtenir un jeton de rafraîchissement pour google plus dans Android?
  • Lien entre les autorisations Android et les groupes de permission
  • Android DatePicker ne modifie que le mois et l'année
  • Modifiez la couleur de texte d'un seul ClickableSpan lorsque vous appuyez sur sans affecter d'autres ClickableSpans dans le même TextView
  • Mise en œuvre de 47deg android-swipelistview pour le déplacement de Android ListViewItem
  • 3 Solutions collect form web for “Traiter avec unicode , comment se débarrasser? Android / java”

    Java stocke le texte en interne comme non codé Unicode. Utilisé pour être 16 bits, maintenant je suppose que c'est 32 en fonction du fait que vous obtenez quatre caractères de sortie sur votre terminal pour chaque caractère unicode que vous essayez de produire.

    Ce que vous voulez probablement faire, c'est utiliser quelque chose comme string.getBytes ("ASCII") pour convertir votre chaîne unicode en ascii simple à un seul octet. Si votre émulateur de terminal gère les autres jeux de caractères (comme Latin-1), utilisez-le au lieu de "ASCII".

    Ensuite, transmettez les octets à votre émulateur de terminal au lieu de la chaîne.

    Remarques: Je ne pense pas que "ASCII" soit le nom exact du jeu de caractères; Vous allez vouloir le rechercher vous-même. En outre, je ne sais pas ce que getBytes () fera avec des caractères unicode qui ne peuvent pas être traduits dans Ascii, donc vous voudrez aussi le rechercher.

    ETA: J'ai du mal à suivre votre logique de code à partir des restes que vous avez posté. Qui appelle l'écriture (), d'où proviennent les données et où est-ce? La même question s'applique à sendOverSerial () et onDataReceived ().

    En tout état de cause, je suis presque certain que quelque part , les données Unicode 32 bit brutes ont été converties en octets sans être codées. À partir de ce moment-là, soit l'envoi tel quel, soit le recodage, car UTF-8 produirait l'effet que vous voyez. Je ne vois pas comment cela aurait pu se produire dans l'un des codes que vous avez posté, alors je suppose que cela s'est produit ailleurs avant que l'une des fonctions que vous nous avez montrées soit appelée.

    J'ai résolu ce problème en éditant la bibliothèque que j'utilise. Ils utilisaient une méthode qui a converti un octet en un int, il a accepté un codePoint et l'a converti. Donc, pour chaque touche, on utilise 4 octets. J'ai changé cela pour qu'un octet soit utilisé au lieu d'un int. Plus d'octets supplémentaires. Il n'y a rien à voir avec le format de codage.

    Il semble que la bibliothèque que vous utilisez envoie des points de code comme int (qui sont 32 bits) et que votre code suppose qu'il est codé comme utf-8 qui ne gère pas correctement les 4 octets. Ceci n'est pas lié à la façon dont les fichiers java stockent en interne. Btw Java stocke le texte en interne comme UTF-16 codé, non codé unicode. Encore une fois, ce n'est pas la cause de ce problème. C'est comment vous interagissez avec la bibliothèque que vous utilisez.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.