miércoles, 29 de febrero de 2012

Crea un buscador en Android: AutoCompleteTextView

Buenas, esta semana volvemos a la programación Android despues de estar instalando la semana pasada un servidor GIT. Vamos a ver como utilizar el control AutoCompleteTextView para construir un buscador que nos vaya dando resultados a medida que escribimos nuestra búsqueda. El buscador va a ir haciendo consultas a una base de datos que previamente hemos creado e insertado datos en nuestra aplicación.


Lo primero que vamos a hacer es crear las 2 vistas que necesitaremos. La primera de ellas es la que tiene el control AutoCompleteTextView y la otra muestra cada uno de los resultados de la búsqueda.
Este es el código del primer archivo, le llamaremos bar_search.xml. He puesto el control y su etiqueta  en un LinearLayout y este a su vez en un RelativeLayout de esta forma podemos hacer que el LinearLayout y su contenido flote en la parte de la pantalla que querais, jugando con los parámetros layout_alignParentTop, Bottom, Left, Right y con los margin y padding.


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"  android:layout_height="fill_parent">
<LinearLayout style="@style/SearchBar" android:layout_width="fill_parent"
android:layout_height="wrap_content">
   <TextView text="Buscar" android:layout_width="wrap_content"
  android:layout_height="wrap_content" />
   <AutoCompleteTextView android:id="@+id/txtSearch"android:layout_width="fill_parent"  android:layout_height="fill_parent" />
  </LinearLayout> 
</RelativeLayout>


Este es el código del segundo archivo, le llamaremos item_search.xml. Este será el que nos de el diseño para cada uno de los items encontrados que nos vaya mostrando el control de autocompletado.


<?xml version="1.0" encoding="utf-8"?>
<TextView android:id="@+id/lblItemSearch"
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:padding="10dp"
  android:textSize="16sp"
  android:textColor="#000">
</TextView>


Una vez que ya tenemos listas las vistas vamos a crear una clase para gestionar la base de datos. Ya hemos visto como hacer esto en otros artículos os dejo el enlace aquí: como guardar datos en base de datos android. En el ejemplo de ese artículo habíamos creado una clase bbdd, la cual retomaremos para añadir un método que será el que va a buscar los resultados, en este caso vamos a buscar en la tabla de libros. El código del método será el siguiente:


public Cursor getCursorBuscador(String textSearch){
    textSearch = textSearch.replace("'", "''");
    SQLiteDatabase db = getReadableDatabase();
    return db.rawQuery("SELECT id_libro AS _id, nombre AS item" + 
      " FROM "+TableLibros + 
      " WHERE nombre LIKE '%" +textSearch+ "%' ", null);
}


El método que añadimos, getCursorBuscador, va a buscar en la tabla libros. Con la instrucción LIKE y los % (caracter comodin) buscamos todos aquellos libros que contengan en su nombre el texto que hemos introducido. En la primera línea hacemos un replace de una comilla simple por dos comillas simples, de lo contrario al hacer una búsqueda que contenga este carácter daría error. El replace lo pongo en este método para simplificar. Lo mejor sería hacerse un método para esto y aplicarlo en todas las consultas a base de datos que se necesite.


También es bastante importante el alias _id que se le da a la columna id_libro ya que el CursorAdapter que utilizaremos más adelante espera que en el cursor de datos exista esta columna que identificará cada uno de los items con este nombre.


Lo siguiente que vamos a hacer es una clase para gestionar el acceso a datos desde el AutoCompleteTextView, le llamaremos CursorAdapterSearch y va a heredar de CursorAdapter.


public class CursorAdapterSearch extends CursorAdapter {

   private bbdd db;
 
   public CursorAdapterSearch(Context context, Cursor c) {
     super(context, c);
     db = new bbdd(context);
   }

   @Override
   public void bindView(View view, Context arg1, Cursor cursor) {
     String item = createItem(cursor);
     ((TextView ) view).setText(item);  
   }

   @Override
   public View newView(Context context, Cursor cursor, ViewGroup parent) {
     final LayoutInflater inflater = LayoutInflater.from(context);
     final TextView view = (TextView) inflater.inflate(R.layout.item_search, parent, false);
        
     String item = createItem(cursor);
     view.setText(item);
        
     return view;
   }

   @Override
   public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
     Cursor currentCursor = null;
         
     if (getFilterQueryProvider() != null) {
        return getFilterQueryProvider().runQuery(constraint);
     }
         
     String args = "";
         
     if (constraint != null) {
        args = constraint.toString();       
     }
  
     currentCursor = db.getCursorBuscador(args);
  
     return currentCursor;
   }
 
   private String createItem(Cursor cursor){
     String item = cursor.getString(1);
     return item;
   }
}


Como os decía, con esta clase gestionaremos el acceso a los datos del AutoCompleteTextView. Estamos leyendo de una base de datos, pero el control también podría por ejemplo conectarse a un servicio web que nos devolviera el resultado de búsqueda. En esta clase hay que destacar como sobrescribimos el método runQueryOnBackgroundThread, en el que args es el texto que va introduciendo el usuario y se lo pasamos al objeto db para llamar a getCursorBuscador que nos devuelve un objeto Cursor que es el que finalmente devuelve.


