lunes, 30 de noviembre de 2020

Android Volley. Consulta programáticamente a servidor Web con PHP desde app Android utilizando librería Volley, con resultados en listView

El usuario se conectará programaticamente a un servidor Web apache desde una app con Android utilizando la librería Volley, los resultados se muestran en Actividad2.java dentro de un listView

Requiere:

- Un Servidor Web con apache, php y mysql instalado.
- Base de Datos con una tabla Alumnos con los siguientes campos: id, nombre, clave, calificacion
- Una PC con Android Studio instalado, con un proyecto en Java creado


################
En el Servidor Web: Apache
################

0. Crear Base de datos id15XXXXX_escuela y tabla Alumnos con anterioridad en el Servidor

1. Colocar en el servidor WEB el script indexJson2.php


------------------------

indexJson2.php

------------------------


<?php


// Consulta a la BD de la tabla Alumnos

// Devuelve un String con un arreglo JSON


//Por seguridad las siguientes 4 variables se recomienda colocarlas en un archivo
//que no se pueda descargar del servidor Apache (usar un #include), por facilidad,
//en esta práctica se colocan dentro del mismo archivo .php 

$servidor="localhost";
$usuario="id15XXXXXX_usrescuela";
$pwdUsuario="C*LJH7XXXXXX";
$nombreBD="id15XXXXX_escuela";



$conexion =  mysqli_connect($servidor, $usuario, $pwdUsuario,$nombreBD);

if (!$conexion) {

    die('No pudo conectarse: ' . mysqli_error($conexion));

}


$consulta = "SELECT * FROM Alumnos";



$result = mysqli_query($conexion, $consulta) or die('No pudo conectarse: ' . mysqli_error($conexion));

$numResults = mysqli_num_rows($result);


        if ($numResults > 0)

        {

    // $data guarda la matriz de los registros consultados

            $data = array();

            while ($row = mysqli_fetch_assoc($result))

            {

                $data[] = $row;

            }

// Crea 3 campos en el arreglo: registros, totRegistros, status

        $result = ['registros' => $data, 'totRegistros' => $numResults, 'status' => 'true'];


// Crea el objeto JSON

        echo json_encode($result);


}else{

    echo "No hay registros";

}



 mysqli_close($conexion);


?> 




######################
En App Android. Crear App  para realizar Consulta con librería Volley
######################


0. Crear proyecto nuevo en Android Studio


1. Requiere permiso de Internet en el Manifest


    <uses-permission android:name="android.permission.INTERNET" />



2. En Gradle Scripts en build.gradle(Module: app) agregar la librería de Volley o actualizar la versión, en versiones nuevas de Android Studio ya esta agregada


implementation 'com.android.volley:volley:1.1.1'

 

Corrección a 2024-3

 

         implementation (libs.volley)


3. Al agregar la línea de volley aparecerá un aviso SyncNow, para descargar las clases de la librería a nuestro proyecto


presionar el link


tardará en descargar algunos segundos o minutos.


4. Crear un nuevo Activity en blanco "Actividad2", en este se muestra el resultado de la consulta



-------------

activity_actividad2.xml

-------------

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    tools:context=".MainActivity" >


    <TextView

        android:id="@+id/tv1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="TextView"

        android:textSize="24sp" />


    <ListView

        android:id="@+id/listView1"

        android:layout_width="match_parent"

        android:layout_height="match_parent" />

</LinearLayout>

-------------




5. En Actividad2.java pegar


-------------

Actividad2.java

-------------

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;


public class Actividad2 extends AppCompatActivity {


    public String[] arregloRegistrosBD;

    private TextView tv1;

    private ListView lv1;



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_actividad2);


        // recibe miArreglo de MainActivity.java

        Bundle bundle = getIntent().getExtras();

        String datos=bundle.getString("miArreglo");

        // Línea siguiente Toast... muestra datos recibidos en miArreglo

        //Toast.makeText(Actividad2.this,datos,Toast.LENGTH_LONG).show();

        parseDataEnArreglo(datos);


        tv1=(TextView)findViewById(R.id.tv1);

        lv1 =(ListView)findViewById(R.id.listView1);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(Actividad2.this, android.R.layout.simple_list_item_1, arregloRegistrosBD);

        lv1.setAdapter(adapter);


        lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {


            @Override

            public void onItemClick(AdapterView<?> parent, View v, int posicion, long id) {

                tv1.setText("Línea: "+ lv1.getItemAtPosition(posicion));

            }

        });


    }


    public void parseDataEnArreglo(String response) {

        /**

         * 1. Convierte String a JSONObject y separa los campos del JSONarray: registros, totRegistros, status

         * 2. Separa los campos de cada línea del arreglo: registros

         * 3. Los coloca en un arreglo de Strings

         */


        try {


            JSONObject jsonObject = new JSONObject(response);

            if (jsonObject.getString("status").equals("true")) {

                JSONArray dataArray = jsonObject.getJSONArray("registros");

                int cuenta = jsonObject.getInt("totRegistros");

                String temporal[] = new String[cuenta];


                for (int i = 0; i < dataArray.length(); i++) {

                    JSONObject dataobj = dataArray.getJSONObject(i);

                    /** Concatena cada campo de la linea en el Arreglo */

                    temporal[i] = dataobj.getString("nombre") +", " +dataobj.getString("clave") +", "+

                            dataobj.getString("calificacion");


                }


                // Copia el arreglo temporal hacia el que se utiliza en el ListView

                arregloRegistrosBD = temporal.clone();

            }else{

                Toast.makeText(Actividad2.this,"No devolvió registros el servidor",Toast.LENGTH_LONG).show();

            }


        } catch (JSONException e) {

            e.printStackTrace();

        }




    }


}



