Mostrando entradas con la etiqueta Android. Mostrar todas las entradas
Mostrando entradas con la etiqueta Android. Mostrar todas las entradas

martes, 18 de diciembre de 2012

Android: Juego de Matemáticas

Como práctica hice este pequeño programa que intenta ser un juego de matemáticas. Operaciones básicas de suma, resta, multiplicación y división, son generadas al azar con la respuesta válida y dos respuestas incorrectas. Cada respuesta correcta acumula un punto.


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

import com.example.mytoolbox.utilities.NumberUtilities;

public class MathRallyActivity extends Activity implements OnClickListener {
 
 public enum Operation {
  SUM, DIVISION, MULTIPLICATION, SUBSTRACT  
 }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_math_rally);
        
        Button buttonOption1 = (Button) findViewById(R.id.buttonMath1);
        Button buttonOption2 = (Button) findViewById(R.id.buttonMath2);
        Button buttonOption3 = (Button) findViewById(R.id.buttonMath3);
        ImageButton buttonHome = (ImageButton) findViewById(R.id.imageButtonHome);
        
        buttonOption1.setOnClickListener(this);
        buttonOption2.setOnClickListener(this);
        buttonOption3.setOnClickListener(this);
        buttonHome.setOnClickListener(this);
        
        createOperation();        
    }
    
    private void createOperation() {
     Operation operation = generateRandOperation();
     
     int operand1 = NumberUtilities.generateRandNumber(2, 100);
     int operand2 = NumberUtilities.generateRandNumber(2, 100);
     
     String operationText = String.valueOf(operand1) + " " +
       getOperationString(operation) + " " + String.valueOf(operand2) + "?";
     
     TextView textViewOperation = (TextView) findViewById(R.id.textViewOperation);
     textViewOperation.setText(operationText);
     float rightValue = calculateRightValue(operation, operand1, operand2);
     
     rightBox = NumberUtilities.generateRandNumber(1, 3);
     float randWrongValue1 = NumberUtilities.generateRandNumber(2);
     float randWrongValue2 = NumberUtilities.generateRandNumber(2);
     
     Button buttonOption1 = (Button) findViewById(R.id.buttonMath1);
        Button buttonOption2 = (Button) findViewById(R.id.buttonMath2);
        Button buttonOption3 = (Button) findViewById(R.id.buttonMath3);
     
     switch (rightBox) {
      case 0:
       buttonOption1.setText(String.valueOf(rightValue));
       buttonOption2.setText(String.valueOf(randWrongValue1));
       buttonOption3.setText(String.valueOf(randWrongValue2));
       break;
      case 1:
       buttonOption2.setText(String.valueOf(rightValue));
       buttonOption1.setText(String.valueOf(randWrongValue1));
       buttonOption3.setText(String.valueOf(randWrongValue2));
       break;
      case 2:
       buttonOption3.setText(String.valueOf(rightValue));
       buttonOption1.setText(String.valueOf(randWrongValue1));
       buttonOption2.setText(String.valueOf(randWrongValue2));
       break;
     }     
    }
    
    private float calculateRightValue(Operation oper, int operand1, int operand2) {
     float calculation = 0;
     
     if (oper == Operation.SUM) {
      calculation = operand1 + operand2;
     } else if (oper == Operation.MULTIPLICATION) {
      calculation = operand1 * operand2;
     } else if (oper == Operation.SUBSTRACT) {
      calculation = operand1 - operand2;
     } else if (oper == Operation.DIVISION) {
      calculation = operand1 / operand2;
     }
     
     return calculation;
    }
    
    private String getOperationString(Operation oper) {
     String operationText = "";
     if (oper == Operation.SUM) {
      operationText = "+";
     } else if (oper == Operation.MULTIPLICATION) {
      operationText = "*";
     } else if (oper == Operation.SUBSTRACT) {
      operationText = "-";
     } else if (oper == Operation.DIVISION) {
      operationText = "/";
     }
     return operationText;
    }
    
    private Operation generateRandOperation() {
     int rand = NumberUtilities.generateRandNumber(1, 4);
     Operation operation = null;
     
     switch(rand) {
      case 0:
       operation = Operation.SUM;
       break;
      case 1:
       operation = Operation.DIVISION;
       break;
      case 2:
       operation = Operation.MULTIPLICATION;
       break;
      case 3:
       operation = Operation.SUBSTRACT;
       break;
     }
     return operation;
    }
  
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_math_rally, menu);
        return true;
    }

 @Override
 public void onClick(View view) {
  boolean correct = false;
  boolean play = true;
  
  switch(view.getId()) {
   case R.id.buttonMath1:
    if (rightBox == 0) {
     correct = true;
    }
    break;
   case R.id.buttonMath2:
    if (rightBox == 1) {
     correct = true;
    }
    break;
   case R.id.buttonMath3:
    if (rightBox == 2) {
     correct = true;
    }
    break;
   case R.id.imageButtonHome:
    startActivity(new Intent(MathRallyActivity.this, ChooseActivity.class));
    play = false;
    break;
  }
  if (correct) {
   points++;
   updateScore();
  } if(play) {
   createOperation();
  }
 }
 
 private void updateScore() {
  EditText editText = (EditText) findViewById(R.id.editTextPoints);
  editText.setText(String.valueOf(points));
 }

 private int rightBox;
 private int points;
}