Ahora vamos a crear una clase que será la que va a gestionar la vista del buscador y que al final pondremos en aquellas pantallas donde queremos utilizarlo. Vamos a crear una clase llamada BarSearch y que hereda de RelativeLayout.


public class BarSeach extends RelativeLayout {

  private Activity activity;
  private AutoCompleteTextView txtSearch;  
  private CursorAdapterSearch CategoriesAdapter;
  private Cursor mCursor;
  private bbdd db;
 
  public BarSeach(Activity activity) {
      super(activity);
      this.activity = activity;
  
      String infService = Context.LAYOUT_INFLATER_SERVICE;
      LayoutInflater li = (LayoutInflater)getContext().getSystemService(infService);
      li.inflate(com.trespies.guia.generic.R.layout.bar_search, this, true);
  
     db = new bbdd(this.activity);
     mCursor = db.getCursorBuscador("");
     
     this.activity.startManagingCursor(mCursor);
     CategoriesAdapter = new CursorAdapterSearch(this.activity, mCursor);
     
     txtSearch = (AutoCompleteTextView) findViewById(R.id.txtSearchPOIs);
     txtSearch.setAdapter(CategoriesAdapter);
     txtSearch.setThreshold(1);
     
     txtSearch.setOnItemClickListener(new OnItemClickListener() {

   public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3) {
     Cursor c = (Cursor) arg0.getAdapter().getItem(position);
     txtSearch.setText(c.getString(1));
    
     int id = c.getInt(0);
     String t = c.getString(1);
    
     ListenerItemClickSearch.onItemClickSearchListener(id, t);
    }
      
 });
  }
 
  public interface OnItemClickSearchListener{
     void onItemClickSearchListener(int idItem, String texto);
  }
 
  private OnItemClickSearchListener ListenerItemClickSearch;
 
  public void setOnItemClickSearchListener(OnItemClickSearchListener l){
     ListenerItemClickSearch = l;
  }

}


En esta clase, hacemos la mayor parte del proceso en el constructor. Primero se inicializa el layout que creamos al principio. Inicializamos un objeto Cursor, pasamos el control (con startManagingCursor) a la Activity para que sea esta la que se encargue de desactivarlo si salimos de ella, y creamos un objeto CursorAdapterSearch al que le pasamos este cursor que será el que maneje.


Después inicializamos el AutoCompleteTextView, seteamos su Adapter con el objeto CursorAdapterSearch. Con setThreshold le decimos cuantos caracteres hay que escribir para que empiece a buscar. Esto debéis setearlo según lo grande que sea el conjunto de datos sobre el que buscamos y lo que va a tardar en hacer la búsqueda, cuanto más datos, más caracteres deberíamos esperar (pero tampoco sin pasarnos, intentad buscar un termino medio).


Por último, seteamos el evento click de cada uno de los resultados, en este para obtener los  datos del item sobre el que hemos hecho click utilizamos el primer parámetro del evento. Con arg0.getAdapter() accedemos al conjunto entero de datos y con getItem y position obtenemos el item seleccionado. Como este cursor tiene los datos de nuestra consulta, podemos acceder a los datos con getInt, getString y su posición correspondiente. Por último, lanzamos el evento ItemClickSearch que nosotros mismos definimos en esta clase.

El evento OnItemClickSearch definido por nosotros nos va a servir para saber desde fuera de nuestra clase cuando se hace click sobre uno de los resultados de la búsqueda. Este lo llamaremos en las Activitys en las que utilicemos nuestra clase para realizar diferentes acciones según nuestras necesidades. El evento nos va a dar el id del item y el texto del item seleccionado, pero podéis poner más parámetros según las necesidades de vuestra aplicación.


Para terminar, vamos a utilizar el buscador en una de nuestras Activitys, para ello, abrimos una Activity de nuestro proyecto y en el método OnCreate añadimos el siguiente código:


BarSearch search = new BarSeach(this);
search.setOnItemClickSearchListener(new OnItemClickSearchListener() {
 public void onItemClickSearchListener(int idItem, String texto) {
 //Aquí va el código que se ejecutará en cada caso al hacer click en un item
 }
});
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
addContentView(search, lp);


Como veis, su utilización final es bastante sencilla, simplemente hemos de crear un objeto BarSearch, setear que es lo que hará en el ItemClickSearch y añadirlo a la vista de nuestra Activity. El objeto LayoutParams es necesario para darle por lo menos un alto y un ancho, ya que sino lanzará una excepción.

martes, 28 de febrero de 2012

Configurar un Servidor DHCP mediante Webmin

Tras retrasarme un par de semanas por ciertas cuestiones, termino por fin estos artículos sobre servidores DHCP. Tenemos nuestro servidor funcionando, sólo nos faltaba configurarlo. Esta configuración dependerá de nuestras necesidades, por ejemplo, si vamos a utilizar muchos ordenadores, no vamos a utilizar la asignacion por dirección física (a no ser que sea necesario).
A lo que me refiero con esto, es que no necesitamos configurar todas las opciones que pongo a continuación. Simplemente, las que necesitemos.

