En este blog voy dejando información que me suelo encuentro en Internet. Para poder tenerla a mano siempre, al igual que otra gente del palo.. Los temas están relacionados con informática, programación, desarrollo web y móvil.
2012-12-19
Nerdi - Muchos recursos para WebMaster ordenados de manera clara y a simple vista.
Me encontre con este sitio web llamado Nerdi el cual tiene muchos recursos que ya comente anterior mente, pero lo bueno del sitio, es que esta todo ordenador de manera muy clara y a simple vista.
2012-11-27
Team Foundation Service "GRATIS", sale a competir de manera dura, contra GitHub, BitBucket entre otros servicios del mismo tipo.
|
|||||
|
2012-11-26
Dos Libros sobre Python + Django en Castellano, Español, Spanish
Aca navegando por Scribd, me encontre con dos estupendo libre en castellano, que explican como desarrollar sitios web desde cero con Django, son libro vastanate nuevos.
Espero que le sean util.
Libro 1: Maestros Del Web Curso Django en Español
Libro 2: Django La Guia Definitiva en Español
2012-11-24
Guia Rapida para iniciarce con Git y trabajar con GitHub
- Cambios locales se refiere a los ficheros del directorio de trabajo (working dir) que hayan sido modificados desde el último commit.
- COMMIT es un indicador cualquiera en el repositorio: SHA1 de un commit, tag, HEAD (ultimo commit de la rama actual), HEAD~1 (antecesor de HEAD)… La mayoría de las veces, si no se indica se asume HEAD (último commit de la rama actual).
Inicializar repositorio
$ git init
$ git add .
$ git commit -m "Estado inicial"
Crear ramas
# Crear la rama en el punto actual. Es necesario hacer checkout a la misma.
$ git branch <nombre>
# Crea la rama a partir del commit dado. Es necesario hacer checkout.
$ git branch <nombre> <COMMIT>
# Crear rama en el punto actual y hacerle checkout.
$ git checkout -b <nombre>
# Crear la rama a partir del commit dado y hacerle checkout.
$ git checkout -b <nombre> <COMMIT>
# Renombrar la rama.
$ git branch -m <actual> <nuevo>
Al crear una rama nueva y hacerle checkout los cambios locales se
trasladan a esa rama, con lo que el siguiente commit será sobre la rama
nueva.Moverse a una rama o a un commit específico
$ git checkout <COMMIT> # No toca los cambios locales
$ git checkout -f <COMMIT> # Sobreescribe los cambios locales
Se puede hacer una rama desde el commit actual para continuar el
desarrollo (git branch). Si se hacen cambios en un commit intermedio (no
es un HEAD) y se commitean sin hacer una rama, se crea un commit separado que sale del actual (rama sin nombre).Fusionar ramas (merge)
$ git merge <nombre> # Fusiona la rama indicada en la rama actual
Las diferencias se resuelven automáticamente si es posible. En caso
de conflictos (código o ficheros binarios modificados en ambas ramas) el
proceso se detiene (merging) a la espera de una resolución manual.Resolver conflictos de fusionado:
Dentro de cada fichero en conflicto se añaden marcas alrededor del código conflictivo, mostrando al mismo tiempo la versión de una y otra rama (excepto en ficheros binarios).
$ git status # Muestra la situación actual del merge (Unmerged paths)
$ git diff # Muestra los ficheros conflictivos y las diferencias
$ git add <file> # Marca el fichero como corregido una vez resuelto el conflicto
$ git rm <file> # Marca el fichero como eliminado en la revisión resuelta
La sección “Unmerged paths” de git status muestra los
ficheros que requieren atención. Debe resolverse cada conflicto
manualmente dentro del fichero (eliminando las marcas agregadas por git)
y marcarlo como resuelto con git add.En vez de editar los ficheros es posible escoger una de las dos versiones disponibles (rama actual o rama que se está fusionando):
# Obtener la versión del fichero en la rama actual
$ git checkout --ours -- <file>
# Obtener la versión del fichero en la rama que se está fusionando con la actual
$ git checkout --theirs -- <file>
Para abortar la acción o anularla una vez realizada:# Abortar el proceso y volver a la situación anterior al intento de merge
$ git reset --hard HEAD
# Deshacer si ya se había confirmado con git commit$ git reset --hard ORIG_HEAD
Una vez resueltos todos los conflictos se confirma el proceso:# Confirmar la fusión (merge) una vez resueltos todos los conflictos
$ git commit
Resolución gráfica de conflictos:# Inicia la herramienta gráfica de resolución de conflictos
$ git mergetool
La herramienta crea ficheros adicionales por cada fichero en
conflicto (backup, base, local, remote) para que la herramienta de
resolución pueda mostrarlos al usuario al mismo tiempo y éste establecer
la versión final. Estos ficheros deberían borrarse automáticamente tras
la edición (en caso de que persistan es necesario borrarlos
manualmente).La resolución básica sólo sirve para ficheros de texto. En ficheros binarios usar git checkout –ours o git checkout –theirs para escoger una de las dos versiones disponibles.
Configurar una herramienta gráfica para resolver conflictos: http://www.davesquared.net/2010/03/easier-way-to-set-up-diff-and-merge.html (Windows) http://gitguru.com/2009/02/22/integrating-git-with-a-visual-merge-tool (Mac)
Deshacer cambios
# La recuperación hace un nuevo commit en la rama actual sin ir "hacia atrás" en la historia
$ git revert <COMMIT>
$ git reset --hard # Deshace los cambios locales
$ git reset --hard HEAD~1 # Elimina el último commit
Recuperar una versión determinada de un fichero o path:$ git reset <COMMIT> -- <path> # git reset NO sobreescribe cambios locales
$ git reset -p <COMMIT> -- <path> # Seleccionar interactivamente las partes a restaurar
$ git checkout <COMMIT> -- <path> # Sobreescribe cambios locales sin preguntar
En Windows se puede abrir git-bash directamente en cualquier
subcarpeta carpeta del proyecto (boton derecho – git bash here).
Entonces para recuperar un fichero o path local:$ git checkout <COMMIT> -- ./<path>
Conocer el historial de un fichero
# Mostrar todos los commits para un fichero especifico con info detallada
$ git log <path>
# Mostrar sólo los dos últimos commits para ese fichero
$ git log -n 2 -- <path>
# Formato abreviado con id de commit y comentario
$ git log -oneline -- <path>
# Mostrar los commits para ese fichero entre dos commits indicados
$ git log <SINCE>..<UNTIL> -- <path>
Abrir GITK mostrando gráficamente el historial para un fichero o ruta dado:$ gitk <path>
Guardar cambios actuales para recuperarlos después
Guarda los cambios desde el último commit. Al recuperarlos, si hay colisiones se hace un merge.$ git stash # Guarda cambios hechos desde el ultimo commit
$ git stash pop # Recupera los cambios guardados
$ git stash list # Lista los estados guardados
$ git stash apply # Aplica cambios guardados sin borrarlos de la lista
Marcar el commit actual (Tag)
$ git tag -s <nombre> -m <mensaje>
El tag queda firmado usando la firma GPG asociada al autor (ver Creating SSH keys).El nombre identifica al tag y se usa en los demás comandos (ej. git checkout). Por ejemplo, v2.32.45r1
$ git tag # Mostrar lista de tags
$ git tag -n # Mostrar lista y descripción
$ git tag -d <nombre> # Eliminar Tag
$ git tag -a <nombre> # Crear Tag no firmado
$ git push --tags # Subir Tags al repositorio remoto
$ git push origin :refs/tags/<nombre> # Eliminar Tag borrado localmente
Localizar ficheros con una cadena de texto
$ git grep <texto> # Mira en todos los ficheros del repositorio
$ git grep <texto> -- <ruta> # Mira sólo en la ruta o rutas especificadas
# Admite patrones (ej. *.cpp)
Trabajo con repositorios remotos
Obtener el repositorio desde otra localización (fork):
# Clonar y hacer checkout del HEAD de la rama actual
$ git clone <ruta al repositorio>
# Clonar pero no hacer checkout
$ git clone -n <ruta al repositorio
No hay que hacer git init ni crear directorio (se crea
automáticamente a partir de la carpeta actual). La ruta puede ser una
carpeta local, carpeta en red, URL, o cualquier otra referencia a un
repositorio remoto. Si es privado será necesario tener la clave SSH
configurada adecuadamente (ejemplo).Recibir los cambios desde el repositorio original:
$ git pull
Es equivalente a:$ git fetch # Trae los cambios
$ git merge origin # Fusionarlos con la versión actual
Subir cambios al repositorio:
$ git push origin <branch> # Subir sólo la rama indicada
$ git push --all # Subir y actualizar todas las referencias remotas
Gestionar Tags en el repositorio:
$ git push --tags # Subir Tags (no suben de otra forma)
$ git push origin :refs/tags/<nombre> # Eliminar Tag borrado localmente
Borrar una rama remota:
$ git push origin :<branch>
$ git push origin --delete <branch> # GIT versión 1.7.0+
Listar los repositorios remotos y sus URLs:
$ git remote -v show
Cambiar la URL de un repositorio remoto (cambia ambos fetch y push)
$ git remote set-url origin <nueva URL>
Revertir un commit en local y también en el repositorio remoto:
(lo lógico es que no hubiera sido subido)$ git reset --hard HEAD~1
$ git push origin +master:master
“The +master:master thing is necessary to tell git that you
really do want to rewind the history here, (it’s definitely not part of
the normal flow).”Tutorial
Push and delete branches
Tareas especiales
Añadir un nuevo fichero o patrón a .gitignore
Añadirlo a .gitignore sigue controlando aquellos ficheros que ya están en el repositorio, ygit rm <file>
eliminaría el fichero del directorio de trabajo.Para dejar de controlar el fichero o patrón manteniendo las copias actuales añadirlo a .gitignore y entonces:
$ git rm --cached <file>
$ git rm --cached -r <pattern> # Eliminar ocurrencias en todo el arbol
Borrar el fichero completamente del repositorio implica reescribir toda la historia. Nada recomendable.Localizar el cambio que originó un problema:
$ git bisect start
$ git bisect bad # La versión actual va mal
$ git bisect good v2.6.13-rc2 # Esta versión es buena
Autor Link
2012-11-14
MobiTest estupenda aplicación para poder testear WebMobiles
Con MobiTest podes ver cuanto tardan en carga tu pagina y como se ven en un celular con solo cargarle la URL, es una herramienta que no tiene que faltar para cuando creamo sitios webs.
2012-10-27
Android inicio de sesión y registro con PHP, MySQL y SQLite
En mi anterior artículo Android inicio de sesión y registro de diseños de pantalla i se explica el diseño de la interfaz de usuario y de registro, pero no tiene funcionalidad.
En este tutorial estoy explicando cómo construir inicio de sesión
completo y sistema de registro en android usando PHP, MySQL y SQLite. También este tutorial se explica cómo construir API simples usando PHP y MySQL.
Android hace peticiones HTTP
Android JSON Tutorial de análisis de
Base de datos SQLite Tutorial Android
Android inicio de sesión y registro de diseños de pantalla
⇒ Interactuar con clases PHP para obtener datos de la base de datos o almacenar en la base de datos
⇒ Por último le dará salida en formato JSON
config.php - Este archivo contiene variables constantes para conectarse a la base de datos.
Db_connect.php - Este archivo se utiliza para conectar o desconectar la base de datos.
DB_Functions.php - Este archivo contiene funciones para almacenar el usuario en la base de datos, obtener el usuario de base de datos. También puede agregar métodos como actualización, el usuario eliminar.
identificador de usuario único - estoy generando identificador de usuario único en PHP usando uniqid (", true) función. Identificación del usuario se muestra como 4f074eca601fb8.88015924
Contraseña encriptada - La contraseña se almacena utilizando el método base64_encode. Cada contraseña se necesitan dos columnas para almacenar en la base de datos. Una es la de almacenar la contraseña cifrada y la segunda columna es la de almacenar sal utilizada para cifrar la contraseña.
index.php - Este archivo se reproduce papel de la recepción de solicitudes y dar respuesta. Este archivo acepta todas las peticiones GET y POST. En cada solicitud se hablará con base de datos y dar respuesta adecuada en formato JSON.
Registro de Respuesta Éxito - Éxito Código = 1 (Usuario éxito Almacenado)
Registro de respuesta Error - Error Code = 1 (Error en el almacenamiento)
Registro de respuesta Error - Error Code = 2 (usuario ya existía)
Ingresa Respuesta Éxito - Éxito Código = 1 (usuario registrado)
Login respuesta Error - Error Code = 1 (Ingresar Error - corrige el usuario / contraseña)
Aquí termina la parte de la API y comenzar el proyecto Android.
En esta clase de todas las funciones que van a interactuar con las clases, JSONParser DatabaseHandler. Estoy probando API en localhost usando software xampp. Normalmente se ejecuta en localhost puerto http://127.0.0.1 o http://localhost/. En AVD para conectarse a localhost es necesario utilizar http://10.0.2.2/ url en lugar de http://localhost/. Si desea implementar el API en la página web del uso de la url http://yoursite.com/api/
register.xml - pantalla de registro de esquema de trazado
dashboard.xml - pantalla salpicadero esquema de trazado
RegisterActivity.java - Actividad de manejar evento de registro
DashboardActivity.java - Actividad para controlar el evento salpicadero
⇒ Añadir Persmissions Internet
⇒ agregar entradas de cada actividad
8. Asegúrese de que dispone de los archivos colocados como en la siguiente imagen
Ejecute el proyecto, haga clic en su carpeta de proyecto ⇒ ⇒ 1 Ejecutar como aplicación Android.
Autor: Link
Requisitos previos
Este tutorial es una combinación de algunos de mis tutoriales anteriores. Espero que cubrió estos tutoriales antes.Android hace peticiones HTTP
Android JSON Tutorial de análisis de
Base de datos SQLite Tutorial Android
Android inicio de sesión y registro de diseños de pantalla
API (Application Programming Interface)
⇒ Se aceptan solicitudes por GET / POST métodos⇒ Interactuar con clases PHP para obtener datos de la base de datos o almacenar en la base de datos
⇒ Por último le dará salida en formato JSON
1. Creación de bases de datos MySQL y tablas
Mientras escribo API en PHP He seleccionado la base de datos MySql para mantener los usuarios y otra información relacionada. Abra la consola de mysql o phpmyadmin y ejecutar la consulta siguiente para crear la base de datos y tabla de usuarios.create database android_api /** Creating Database **/ |
use android_api /** Selecting Database **/ |
create table users( uid int( 11 ) primary key auto_increment, unique_id varchar( 23 ) not null unique, name varchar( 50 ) not null, email varchar( 100 ) not null unique, encrypted_password varchar( 80 ) not null, salt varchar( 10 ) not null, created_at datetime, updated_at datetime null ); /** Creating Users Table **/ |
2. Edificio PHP API Clases
Para que sea mínimo traté de utilizar menos cantidad de archivos php. Los siguientes son los archivos son necesarios para construir API en PHP. Usted puede encontrar la descripción de cada archivo de la imagen de abajo.<?php /** * Database config variables */ define( "DB_HOST" , "localhost" ); define( "DB_USER" , "root" ); define( "DB_PASSWORD" , "" ); define( "DB_DATABASE" , "android_api" ); ?> |
<?php class DB_Connect { // constructor function __construct() { } // destructor function __destruct() { // $this->close(); } // Connecting to database public function connect() { require_once 'config.php' ; // connecting to mysql $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); // selecting database mysql_select_db(DB_DATABASE); // return database handler return $con ; } // Closing database connection public function close() { mysql_close(); } } ?> |
identificador de usuario único - estoy generando identificador de usuario único en PHP usando uniqid (", true) función. Identificación del usuario se muestra como 4f074eca601fb8.88015924
Contraseña encriptada - La contraseña se almacena utilizando el método base64_encode. Cada contraseña se necesitan dos columnas para almacenar en la base de datos. Una es la de almacenar la contraseña cifrada y la segunda columna es la de almacenar sal utilizada para cifrar la contraseña.
<?php class DB_Functions { private $db ; //put your code here // constructor function __construct() { require_once 'DB_Connect.php' ; // connecting to database $this ->db = new DB_Connect(); $this ->db->connect(); } // destructor function __destruct() { } /** * Storing new user * returns user details */ public function storeUser( $name , $email , $password ) { $uuid = uniqid( '' , true); $hash = $this ->hashSSHA( $password ); $encrypted_password = $hash [ "encrypted" ]; // encrypted password $salt = $hash [ "salt" ]; // salt $result = mysql_query( "INSERT
INTO users(unique_id, name, email, encrypted_password, salt,
created_at) VALUES('$uuid', '$name', '$email', '$encrypted_password',
'$salt', NOW())" ); // check for successful store if ( $result ) { // get user details $uid = mysql_insert_id(); // last inserted id $result = mysql_query( "SELECT * FROM users WHERE uid = $uid" ); // return user details return mysql_fetch_array( $result ); } else { return false; } } /** * Get user by email and password */ public function getUserByEmailAndPassword( $email , $password ) { $result = mysql_query( "SELECT * FROM users WHERE email = '$email'" ) or die (mysql_error()); // check for result $no_of_rows = mysql_num_rows( $result ); if ( $no_of_rows > 0) { $result = mysql_fetch_array( $result ); $salt = $result [ 'salt' ]; $encrypted_password = $result [ 'encrypted_password' ]; $hash = $this ->checkhashSSHA( $salt , $password ); // check for password equality if ( $encrypted_password == $hash ) { // user authentication details are correct return $result ; } } else { // user not found return false; } } /** * Check user is existed or not */ public function isUserExisted( $email ) { $result = mysql_query( "SELECT email from users WHERE email = '$email'" ); $no_of_rows = mysql_num_rows( $result ); if ( $no_of_rows > 0) { // user existed return true; } else { // user not existed return false; } } /** * Encrypting password * @param password * returns salt and encrypted password */ public function hashSSHA( $password ) { $salt = sha1(rand()); $salt = substr ( $salt , 0, 10); $encrypted = base64_encode (sha1( $password . $salt , true) . $salt ); $hash = array ( "salt" => $salt , "encrypted" => $encrypted ); return $hash ; } /** * Decrypting password * @param salt, password * returns hash string */ public function checkhashSSHA( $salt , $password ) { $hash = base64_encode (sha1( $password . $salt , true) . $salt ); return $hash ; } } ?> |
<?php /** * File to handle all API requests * Accepts GET and POST * * Each request will be identified by TAG * Response will be JSON data /** * check for POST request */ if (isset( $_POST [ 'tag' ]) && $_POST [ 'tag' ] != '' ) { // get tag $tag = $_POST [ 'tag' ]; // include db handler require_once 'include/DB_Functions.php' ; $db = new DB_Functions(); // response Array $response = array ( "tag" => $tag , "success" => 0, "error" => 0); // check for tag type if ( $tag == 'login' ) { // Request type is check Login $email = $_POST [ 'email' ]; $password = $_POST [ 'password' ]; // check for user $user = $db ->getUserByEmailAndPassword( $email , $password ); if ( $user != false) { // user found // echo json with success = 1 $response [ "success" ] = 1; $response [ "uid" ] = $user [ "unique_id" ]; $response [ "user" ][ "name" ] = $user [ "name" ]; $response [ "user" ][ "email" ] = $user [ "email" ]; $response [ "user" ][ "created_at" ] = $user [ "created_at" ]; $response [ "user" ][ "updated_at" ] = $user [ "updated_at" ]; echo json_encode( $response ); } else { // user not found // echo json with error = 1 $response [ "error" ] = 1; $response [ "error_msg" ] = "Incorrect email or password!" ; echo json_encode( $response ); } } else if ( $tag == 'register' ) { // Request type is Register new user $name = $_POST [ 'name' ]; $email = $_POST [ 'email' ]; $password = $_POST [ 'password' ]; // check if user is already existed if ( $db ->isUserExisted( $email )) { // user is already existed - error response $response [ "error" ] = 2; $response [ "error_msg" ] = "User already existed" ; echo json_encode( $response ); } else { // store user $user = $db ->storeUser( $name , $email , $password ); if ( $user ) { // user stored successfully $response [ "success" ] = 1; $response [ "uid" ] = $user [ "unique_id" ]; $response [ "user" ][ "name" ] = $user [ "name" ]; $response [ "user" ][ "email" ] = $user [ "email" ]; $response [ "user" ][ "created_at" ] = $user [ "created_at" ]; $response [ "user" ][ "updated_at" ] = $user [ "updated_at" ]; echo json_encode( $response ); } else { // user failed to store $response [ "error" ] = 1; $response [ "error_msg" ] = "Error occured in Registartion" ; echo json_encode( $response ); } } } else { echo "Invalid Request" ; } } else { echo "Access Denied" ; } ?> |
Tipos de Respuestas API JSON
Los siguientes son los diferentes tipos de respuestas de JSON generados por API.Registro de Respuesta Éxito - Éxito Código = 1 (Usuario éxito Almacenado)
{ "tag" : "register" , "success" : 1, "error" : 0, "uid" : "4f074ca1e3df49.06340261" , "user" : { "name" : "Ravi Tamada" , "email" : "ravi8x@gmail.com" , "created_at" : "2012-01-07 01:03:53" , "updated_at" : null } } |
{ "tag" : "register" , "success" : 0, "error" : 1, "error_msg" : "Error occured in Registartion" } |
{ "tag" : "register" , "success" : 0, "error" : 2, "error_msg" : "User already existed" } |
{ "tag" : "login" , "success" : 1, "error" : 0, "uid" : "4f074eca601fb8.88015924" , "user" : { "name" : "Ravi Tamada" , "email" : "ravi8x@gmail.com" , "created_at" : "2012-01-07 01:03:53" , "updated_at" : null } } |
{ "tag" : "login" , "success" : 0, "error" : 1, "error_msg" : "Incorrect email or password!" } |
3. A partir Android Project
Hasta ahora hemos escrito la programación del lado del servidor para construir api simple. Lo siguiente es construir android aplicación para interactuar con el API. En este proyecto estoy codificación aplicación sencilla que contará con tres pantallas Pantalla de inicio, pantalla de registro y una pantalla de panel de bienvenida. Así que vamos a empezar por la creación de un nuevo proyecto en Eclipse IDE usted.
1. Crear un nuevo proyecto, vaya a Archivo ⇒ Nuevo Android Project. Rellene todos los detalles y el nombre de su actividad como DashboardActivity.
2. El siguiente paso es crear un nuevo paquete para almacenar todos nuestros archivos de biblioteca. Haga clic derecho sobre ⇒ ⇒ New src del paquete ⇒ y el nombre como biblioteca.
2. El siguiente paso es crear un nuevo paquete para almacenar todos nuestros archivos de biblioteca. Haga clic derecho sobre ⇒ ⇒ New src del paquete ⇒ y el nombre como biblioteca.
Clase analizador JSON
3. Lo siguiente que necesitamos clase analizador para analizar api respuesta JSON. Por lo tanto crear una nueva clase en el nombre del paquete de biblioteca como JSONParser.java y llenarlo con el siguiente código.
package com.example.androidhive.library; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; public class JSONParser { static InputStream is = null ; static JSONObject jObj = null ; static String json = "" ; // constructor public JSONParser() { } public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) { // Making HTTP request try { // defaultHttpClient DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); httpPost.setEntity( new UrlEncodedFormEntity(params)); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { BufferedReader reader = new BufferedReader( new InputStreamReader( is, "iso-8859-1" ), 8 ); StringBuilder sb = new StringBuilder(); String line = null ; while ((line = reader.readLine()) != null ) { sb.append(line + "n" ); } is.close(); json = sb.toString(); Log.e( "JSON" , json); } catch (Exception e) { Log.e( "Buffer Error" , "Error converting result " + e.toString()); } // try parse the string to a JSON object try { jObj = new JSONObject(json); } catch (JSONException e) { Log.e( "JSON Parser" , "Error parsing data " + e.toString()); } // return JSON String return jObj; } } |
Base de datos SQLite controlador de clase
4. En la aplicación para almacenar información del usuario que estoy usando la base de datos SQLite. Así que crear nueva clase en que carpeta paquete de biblioteca y el nombre como DatabaseHandler.java y llenar la clase de código siguiente.
Este archivo de clase tiene funciones para manejar las operaciones de
base de datos como usuario almacenar y fácil de conseguir.
package com.example.androidhive.library; import java.util.HashMap; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DatabaseHandler extends SQLiteOpenHelper { // All Static variables // Database Version private static final int DATABASE_VERSION = 1 ; // Database Name private static final String DATABASE_NAME = "android_api" ; // Login table name private static final String TABLE_LOGIN = "login" ; // Login Table Columns names private static final String KEY_ID = "id" ; private static final String KEY_NAME = "name" ; private static final String KEY_EMAIL = "email" ; private static final String KEY_UID = "uid" ; private static final String KEY_CREATED_AT = "created_at" ; public DatabaseHandler(Context context) { super (context, DATABASE_NAME, null , DATABASE_VERSION); } // Creating Tables @Override public void onCreate(SQLiteDatabase db) { String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_LOGIN + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_EMAIL + " TEXT UNIQUE," + KEY_UID + " TEXT," + KEY_CREATED_AT + " TEXT" + ")" ; db.execSQL(CREATE_LOGIN_TABLE); } // Upgrading database @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Drop older table if existed db.execSQL( "DROP TABLE IF EXISTS " + TABLE_LOGIN); // Create tables again onCreate(db); } /** * Storing user details in database * */ public void addUser(String name, String email, String uid, String created_at) { SQLiteDatabase db = this .getWritableDatabase(); ContentValues values = new ContentValues(); values.put(KEY_NAME, name); // Name values.put(KEY_EMAIL, email); // Email values.put(KEY_UID, uid); // Email values.put(KEY_CREATED_AT, created_at); // Created At // Inserting Row db.insert(TABLE_LOGIN, null , values); db.close(); // Closing database connection } /** * Getting user data from database * */ public HashMap<String, String> getUserDetails(){ HashMap<String,String> user = new HashMap<String,String>(); String selectQuery = "SELECT * FROM " + TABLE_LOGIN; SQLiteDatabase db = this .getReadableDatabase(); Cursor cursor = db.rawQuery(selectQuery, null ); // Move to first row cursor.moveToFirst(); if (cursor.getCount() > 0 ){ user.put( "name" , cursor.getString( 1 )); user.put( "email" , cursor.getString( 2 )); user.put( "uid" , cursor.getString( 3 )); user.put( "created_at" , cursor.getString( 4 )); } cursor.close(); db.close(); // return user return user; } /** * Getting user login status * return true if rows are there in table * */ public int getRowCount() { String countQuery = "SELECT * FROM " + TABLE_LOGIN; SQLiteDatabase db = this .getReadableDatabase(); Cursor cursor = db.rawQuery(countQuery, null ); int rowCount = cursor.getCount(); db.close(); cursor.close(); // return row count return rowCount; } /** * Re crate database * Delete all tables and create them again * */ public void resetTables(){ SQLiteDatabase db = this .getWritableDatabase(); // Delete All Rows db.delete(TABLE_LOGIN, null , null ); db.close(); } } |
Funciones de usuario Clase
5. Crear un nuevo archivo de clase en el paquete de biblioteca y el nombre como UserFunctions.java. Esta clase tendrá funciones para manejar todos los eventos de usuario como
loginUser ()
RegisterUser ()
getLoginStatus ()
logoutUser ().
loginUser ()
RegisterUser ()
getLoginStatus ()
logoutUser ().
package com.example.androidhive.library; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONObject; import android.content.Context; public class UserFunctions { private JSONParser jsonParser; // Testing in localhost using wamp or xampp // use http://10.0.2.2/ to connect to your localhost ie http://localhost/ private static String login_tag = "login" ; private static String register_tag = "register" ; // constructor public UserFunctions(){ jsonParser = new JSONParser(); } /** * function make Login Request * @param email * @param password * */ public JSONObject loginUser(String email, String password){ // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add( new BasicNameValuePair( "tag" , login_tag)); params.add( new BasicNameValuePair( "email" , email)); params.add( new BasicNameValuePair( "password" , password)); JSONObject json = jsonParser.getJSONFromUrl(loginURL, params); // return json // Log.e("JSON", json.toString()); return json; } /** * function make Login Request * @param name * @param email * @param password * */ public JSONObject registerUser(String name, String email, String password){ // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add( new BasicNameValuePair( "tag" , register_tag)); params.add( new BasicNameValuePair( "name" , name)); params.add( new BasicNameValuePair( "email" , email)); params.add( new BasicNameValuePair( "password" , password)); // getting JSON Object JSONObject json = jsonParser.getJSONFromUrl(registerURL, params); // return json return json; } /** * Function get Login status * */ public boolean isUserLoggedIn(Context context){ DatabaseHandler db = new DatabaseHandler(context); int count = db.getRowCount(); if (count > 0 ){ // user logged in return true ; } return false ; } /** * Function to logout user * Reset Database * */ public boolean logoutUser(Context context){ DatabaseHandler db = new DatabaseHandler(context); db.resetTables(); return true ; } } |
El diseño de las pantallas
6. Hasta ahora se han desarrollado las clases de biblioteca necesarios en esta aplicación. Lo siguiente es construir pantallas. Necesitamos tres pantallas Pantalla de inicio, pantalla de registro y pantalla de Dashboard.
Cree 3 archivos xml según Resol ⇒ r disposición folde y nombrarlos como login.xml, register.xml y dashboard.xml
login.xml - Diseño de pantalla de inicio de sesión de diseño Cree 3 archivos xml según Resol ⇒ r disposición folde y nombrarlos como login.xml, register.xml y dashboard.xml
<? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:background = "#3b3b3b" > < LinearLayout android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:orientation = "vertical" android:padding = "10dip" > <!-- View Title Label --> < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginBottom = "10dip" android:text = "LOGIN" android:textSize = "25dip" android:textStyle = "bold" /> <!-- Email Label --> < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "Email" /> <!-- Email TextField --> < EditText android:id = "@+id/loginEmail" android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> <!-- Password Label --> < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginTop = "15dip" android:text = "Password" /> <!-- Password TextField --> < EditText android:id = "@+id/loginPassword" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:password = "true" /> <!-- Error message --> < TextView android:id = "@+id/login_error" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:textColor = "#e30000" android:padding = "10dip" android:textStyle = "bold" /> <!-- Login Button --> < Button android:id = "@+id/btnLogin" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginTop = "20dip" android:text = "Login" /> <!-- Link to Registration Screen --> < Button android:id = "@+id/btnLinkToRegisterScreen" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginTop = "40dip" android:background = "@null" android:text = "I don't have account. Register Me!" android:textColor = "#21dbd4" android:textStyle = "bold" /> </ LinearLayout > </ ScrollView > |
<? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:background = "#3b3b3b" > < LinearLayout android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:orientation = "vertical" android:padding = "10dip" > <!-- View Title Label --> < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginBottom = "10dip" android:text = "REGISTER" android:textSize = "25dip" android:textStyle = "bold" /> <!-- Name Label --> < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "Full Name" /> <!-- Name TextField --> < EditText android:id = "@+id/registerName" android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> <!-- Email Label --> < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "Email" /> <!-- Email TextField --> < EditText android:id = "@+id/registerEmail" android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> <!-- Password Label --> < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginTop = "15dip" android:text = "Password" /> <!-- Password TextField --> < EditText android:id = "@+id/registerPassword" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:password = "true" /> <!-- Error message --> < TextView android:id = "@+id/register_error" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:textColor = "#e30000" android:padding = "10dip" android:textStyle = "bold" /> <!-- Login Button --> < Button android:id = "@+id/btnRegister" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginTop = "20dip" android:text = "Register" /> <!-- Link to Login Screen --> < Button android:id = "@+id/btnLinkToLoginScreen" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginTop = "40dip" android:background = "@null" android:text = "Already registred. Login Me!" android:textColor = "#21dbd4" android:textStyle = "bold" /> </ LinearLayout > </ ScrollView > |
<? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" android:background = "#3b3b3b" > < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "WELCOME" android:textSize = "40dip" android:gravity = "center" android:layout_marginTop = "20dip" /> < Button android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "Logout Me" android:textSize = "20dip" android:textColor = "#21dbd4" android:textStyle = "bold" android:id = "@+id/btnLogout" android:layout_marginTop = "80dip" android:background = "@null" /> </ LinearLayout > |
El cambio entre Activites
7.
Ahora la parte de diseño de la aplicación se lleva a cabo lo siguiente
es crear actividades para cada diseño y funcionalidad de grabación para
lograr acceso y el proceso de registro.
Crear nuevo LoginActivity.java actividades y RegisterActivity.java y llenarlos con código que aparece más abajo.
LoginActivity.java - Actividad para controlar el evento de inicio de sesión Crear nuevo LoginActivity.java actividades y RegisterActivity.java y llenarlos con código que aparece más abajo.
package com.example.androidhive; import java.util.HashMap; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.example.androidhive.library.DatabaseHandler; import com.example.androidhive.library.UserFunctions; public class LoginActivity extends Activity { Button btnLogin; Button btnLinkToRegister; EditText inputEmail; EditText inputPassword; TextView loginErrorMsg; // JSON Response node names private static String KEY_SUCCESS = "success" ; private static String KEY_ERROR = "error" ; private static String KEY_ERROR_MSG = "error_msg" ; private static String KEY_UID = "uid" ; private static String KEY_NAME = "name" ; private static String KEY_EMAIL = "email" ; private static String KEY_CREATED_AT = "created_at" ; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.login); // Importing all assets like buttons, text fields inputEmail = (EditText) findViewById(R.id.loginEmail); inputPassword = (EditText) findViewById(R.id.loginPassword); btnLogin = (Button) findViewById(R.id.btnLogin); btnLinkToRegister = (Button) findViewById(R.id.btnLinkToRegisterScreen); loginErrorMsg = (TextView) findViewById(R.id.login_error); // Login button Click Event btnLogin.setOnClickListener( new View.OnClickListener() { public void onClick(View view) { String email = inputEmail.getText().toString(); String password = inputPassword.getText().toString(); UserFunctions userFunction = new UserFunctions(); JSONObject json = userFunction.loginUser(email, password); // check for login response try { if (json.getString(KEY_SUCCESS) != null ) { loginErrorMsg.setText( "" ); String res = json.getString(KEY_SUCCESS); if (Integer.parseInt(res) == 1 ){ // user successfully logged in // Store user details in SQLite Database DatabaseHandler db = new DatabaseHandler(getApplicationContext()); JSONObject json_user = json.getJSONObject( "user" ); // Clear all previous data in database userFunction.logoutUser(getApplicationContext()); db.addUser(json_user.getString(KEY_NAME),
json_user.getString(KEY_EMAIL), json.getString(KEY_UID),
json_user.getString(KEY_CREATED_AT)); // Launch Dashboard Screen Intent dashboard = new Intent(getApplicationContext(), DashboardActivity. class ); // Close all views before launching Dashboard dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(dashboard); // Close Login Screen finish(); } else { // Error in login loginErrorMsg.setText( "Incorrect username/password" ); } } } catch (JSONException e) { e.printStackTrace(); } } }); // Link to Register Screen btnLinkToRegister.setOnClickListener( new View.OnClickListener() { public void onClick(View view) { Intent i = new Intent(getApplicationContext(), RegisterActivity. class ); startActivity(i); finish(); } }); } } |
package com.example.androidhive; import org.json.JSONException; import org.json.JSONObject; import com.example.androidhive.library.DatabaseHandler; import com.example.androidhive.library.UserFunctions; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class RegisterActivity extends Activity { Button btnRegister; Button btnLinkToLogin; EditText inputFullName; EditText inputEmail; EditText inputPassword; TextView registerErrorMsg; // JSON Response node names private static String KEY_SUCCESS = "success" ; private static String KEY_ERROR = "error" ; private static String KEY_ERROR_MSG = "error_msg" ; private static String KEY_UID = "uid" ; private static String KEY_NAME = "name" ; private static String KEY_EMAIL = "email" ; private static String KEY_CREATED_AT = "created_at" ; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.register); // Importing all assets like buttons, text fields inputFullName = (EditText) findViewById(R.id.registerName); inputEmail = (EditText) findViewById(R.id.registerEmail); inputPassword = (EditText) findViewById(R.id.registerPassword); btnRegister = (Button) findViewById(R.id.btnRegister); btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen); registerErrorMsg = (TextView) findViewById(R.id.register_error); // Register Button Click event btnRegister.setOnClickListener( new View.OnClickListener() { public void onClick(View view) { String name = inputFullName.getText().toString(); String email = inputEmail.getText().toString(); String password = inputPassword.getText().toString(); UserFunctions userFunction = new UserFunctions(); JSONObject json = userFunction.registerUser(name, email, password); // check for login response try { if (json.getString(KEY_SUCCESS) != null ) { registerErrorMsg.setText( "" ); String res = json.getString(KEY_SUCCESS); if (Integer.parseInt(res) == 1 ){ // user successfully registred // Store user details in SQLite Database DatabaseHandler db = new DatabaseHandler(getApplicationContext()); JSONObject json_user = json.getJSONObject( "user" ); // Clear all previous data in database userFunction.logoutUser(getApplicationContext()); db.addUser(json_user.getString(KEY_NAME),
json_user.getString(KEY_EMAIL), json.getString(KEY_UID),
json_user.getString(KEY_CREATED_AT)); // Launch Dashboard Screen Intent dashboard = new Intent(getApplicationContext(), DashboardActivity. class ); // Close all views before launching Dashboard dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(dashboard); // Close Registration Screen finish(); } else { // Error in registration registerErrorMsg.setText( "Error occured in registration" ); } } } catch (JSONException e) { e.printStackTrace(); } } }); // Link to Login Screen btnLinkToLogin.setOnClickListener( new View.OnClickListener() { public void onClick(View view) { Intent i = new Intent(getApplicationContext(), LoginActivity. class ); startActivity(i); // Close Registration View finish(); } }); } } |
package com.example.androidhive; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import com.example.androidhive.library.UserFunctions; public class DashboardActivity extends Activity { UserFunctions userFunctions; Button btnLogout; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); /** * Dashboard Screen for the application * */ // Check login status in database userFunctions = new UserFunctions(); if (userFunctions.isUserLoggedIn(getApplicationContext())){ // user already logged in show databoard setContentView(R.layout.dashboard); btnLogout = (Button) findViewById(R.id.btnLogout); btnLogout.setOnClickListener( new View.OnClickListener() { public void onClick(View arg0) { // TODO Auto-generated method stub userFunctions.logoutUser(getApplicationContext()); Intent login = new Intent(getApplicationContext(), LoginActivity. class ); login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(login); // Closing dashboard screen finish(); } }); } else { // user is not logged in show login screen Intent login = new Intent(getApplicationContext(), LoginActivity. class ); login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(login); // Closing dashboard screen finish(); } } } |
Finalmente Actualización AndroidManifest.xml
No se olvide de actualizar usted AndroidManifest.xml archivo. Cambiar siguientes modificaciones⇒ Añadir Persmissions Internet
⇒ agregar entradas de cada actividad
<? xml version = "1.0" encoding = "utf-8" ?> package = "com.example.androidhive" android:versionCode = "1" android:versionName = "1.0" > < uses-sdk android:minSdkVersion = "8" /> < application android:icon = "@drawable/ic_launcher" android:label = "@string/app_name" > < activity android:label = "@string/app_name" android:name = ".DashboardActivity" > < intent-filter > < action android:name = "android.intent.action.MAIN" /> < category android:name = "android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > <!-- Login Activity --> < activity android:label = "Login Account" android:name = ".LoginActivity" ></ activity > <!-- Register Activity --> < activity android:label = "Register New Account" android:name = ".RegisterActivity" ></ activity > </ application > <!-- Allow to connect with internet --> < uses-permission android:name = "android.permission.INTERNET" /> </ manifest > |
Autor: Link
Suscribirse a:
Entradas (Atom)