sábado, 3 de diciembre de 2016

Curso Json. XAMP. Clases.

XAMP


Apache + PHP + MariaDB(MySQL se cerro) + Pearl

Se utilizara XAMP para intercambiar datos con la aplicación móvil.

Video de la página oficial(en ingles).


Apache ofrece muchas ventajas, es posible escoger que directorio utilizar para los archivos de la web. Por ejemplo, utilizar una Raspberry y conectar un disco externo para alojar archivos(videos, la interfaz de administración, probar desarrollos o respaldos), mientras ella ejecuta su sistema desde una tarjeta SD.

Por favor: no uses C:/Program Files.

Solo usaremos

Apache
PHP
Maria

MyAdmin.

Se recomienda una partición para archivos y una de sistema, pero eso es de otro tema. Por suerte XAMPP permite montar en raíz un directorio. Y si el directorio web sera muy pesado, se podría montar en un disco externo, es cuestión de modificar el httpd.conf del apache.


Inicio>XAMPP>XAMPP Control Panel

Idioma
Español o Inglés

Abrirá en alemán, reiniciamos el panel de control.

Cerramos la ventana y del menú de la barra de tareas presionamos Bendeen.

Lo abrimos.


Arrancamos mysql y apache. Nos vamos al myadmin.

La instalación ha sido exitosa.

Para usuarios de Linux, recuerden no correr el demonio directamente como root, creen el usuario www.

Lo siguiente es crear un usuario para la conexión, una tabla para intercambiar datos, y un "manipulador" de la conexión.


Recomiendo(y cualquiera que conozca del tema lo haría) guardar valores que se repiten demasiado en "enums". Por ejemplo marca y modelo. No vamos a llenar discos duros con datos redundantes de un esquema que podemos mantener en cache. Además el gasto energético, CPU, ancho de banda, étc.

Recomendación: usar un XML para esas listas, debe ser el mismo para el modo Web que para el móvil, así cuando actualices el del servidor, poner el mismo en el update de la app móvil.

Código


Buscamos la carpeta htdocs, se puede trabajar con un bloc de notas, pero recomiendo Visual Studio Code o notepad ++.

Clase vehículo

<?php

class vehiculo

{

public $numeroEjes = 0;
public $llantasEje = 0;
public $marca=0;
public $modelo=0;
public $uso=0;

}

?>

Clase auto

<?php

include('vehiculo.php');

class auto extends vehiculo{

public $motor=0;
public $numeroAsientos=0;
public $GPS=0;
public $camaraTrasera=0;

}

?>



Observarán que es versátil, puedo poner una bicicleta: 2 ejes, 1 llanta por eje, marca, el índice de una lista de marcas, modelo, de BMX, el uso: privado, público, transporte(públicas, las que prestan algunas ciudades, como la CDMX), naturalmente de una lista.

Creamos un auto. Para leer los valores podemos usar un switch e imprimirlos.

<?php

include('auto.php');

$miAuto=new auto;

?>

No debe arrojar error.

Recuerden desactivar las alertas en producción.

Ahora veremos como devolver valores.

Las funciones de PHP nos servirán para esto. Recuerden deben encontrar una forma de programar que les acomode, si trabajan en equipo llegar a un acuerdo para el mantenimiento adecuado del código. El código debe ser simple, para que sea fácil de comprender, pero debe cubrir las expectativas.

Aquí vemos los enums en prueba:

<?php

class vehiculo

{

public $numeroEjes = 0;
public $llantasEje = 0;
public $marca=0;
public $modelo=0;
public $uso=0;

privade $marcas=array("VolksWagen", "Chevrolet", "Subaru", "Cherokee", "Toyota", "KIA", "Nissan");

privade $modelos=array("leaf", "tornado", "beetle", "crossfox");

privade $usos=array("público", "partícular", "gubernamental");

function getCadenaMarcas(){

return $this->marcas[$this->marca];

}

function getCadenaModelo(){

return $this->modelos[$this->modelo];

}

function getCadenaUso(){

return $this->usos[$this->uso];

}

}

?>

<?php

include('vehiculo.php');