Date una vuelta por el artículo de instalación del servidor ubuntu, el cual tiene las instrucciones para poder instalarlo y los pasos previos a seguir antes de configurarlo.

Tenemos nuestro webmin abierto y nos dirigimos a la sección de servidores, y entramos en el servidor de DHCP:

Una vez dentro veremos algo como esto:



Asignar configuraciones de red a dispositivos 

El uso principal que le daremos a un servidor DHCP es el de asignar automáticamente direcciones IP a los dispositivos que se conecten a la red. Para ello debemos Añadir una nueva subred (en la pantalla del servidor DHCP de webmin).
En "Subnet description" debemos asignar un nombre para poder diferenciar unas de otras, este nombre es irrelevante en el funcionamiento, pero es útil a nivel organizativo.

La dirección de Red, es la dirección de red en la cual va a funcionar el servidor DHCP

Nota:
La dirección de red, recuerdo que es la que tiene la parte de red original, y la parte de host con el número 0. Por ejemplo 172.16.0.0 , sería la red 172.16.

El rango de direcciones, se refiere a las direcciones IP que va a poder asignar el servicio. En el ejemplo asigne 30 direcciones libres.

Máscara de Red(subred), debemos poner todos los bytes de la direccion de red en 255 y los de host en 0.

Cuando terminemos estas configuraciones básicas le damos a crear en la parte inferior de la página y veremos que se ha creado correctamente:

Hasta ahora sólamente hemos proporcionado al dispositivo una dirección IP, una máscara de subred, y una red. Nos queda asignarle una puerta de enlace, para que tenga salida a internet y a otros ordenadores de otras áreas locales. Y además los servidores DNS para resolver direcciones IP.
Ahora debemos dirigirnos a "Editar Opciones de Cliente" para agregar unas características comunes a todas las subredes creadas como en el paso anterior.


Una vez dentro veremos algo como esto:

En enrutadores por defecto, debemos poner la dirección IP del router y en servidores DNS, las direccion del servidor DNS que nos proporcione el ISP (proveedor del servicio de Internet) o un DNS público como el de la imagen.


Seleccionar interfaz de red

Si tenemos varias tarjetas de red, debemos elegir en cual debe funcionar el servidor DHCP. En la página inicial de DHCP, debemos hacer click en "Edit Network Interface" y allí nos saldrán todas las interfaces que tiene nuestro ordenador, allí elegiremos la que deseamos. En mi caso solo hay una, sin contar la de loopback.



Asignar una dirección fija a una máquina en un servidor DHCP mediante dirección MAC

Debemos estar en la página principal y dirigirnos a Máquinas y Grupos de Máquinas y añadir una nueva máquina.
 


Una vez ahi, debemos añadir un nombre para diferenciarlo, el nombre de la máquina.
Debemos añadir también la dirección hardware (en la imagen sale direccion MAC) y la ip que queremos asignar. seleccionamos crear y listo.


Ver los arrendamientos activos

Para poder ver las direcciones IP, sus direcciones físicas de todos los ordenadores a los cuales a asignado una dirección el servidor




Para finalizar, debemos acordarnos cada vez que realicemos un cambio, reiniciar el servicio mediante la interfaz del webmin.




Y con esto concluimos la parte de servidores DHCP. Un saludo y gracias por todo vuestro apoyo.

domingo, 26 de febrero de 2012

El Escritorio del Lector #65

Finalizando la semana ya estamos aquí con una nueva edición de "El Escritorio del Lector". Sección que me ha sorprendido muy gratamente, ya que vosotr@s sois los que la hacéis seguir enviando vuestras capturas y características. Es muy gratificante que os impliquéis con el blog, así que desde aquí os agradecemos que sigáis participando y comentando.

Hoy nos visita Daniel Romero, quien nos explica

Cita
"Mi actual escritorio es Ubuntu 11.10 con Gnome 3, y la verdad es que estoy super contento con la versión que han sacado. Funciona todo, rapidez, sencillez, básicamente es genial.

Esta versión que tengo la he personalizado a mi gusto con toques muy

minimalistas, lo podréis comprobar nada más veas el escritorio, ya que no hay iconos. Lo encuentro un poco feo tener iconos.. Me gusta el rollo minimalista."










Desde aquí os animo (algo que agradezco de antemano) a participar enviando vuestra captura o capturas con sus correspondientes características, como Sistema Operativo, Fondo de Escritorio, Tema de Ventanas y Tema de iconos a nosinmiubuntublog@gmail.com 

Saludos.

miércoles, 22 de febrero de 2012

Instalar GIT en Ubuntu, sistema de control de versiones

Buenas, hasta ahora siempre he trabajado en empresas pequeñas donde la programación en ciertos aspectos era un poco de andar por casa. Sobre todo lo que se refiere al control de versiones. Este se hacía de una manera muy manual, con un excel donde apuntábamos lo que íbamos cambiando y avisándonos unos a otros cuando trabajábamos en un archivo de un proyecto compartido entre varios. Esta forma de trabajar siempre hará que cometamos errores debido a la falta de documentación en el excel o por la necesidad de modificar archivos por tareas de mantenimiento pero que se están modificando para un desarrollo.


