
Login en Android con jSon y Asynctask
A la hora de crear un login para android existen miles de maneras para realizar esta tarea tan común, en este caso haremos un login con una información alojada en un jSon, y este, en un servidor de internet.
Tengamos en cuenta algunas consideraciones, las peticiones http deben ejecutarse de una manera asíncrona, el motivo es porque a partir de la versión 4 de android dará un error si estas peticiones se ejecutan en el hilo principal, y esto tiene sentido, pues este tipo de sentencias pueden ralentizar la aplicación, aún así, en las versiones 2.x de android funcionará si lo ejecutamos en el hilo principal. Para evitar errores usaremos un proceso Asynctask para comunicarnos con el servidor.
Veamos, primero necesitaremos el diseño de la actividad principal, algo simple, no se necesita pintar la capilla sixtina, el xml del diseño principal quedaría así.
[xml]
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:orientation=”vertical” >
<TextView
android:id=”@+id/textView1″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/usuario”
android:textAppearance=”?android:attr/textAppearanceLarge” />
<EditText
android:id=”@+id/txtUsuario”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:ems=”10″ >
<requestFocus />
</EditText>
<TextView
android:id=”@+id/textView2″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginTop=”@dimen/margTop”
android:text=”@string/pass”
android:textAppearance=”?android:attr/textAppearanceLarge” />
<EditText
android:id=”@+id/txtPass”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:ems=”10″
android:inputType=”textPassword” />
<Button
android:id=”@+id/button1″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_gravity=”center_horizontal”
android:layout_marginTop=”@dimen/margTop”
android:padding=”@dimen/padGeneral”
android:text=”@string/send” />
<TextView
android:id=”@+id/LblMensaje”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_gravity=”center_horizontal”
android:padding=”20dip”
android:textColor=”#FF0000″
android:textSize=”20sp”
android:textStyle=”bold” />
</LinearLayout>
[/xml]
Bien, ahora dentro del java de la actividad principal, en el evento onCreate, asignamos un listener al botón para enviar el formulario, quedaría así:
[java]
Button boton = (Button) findViewById(R.id.button1);
boton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
//Instanciamos y ejecutamos el proceso Asnyctask
new usersJson().execute();
}
});
[/java]
Una vez presionado el botón, se ejecuta un segundo hilo que se encargará de hacer una petición http a un json alojado en un servidor externo, para ello usaremos Asynctask, ya he hablado de ello en mi anterior post, en él usaremo la clase Gson, pero antes deberemos descargárla, e instalarla en nuestra carpeta libs del proyecto (luego, en eclipse, refrescamos, 2º botón en el jar, build path->add to build path).
La clase Asynctask debe tener 3 parámetros, pero sólo necesitaremos el tercero, para saber si el login es correcto o incorrecto.
[java]
class usersJson extends AsyncTask<Void, Void, Boolean>
[/java]
El método que ejecutará casi todo será el doInBackground y quedaría algo como así:
[java]
@Override
protected Boolean doInBackground(Void… arg0) {
try {
EditText userEdit = (EditText) findViewById(R.id.txtUsuario);
EditText passEdit = (EditText) findViewById(R.id.txtPass);
/*
* Creamos el objeto Gson al que le pasamos una URL
*/
Gson miGson = new Gson();
URL url = new URL(“http://aboutgrand.com/prueba.json”);
BufferedReader reader = new BufferedReader(
new InputStreamReader(url.openStream(),
Charset.forName(“UTF-8”)));
//Pasamos la info del json a un objeto para consultarlo
Usuarios data = miGson.fromJson(reader, Usuarios.class);
List<Usuario> users = data.getUsers();
for (int i = 0; i < users.size(); i++) {
if (userEdit.getText().toString()
.equals(users.get(i).getName().toString())
&& passEdit.getText().toString()
.equals(users.get(i).getPass().toString())) {
return true;
} else
return false;
}
} catch (Exception e) {
Log.i(“valores”, “Error al leer el json de internetria”);
e.printStackTrace();
}
return false;
}
[/java]
Al comienzo del método, cogemos los valores de los EditText para comparárlos posteriormente, luego instanciamos las clases necesarias para la conexión, como Gson, al que le pasaremos un objeto BufferedReader que tenga una URL con la dirección del jSon.
Posteriormente volcaremos el contenido a una clase previamente creada de usuarios, y necesitaremos otra para cada elemento. Recorremos los usuarios y comprobamos si existe
[java]
public class Usuarios {
private List<Usuario> users;
public List<Usuario> getUsers() {
return users;
}
public void setUsers(List<Usuario> users) {
this.users = users;
}
}
public class Usuario {
private String name;
private String email;
private String pass;
private List<Usuarios> friends;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Usuarios> getFriends() {
return friends;
}
public void setFriends(List<Usuarios> friends) {
this.friends = friends;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
[/java]
Al final de doInBackground, si el usuario existe devolvemos true o false en caso contrario, ese booleano va directo al método onPostExecute, en el que si es true lanzamos un intent a una actividad con un ‘Bienvenido!’, por el contrario si es false, se imprimirá en la pantalla de login un ‘login incorrecto’, el método quedaría así:
[java]
protected void onPostExecute(Boolean result) {
if (result) {
pasar = new Intent(getApplicationContext(), Pagina_admin.class);
startActivity(pasar);
} else {
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
TextView error = (TextView) findViewById(R.id.textError);
error.setText(“Login incorrecto”);
}
}
[/java]
El objeto InputMethodManager lo usaremos para ocultar el teclado.
No se nos debe olvidar crear la actividad a la que irá el login correcto y tocar el android_manifest para incluir permisos de internet y añadir las actividades.
Puedes DESCARGAR El CÓDIGO
Pedro
4th junio 2013 5:44 pmBuenas Javier!
Estoy siguiendo este tutorial y me surge una pequeña duda… ¿No sería más fácil enviar los datos a un php y que este realice las comparaciones de datos contra una BBDD MySQL retornando un true o false para indicar a la app si el usuario es correcto o erróneo? tal vez esta duda venga de mi parte de php XD
javiertellez
5th junio 2013 7:58 amHola Pedro! pues en la típica situación de comprobación de usuario, se haría de otras maneras como bien dices, este tutorial no va encaminado a eso, sino a leer jSon y usar procesos paralelos y ver como sería el flujo. Y si, siempre es más facil enviar a php, devolver un booleano y a correr
Samuel
5th junio 2013 7:02 amYo también tengo la misma pregunta que el compañero Pedro!
jose
21st junio 2013 2:25 amhola hermanaso tu tuto esta genial te tengo una pregunta puesto q soy novato en cosas de java yo quiero hacer lo siguiente se generaran numeros aleatorios y quiero q cada vez q el numero sea superior a 120 este inserte una serie de datos sin necesidad de ejecutar un boton o algo no se si me explico quiero hacer inserciones a la base de datos sin necesidad de usar un boton para ejecutar la accion si no cuando se genere un numero superior a 120 no se si tengas algun ejemplo de esto realmente me interesa mi nombre es jose dejo mi correo jose_xp_799@hotmail.com
javiertellez
21st junio 2013 10:31 amHola jose! pues verás, el flujo debe ser un bucle en el que dentro esté el random y ahí comprobar si es mayor que 120 y guardar, no entiendo lo del botón, espero haberte ayudado
jose
21st junio 2013 10:05 pmpublic void onClick(View v) {
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView tv = (TextView) findViewById(R.id.tv2);
final Random myRandom = new Random();
switch (contador){
case 1: tv.setText(String.valueOf(myRandom.nextInt(95-90)+90));
numero=myRandom.nextInt();
if(numero>=90 ) {
class Insertar extends AsyncTask {
protected String doInBackground(String… args) {
String nombre= (“Jose”);
String Npulso=””;
numero= Integer.parseInt(Nnumero);;
// Building Parameters
List params = new ArrayList();
params.add(new BasicNameValuePair(“nombre”, nombre));
params.add(new BasicNameValuePair(“Nnumero”, Nnumero));
// getting JSON Object
// Note that create product url accepts POST method
JSONObject json = jsonParser.makeHttpRequest(url_create_paciente,
“POST”, params);
// check log cat fro response
Log.d(“Creacion Exitosa”, json.toString());
// check for success tag
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully created product
Intent i = new Intent(getApplicationContext(), monitor.class);
startActivity(i);
// closing this screen
finish();
} else {
// failed to create product
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
}
break;
}
contador+=1;
}
});
}
}, 60000, 60000);
}
});
}
esto estoy haciendo y no me inserta no se que este haciendo mal T.T por que no me inserta y este es el php q uso
la verdad no se que estoy haciendo mal seria de gran ayuda ;( no quiere insertar u.u
DVLPANA
10th abril 2014 9:16 pmEstimado buen ejemplo, pero al ejecutar me sale esta excepcion
Log.i(“valores”, “Error al leer el json de internetria”);
rapser
2nd noviembre 2014 2:35 amuna pregunta, cual seria el user y el pass?
gabriel ramos
27th enero 2015 5:45 pmPregunto lo mismo que el compañero rasper
Giancarlo
31st diciembre 2015 12:50 amSi se utiliza AsynTask para realizar el login, entonces el proceso se realiza en background, si se utiliza json como en el ejemplo, y al traer no solo usuario y password, sino tambien toda una configuracion de perfiles para ese usuario, el proceso de login tomaria mucho tiempo ( aprox. entre 30segundos a 3 minutos), incluso poniendo alta prioridad a ese thread de background, entonces, es recomendable utilizar AsynTask + Json para realizar un login, que otra opción existe ?
Matias
6th enero 2016 9:56 pmBuenas tardes,
primero gracias por compartir tu conocimiento.
Quisiera saber que estructura debería tener el archivo JSON para el correcto funcionamiento. Te agradecería tu respuesta.
Un cordial saludo.
Jossii
29th mayo 2017 5:42 pmhola buenas e seguido el tutorial paso a paso pero no logro desmarcar los import en rojo me salen noc q tengo q hacer algo mas o agregar algo en otra parte pero los import de la clase jsonparser no se me desmarcan q tengo q hacer gracias