class auto extends vehiculo{

public $numeroAsientos=0;
public $motor=0;
public $GPS=0;
public $camaraTrasera=0;

//motor puede ser más rico, pero en vehículo ya éxplique a lo que van los enums

privade $motores=array("diesel", "magna", "premium", "híbrido", "eléctrico");

function getMotorCadena(){

   return $this->motores[$this->motor];

}

function getGPS(){

   switch $this->GPS{

      case 0:

         return "Si";

      break;

      case 1:

         return "No";

      break;

}

function getCamaraTrasera(){

   switch $this->camaraTrasera{

      case 0:

         return "Si";

      break;

      case 1:

         return "No";

      break;

}

}

}

?>

<?php
//error_reporting('0');
include('auto.php');

//echo "Hola";

$miAuto=new auto();


echo $miAuto->getMotorCadena();
//recuerda que el motor se fija en la variable

?>

Android solo recibirá directamente el número y lo deberá interpretar.

Aquí se puede hacer algo parecido con javascript, para el entorno web, json es recomendable.

El link de la carpeta:

https://drive.google.com/drive/folders/0B0zrGMhduaXIWURlV1NyczFzaVU?usp=sharing

En el siguiente episodio una base de datos, luego Json y app estara terminada.


domingo, 27 de noviembre de 2016

Curso Json

¿Que es Json?
Json es (de acuerdo al sitio oficial) un lenguaje de intercambio de datos. Ligero y fácil de interpretar tanto por humanos y máquinas.

¿Para que sirve Json?

Para intercambio de datos, dinámicos.
Ejemplo: una aplicación android que realiza un intercambio de datos con un servidor, o lee una base de datos local.


Estructura básica de Json


Un conjunto de pares:

{"nombre", "valor"} es decir: nombre:valor


o                                          nombre=valor.


Un arreglo de datos ordenados.

{
//abrimos el json
"autos":[   //es un arreglo, por lo tanto, adentro o hay valores, o hay objetos.
{"marca":"vw",
"modelo":"sedan"
},
{
"marca":"vw",
"modelo":"beetle"
}
]
}

En resumen. Es un arreglo. Los objetos se componen de pares. Es fácil de interpretar. Es casi texto plano(debemos encriptar las comunicaciones, pero es texto plano).

Queda un string  o cadena que es el que se envía o recibe.

{
"autos":[
{"marca":"vw",
"modelo":"sedan"
},
{
"marca":"vw",
"modelo":"beetle"
}
]
}

Podemos comenzar.


Código


Creanos un nuevo proyecto con un activity, puede ser vacío.

Imports


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

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

import java.util.ArrayList;
import java.util.HashMap;

import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;


Vamos a usar un list view para demostrar que Android esta leyendo el arreglo de objetos,
y que accede a los valores de dichos objetos.

Agregamos un list view a la interfaz gráfica, eliminamos el texto de la vista, ya que no nos va a servir.
...
tools:context="com.example.wikifry.jsonproject.MainActivity">


<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    android:id="@+id/lstJson" />

Y el java:

    //Declaramos
    ListView lstJson;

public class MainActivity extends AppCompatActivity {

    lstJson=(ListView)findViewById(R.id.lstJson);
//Importamos el listview
    


Empezamos a leer la cadena:

protected void leerJson(String jSonStr){
//En ese método recibimos la cadena, nuesto json en cuestión
    try{
    JSONObject jsonOb=new JSONObject(jSonStr);//Recordemos que es un arreglo con nombre
//podríamos tener varios arreglos, de distinta estructura, autos, aviones,etc.
        JSONArray autos=jsonOb.getJSONArray("autos");//El objeto contiene nuestro arreglo

    }catch(Exception e){}
}



JSONArray autos=new JSONArray("autos"); //Tomamos todos los autos, irán a un arreglo

for(Integer i=0; i < autos.length(); i++){
//Los búcles se usan para recorrer arreglos: for tiene 3 partes:    
//inicio, condición y siguiente.    //en un array, se empieza por cero    
//la posición final es la longitud o tamaño menos 1}
}catch(Exception e){}



}

Es un arreglo. Seguimos con ese bucle


for(Integer i=0; i < autos.length(); i++){

JSONObject a=autos.getJSONObject(i);
//obtenemos un auto del arreglo

String marca=a.getString("marca");
String modelo=a.getString("modelo");

//extraemos los valores del arreglo
//creo una clase auto, para guardar los datos en un arreglo y manejar el objeto
//auto carro=new auto(marca, modelo);

atos.add(new auto(marca, modelo));
//Se puede directamente, sí:
//atos.add(new auto(a.getString("marca"),a.getString("modelo")));
}

//sub carpeta modelos

La clase del auto:
package com.example.wikifry.jsonproject.modelos;
/** * Created by Wilbert on 22/11/2016. */
public class auto {
    String marca;
    String modelo;