viernes, 23 de noviembre de 2012

Android: Chequear conectividad con WiFi

Para poder chequear la conectividad con WiFi primero hay que agregar los permisos respectivos en el manifiesto de Android:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mytoolbox"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
 ...
 
</manifest>

Aquí dejo un código que verifica la conectividad. Si no existe entonces despliega un mensaje indicando al usuario que debe haber conectividad para poder usar la aplicación. Seguidamente termina la aplicación.

private void checkWiFiConnectivity() {
  ConnectivityManager connMan =  (ConnectivityManager) 
       getSystemService(Context.CONNECTIVITY_SERVICE);
  boolean wifiIsOn = connMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
        .isConnectedOrConnecting();
  Log.d("GABO", "WiFi is : " + wifiIsOn);
  
  if(!wifiIsOn) {
   finishApplication();
  }  
}

private void finishApplication() {
  AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
  builder.setMessage("You need WiFi connection to access this App!");
  builder.setCancelable(false);
     
  builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
       MainActivity.this.finish();    
   }
  });
     
  AlertDialog alert = builder.create();
  alert.show();  
}

lunes, 5 de noviembre de 2012

Android: "Piedra, papel y tijeras"

Aquí dando mis primeros gateos en el mundo de desarrollo de Android. En esta simple aplicación ejemplifico el uso de:
  • Buttons
  • Click events
  • Image Views
  • Alert dialogs
La aplicación es un simple juego de"Piedra, Papel y Tijeras". El usuario hace la selección entre las clásicas tres opciones, y luego Android hace una selección aleatoria. De acuerdo a las básicas reglas universales de este conocido juego, el resultado es determinado y mostrado en un mensaje de alerta.

Este es el layout básico del juego. Las dos imágenes de signo de interrogación son para desplegar las dos selecciones. Las otras tres imágenes son para que el usuario haga la selección.



