Hasta ahora nunca había trabajado con ningún control de versiones, pero llevaba bastante tiempo escuchando hablar de ellos, sobre todo GIT. Así que ahora me he decidido a montarme mi propio servidor personal git.


Git ha sido desarrollado ni más ni menos que por el propio Linus Torvalds, y es utilizado para el nucleo de Linux entre otros muchos proyectos importantes. El desarrollador que va a trabajar en un determinado proyecto descarga una copia a su pc del proyecto, realiza los cambios necesarios y puede enviar después sus cambios. Otro de los aspectos importantes es que podremos crear una rama de nuestro proyecto, por lo que podremos hacer varias variantes de un desarrollo y escoger cual es la que queremos enviar a nuestro repositorio. Hoy veremos como instalarlo y poco a poco iremos viendo los comandos necesarios para trabajar con git.


Empezamos instalando los paquetes necesarios, entre los que tenemos 2 de git: git-core y gitweb (uno es el núcleo y otro la interfaz web), otro para el server SSH y apache. Con el siguiente comando instalaremos todo.


# aptitude install apache2 git-core gitweb openssh-server


Ahora debemos crear un directorio para el repositorio de git /var/cache/git y otro para la interfaz web gitweb.cgi /var/www/git


# mkdir /var/www/git
# [ -d “/var/cache/git” ] || sudo mkdir /var/cache/git


Ahora vamos a crear un archivo de configuración en Apache para nuestro servidor git.


# nano /etc/apache2/conf.d/git


Y escribimos la siguiente configuración dentro de  este archivo:


<Directory /var/www/git>
Allow from all
AllowOverride all
Order allow,deny
Options ExecCGI
<Files gitweb.cgi>
SetHandler cgi-script
</Files>
</Directory>
DirectoryIndex gitweb.cgi
SetEnv  GITWEB_CONFIG  /etc/gitweb.conf

Ahora debemos mover los archivos gitweb.cgi, .css y .png de git a /var/ww/git

# mv -v /usr/share/gitweb/* /var/www/git
# mv -v /usr/lib/cgi-bin/gitweb.cgi /var/www/git


Y debemos hacer algún cambio en el archivo de configuración debido a los archivos movidos en /etc/gitweb.conf, abrimos el archivo con el editor nano y modificamos el archivo así:


# nano /etc/gitweb.conf


$projectroot = '/var/cache/git/';
$git_temp = "/tmp";
#$home_link = $my_uri || "/";
$home_text = "indextext.html";
$projects_list = $projectroot;
$stylesheet = "/git/gitweb.css";
$logo = "/git/git-logo.png";
$favicon = "/git/git-favicon.png";


Por último volvemos a recargar la configuración de Apache:


# /etc/init.d/apache2 reload


Ya está montado nuestro control de versiones git y la interfaz web, podemos comprobarlo llamando a la siguiente dirección desde nuestro navegador: http://localhost/cgi

Ahora vamos a crear un proyecto.


# cd /var/cache/git/
# mkdir proyecto.git
# cd proyecto.git

Iniciamos un nuevo repositorio y lo configuramos. Dentro de la carpeta de nuestro proyecto se creará la carpeta .git que es la que contendrá información para git.


# git init
# echo “descripción del proyecto” > .git/description
# git config -global user.name “Tu nombre”
# git config -global user.email “tu@correo.com”
# git commit -a


Si ahora volvemos a llamar la interfaz web veremos que aparece el repositorio que hemos creado. Ahora para marcar un repositorio como exportado se utiliza el archivo git-daemon-export-ok


# touch .git/git-daemon-export-ok


Ahora iniciaremos un servicio que hará publico nuestro repositorio.


# git daemon -base-path=/var/cache/git -detach -syslog -export-all


Ahora nuestro repositorio está en el puerto 9418, y le daremos permisos a un usuario diferente de root.


# adduser usuariogit
# passwd usuariogit
# chown -Rv usuariogit:usuariogit /var/cache/git/proyecto.git


Por último, para descargar el repositorio basta con la siguiente instrucción:


# git clone git://ip_servidor/proyecto.git proyecto


Ahora ya tenemos una copia en nuestro pc del proyecto con el que podremos trabajar para luego enviar los cambios al repositorio. La semana que viene veremos en más detalle como trabajar con git.

domingo, 19 de febrero de 2012

El Escritorio del Lector #64

Finalizando la semana ya estamos aquí con una nueva edición de "El Escritorio del Lector". Sección que me ha sorprendido muy gratamente, ya que vosotr@s sois los que la hacéis seguir enviando vuestras capturas y características. Es muy gratificante que os impliquéis con el blog, así que desde aquí os agradecemos que sigáis participando y comentando.

El protagonista de hoy es Kelvin Feliz, quien nos explica un poco los motivos de la elección de las características de su escritorio.

Nos comenta:
"Como muchos usuarios he usado Gnome Shell y Unity, pero ninguno cumplía con mis expectativas en cuanto a rendimiento, así que probé xfce y estoy encantado. Si lo hubiese conocido antes de Gnome 2x seria mi favorito desde aquel entonces, así que le he dado una tuneada para compartirlo para motivar a usuarios a usarlo"