    public auto(String marca, String modelo){
        this.marca=marca;
        this.modelo=modelo;
    }
}

Creo un arreglo que guardara los autos extraídos, en el main y permitira leerlos en el adaptador

import java.util.ArrayList;


En el constructor:
ArrayList<auto> atos=new ArrayList<>();

ArrayList permite usar los tipos que creemos, y la pila es dinámica

//Ahora a rellenar el ListView

Rellenar el ListView



Diseñar la celda(celda personalizada)

Creamos un layout, relativo, no linear con dos TextView.

res>layout

Click derecho sobre layout


New>Layout Resource File

File name: celda_auto
Root Element: RelativeLayout


Insertamos dos TextView
El primero sera txtMarca y el de abajo txtModelo.

Así debería quedar despues de un par de ajustes el XML de la celda:


<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent" android:layout_height="match_parent">

    <TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:id="@+id/txtMarca" />

    <TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txtMarca"
        android:id="@+id/txtModelo" />
</RelativeLayout>

Crear el adaptador(adapter)

En mi caso click derecho sobre
com.example.wikifry.jsonproject/adapters
New
Javaclass
public class auto_adapter {

}

Los imports:

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;

import com.example.wikifry.jsonproject.*;
import com.example.wikifry.jsonproject.modelos.auto;
//estamos en una subcarpeta
//, así 
Y modificamos la clase

public class auto_adapter extends BaseAdapter {

}

Declaramos las variables
public class auto_adapter extends BaseAdapter {

Context context;
ArrayList<auto> atos=new ArrayList<>();
LayoutInflater inflater;

//El método constructor, permite construir la instancia de la clase cuando es llamado,
//
//es decir, la clase no es más que un molde para nuestros objetos

public auto_adapter(Context context, ArrayList<auto> atos){
    this.context=context;
    this.atos=atos;
}



//Overrides

//Son métodos requeridos por la clase

@Overridepublic int getCount(){
    return atos.size();
}

@Override
public Object getItem(int position){
    return null;
}

@Override
public long getItemId(int position){

    return 0;
}


public View getView(int position, View convertView, ViewGroup parent){
    TextView txtMarca;
    TextView txtModelo;

//Declaramos dos cajas de texto

inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

//Vamos a "inflar" con elementos visuales

View itemView=inflater.inflate(R.layout.celda_auto, parent, false);

//El ítem a utilizar es la celda que personalizamos

txtMarca=(TextView)itemView.findViewById(R.id.txtMarca);
txtModelo=(TextView)itemView.findViewById(R.id.txtModelo);
//El parceo es dinámico, por que el inflado lo es, cada ves que se inflé una celda, se copia
//la celda que creamos

//Abajo de los TextView:
TextView txtMarca;
TextView txtModelo;
String strMarca="Marca: ";
String strModelo="Modelo: ";

Obtenemos del arreglo y retornamos la vista:

txtMarca.setText(strMarca.concat(atos.get(position).getMarca()));
txtModelo.setText(strModelo.concat(atos.get(position).getModelo()));

return itemView;

}
}//Aquí términa el Java del adapter

Leer Json y rellenar tabla

//Vamos al main y agregamos al import

import com.example.wikifry.jsonproject.adapters.auto_adapter;

//Que es el adaptador que acabamos de crear

//Ponemos una Json String:
String jsonString="{\"autos\":[{\"marca\":\"vw\",\"modelo\":\"sedan\"},{\"marca\":\"vw\",\"modelo\":\"beetle\"}]";
//Las comillas dobles se añaden de esa forma, debido a que las comillas dobles están reservadas
//para representar cadenas de texto

//Se convierte el Json a objetos y a rellenarla.
leerJson(jsonString);

lstJson.setAdapter(ListAutoAdapter);


Voila.

Debería funcionar, recuerda descargar el ejemplo y revisarlo.

https://drive.google.com/file/d/0B0zrGMhduaXId0VIQ25vWGRzSVk/view?usp=sharing



miércoles, 23 de noviembre de 2016

Entrada Rápida. Comprimir projecto.

Se darán cuenta que un projecto pesa más de 30MB, siendo que un apk generado por Android Studio pesa mínimo 1 MB.

Comencemos.

Buscamos nuestro proyecto.