XML del layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:padding="@dimen/padding_medium"
        android:text="Rock, Paper, Scissors!"
        tools:context=".RockPaperScissors" />

    <Button
        android:id="@+id/buttonRock"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="147dp"
        android:layout_marginRight="20dp"
        android:layout_toLeftOf="@+id/textView1"
        android:background="@drawable/rock_small" />

    <Button
        android:id="@+id/buttonPaper"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/buttonRock"
        android:layout_alignBottom="@+id/buttonRock"
        android:layout_centerHorizontal="true"
        android:background="@drawable/paper_small" />

    <Button
        android:id="@+id/buttonScissors"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/buttonPaper"
        android:layout_alignBottom="@+id/buttonPaper"
        android:layout_marginLeft="23dp"
        android:layout_toRightOf="@+id/textView1"
        android:background="@drawable/scissors_small" />

    <ImageView
        android:id="@+id/imageViewAnswerUser"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="26dp"
        android:layout_toLeftOf="@+id/buttonPaper"
        android:src="@drawable/question" />

    <ImageView
        android:id="@+id/ImageViewAnswerAndroid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/buttonScissors"
        android:layout_alignTop="@+id/imageViewAnswerUser"
        android:src="@drawable/question" />

    <ImageButton
        android:id="@+id/imageButtonHome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/buttonPaper"
        android:layout_below="@+id/buttonPaper"
        android:layout_marginTop="38dp"
        android:src="@drawable/home" />

</RelativeLayout>

código de la actividad:
package com.example.mytoolbox;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;

public class RockPaperScissors extends Activity implements OnClickListener {
 
 public enum Option {
  ROCK, PAPER, SCISSORS
 }
 
 public enum Result {
  WIN, LOSS, DRAW  
 }
 
 private Option userSelection;
 private Result gameResult;
 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rock_paper_scissors);
        
        Button buttonRock = (Button) findViewById(R.id.buttonRock);
        Button buttonpaper = (Button) findViewById(R.id.buttonPaper);
        Button buttonScissors = (Button) findViewById(R.id.buttonScissors);
        ImageButton buttonHome = (ImageButton) findViewById(R.id.imageButtonHome);
        
        // Set click listening event for all buttons.
        buttonRock.setOnClickListener(this);
        buttonpaper.setOnClickListener(this);
        buttonScissors.setOnClickListener(this);
        buttonHome.setOnClickListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_rock_paper_scissors, menu);
        return true;
    }

 @Override
 public void onClick(View v) {
  
  ImageView imageView = (ImageView) findViewById(R.id.imageViewAnswerUser);
  boolean play = true;
  
  switch (v.getId()) {
   case R.id.buttonRock:
    userSelection = Option.ROCK;
    imageView.setImageResource(R.drawable.rock);
    break; 
   case R.id.buttonPaper:
    userSelection = Option.PAPER;
    imageView.setImageResource(R.drawable.paper);
    break;
   case R.id.buttonScissors:
    userSelection = Option.SCISSORS;
    imageView.setImageResource(R.drawable.scissors);
    break;
   case R.id.imageButtonHome:
    startActivity(new Intent(RockPaperScissors.this, ChooseActivity.class)); // To go home.
    play = false;
    break;
  }
  
  if(play) {
   play();
   showResults();
  }
 }

 private void showResults() {
  AlertDialog.Builder builder = new AlertDialog.Builder(RockPaperScissors.this);     
     builder.setCancelable(false);     
     builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // Do nothing   
   }
  });
     
     // Sets the right message according to result.
     if(gameResult == Result.LOSS) {
      builder.setMessage("You Loose!");
     } else if(gameResult == Result.WIN) {
      builder.setMessage("You Win!");
     } else if(gameResult == Result.DRAW) {
      builder.setMessage("It's a draw!");
     } 
     
     AlertDialog alert = builder.create();
     alert.show();  
    } 

 private void play() {
  // Generates a random play.
  int rand =  ((int)(Math.random() * 10)) % 3;
  Option androidSelection = null;
  ImageView imageView = (ImageView) findViewById(R.id.ImageViewAnswerAndroid);
  
  // Sets the right image according to random selection.
  switch (rand) {
   case 0:
    androidSelection = Option.ROCK;
    imageView.setImageResource(R.drawable.rock);
    break;
   case 1:
    androidSelection = Option.PAPER;
    imageView.setImageResource(R.drawable.paper);
    break;
   case 2:
    androidSelection = Option.SCISSORS;
    imageView.setImageResource(R.drawable.scissors);
    break;
  }
  // Determine game result according to user selection and Android selection.
  if(androidSelection == userSelection) {
   gameResult = Result.DRAW;
  }
  else if(androidSelection == Option.ROCK && userSelection == Option.SCISSORS) {
   gameResult = Result.LOSS;
  }
  else if(androidSelection == Option.PAPER && userSelection == Option.ROCK) {
   gameResult = Result.LOSS;
  } 
  else if(androidSelection == Option.SCISSORS && userSelection == Option.PAPER) {
   gameResult = Result.LOSS;
  } else {
   gameResult = Result.WIN;
  }  
 }    
}