Desde aquí os animo (algo que agradezco de antemano) a participar enviando vuestra captura o capturas con sus correspondientes características, como Sistema Operativo, Fondo de Escritorio, Tema de Ventanas y Tema de iconos a nosinmiubuntublog@gmail.com 

Saludos.

miércoles, 15 de febrero de 2012

Navegando en nuestra aplicación Android

Buenas, la entrada de esta semana, es de esas sencillas pero bastante prácticas. Hoy veremos como navegar entre diferentes activitys.
Normalmente, una aplicación cualquiera suele tener más de una pantalla, bien porque añadimos una pantalla de configuración, porque tenemos una lista y un detalle, o un menú enlazado a sus diferentes pantallas.


Lo primero que vamos a hacer es crear un nuevo proyecto, yo le he llamado Navigation, y mi activity de inicio se llamará NavigationActivity. Y ahora crearemos dos activitys más, una de ellas le llamaremos NavigationDetail y la otra NavigationResult, para hacer esto basta ir a crear una clase nueva y hacer que herede de Activity.


También hemos de crear dos nuevos layouts para estas activitys, para ello en la carpeta layout hacemos botón derecho y creamos un nuevo archivo, yo les llamaré navigationdetail.xml y navigationresult.xml. El contenido inicial lo podemos copiar del layout main.xml que ha creado al hacer el proyecto.
el código que hemos de añadir en un principio para nuestras activitys es muy sencillo, simplemente debemos decirle cual es el layout que debe llamar, poniendo navigationdetail o navigationresult según sea el caso.


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.navigationdetail);
    }


Por último, debemos decirle a nuestra aplicación que tenemos estas dos nuevas pantallas de nuestra aplicación, para ello abrimos el archivo AndroidManifest.xml, en la vista de código debéis localizar el tag <application>, dentro de este es donde se declaran todas las activitys de nuestra aplicación. Como veis, por defecto ya está declarada nuestra activity principal, la cual además tiene un par de tags que indican que será la activity que se lanzará en el inicio de la aplicación. Si quisierais cambiar vuestro activity principal, simplemente deberéis llevaros estos tags a la activity principal.

Para declarar una nueva activity es muy sencillo, dentro del tag <application> definis un nuevo tag <activity>, que en nuestro caso quedaría de la siguiente forma:


<activity android:name=".NavigationDetail" />
<activity android:name=".NavigationResult" />


Una vez hecho esto nos falta navegar de una pantalla a otra. Para ello vamos a hacer una clase que nos ayude a centralizar las llamadas de navegación que llamaremos NavigationManager. En principio va a tener el siguiente código:


public static void navegarAActivityPrincipal(Activity activity){
  activity.finish();
  Intent itemintent = new Intent(activity, NavigationActivity.class);
  activity.startActivity(itemintent);
 }
 
 public static void navegarAActivityDetail(Activity activity, int id1, int id2){
  activity.finish();    
  Intent itemintent = new Intent(activity, NavigationDetail.class);
  Bundle b = new Bundle();
  b.putInt("id1", id1);
  b.putInt("id2", id2);
  itemintent.putExtra("android.intent.extra.INTENT", b);
  activity.startActivity(itemintent);
 }
 
 public static int getId1(Activity activity){
  int id1 = 0;
  Intent startingIntent = activity.getIntent();
        if (startingIntent != null)
        {
         Bundle b = startingIntent.getBundleExtra("android.intent.extra.INTENT");
         if (b != null) {
          id1 = b.getInt("id1");          
         }
        }
        return id1;
 }
 
 public static int getId2(Activity activity){
  int id2 = 0;
  Intent startingIntent = activity.getIntent();
        if (startingIntent != null)
        {
         Bundle b = startingIntent.getBundleExtra("android.intent.extra.INTENT");
         if (b != null) {
          id2 = b.getInt("id2");          
         }
        }
        return id2;
 }

 private final static int KEY_RESULT = 89865; 
 
 public static void navegarAActivityResult(Activity activity){
  Intent itemintent = new Intent(activity, NavigationResult.class);
  activity.startActivityForResult(itemintent, KEY_RESULT);
 }
 
 public static void returnValueActivityResult(Activity activity, int id1){
  Bundle bundle = new Bundle();
     bundle.putInt("id1", id1);
     Intent mIntent = new Intent();
     mIntent.putExtras(bundle);
     activity.setResult(Activity.RESULT_OK, mIntent);
     activity.finish();
 }
 
 public static int getValueActivityResult(int requestCode, int resultCode, Intent data){
  int id1 = 0;
  if(data != null && requestCode == KEY_RESULT && Activity.RESULT_OK == resultCode){
   id1 = data.getExtras().getInt("id1");  
  }  
  return id1;
 }
 
Tiene bastantes métodos pero yo prefiero tenerlos todos en el mismo punto para tener un mejor control de la navegación. Todos los métodos son estáticos para que no haga falta instanciar esta clase.


El primer método navegarAActivityPrincipal nos lleva a la activity de inicio. En todos los métodos para navegar definimos un objeto Intent que es una clase que nos permite una activity a ejecutar. En este caso le decimos que es la principal y después llamamos al método startActivity pasándole como parámetro el intent. Lo podemos utilizar así en un Button en nuestra activity NavigationDetail:


btn.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
           NavigationManager.navegarAActivityPrincipal(NavigationDetail.this);
      }
});


El segundo método, navegarAActivityDetail, hace casi lo mismo que es el anterior, pero ahora queremos pasarle una serie de parámetros a nuestra activity, para ello nos ayudamos de la calse Bundle a la que le vamos indicando todos los parámetros que enviaremos, y este Bundle se lo añadimos a nuestro Intent para que se lo envíe a la activity que vamos a abrir.


Para recoger estos parámetros utilizaremos los métodos getId1 y getId2, cada uno de estos revisan en el Intent de destino los BundleExtra que indicamos en el método anterior y buscar nuestros parámetros para devolverlos finalmente. Estos dos métodos debemos utilizarlos en el OnCreate del activity NavigationDetail. Para comprobar que funcionan podéis crear un TextView y mostrar los valores que habéis pasado desde otra activity.


@Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.navigationdetail);
       
        int id1 = NavigationManager.getId1(this);
        int id2 = NavigationManager.getId2(this);
}


Los siguientes métodos se utilizan cuando desde una activity estamos realizando un proceso que por el medio necesita llamar a otra activity, desde esa nueva activity iniciamos un nuevo proceso que generará un resultado y se lo enviaremos a nuestra primera activity. Por ejemplo, seleccionar una foto o un contacto de nuestra agenda.


El método navegarAActivityResult, hace casi lo mismo que el resto, pero ahora llamamos a startActivityForResult y como segundo parámetro le pasamos una clave que hemos creado en esta misma clase con un código que elegimos nosotros. El cual nos servirá para recoger después el resultado.


El siguiente método, returnValueActivityResult, lo utilizaremos en el activity al que llamamos para devolver el resultado. Simplemente mete en el BundleExtra los valores que vamos a devolver y le decimos que el resultado de la operación ha sido correcto. Si quisierais controlar en la vuelta errores, etc.. podríais hacerlo con los distintos valores de RESULT.


Por último, una vez que hemos regresado a la activity de origen, debemos recoger estos parámetros, para ello debemos hacerlo en el método OnActivityResult, que es el encargado de recoger estas peticiones y procesarlas. Nosotros sobrescribiremos el método con el siguiente código:


@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      int id1 = NavigationManager.getValueActivityResult(requestCode, resultCode, data);
}


Con estos pocos casos podeis controlar la mayor parte de la navegación de una aplicación. Por último deciros que es en la clase NavigationManager donde deberiais añadir las llamadas para registrar como navegan los usuarios por vuestra aplicación. Si os acordáis vimos como hacerlo la semana pasada con Google Analitycs.

domingo, 12 de febrero de 2012

El Escritorio del Lector #63

Finalizando la semana ya estamos aquí con una nueva edición de "El Escritorio del Lector". Sección que me ha sorprendido muy gratamente, ya que vosotr@s sois los que la hacéis seguir enviando vuestras capturas y características. Es muy gratificante que os impliquéis con el blog, así que desde aquí os agradecemos que sigáis participando y comentando.


Mariano Cabrera es el protagonista de hoy, quien nos comenta que usa Cinnamon, un Fork basado en Gnome Shell,  que hace al usuario tener un entorno muy similar a Gnome 2. Además nos aclara que también es usario de Unity y Gnome Shell.




 
  • Iconos: Ambiance


Desde aquí os animo (algo que agradezco de antemano) a participar enviando vuestra captura o capturas con sus correspondientes características, como Sistema Operativo, Fondo de Escritorio, Tema de Ventanas y Tema de iconos a nosinmiubuntublog@gmail.com 

Saludos.

jueves, 9 de febrero de 2012

Instalar R (paquete estadístico) desde código fuente

R es un entorno libre orientado al cálculo estadístico que utiliza los lenguajes de programación C, C++ y Fortran para realizar las tareas solicitadas por el usuario, y que se caracteriza por la particularidad de que sus comandos se ejecutan desde una terminal. Instalar R en Ubuntu es realmente sencillo, pues está incluido en los repositorios de esta distribución; nos bastaría con un simple:

sudo apt-get install r-base

y ya tendríamos R instalado en nuestro sistema.

En esta entrada vamos a hacerlo un poco más difícil: instalaremos R desde su código fuente. Así conoceremos los pasos que constituyen el proceso estándar de compilación/instalación en Linux, y que son los siguientes:

./configure
make
sudo make install

Manos a la obra:

1) Nos bajamos el código fuente de R (http://cran.freestatistics.org/src/base/R-2/R-2.14.1.tar.gz).

2) Abrimos una terminal y descomprimimos el archivo R-2.14.1.tar.gz:

$ tar xvzf Descargas/R-2.14.1.tar.gz

3)
Entramos en el directorio del código fuente de R y ejecutamos
./configure. Este script comprueba las dependencias necesarias para la compilación; si todas ellas están disponibles se creará un archivo Makefile, necesario para la posterior ejecución de make. En caso contrario, ./configure nos irá detallando qué dependencias faltan:

$ cd R-2.14.1
$ ./configure
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details

* No hay compilador de C. Lo instalamos (de paso también instalamos make) y probamos de nuevo:

