Android, PHP and HttpURLConnection - Send message to PHP with UTF-8

2

Sirs, very good day / afternoon / evening!

I'm having problems with word accentuation. The backend of my system works in PHP by talking to an Android app. When I send the message from the App to the server PHP works normally, and PHP responds as expected, but if the message sent to PHP includes characters with an accent the App presents an error and stops.

I've researched of course, but a lot of people are using HttpClient and I'm using HttpURLConnection.

I have tried to include a line saying RequestProperty is UTF-8, but it did not work.

Follow the Connection class I'm using.

package Conexao;

import android.util.Log;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by billy on 21/05/2016.
 */
public class Conexao {

    private static Conexao instancia;
    public static String urlString;

    private Conexao() {
        //nothing
    }

    public static Conexao getInstancia() {
        if (instancia == null) {
            instancia = new Conexao();
        }
        return instancia;
    }

    public static JSONArray executePost(JSONObject json) {

        JSONArray jsonArray = null;

        try {
            URL url = new URL(urlString);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");

            conn.setRequestProperty("contentType", "application/json");

            conn.connect();

            conn.setConnectTimeout(1000);

            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());

            wr.writeBytes(json.toString());

            InputStream is = conn.getInputStream();
            BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            StringBuilder responseStrBuilder = new StringBuilder();

            String inputStr;
            while ((inputStr = streamReader.readLine()) != null)
                responseStrBuilder.append(inputStr);

            jsonArray = new JSONArray(responseStrBuilder.toString());

        } catch (Exception e) {
            Log.e("Erro ", e.toString());
        }

        Log.i("Resposta: ", jsonArray.toString());

        return jsonArray;
    }

}

Thanks in advance.

Gentlemen, as requested, follows the logcat:

09-22 20:01:39.959 25838-25838/? E/Zygote: v2
09-22 20:01:39.969 25838-25838/? E/SELinux: [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
09-22 20:02:06.999 25838-26110/br.com.infogruposi.sct E/Erro: org.json.JSONException: Value Nenhum of type java.lang.String cannot be converted to JSONArray
09-22 20:02:07.019 25838-26110/br.com.infogruposi.sct E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #4
                                                                        Process: br.com.infogruposi.sct, PID: 25838
                                                                        java.lang.RuntimeException: An error occured while executing doInBackground()
                                                                            at android.os.AsyncTask$3.done(AsyncTask.java:300)
                                                                            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
                                                                            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
                                                                            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                                                                            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
                                                                            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                                            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                                            at java.lang.Thread.run(Thread.java:818)
                                                                         Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.json.JSONArray.toString()' on a null object reference
                                                                            at Conexao.Conexao.executePost(Conexao.java:68)
                                                                            at br.com.infogruposi.sct.ActAbreChamadoUsu$JSONTransmitter.doInBackground(ActAbreChamadoUsu.java:47)
                                                                            at br.com.infogruposi.sct.ActAbreChamadoUsu$JSONTransmitter.doInBackground(ActAbreChamadoUsu.java:42)
                                                                            at android.os.AsyncTask$2.call(AsyncTask.java:288)
                                                                            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
                                                                            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                                                                            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                                                                            at java.lang.Thread.run(Thread.java:818) 

Gentlemen, I'm doing tests and the following excerpt I removed from my debug:

json = {JSONObject@18906} "{"cha_gru_codigo":"1","cha_pes_usuario":"3","cha_solicitacao":"zé","cha_des_texto":"zinho","classe":"chamado","acao":"usuAbrirChamado"}"
jsonArray = null
url = {URL@18958} "http://www.solusinformatica.890m.com/SCT/SCT/facade/Facade.php"
conn = {HttpURLConnectionImpl@18961} "com.android.okhttp.internal.http.HttpURLConnectionImpl:http://www.solusinformatica.890m.com/SCT/SCT/facade/Facade.php"
wr = {DataOutputStream@18978} 
is = {RealBufferedSource$1@18992} "buffer(com.android.okio.GzipSource@2be6139).inputStream()"
streamReader = {BufferedReader@18997} 
responseStrBuilder = {StringBuilder@19002} ""
inputStr = {String@19007} "Nenhum comando selecionado - <pre>null</pre>"

This last inputStr field is the variable that received the Backend response and the field between the pre tags, with null value is what the backend received from the Android App, that is, when the message has an accent the backend does not receive the data, I think because Android simply does not send them.

I tried to apply the solution described in the post:

#

The App this time sent the message, but PHP received it like this: ze = z% C3% A9

    
asked by anonymous 22.09.2016 / 15:49

1 answer

2

Java code in Android App:

String solicitacao = URLEncoder.encode(txSolicitacao.getText().toString(), "UTF-8");
String descricao = URLEncoder.encode(txDescricao.getText().toString(), "UTF-8");

PHP code in the Backend:

$solicitacao = urldecode(rawurldecode($arrayJson["cha_solicitacao"]));
$descricao = urldecode(rawurldecode($arrayJson["cha_des_texto"]));

urldecode () = converts the + sign to spaces. If you do not use this command, the string looks like this:

here + will + an + example

The problem is that the "+" sign will always be converted to space.

In this case, I think the best option is to send character entities so that they do not have accented characters in the String. When receiving String jSon, PHP can make a parser and replace the character entities with the appropriate special characters, so that it is possible to write to a database.

    
01.10.2016 / 17:11