   Nos vamos a esta carpeta:

build/generated


Borramos este archivo.

Ya ahorramos unos 30 megabytes.

El apk esta en \app\build\outputs\apk. Se puede borrar, también hay muchos jar en otros espacios, pero llevaría demasiado tiempo, toma mucho tiempo arrancar un proyecto, pero cortar un pedazo de 30 MB que el sistema reconstruye elimina muchas molestias.

Para subirlo a la nube es recomendable comprimir el proyecto: cada sistema de archivos debe, antes de escribir un archivo hacer varias tareas: revisar el espacio disponible, crear el archivo, en este caso preguntar por el siguiente... Al comprimir un archivo para su transferencia solo hay que revisar el espacio disponible una vez. Mucho más rápido, y hay buenos compresores.

lunes, 21 de noviembre de 2016

Insertar componentes en la interfaz, escuchar eventos, cambio de ventana(activity), interfaz polimórfica

Insertar componentes en la interfaz, cambio de ventana(activity), interfaz polimórfica

Hoy veremos:
  • Como agregar componentes y manipularlos
  • Como cambiar de activities
  • Como reducir el número de activities necesarios
En la parte de código básico:

  • Sentencia if(Java)
  • Sentencia switch(Java)
Agregamos una interfaz básica, o creamos un nuevo proyecto y la creamos.





Ya tenemos la interfaz gráfica básica.

Agregar componentes visuales

Esto es muy importante, ya que si agregamos demasiadas interfaces, o lo hacemos mal, nuestro proyecto sera demasiado pesado, o difícil de mantener.

Estamos en el código Java





Cambiamos al XML que es nuestra interfaz gráfica.






Presionamos en "design", y veremos un preview


Arrastramos un botón

Vemos que su Id es "button".

Ahora manipularemos su código...

Para eso vamos al código Java.

En las lineas de "import" agregamos:

import android.widget.Button;


Despues de crear la clase definimos un botón.

public class MainActivity extends AppCompatActivity {

    Button button;



Despues de que se haya creado la interfaz, importamos el boton del XML.

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button=(Button)findViewById(R.id.button);
}

button es el boton en el Java.
(Button) es el casteo, "castear", convertir un tipo a otro, en este caso estamos importando un objeto.
findViewById encontrara el elemento que queremos, y R.id.id se lo entregara.
R contiene los recursos que estamos usando.

Hora de mostrar que si lo importamos.


@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button=(Button)findViewById(R.id.button);
//manipulamos el texto, esto nos servirá en lo que sigue, esto es un comentario
    button.setText("importado");
}

Corremos nuestra aplicación, conectamos el celular o tablet.

El ADB debe mostrar el movil o el emulador.




Es importante tener habilitado el modo de desarrollador.


Tomara un poco compilar el proyecto. Posteriormente les explicare como comprimir el
proyecto para enviarlo por Internet o subirlo a su disco en la nube.

Aqui una captura

Se ve oscuro por una máscara.

Cambio de ventana

Agregamos otro ACTIVITY:
Clic derecho sobre app>new>Activity>Empty Activity
ya vimos los pasos que siguen.



Agrego un boton y le llamo btnReceptor


Volvemos al primer código Java

MainActivity.java

agregamos a los imports:

import android.view.View;
import android.widget.Button;

Vamos a escuchar el botón

Después del método onCreate agregamos un método para escuchar.