$ sudo apt-get install gcc make
$ ./configure
configure: error: No F77 compiler found

* No hay compilador de Fortran. También lo instalamos:

$ sudo apt-get install gfortran
$ ./configure
configure: error: --with-readline=yes (default) and headers/libs are not available

* No se encuentra la librería de desarrollo (dev) readline:

$ sudo apt-get install libreadline-dev
$ ./configure
configure: error: --with-x=yes (default) and X11 headers/libs are not available

* Falta la librería de desarrollo (dev) xorg:

$ sudo apt-get install xorg-dev
$ ./configure

¡Por fin! Esta vez ./configure nos confirma que ya disponemos de todas las dependencias, pues, como podemos observar, el script completa su ejecución:


4) Lanzamos make, que se encargará de leer y ejecutar todas las órdenes de compilación contenidas en el recién creado Makefile:


5) Compilado. En este punto del proceso, ya podríamos utilizar R sin necesidad de instalarlo a nivel de sistema (para todos los usuarios); sólo tendríamos que hacer ./bin/R :


6) Pero vamos a hacer que esté disponible para todos con sudo make install :


Con el comando which confirmamos que el ejecutable de R se encuentra en /usr/local/bin.

Saludos.

miércoles, 8 de febrero de 2012

Google Analytics en Android

Buenas, hace poco he integrado las estadísticas de Google Analytics en una aplicación que estoy preparando. La verdad es que visto al final, el proceso no parece muy complicado, pero ir siguiendo los diferentes pasos a través de diferentes páginas y en inglés puede llegar a ser un tema que se le puede atragantar a más de uno. Hoy veremos como hacer esto en unos sencillos pasos.

Lo primero que tenemos que hacer es acceder con nuestra cuenta Google en la web de Google Analytics. Las pasos a seguir los voy a hacer con  la nueva interfaz de Google por lo que puede variar algo para los que teneis la antigua. Pinchamos en el icono de administración de cuentas (barra naranja a la derecha), ahi teneis un botón para crear una cuenta nueva. Por cada una de vuestras aplicaciones creareis una.




Para los que ya han añadido estas estadísticas en una página web, deciros que son los mismos pasos, solo que con alguna pequeña diferencia. Le damos nombre a nuestra cuenta e indicamos que no es una página web, aunque podéis poner que es una web e inventaros el dominio, por ejemplo con el espacio de nombres de vuestro proyecto o con un subdominio de alguna web vuestra.

Una vez rellenado todo, guardamos, y nos quedamos con el id de seguimiento, olvidándonos de todo el javascript que nos da (solo es necesario si lo integramos en una web). Además nos muestran un botón para descargar el SDK de Android. Desde aquí vais a la zona de descargas y descargais la versión para Android.

Descomprimimos el archivo, dentro de este tenemos un archivo libGoogleAnalytics.jar y algún ejemplo para integrar en nuestras aplicaciones. Lo que hago normalmente es en la carpeta donde tengo mis proyectos, tengo una carpeta libs para tener a mano siempre estas librerias que voy descargando.

Lo que si que teneis que hacer es abrir vuestro proyecto, y crear una carpeta llamada libs en el raíz de la aplicación, y colocar aquí el archivo .jar. Ahora hacemos botón derecho sobre el nombre de nuestro proyecto y vamos a Properties -> Java Build Path -> Pestaña Libraries -> Botón add jars... en la pantalla que aparece buscamos nuestro proyecto y seleccionamos el archivo jar de la carpeta libs, y aceptamos todo.

Ahora en el archivo AndroidManifest.xml  añadimos los siguientes permisos para que la librería pueda funcionar, acceder a internet y comprobar el estado de nuestra conexión para registrar las visitas.


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


Y vamos a crear una clase para que sea más sencillo utilizar las estadísticas en toda nuestra aplicación, le llamaremos AnalyticsManager:


private GoogleAnalyticsTracker tracker;
 private String UA_Code;
 private int frecuencyUpdateGoogle = 60;
 private Context context;
 
 private GoogleAnalyticsTracker getTracker(){
  if(tracker == null){
   tracker = GoogleAnalyticsTracker.getInstance();
   tracker.startNewSession(UA_Code, frecuencyUpdateGoogle ,this.context);
  }
  return tracker;
 }
 
 public AnalyticsManager(Context context,String UACode){
  this.context = context;  
  this.UA_Code = UACode;
 }
 
 public void registerPage(String page, String parameter){
  this.getTracker().trackPageView("/" + page+ "/" + parameter);
 }
 
 public void registerPage(String page){  
  this.getTracker().trackPageView("/" + page);
 }
 
 public void registerAction(String Category, String Action, String Label, int Value){
  this.getTracker().trackEvent(Category, Action, Label, Value);
 }
 
 public void stopTracker(){
  if(this.getTracker() != null)
   this.getTracker().stopSession();
 }
}


La clase no es muy extensa, en el constructor le pasamos el context donde estamos y el id de seguimiento o UA_Code de Google. El UA_Code lo podéis guardar como una variable global, como veremos después, y de esta forma podéis exportar esta clase a cualquiera de vuestros proyectos. La frecuencia de refresco está en 60 segundos, si lo creéis oportuno, ajustad este parámetro a vuestras necesidades.

