Android Volley JsonArrayRequest

1

The PHP that gives me a list of records through an SQL returns the following

PHP
$result = $con->query($query);
for ($set = array (); $row = $result->fetch_assoc(); $set[] = json_encode($row));
print_r($set);

RESULTADO
Array
(
[0] => {"id":"8783","nombre":"pepe","username":"demo"}
[1] => {"id":"8784","nombre":"garcia","username":"demo"}
)

Now as a process that from Android with Volley, I have the following but obviously it does not work

JsonArrayRequest request = new JsonArrayRequest(URL_2,
                        new Response.Listener<JSONArray>() {
                            @Override
                            public void onResponse(JSONArray jsonArray) {
                                for(int i = 0; i < jsonArray.length(); i++) {
                                    try {
                                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                                        String nombre = jsonObject.getString("name");
                                        Log.e("nombre", nombre);
                                        mEntries.add(jsonObject.toString());

                                    }
                                    catch(JSONException e) {
                                        mEntries.add("Error: " + e.getLocalizedMessage());
                                    }

The error it throws is

com.android.volley.ParseError: org.json.JSONException: Value Array of Type 
java.lang.String cannot be converted to JSONArray

I thank you if you could verify the Volley or modify the PHP to suit the Volley

I modify the volley leaving only the following inside the try and it throws the same error

try {
   Integer cantidad = jsonArray.length();
   Log.e("cantidad: ", cantidad.toString());
}
    
asked by desarrollosTELLO 18.07.2017 в 15:28
source

3 answers

1

The error message tells you that you are sending a string, when Android is expecting a JSONArray , which is not the same as a JSONObject .

public void onResponse(JSONArray jsonArray) { ...

How is a JSONArray of a JSONObject different?

That the JSONArray would be something like this (starts and ends with [] ):

[{
    "0": {
        "id": "8783",
        "nombre": "pepe",
        "username": "demo"
    },
    "1": {
        "id": "8784",
        "nombre": "garcia",
        "username": "demo"
    }
}]

This is the only thing that your PHP service should print, nothing more.

If Android expected a JSONObject would be something like this (starts and ends with {} and Android treats it as a string, in fact, to manipulate a JSONObject you must convert it:

{
    "1": {
        "id": "8783",
        "nombre": "pepe",
        "username": "demo"
    },
    "2": {
        "id": "8784",
        "nombre": "garcia",
        "username": "demo"
    }
}

Since you have this in the code:

public void onResponse(JSONArray jsonArray) {...

Your answer should be something like this :

[{
    "0": {
        "id": "8783",
        "nombre": "pepe",
        "username": "demo"
    },
    "1": {
        "id": "8784",
        "nombre": "garcia",
        "username": "demo"
    }
}]

or any other form of valid JSONArray .

If you expect a JSONArray you can create your JSON like this:

$json=json_encode($set);
header('Content-Type: application/json; charset=utf8');
echo "[".$json."]";

If on the contrary, Android expected a JSONObject ...

public void onResponse(JSONObject jsonObject) { ...

$json=json_encode($set);
header('Content-Type: application/json; charset=utf8');
echo $json;

Obviously, in this second case, the way to read the answer ( parsear ), would be different.

Note: The last line is the only screen output that your service should have. That is, the only thing you should print is what Android expects, and as Android expects, nothing more.

Regarding this line: header('Content-Type: application/json; charset=utf8'); , if you already have it in another part of the script, it is not necessary to put it here. It is used to indicate that the response will have a content of type json and that the encoding will be utf-8 .

    
answered by 18.07.2017 в 16:58
1

According to the documentation of the source code of the class com.android.volley.ParseError

  

Indicate that the server's response could not be parsed.

The problem is not in the Java code but in the PHP code and the way you return the results. The following code works, assumes that the users table exists with the id, nombre, username fields:

<?php

$con = new mysqli("localhost", "root", "yo", "test");

/* comprobar la conexion */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    die;
}

$query = "SELECT * FROM users";
$set = array();

if ($result = $con->query($query)){
    while($row = $result->fetch_assoc()){
        $set[] = $row;
    }

    $result->close();
}
$con->close();

// Especificar que el contenido es del tipo application/json
header("Content-Type: application/json");
print json_encode($set);

This code returns:

[{"id":"1","nombre":"Pepe","username":"user_pepe"},{"id":"2","nombre":"Roberto","username":"user_roberto"},{"id":"3","nombre":"Alberto","username":"user_alberto"}] 

which is a valid response of JSON .

    
answered by 18.07.2017 в 16:40
0

I'll leave you as I'm armed

PHP

<?php
require_once 'conexion.php';
$username = $_REQUEST["username"];
if ($con){
    if ($resultado = $con->query("SELECT r.id, r.'lote', r.'medidor', r.'tarifa', u.id AS idUsuario, u.username FROM lecturas r, usuarios u WHERE r.usuario = u.id AND u.username = '$username' AND r.terminado = 0 AND r.enproceso = 0")) {
        if ($resultado->num_rows > 0) {
            //echo "La selección devolvió filas.\n", $resultado->num_rows;
            $rows = array();
            while($r = mysqli_fetch_array($resultado,MYSQL_ASSOC)) {
                $row_array = $r;
                array_push($rows,$row_array);
            }
            echo utf8_encode(json_encode($rows));
        }else{
            echo "SQL vacía";
        }
    }
}else{
    echo "No nos pudimos conectar con la Base de Datos";
}
?>

And the android code stayed that way, as you can see I send a "username" parameter in the url, I know it can be sent by the Volley but that's how I find it hahaha

button_recibir.setOnClickListener(new View.OnClickListener() {
    public void onClick(View view) {
       dialog = new ProgressDialog(MainActivity.this);
       dialog.setMessage("Recibiendo Trabajos...");
       dialog.show();
       String usuario_z = "demo";
       String URL_2 = "http://www.gesis.com.ar/v2/scripts-E/selectLecturas.php?username=" + usuario_z;

      JsonArrayRequest request = new JsonArrayRequest(URL_2,
        new Response.Listener<JSONArray>() {
        @Override
        public void onResponse(JSONArray jsonArray) {
       //   ArrayList al = new ArrayList(); // esto lo declare mas arriba
       for(int i = 0; i < jsonArray.length(); i++) {
         try {
              JSONObject jsonObject = jsonArray.getJSONObject(i);
              String id = jsonObject.getString("id");
              String medidor = jsonObject.getString("medidor");
              String lote = jsonObject.getString("lote");
              Log.e("Registro", "ID: " + id + "Medidor: " + medidor);
              al.add(i,"ID: " + id + "Lote: " + lote);
         } catch (JSONException e) {
              dialog.dismiss();
              Log.e("error: ", e.toString());
         }
     }
     dialog.dismiss();
     ArrayAdapter adapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, al);
     fruitsList.setAdapter(adapter);
}
},
 new Response.ErrorListener() {
  @Override

  public void onErrorResponse(VolleyError error) {
      Toast.makeText(getApplicationContext(), "Ocurrió un error!!", Toast.LENGTH_SHORT).show();
      Log.e("ERROR", error.toString());
      dialog.dismiss();
}
}) {

 public Map<String, String> getHeaders() throws AuthFailureError {
 HashMap<String, String> headers = new HashMap<String, String>();
 headers.put("Content-Type", "application/json; charset=utf-8");
 headers.put("User-agent", System.getProperty("http.agent"));
  return headers;
}
};
requestQueue.add(request);
}
});
    
answered by 20.07.2017 в 13:55