App corriendo:


domingo, 7 de octubre de 2012

Android: Nombres de recursos

Si obtienes un error diciendo lo siguiente:

"Invalid file name: must contain only [a-z0-9_.]"

Es porque alguno de los recursos que colocaste en la carpeta "res" no sigue las reglas de nombres de archivos apropiada.

Recientemente, en mis primeras incursiones en el desarrollo Android, nombre un archivo como "the-beatles-band". Según yo estaba usando caracteres válidos, pero no había notado que el guion que sale en la regla es para describir una expresión regular. "a-z" significa letras de la "a" a la "z" en minúscula. De igual forma "0-9" significa los números del 0 al 9. Así que tuve que reemplazar el guion por la raya abajo ("_").

jueves, 27 de septiembre de 2012

Android: Nombres código de los Sistemas Operativos



Quizás muchos estén familiarizados ya con los nombres tan llamativos que se le designan a las versiones de los distintos sistemas operativos de Android. Pero si son tan despistados como quien escribe en este blog, tal vez no habrán notado el patrón que siguen estos particulares nombres código.

Para los que sí ponen atención, sabrán que las distintas versiones de Android son nombradas a partir de nombres de bocadillos dulces: Cupcake, Donut, Éclair, Froyo, Gingerbread, Honeycomb, Ice Cream Sandwich, Jelly Bean. Para los aún más observadores, ya se dieron cuenta que cada uno de los postres lleva   un orden alfabético que comienza a partir de la letra C.

Android 1.5 - Cupcake
Android 1.6 - Donut
Android 2.0 - Éclair
Android 2.1 - Éclair
Android 2.2 - Froyo
Android 2.3 - Gingerbread
Android 3.0 - Honeycomb
Android 4.0 - Ice Cream Sandwich
Android 4.1 - Jelly Bean

En cuanto a por qué comienza con la letra C, y dónde están los snacks con A y B, muchos podrían pensar que se debe a la típica denominación en el mundo del software como Alfa y Beta. Pero parece que antes de Cupcake, simplemente las versiones tenían nombre aburridos con códigos alfa numéricos y por tanto comenzaron a utilizar nombres código más fáciles de recordar como se acostumbra en los proyectos tecnológicos.

sábado, 23 de abril de 2011

Programación Android: Primeros pasos

En esta entrada de blog quisiera recomendar un video tutorial que explica de manera muy concisa, cómo instalar el ambiente para el desarrollo en Android. No pretendo detallar mucho pues el tutorial es muy claro. En resumen, los pasos a seguir son los siguientes:
  1. Revisar pre-requisitios: Java SDK (1.6 hacia arriba preferiblemente) y Eclipse como IDE de desarrollo (cualquier versión reciente funciona. En mi caso yo utilizo Helios).
  2. Decargar e instalar el SDK de Android.
  3. Ejecutar el administrador del SDK de Android (SDK manager).
  4. Ir al menú de la izquierda en la opción de paquetes disponibles ("available packages") y seleccionar la versión del API para descargarla. En este momento la 2.2 es la más utilizada. También es bueno descargar los ejemplos de la API.
  5. Instalar el plugin Android para eclipse (instrucciones disponibles en el sitio del SDK).
  6. Ir a las preferencias de Eclipse para configurar el path en donde está el SDK de Android.
  7. Para probar que todo funciona bien, creamos un nuevo proyecto de tipo Android el cual crea una clase principal con un simple "Hola Mundo".
  8. Ejecutamos el proyecto como una aplicación de Android.
  9. La primera vez para a solicitar que se configure en un emulador de un dispositivo Android. Se hace con las características deseadas como tamaño de pantalla y cantidad de memoria del dispositivo.
  10. Arranca el emulador (puede tomar un rato) y se ejecuta la aplicación desplegando el hola mundo.