View.OnClickListener miEscuchaClick=new View.OnClickListener(){

//La pantalla es táctil, o tiene entradas, la vista
//servira para escuchar sus elementos


    public void onClick(View v){//vemos que algo fue clickeado, presionado, y escuchamos la vista

switch (v.getId()){

//Tenemos la sentencia switch, que nos permite comparar los valores
//De acuerdo a lo recibido por ella hara algo u otra acción
//v es nuestra vista, Id es el identificador de un elemento, en este caso el que fue presionado
    case R.id.button:
//si el botón fue presionado hara el código que sigue
        break;
//aquí cerramos ese bloque del switch
}
    }
};


Agregamos un método para cambiar de Activity:

public void cambiar(View v){
    Intent i=new Intent(this, receptor.class);
    startActivity(i);
}

Llamamos al método desde el listener

case R.id.button:
cambiar(v);
        break;
Debería funcionar.

Cambiamos el texto del botón del segundo activity.

Lo hacemos desde la propiedad android:text
queda entre comillas.

<Button    android:text="Cambiado"

Debería cambiar

Probamos la aplicación: la abrimos y presionamos el boton, debería cambiar de activity.

Ya probaron la aplicación. Vamos a mostrar que un botón puede cambiar de acción,
de acuerdo a un mensaje que le enviemos.

GUI polimórfica, envío de mensajes entre GUI

Vamos al XML de la primera ventana y agregamos otro botón:
Vamos al java.
Declaramos los dos botones.
public class MainActivity extends AppCompatActivity {

    Button btnGuardar;
    Button btnEditar;

Quitamos el primer botón, pero paso a paso, si no vamos a destruir el código.


@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnGuardar=(Button)findViewById(R.id.guardar);
    btnEditar=(Button)findViewById(R.id.editar);
    
    btnGuardar.setOnClickListener(miEscuchaClick);
    btnEditar.setOnClickListener(miEscuchaClick);
}

Editamos el listener agregando los id's de los botones.

View.OnClickListener miEscuchaClick=new View.OnClickListener(){
    public void onClick(View v){
switch (v.getId()){

//    case R.id.button://cambiar(v);//        break;
    case R.id.guardar:
        
        break;
    
    case R.id.editar:
        
        break;
}
    }
};

Creamos una variable al principio de la clase que guardara el mensaje que pasaremos.

    case R.id.guardar:
funcion="guardar";
    break;

    case R.id.editar:
funcion="editar";
    break;

Usamos  el metodo "putExtra", permite pasar variables a otros activities.

public void cambiar(View v, String mensaje){
    Intent i=new Intent(this, receptor.class);
    i.putExtra("mensaje", mensaje);
    startActivity(i);
}


Agregamos la función cambiar a los listeners:

case R.id.guardar:
funcion="guardar";
    cambiar(v, funcion);
    break;

case R.id.editar:
funcion="editar";
    cambiar(v, funcion);
    break;

Vamos al la GUI receptora.
Recibimos el mensaje:
Importamos la clase boton, extraemos el mensaje y lo colocamos en una variable local.
Cambiamos el texto del mensaje por el mensaje recibido.

import android.widget.Button;

public class receptor extends AppCompatActivity {
public String funcion;
    Button btnFuncion;
    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_receptor);
        Bundle bundle=getIntent().getExtras();
        funcion=bundle.getString("funcion");
        btnFuncion=(Button)findViewById(R.id.btnReceptor);
        btnFuncion.setText(funcion);
    }


Agregamos un listener para los clicks:

View.OnClickListener miEscuchaClick=new View.OnClickListener(){
    public void onClick(View v){
        switch (v.getId()){
            
            case R.id.btnReceptor:
                switch(funcion){
                    case "guardar":
                        btnFuncion.setText("Presionaste guardar");
                        break;

                    case "editar":
                        btnFuncion.setText("Presionaste editar");
                        break;
                    
                }
                
                
                break;

            //   //otro botón              //  funcion="editar";                //cambiar(v, funcion);                //break;        }
    }
};
Vemos un switch anidado que hara una u otra opción, de acuerdo al mensaje enviado.

Llamamos al listener desde el boton en el método onCreate.

btnFuncion.setOnClickListener(miEscuchaClick);

Ya debería funcionar. Aquí terminamos esta sección. Muchas gracias por tu visita, dona o comparte.



Aquí el proyecto:
https://drive.google.com/file/d/0B0zrGMhduaXIcU1nVmJkeGNXVTQ/view?usp=sharing