Bienvenidos sean a este post, hoy implementaremos las paginas creadas en el post anterior en nuestro juego Asteroides, para ello deberemos abrir con Android Studio nuestro proyecto y efectuar algunas modificaciones.

Anuncios

La primera modificacion la realizaremos sobre el metodo onCreate() de la clase MainActivity donde agregaremos la siguiente linea:

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.permitNetwork().build());

Nuestro siguiente paso sera crear una nueva clase llamada AlmacenPuntuacionesSW_PHP donde modificaremos el codigo generado automaticamente por el siguiente:

package org.example.asteroides;

import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Vector;

public class AlmacenPuntuacionesSW_PHP implements AlmacenPuntuaciones {

    public Vector<String> listaPuntuaciones(int cantidad) throws IOException {
        Vector<String> resultado = new Vector<String>();
            URL url = new URL("http://172.128.10.9/lista.php?max=20");
            HttpURLConnection conexion = (HttpURLConnection) url.openConnection();
        try{
            if (conexion.getResponseCode() == HttpURLConnection.HTTP_OK){
                BufferedReader lector = new BufferedReader(new
                        InputStreamReader(conexion.getInputStream()));
                String linea = lector.readLine();
                while (!linea.equals("")){
                    resultado.add(linea);
                    linea = lector.readLine();
                }
                lector.close();
            } else {
                Log.e("Asteroides", conexion.getResponseMessage());
            }
        } catch (Exception e){
            Log.e("Asteroides", e.getMessage(),e);
        } finally {
            conexion.disconnect();
            return resultado;
        }
    }

    public void guardarPuntuacion(int puntos, String nombre, long fecha) throws IOException {
        URL url = new URL("http://172.128.10.9/nuevo.php"
                + "?puntos=" + puntos
                + "&nombre=" + URLEncoder.encode(nombre, "UTF-8")
                + "&fecha=" + fecha);
        HttpURLConnection conexion = (HttpURLConnection) url
                .openConnection();
        try{
            if (conexion.getResponseCode()==HttpURLConnection.HTTP_OK) {
                BufferedReader lector = new BufferedReader(
                        new InputStreamReader(conexion.getInputStream()));
                String linea = lector.readLine();
                if (!linea.equals("Ok.")){
                    Log.e("Asteroides", "Error en servicio web nuevo");
                }
            } else {
                Log.e("Asteroides", conexion.getResponseMessage());
            }
        } catch (Exception e){
            Log.e("Asteroides", e.getMessage(),e);
        } finally {
            conexion.disconnect();
        }
    }
}

En este caso tendremos una implementacion de la interfaz AlmacenPuntuaciones por lo tanto debemos redefinir a los dos metodos listaPuntuaciones y guardarPuntuacion como hicimos en los casos anteriores pero vamos a hacer una diferencia la cual es decir que va lanzar una excepcion IOException, luego explicaremos porque, pero primero hablemos de listaPuntuaciones.

Anuncios

Este metodo primero creara una variable llamada resultado de tipo Vector y datos de tipo String, luego crearemos un objeto de tipo URL llamado url donde almacenaremos la url que usaremos para obtener el listado almacenado en la tabla puntuaciones, como vimos en el post anterior, luego creara un objeto de tipo HttpURLConnection llamado conexion la cual se encargara de abrir la direccion informada en url, despues usaremos el bloque try/catch para cualquier eventualidad, primero usaremos un condicional donde chequearemos si la conexion nos devolvio una constante que nos dice que la conexion fue establecida, en caso de ser verdadero creara un objeto llamado lector de tipo BufferedReader y diremos que conexion sera usada como nuestro stream de entrada, el siguiente objeto sera llamado linea de tipo String y almacenara el contenido de lector por medio de readline(), despues usaremos un bucle while que chequeara mientras linea no sea igual a nada, en caso de ser verdadero agregara a resultado el valor de linea, luego volvera a leer a lector y lo almacenara en linea, asi repitiendo el ciclo y una vez terminado procedemos a cerrar a lector, en caso contrario creara un mensaje en el log indicando la falla de conexion, en el catch ante un caso de error tambien mostrara el mensaje en el log pero indicando el nombre y codigo de error, en el ultimo bloque llamado finally cerrara la conexion, pasemos al siguiente metodo.

Nota: en url deben poner la direccion del equipo que crearon en los posts anteriores.