domingo, 27 de febrero de 2011

Más que un juguete de geek...


En el tiempo que llevo de desenvolverme en el ámbito de las tecnologías de información, tomando en cuenta mi formación universitaria y experiencia laboral, siempre he considerado que no calzo por completo con el perfil de un geek. Bueno, habría que definir a que me refiero con geek en este contexto, ya que este es un calificativo que hoy en día se usa de manera muy libre. Me refiero a que no he sido tan geek desde el punto de vista de mantenerme muy actualizado con las novedades en gadgets. No soy el tipo de persona que quiero cambiar de PC cada 2 o 3 años. De hecho, mi computadora de escritorio lleva conmigo casi 10 años. Ya está pidiendo jubilación pero aún no he querido dejarla ir, porque a la verdad, no he sentido necesidad de hacer un cambio. Y es que siendo que en la universidad siempre tenía acceso a las computadoras de los laboratorios, y ahora en el trabajo he tenido mi computador personal y en ocasiones una laptop que puedo llevarme a casa, no veo una gran urgencia de buscar refrescarme tecnológicamente. Pero aún si lo hubiese requerido, siento que no soy el típico geek que por ejemplo ahorra parte de su salario para comprarse lo último en aparatos sofisticados como un Ipad .

También todos mis celulares hasta hace poco eran una versión bonita de un ladrillo. No es que sea mal agradecido con ellos, solo quiero decir que comparados con sus contemporáneos más modernos, realmente sí eran ladrillos en aspectos de tecnología. Sin embargo recientemente creo que estoy modificando un poco ese patrón conservador a la modernidad, no por un aspecto de sed consumidora, sino que creo de estrategia profesional. Doy gracias a Dios por mi nuevo aparatito, acabo de adquirir un celular HTC Legend el cual lo tengo actualizado con la más reciente versión 2.2 de Android. En verdad me deje seducir el oído con los comentarios y revisiones acerca de los celulares con sistema operativo Android. Debo confesar que mi impulso consumista se reparte en varios porcentajes: 40% en sentirme relegado con los compañeros de trabajo con sus Iphones y demás celulares inteligentes (lo que mi esposa llama el síndrome Quico), otro 40% en sentir la necesidad de contar con un aparato más sofisticado (“necesidad creada”, pero necesidad a fin de cuentas) y otro 20% en conocer la plataforma de la cual todos hablan hoy en día. ¿Solo un 20%? Pues sí, casi, casi compro un llamativo Iphone. En todo caso, y ya aterrizando esta corta disertación, creo que adquirir este celular ha sido más que un juguete nuevo, una verdadera inversión.

Ya hace un tiempo tenía la inquietud de comenzar a reservar neuronas para el desarrollo de móviles, pero no ha sido hasta que he tenido la experiencia de usar la enorme cantidad de aplicaciones que hay para el Android, que he comprendido el salto tecnológico que estamos experimentando en la interacción humano-computador. Aún teniendo una laptop que puedo llevarme a la cama, casi nunca siento ganas de prenderla para hacer cualquier cosa con ella. Casi siento el mismo nivel de esfuerzo de ir a sentarme al escritorio donde tengo la PC. Pero en cambio la experiencia de un celular con aplicaciones está a varias pulsaciones de distancia. Es más fácil comprender por qué tanto escándalo con este tipo de celulares cuando se tiene uno a mano. Sin duda el desarrollo para este tipo de aparatos va ir cobrando cada vez mayor relevancia, y tenemos que estar preparados para ello.

Así que a codificar se ha dicho…