Problème Android Java UTF-8 HttpClient

J'ai des problèmes étranges de codage de caractères avec un tableau JSON qui est saisi à partir d'une page Web. Le serveur renvoie cet en-tête:

Content-Type text / javascript; Charset = UTF-8

  • WearableListenerService, onDataChanged () n'est pas appelé
  • Comment passer un paramètre au code Java dans la configuration run / debug depuis Android Studio
  • Comment déployer le projet Android Xamarin vers Xamarin Android Player dans VS 2015
  • Android ContentProvider URI scheme pour notifier CursorAdapters en écoutant les requêtes OUTER JOIN
  • Espace entre editText et softkeyboard
  • Comment afficher l'imageVoir l'écran complet sur imageVoir cliquer?
  • Aussi, je peux regarder la sortie JSON dans Firefox ou tout navigateur et les caractères Unicode s'affichent correctement. La réponse contiendra parfois des mots d'une autre langue avec des symboles d'accent et autres. Cependant, j'ai des signes de questions étranges lorsque je le retiens et je l'ai mis dans une chaîne Java. Voici mon code:

    HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, "utf-8"); params.setBooleanParameter("http.protocol.expect-continue", false); HttpClient httpclient = new DefaultHttpClient(params); HttpGet httpget = new HttpGet("http://www.example.com/json_array.php"); HttpResponse response; try { response = httpclient.execute(httpget); if(response.getStatusLine().getStatusCode() == 200){ // Connection was established. Get the content. HttpEntity entity = response.getEntity(); // If the response does not enclose an entity, there is no need // to worry about connection release if (entity != null) { // A Simple JSON Response Read InputStream instream = entity.getContent(); String jsonText = convertStreamToString(instream); Toast.makeText(getApplicationContext(), "Response: "+jsonText, Toast.LENGTH_LONG).show(); } } } catch (MalformedURLException e) { Toast.makeText(getApplicationContext(), "ERROR: Malformed URL - "+e.getMessage(), Toast.LENGTH_LONG).show(); e.printStackTrace(); } catch (IOException e) { Toast.makeText(getApplicationContext(), "ERROR: IO Exception - "+e.getMessage(), Toast.LENGTH_LONG).show(); e.printStackTrace(); } catch (JSONException e) { Toast.makeText(getApplicationContext(), "ERROR: JSON - "+e.getMessage(), Toast.LENGTH_LONG).show(); e.printStackTrace(); } private static String convertStreamToString(InputStream is) { /* * To convert the InputStream to String we use the BufferedReader.readLine() * method. We iterate until the BufferedReader return null which means * there's no more data to read. Each line will appended to a StringBuilder * and returned as String. */ BufferedReader reader; try { reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); } catch (UnsupportedEncodingException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } StringBuilder sb = new StringBuilder(); String line; try { while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } 

    Comme vous pouvez le voir, je spécifie UTF-8 sur InputStreamReader mais chaque fois que je visualise le texte JSON retourné via Toast, il a des points d'interrogation étranges. Je pense que je dois envoyer InputStream à un octet [] à la place?

    Merci d'avance pour votre aide.

  • GridView avec différentes tailles de cellules, style pinterest
  • Android Fragment transition exit animation joué ci-dessus, entrez l'animation
  • Prévisualisation de la vue de recyclage horizontale dans le studio Android
  • Un équivalent équivalent pour View.getX () avant l'API 11?
  • La vidéo ne s'affiche pas sur VideoView mais je peux entendre son son
  • Android - Obtenir de l'audio pour jouer à travers l'écouteur
  • 5 Solutions collect form web for “Problème Android Java UTF-8 HttpClient”

    Essaye ça:

     if (entity != null) { // A Simple JSON Response Read // InputStream instream = entity.getContent(); // String jsonText = convertStreamToString(instream); String jsonText = EntityUtils.toString(entity, HTTP.UTF_8); // ... toast code here } 

    @ La réponse d'Arhimed est la solution. Mais je ne vois rien de tout à fait erroné avec votre code convertStreamToString .

    Mes suppositions sont:

    1. Le serveur met en place une marque de commande d'octet UTF (BOM) au début du flux. Le décodeur de caractères Java UTF-8 standard ne supprime pas la nomenclature, donc il est probable qu'il finisse dans la chaîne résultante. (Cependant, le code pour EntityUtils ne semble pas faire quoi que ce soit avec les BOM non plus).
    2. Votre convertStreamToString lit le flux de caractères d'une ligne à la fois et le réassemblant à l'aide d'un '\n' câblé comme marqueur de fin de ligne. Si vous allez l'écrire à un fichier ou une application externe, vous devriez probablement utiliser un marqueur de fin de ligne spécifique à la plate-forme.

    C'est que votre convertStreamToString n'engage pas l'encodage dans HttpRespnose. Si vous regardez à l'intérieur de EntityUtils.toString(entity, HTTP.UTF_8) , vous verrez que EntityUtils découvre s'il existe un encodage défini dans HttpResponse en premier, alors s'il existe, EntityUtils utilise ce codage. Il ne retombera que sur le codage passé dans le paramètre (dans ce cas HTTP.UTF_8) s'il n'y a pas de codage défini dans l'entité.

    Vous pouvez donc dire que votre HTTP.UTF_8 est passé dans le paramètre, mais il ne s'utilise jamais car il s'agit d'un mauvais codage. Voici donc la mise à jour de votre code avec la méthode helper à partir d'EntityUtils.

      HttpEntity entity = response.getEntity(); String charset = getContentCharSet(entity); InputStream instream = entity.getContent(); String jsonText = convertStreamToString(instream,charset); private static String getContentCharSet(final HttpEntity entity) throws ParseException { if (entity == null) { throw new IllegalArgumentException("HTTP entity may not be null"); } String charset = null; if (entity.getContentType() != null) { HeaderElement values[] = entity.getContentType().getElements(); if (values.length > 0) { NameValuePair param = values[0].getParameterByName("charset"); if (param != null) { charset = param.getValue(); } } } return TextUtils.isEmpty(charset) ? HTTP.UTF_8 : charset; } private static String convertStreamToString(InputStream is, String encoding) { /* * To convert the InputStream to String we use the * BufferedReader.readLine() method. We iterate until the BufferedReader * return null which means there's no more data to read. Each line will * appended to a StringBuilder and returned as String. */ BufferedReader reader; try { reader = new BufferedReader(new InputStreamReader(is, encoding)); } catch (UnsupportedEncodingException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } StringBuilder sb = new StringBuilder(); String line; try { while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } 

    La réponse d'Archimed est correcte. Cependant, cela peut se faire simplement en fournissant un en-tête supplémentaire dans la requête HTTP:

     Accept-charset: utf-8 

    Pas besoin d'enlever quoi que ce soit ou d'utiliser une autre bibliothèque.

    Par exemple,

     GET / HTTP/1.1 Host: www.website.com Connection: close Accept: text/html Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.10 Safari/537.36 DNT: 1 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: utf-8 

    Très probablement, votre demande n'a pas d'en Accept-Charset tête Accept-Charset .

    Extrayez le jeu de caractères à partir du champ de type de contenu de réponse. Vous pouvez utiliser la méthode suivante pour ce faire:

     private static String extractCharsetFromContentType(String contentType) { if (TextUtils.isEmpty(contentType)) return null; Pattern p = Pattern.compile(".*charset=([^\\s^;^,]+)"); Matcher m = p.matcher(contentType); if (m.find()) { try { return m.group(1); } catch (Exception e) { return null; } } return null; } 

    Ensuite, utilisez le jeu de caractères extrait pour créer InputStreamReader :

     String charsetName = extractCharsetFromContentType(connection.getContentType()); InputStreamReader inReader = (TextUtils.isEmpty(charsetName) ? new InputStreamReader(inputStream) : new InputStreamReader(inputStream, charsetName)); BufferedReader reader = new BufferedReader(inReader); 
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.