--------------



6. En activity_main.xml crear un boton y un TextView dentro de un scrollview (solo para ver resultados, es opcional)


-------------

activity_main.xml

-------------


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent">


    <Button

        android:id="@+id/buttonVolley"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:onClick="buscaVolley"

        android:text="Buscar con Volley" />



    <ScrollView

        android:layout_width="match_parent"

        android:layout_height="match_parent">


        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="vertical" >


            <TextView

                android:id="@+id/TextView01"

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:textSize="8pt" />

        </LinearLayout>

    </ScrollView>



</LinearLayout>


-------------





7. En MainActivity.java colocar el código para hacer la consulta con Volley, en este Activity se hace la conexión con Volley y se pasa el resultado a Actividad2


Inicializar cola de peticiones Volley


Conectar al servidor donde esta el script "https://nombreDeServidor/ejemplo/indexJson2.php"



-------------

MainActivity.java

-------------

import androidx.appcompat.app.AppCompatActivity;



import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.widget.TextView;

import android.widget.Toast;

import com.android.volley.Request;

import com.android.volley.RequestQueue;

import com.android.volley.Response;

import com.android.volley.VolleyError;

import com.android.volley.toolbox.StringRequest;

import com.android.volley.toolbox.Volley;

import java.util.HashMap;


import java.util.Map;

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;


public class MainActivity extends AppCompatActivity {

    private TextView salida;

    private RequestQueue requestQueue;


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        salida = (TextView) findViewById(R.id.TextView01);


        //Inicializa cola de Volley

        requestQueue = Volley.newRequestQueue(this);


    }


    // Volley

    public void buscaVolley(View v){

        /**

         * Conecta al servidor utilizando Volley con POST

         * El servidor devuelve un ObjetoJSON con 3 campos: registros, status

         * Se le pueden pasar parámetros a través de un HashMap

         * Más información de Volley en : https://demonuts.com/android-volley/

         */


        // En la siguiente línea se debe sustituir con el nombreDelServidor

        String URLline = "https://nombreDelServidor.com/ejemplo/indexJson2.php";

        


        /** Para pasar algun parámetro al servidor por POST, se crean propiedades

         *  que obtienen información de los EditText, ejemplo: siguientes 2 lineas

         *  */


        //final String username = etUname.getText().toString().trim();

        //final String password = etPass.getText().toString().trim();


        StringRequest stringRequest = new StringRequest(Request.Method.POST, URLline,

                new Response.Listener<String>() {

                    @Override

                    public void onResponse(String response) {

                        Toast.makeText(MainActivity.this,"Conectando usando Volley",Toast.LENGTH_SHORT).show();


                        // LINEA SIGUIENTE CANCELADA Muestra los registros en TextView: salida

                        //parseData(response);


                        // Lanza Actividad2 y envia String con JSONarray: miArreglo

                        Intent i=new Intent(MainActivity.this, Actividad2.class);

                        i.putExtra("miArreglo", response);

                        startActivity(i);


                    }


                },

                new Response.ErrorListener() {

                    @Override

                    public void onErrorResponse(VolleyError error) {

                        Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_LONG).show();

                        salida.setText("Error de Volley, posible falla en conexión \n"+error.toString());

                    }

                }){


            @Override


            protected Map<String,String> getParams(){

                /**

                 *   Cada parámetro que se pasa al Servidor por POST, se coloca en el HashMap

                 * */


                Map<String,String> params = new HashMap<String, String>();

                // 2 Lineas CANCELADAS, muestran ejemplo de paso de parámetros

                //params.put("username",username);

                //params.put("password",password);


                return params;

            }

        };

        requestQueue.add(stringRequest);

    }


    public void parseData(String response) {

        /**

         * 1. Convierte String a JSONObject y separa los campos del JSONarray: registros, status

         * 2. Separa los campos de cada línea del arreglo: registros

         */


        try {

            JSONObject jsonObject = new JSONObject(response);

            if (jsonObject.getString("status").equals("true")) {

                JSONArray dataArray = jsonObject.getJSONArray("registros");

                for (int i = 0; i < dataArray.length(); i++) {

                    JSONObject dataobj = dataArray.getJSONObject(i);

                    /** Concatena cada linea en el TextView salida */

                    salida.append(dataobj.getString("nombre") +"  ");

                    salida.append(dataobj.getString("clave") +"  ");

                    salida.append(dataobj.getString("calificacion") +"\n");

                }

                //Intent intent = new Intent(MainActivity.this,HobbyActivity.class);

                //startActivity(intent);

            }

        } catch (JSONException e) {

            e.printStackTrace();

        }

    }


}

------------- Termina MainActivity.java

Proyectos 2024. Desarrollo de Aplicaciones Móviles. UAT-FIC

Profesor: Dr. Juan José Garza Saldaña   Facultad de Ingeniería y Ciencias Universidad Autónoma de Tamaulipas Los estudiantes de la materia d...