El siguiente metodo se encargara de guardar la puntuacion donde recibiremos tres datos: nombre, puntos y fecha, al igual que el caso anterior crearemos un objeto de tipo URL llamado url donde almacenaremos la direccion a la cual le adicionaremos los tres datos recibidos, es la misma sintaxis del post anterior, luego crearemos el objeto conexion que se encargara de conectar a la direccion guardada en url, al igual que en el caso anterior tendremos un bloque try/catch en ella tendremos otro objeto lector y linea similar al metodo anterior pero la diferencia va a estar que en lugar de tener un bucle habra un condicional donde chequeara si linea no es igual a “Ok.” donde en ese caso agregara un mensaje de error en el log, en caso de no haberse establecido la conexion lo mostrara en el log tambien pero con la descripcion correspondiente, en el catch lo agregara al log con la descripcion y el error y en el finally cerraremos la conexion. La modificacion de throws IOException es necesaria para nuestras conexiones ya que necesitan devolver esa excepcion para poder funcionar, en el caso puntual de la URL debe devolver MalFormedURLException y openConnection necesita de IOException pero como este cubre al anterior no es necesario usar los dos sino solamente el segundo, esto implica que al ser heredado de una interfaz (por su implementacion) debemos modificar a la interfaz AlmacenPuntuaciones de la siguiente forma:

public interface AlmacenPuntuaciones {
    void guardarPuntuacion(int puntos, String nombre,
                          long fecha) throws IOException;

    Vector<String> listaPuntuaciones(int cantidad) throws IOException;
}

Esto es para que la nueva clase pueda redefinir correctamente a las clases de la interfaz y a su vez poder implementarlas pero esto implica que debemos modificar unas secciones mas de nuestro codigo porque es necesario que los metodos que utilicemos de la nueva clase permitan devolver la excepcion IOException, para ello primero modificaremos al metodo onActivityResult de la clase MainActivity de la siguiente forma:

Anuncios

Para este caso debemos agregarle a la siguiente linea:

almacen.guardarPuntuacion(puntuacion,nombre, System
                                        .currentTimeMillis());

Los bloques try/catch para que en caso de un error el catch devuelva la excepcion IOException, la excepcion quedara del siguiente modo:

try {
    almacen.guardarPuntuacion(puntuacion,nombre, System
            .currentTimeMillis());
} catch (IOException e) {
    e.printStackTrace();
}

Esto mismo debemos hacerlo en los dos botones lo cual producira que el metodo quede de la siguiente forma:

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent datos){
        super.onActivityResult(requestCode, resultCode, datos);
        if(requestCode == 1234 && resultCode == RESULT_OK && datos!=null) {
            puntuacion = datos.getExtras().getInt("puntuacion");
            final EditText a_nombre = new EditText(this);
            a_nombre.setInputType(InputType.TYPE_CLASS_TEXT);
            new AlertDialog.Builder(this)
                    .setTitle("Puntuacion alcanzada")
                    .setMessage("Ingresa tu nombre")
                    .setView(a_nombre)
                    .setPositiveButton("Ok", new DialogInterface
                            .OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogo, int i) {
                            nombre = a_nombre.getText().toString();
                            try {
                                almacen.guardarPuntuacion(puntuacion,nombre, System
                                        .currentTimeMillis());
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            lanzarPuntuaciones(null);
                        }
                    })
                    .setNegativeButton("Cancelar", new DialogInterface
                            .OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogo, int i) {
                            nombre = "AAA";
                            try {
                                almacen.guardarPuntuacion(puntuacion,nombre, System
                                        .currentTimeMillis());
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            lanzarPuntuaciones(null);
                        }
                    })
                    .show();
        }
    }

Con esto modificamos el acceso al metodo guardarPuntuacion pero ahora nos falta modificar el acceso al metodo listaPuntuaciones y para ello debemos ir a la clase Puntuaciones y modificaremos la siguiente linea:

setListAdapter(new MiAdaptador(this,
                     MainActivity.almacen.listaPuntuaciones(10)));

De la siguiente forma:

try {
    setListAdapter(new MiAdaptador(this,
            MainActivity.almacen.listaPuntuaciones(10)));
} catch (IOException e) {
    e.printStackTrace();
}
Anuncios

En este caso le agregamos el bloque try/catch para poder lanzar la excepcion IOException ante cualquier eventualidad, nuestra ultima modificacion sera en la clase MainActivity y debemos cambiar la clase que almacenara la informacion en almacen de la siguiente forma:

almacen = new AlmacenPuntuacionesSW_PHP();

Por ultimo deberemos modificar nuestro archivo AndroidManifest.xml agregando las siguientes dos lineas:

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

La primera linea le concedera el acceso a internet a la aplicacion y la segunda establecera que la version minima de SDK debe ser 9 porque a partir de esta version se comenzo a utilizar StrictMode y cualquier version por debajo de esta no funcionara, con estas modificaciones realizadas podemos proceder a probarlo, el siguiente video nos mostrara el funcionamiento

Si hacemos click en el boton Puntuaciones veremos los datos que ingresamos en los posts anteriores pero si jugamos veremos como al terminar si agregamos el nuevo puntaje este se agrego perfectamente.

Anuncios

En resumen, hoy hemos visto como usar archivos de tipo PHP para obtener y agregar informacion en bases de datos desde un servidor, hemos hecho las modificaciones necesarias para implementarla, es un metodo seguro para almacenar informacion sin necesidad que el usuario realice un back up de la informacion de la misma, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00