Implementar una aplicación que permita consultar, modificar y borrar registros de una tabla de MySQL localizada en Internet y su acceso por un Script en PHP.
Tenemos la tabla en un servidor web llamada:
create table articulos ( codigo int primary key AUTO_INCREMENT, descripcion varchar(50), precio float );
Crearemos el proyecto 'Compose25'
Agregamos las dependencias de la biblioteca Volley:
dependencies { ... implementation 'com.android.volley:volley:1.2.0' }
Nuestra aplicación debe acceder a internet por lo que debemos pedir dicho permiso:
<uses-permission android:name="android.permission.INTERNET"/>
Debemos llamar a las URLs:
https://scratchya.com.ar/videosandroidjava/volley/consultar.php?codigo=? https://scratchya.com.ar/videosandroidjava/volley/modificar.php https://scratchya.com.ar/videosandroidjava/volley/borrar.php
En el servidor hay un archivo en PHP llamado 'consultar.php':
<?php header('Content-Type: application/json'); require("conexion.php"); $conexion = retornarConexion(); $datos = mysqli_query($conexion, "select codigo,descripcion,precio from articulos where codigo=$_GET[codigo]"); $resultado = mysqli_fetch_all($datos, MYSQLI_ASSOC); echo json_encode($resultado); ?>
En el servidor hay otro archivo PHP llamado 'modificar.php':
<?php header('Content-Type: application/json'); $datos = json_decode(file_get_contents("php://input"), true); require("conexion.php"); $conexion = retornarConexion(); mysqli_query($conexion, "update articulos set descripcion='$datos[descripcion]', precio=$datos[precio] where codigo=$datos[codigo]"); $cant = mysqli_affected_rows($conexion); if ($cant==1) echo '{"resultado":"1"}'; else echo '{"resultado":"0"}';
En el servidor hay otro archivo PHP llamado 'borrar.php':
<?php header('Content-Type: application/json'); $datos = json_decode(file_get_contents("php://input"), true); require("conexion.php"); $conexion = retornarConexion(); mysqli_query($conexion, "delete from articulos where codigo=$datos[codigo]"); $cant = mysqli_affected_rows($conexion); if ($cant==1) echo '{"resultado":"1"}'; else echo '{"resultado":"0"}';Y un archivo 'conexion.php'
<?php function retornarConexion() { $server="localhost"; $usuario="xxxx"; $clave="xxxx"; $base="xxxx"; $con=mysqli_connect($server,$usuario,$clave,$base) or die("problemas") ; mysqli_set_charset($con,'utf8'); return $con; } ?>
La interfaz visual que debemos implementar con Compose debe ser similar a:
El código a implementar en Kotlin para obtener dicha funcionalidad es:
package com.tutorialesprogramacionya.compose25 import android.content.Context import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Button import androidx.compose.material.OutlinedTextField import androidx.compose.material.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.input.KeyboardType import com.android.volley.Request import org.json.JSONException import org.json.JSONObject import com.android.volley.toolbox.JsonArrayRequest import com.android.volley.toolbox.Volley import com.android.volley.toolbox.JsonObjectRequest class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ConsultaArticulo() } } } @Composable fun ConsultaArticulo() { val contexto = LocalContext.current Column( modifier = Modifier.fillMaxSize() ) { var codigo by remember { mutableStateOf("") } var descripcion by remember { mutableStateOf("") } var precio by remember { mutableStateOf("") } var mensaje by remember { mutableStateOf("") } OutlinedTextField( value = codigo, onValueChange = { codigo = it }, label = { Text("Código") }, modifier = Modifier .fillMaxWidth() .padding(10.dp), singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) ) OutlinedTextField( value = descripcion, onValueChange = { descripcion = it }, label = { Text("Descripción") }, modifier = Modifier .fillMaxWidth() .padding(10.dp), singleLine = true ) OutlinedTextField( value = precio, onValueChange = { precio = it }, label = { Text("Precio") }, modifier = Modifier .fillMaxWidth() .padding(10.dp), singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) ) Button( onClick = { ConsultaCodigo( codigo = codigo.toString(), respuesta = { if (it!=null) { descripcion = it.descripcion precio = it.precio.toString() mensaje="" } else { mensaje = "No existe el código de producto ingresado" descripcion="" precio="" } }, contexto = contexto ) }, modifier = Modifier.padding(10.dp) ) { Text(text = "Consultar por código") } Button( onClick = { Modificar( articulo = Articulo(codigo.toInt(),descripcion,precio.toFloat()), respuesta = { if (it) mensaje="Los datos fueron modificados" else mensaje = "No existe el código de producto ingresado" }, contexto = contexto ) }, modifier = Modifier.padding(10.dp) ) { Text(text = "Modificar") } Button( onClick = { Borrar( codigo = codigo, respuesta = { if (it) { mensaje = "Se eliminó el artículo" codigo="" descripcion="" precio="" } else mensaje = "No existe el código de producto ingresado" }, contexto = contexto ) }, modifier = Modifier.padding(10.dp) ) { Text(text = "Borrar artículo (ingresando código)") } Text(text = "$mensaje") } } data class Articulo(val codigo: Int, val descripcion: String, val precio: Float) fun ConsultaCodigo(codigo: String, respuesta: (Articulo?) -> Unit, contexto: Context) { val requestQueue = Volley.newRequestQueue(contexto) val url = "https://scratchya.com.ar/videosandroidjava/volley/consultar.php?codigo=$codigo" val requerimiento = JsonArrayRequest( Request.Method.GET, url, null, { response -> if (response.length() == 1) { try { val objeto = JSONObject(response[0].toString()) val articulo = Articulo( objeto.getString("codigo").toInt(), objeto.getString("descripcion"), objeto.getString("precio").toFloat() ) respuesta(articulo) } catch (e: JSONException) { } } else respuesta(null); } ) { error -> } requestQueue.add(requerimiento) } fun Modificar(articulo: Articulo, respuesta: (Boolean) -> Unit, contexto: Context) { val requestQueue = Volley.newRequestQueue(contexto) val url = "https://scratchya.com.ar/videosandroidjava/volley/modificar.php" val parametros = JSONObject() parametros.put("codigo", articulo.codigo.toString()) parametros.put("descripcion", articulo.descripcion) parametros.put("precio", articulo.precio.toString()) val requerimiento = JsonObjectRequest( Request.Method.POST, url, parametros, { response -> try { val resu = response["resultado"].toString() if (resu == "1") respuesta(true) else respuesta(false) } catch (e: JSONException) { respuesta(false) } } ) { error -> respuesta(false) } requestQueue.add(requerimiento) } fun Borrar(codigo: String, respuesta: (Boolean) -> Unit, contexto: Context) { val requestQueue = Volley.newRequestQueue(contexto) val url = "https://scratchya.com.ar/videosandroidjava/volley/borrar.php" val parametros = JSONObject() parametros.put("codigo", codigo) val requerimiento = JsonObjectRequest( Request.Method.POST, url, parametros, { response -> try { val resu = response["resultado"].toString() if (resu == "1") respuesta(true) else respuesta(false) } catch (e: JSONException) { respuesta(false) } } ) { error -> respuesta(false) } requestQueue.add(requerimiento) }
El algoritmo de la consulta ya lo vimos en un concepto anterior, veamos que sucede con el algoritmo de la modificación.
En la función Button configuramos la función lambda para cuando se presiona el botón "modificar", creamos un objeto del data class Articulo con los datos ingresados en el formulario y llamamos a la función 'Modificar', dicha función mediante otra función lambda nos retorna un true o false si la modificación se efectuó en forma correcta:
Button( onClick = { Modificar( articulo = Articulo(codigo.toInt(),descripcion,precio.toFloat()), respuesta = { if (it) mensaje="Los datos fueron modificados" else mensaje = "No existe el código de producto ingresado" }, contexto = contexto ) }, modifier = Modifier.padding(10.dp) ) { Text(text = "Modificar") }
La función Modificar crea un objeto de la clase JSONObject y configura las datos a enviar al servidor. Seguidamente creamos un objeto de la clase JsonObjectRequest, pasando por el método POST los parámetros y mediante una función lambda esperamos la respuesta del servidor. Según dicha respuesta llamamos a la función lambda de la otra función con un true o false:
fun Modificar(articulo: Articulo, respuesta: (Boolean) -> Unit, contexto: Context) { val requestQueue = Volley.newRequestQueue(contexto) val url = "https://scratchya.com.ar/videosandroidjava/volley/modificar.php" val parametros = JSONObject() parametros.put("codigo", articulo.codigo.toString()) parametros.put("descripcion", articulo.descripcion) parametros.put("precio", articulo.precio.toString()) val requerimiento = JsonObjectRequest( Request.Method.POST, url, parametros, { response -> try { val resu = response["resultado"].toString() if (resu == "1") respuesta(true) else respuesta(false) } catch (e: JSONException) { respuesta(false) } } ) { error -> respuesta(false) } requestQueue.add(requerimiento) }
Finalmente para el borrado pasamos a la función Borrar el código de artículo:
Button( onClick = { Borrar( codigo = codigo, respuesta = { if (it) { mensaje = "Se eliminó el artículo" codigo="" descripcion="" precio="" } else mensaje = "No existe el código de producto ingresado" }, contexto = contexto ) }, modifier = Modifier.padding(10.dp) ) { Text(text = "Borrar artículo (ingresando código)") }
En la función borrar pasamos por POST el código de artículo y esperamos la respuesta del servidor:
fun Borrar(codigo: String, respuesta: (Boolean) -> Unit, contexto: Context) { val requestQueue = Volley.newRequestQueue(contexto) val url = "https://scratchya.com.ar/videosandroidjava/volley/borrar.php" val parametros = JSONObject() parametros.put("codigo", codigo) val requerimiento = JsonObjectRequest( Request.Method.POST, url, parametros, { response -> try { val resu = response["resultado"].toString() if (resu == "1") respuesta(true) else respuesta(false) } catch (e: JSONException) { respuesta(false) } } ) { error -> respuesta(false) } requestQueue.add(requerimiento) }
Este proyecto lo puede descargar en un zip desde este enlace: Compose25.zip