Para registrar estadísticas tenéis el método registerPage al cual podéis indicar el nombre de la página, aquí será una activity, a la que navega el usuario, y podéis indicar también un parámetro más por si es una vista que muestra el detalle de algún ítem, y podáis saber hacia cuales navegan vuestros usuarios.

El otro método es registerAction y va a permitirnos registrar cuales son los botones, acciones etc... que más utilizan los usuarios. Podemos indicar la categoría, acción, etiqueta y valor de nuestros botones.

Llegados a este punto ya tenemos totalmente operativa nuestra aplicación, a partir de aquí sería tan fácil como instanciar esta clase y llamar a estos métodos cuando los necesitemos. Advertiros que Google no va a empezar a reflejar el histórico de las estadísticas hasta pasado un día, pero, hay una opción en la que podéis ver las estadísticas en tiempo real de los últimos 30 minutos y no necesitáis esperar un día para saber si está funcionando o no las estadísticas.

Ahora os voy a enseñar como registro en mi aplicación las estadísticas. Por un lado me creo una clase AppGlobals que hereda de Application y me permite acceder a propiedades u objetos que quiero tener de forma global en mi aplicación. Una vez creada teneis que abrir el archivo AndroidManifest.xml y en la pestaña Application chequeais la opción Define an <application> tag in the AndroidManifest.xml y en Name pinchais en Browse y os aparecerá la clase AppGlobals, la seleccionais y guardais.

En la clase AppGlobals vamos a tener el siguiente código, los métodos son static, de esta forma no es necesario instanciar esta clase para llamarlos:


public static String getUACodeAnalytics(){return "UA-xxxxxxxxx-x";}
private static AnalyticsManager analyticsManager = null;

public static AnalyticsManager getAnalyticsManager(Context context){
 if(analyticsManager == null)
  analyticsManager = new AnalyticsManager(context,getUACodeAnalytics());
 return analyticsManager;
}
 
public static AnalyticsManager getAnalyticsManager(){
 return analyticsManager;
}


Lo que estamos haciendo aquí es utilizar el AppGlobals para poder llamar la clase analytics, está ya se encarga de crear el objeto y pasarle el UA_Code si es necesario, de esta forma utilizarlo desde nuestras activitys es muy fácil, solo tenemos que hacer una llamada más o menos así pero utilizando registerPage o registerAction según vuestras necesidades y con los parámetros que consideréis oportunos:


AppGlobals.getAnalyticsManager(this.getApplicationContext()).registerPage("MainMenu");


Para abrir una nueva activity también suelo tener una clase donde tengo todas las llamadas a mis activitys localizadas, de esta forma si tengo que cambiar, como por ejemplo el nombre de la visita solamente hago el cambio aquí. Este es un tema diferente que no voy a tratar aquí pero seguramente no tardaré en hacerlo.

martes, 7 de febrero de 2012

Instalar un servidor DHCP en Ubuntu

Comenzamos la parte práctica de los 2 últimos artículos, para así tener nuestro servidor DHCP en casa, o en cualquier entorno doméstico, configurado a nuestra manera, cubriendo nuestras necesidades y librándonos de asignar manualmente las opciones de red.
Tenemos nuestro Ubuntu preparado, así que vamos a ver los pasos de la instalación del servicio.


Requisitos 




  • Asignar una IP fija (o estática). Es recomendable (obligatorio) para todos los tipos de servidores que montemos en un ordenador, tenerlos localizados siempre en la red. Así que si no está asignado ya, aquí tenéis el artículo dónde podréis cambiar la IP.

Detalles a tener en cuenta

Lo normal en una red local, es que nuestro router funcione como servidor DHCP y asigne la configuración de red. Con lo cual, si tenemos este servicio funcionando, es recomendable que se desactive. Esto se debe a que no se puede asignar una dirección IP a dos ordenadores, y si esto ocurre, da un error de conflicto de IP. Y el que primero la tenga asignada, se quedará con ella,y el segundo se quedará con una dirección alternativa.
También debemos planificar nuestro mapa de equipos en la red, y sus respectivas asignaciones de IP.
Otro detalle más que obvio, es que si el servidor en dónde lo instalamos está apagado, ningún ordenador que se conecte posteriormente recibirá la información de red, y obviamente, no tendrá acceso a la misma.

Instalación

Lo primero, es instalar el software que nos permita que nuestro ordenador funcione a modo DHCP. Para ello, como buenos usuarios de ubuntu que somos, utilizaremos el terminal.

$ sudo apt-get install dhcp3-server


Con esto instalaremos el software que necesita el ordenador, y si necesitamos dependencias:

$sudo apt-get install -f


Ya está. Simple ¿no?

El siguiente paso (como ya tenemos instalado webmin) es entrar en él:

https://localhost:10000

Y una vez dentro refrescaremos los módulos, y nos dirigiremos a la pestaña de servidores, y comprobaremos que lo reconoce.

Dejamos esta semana la publicación aquí, y en una semana, nos ocuparemos de configurarlo!
Es mucho más importante esa parte que ésta, pero sin este artículo no se puede realizar la segunda.

Un saludo.
Licencia de Creative Commons