<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Linux, Java y programación &#187; ide</title>
	<atom:link href="http://casidiablo.net/tag/ide/feed/" rel="self" type="application/rss+xml" />
	<link>http://casidiablo.net</link>
	<description>Blog de Java, Programación y Linux</description>
	<lastBuildDate>Fri, 11 Nov 2011 05:41:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Iniciar servicio en android después del boot</title>
		<link>http://casidiablo.net/iniciar-servicio-android-boot/</link>
		<comments>http://casidiablo.net/iniciar-servicio-android-boot/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 18:08:00 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[ejemplos]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3839</guid>
		<description><![CDATA[Esta entrada, principalmente dedicada a mi mismo ya que se que se me va a olvidar cómo hacerlo, indica paso a paso como crear un servicio en Android que se ejecute al iniciar el sistema. Como sabemos, un servicio es un proceso que se ejecuta en background aun cuando ningún componente visual de nuestra aplicación [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Finiciar-servicio-android-boot%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fcasidiablo.in%2FcJOgRT%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Iniciar%20servicio%20en%20android%20despu%C3%A9s%20del%20boot%22%20%7D);"></div>
<p>Esta entrada, principalmente dedicada a mi mismo ya que se que se me va a olvidar cómo hacerlo, indica paso a paso como crear un servicio en Android que se ejecute al iniciar el sistema. Como sabemos, un servicio es un proceso que se ejecuta en background aun cuando ningún componente visual de nuestra aplicación se encuentre activo.</p>
<p>La idea es más o menos sencilla: una vez que un sistema Android ha iniciado envía una acción broadcast llamada <code>android.intent.action.BOOT_COMPLETED</code>. La idea es crear un <code>BroadcastReceiver</code> que escuche este tipo de acciones e inicie el servicio que deseemos. Así pues, el primer paso es crear una clase que extienda <code>BroadcastReceiver</code>:</p>
<pre class="brush: java; title: ; notranslate">public class Recibidor extends BroadcastReceiver{
	@Override
	public void onReceive(Context context, Intent intent) {
		Intent servicio = new Intent();
		servicio.setAction(&quot;foo.bar.Servicio&quot;);
		context.startService(servicio);
	}
}</pre>
<p>Lo interesante aquí es que se ejecuta el método <code>startService</code> enviando como parámetro un <code>Intent</code> cuyo <em>action</em> es <em>&#8220;foo.bar.Servicio&#8221;</em>, el cual es el servicio que deseamos ejecutar. Dicho servicio es una clase que extiende de <code>Service</code>, y del cual debemos sobrescribir los métodos <code>onCreate</code> y <code>onStart</code>:</p>
<pre class="brush: java; title: ; notranslate">public class Servicio extends Service{

	private static final String TAG = &quot;EjemploServicioBoot&quot;;

	private Timer timer;

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate(){
		super.onCreate();
		Log.d(TAG, &quot;Servicio creado&quot;);
		timer = new Timer();
	}

	@Override
	public void onStart(final Intent intent, final int startId){
		super.onStart(intent, startId);
		timer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				Log.i(TAG, &quot;Se ejecuta la tarea&quot;);
			}
		}, 0, 15000);
	}
}</pre>
<p>En este caso, el servicio realiza una tarea muy simple: imprime en el log del sistema un mensaje. Básicamente tenemos un objeto tipo <code>Timer</code> que ejecutará una tarea; en <code>onCreate</code> simplemente iniciamos el objeto <code>Timer</code>, mientras que en <code>onStart</code> usamos el método <code>scheduleAtFixedRate</code> indicando que ejecutaremos dicha tarea cada 15 segundos.</p>
<p>Por último, debemos registrar en el archivo <code>AndroidManifest.xml</code> el <code>BroadcastReceiver</code> y el servicio:</p>
<pre class="brush: xml; highlight: [12,17]; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
      package=&quot;foo.bar&quot; android:versionCode=&quot;1&quot; android:versionName=&quot;1.0&quot;&gt;
    &lt;application&gt;
        &lt;service android:name=&quot;.Servicio&quot;&gt;
        	&lt;intent-filter&gt;
        		&lt;action android:name=&quot;foo.bar.Servicio&quot;/&gt;
        	&lt;/intent-filter&gt;
        &lt;/service&gt;
        &lt;receiver android:name=&quot;.Recibidor&quot;&gt;
        	&lt;intent-filter&gt;
        		&lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot;/&gt;
        	&lt;/intent-filter&gt;
        &lt;/receiver&gt;
    &lt;/application&gt;
    &lt;uses-sdk android:minSdkVersion=&quot;3&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.RECEIVE_BOOT_COMPLETED&quot; /&gt;
&lt;/manifest&gt;</pre>
<p>En el manifest podemos ver que añadimos un elemento <code>service</code> dentro de <code>application</code>, para registrar nuestro servicio. Y lo más interesante se ve en las líneas 12 y 17, que es donde indicamos el tipo de mensaje que nuestro recibidor estará esperando antes de ejecutar la tarea e indicamos que la aplicación requiere permisos para conocer cuando el boot del sistema a finalizado.</p>
<p><a class="descargacodigo" href="http://casidiablo.net/descargar/Servicio+Android" title="Descargar código fuente del ejemplo">Descargar código fuente</a></p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/iniciar-servicio-android-boot/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Sorteo 4 e-books de Android</title>
		<link>http://casidiablo.net/sorteo-4-e-books-de-android/</link>
		<comments>http://casidiablo.net/sorteo-4-e-books-de-android/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 00:50:47 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[off-topic]]></category>
		<category><![CDATA[ejemplos]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programación]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3818</guid>
		<description><![CDATA[Mark Murhpy es uno de los personajes más conocidos en el mundo de Android y el autor de 4 excelentes libros: The Busy Coder&#8217;s Guide to Android Development, The Busy Coders Guide to Advanced Android Development, Android Programming Tutorials y Android Beyond Java. El valor de los cuatro libros es de $40 USD, el cual [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Fsorteo-4-e-books-de-android%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fcasidiablo.in%2F9oc2Rg%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Sorteo%204%20e-books%20de%20Android%22%20%7D);"></div>
<p><img src="http://casidiablo.net/wordpress/wp-content/uploads/2010/06/android_development.png" alt="" title="android_development" width="120" height="147" style="float:left; margin: 5px;" /> <strong><a href="http://commonsware.com/">Mark Murhpy</a></strong> es uno de los personajes más conocidos en el mundo de Android y el autor de 4 excelentes libros: <a href="http://commonsware.com/Android/">The Busy Coder&#8217;s Guide to Android Development</a>, <a href="http://commonsware.com/AdvAndroid">The Busy Coders Guide to Advanced Android Development</a>, <a href="http://commonsware.com/AndTutorials">Android Programming Tutorials</a> y <em>Android Beyond Java</em>. El valor de los cuatro libros es de $40 USD, el cual es un precio bastante bajo para la calidad de los mismos.</p>
<p>Los ejemplos utilizados en los libros pueden ser descargados gratuitamente en el <a href="http://github.com/commonsguy">repositorio de Github</a>. Además de esto, <a href="http://stackoverflow.com/users/115145/commonsware">Mark es un usuario activo de StackOverflow.com</a>&#8230; ¿y qué con eso? Bueno, personalmente me ha resuelto bastantes dudas allí (¿qué mejor que tener un experto dispuesto a solucionarte dudas puntuales?). También se le ve en <a href="http://twitter.com/commonsguy">twitter</a> por si lo quieren seguir <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>En fin&#8230; Mark me ha enviado un cupón que permite subscribirse a su librería virtual por seis meses, y con la cual se puede acceder <strong>legalmente</strong> a todos sus contenidos. Los libros son actualizados regularmente cada mes o cada que sale una nueva versión del SDK. Además son distribuidos en formato PDF, EPUB o MOBI&#8230;</p>
<p>Así que pensé en sortear dicho cupón entre los lectores del blog que quisieran iniciarse en el mundo de <a href="http://casidiablo.net/tutorial-basico-android/">Android</a> (o que ya tengan experiencia pero quieran tener una referencia avanzada más directa). La verdad no sé que tanto pueda interesar a los lectores del blog el sorteo, pues no todos los que lo leen están interesados en la programación, pero no puedo dejar de compartir este valioso recurso con ustedes (tener en cuenta además que los libros están en inglés, por supuesto).</p>
<p>Así pues, si está interesado en adquirir estos títulos puede dejar un comentario indicando su interés, y si fuese posible la razón principal por la que desea aprender a desarrollar en esta plataforma (quisiera que el cupón se lo ganara alguien que realmente desea aprender del tema). El sorteo se realizará usando random.org (como habitualmente se hace) el día 2 de Julio (en honor al gran <a href="http://es.wikipedia.org/wiki/Andr%C3%A9s_Escobar">Andrés Escobar</a>&#8230; bueno, en realidad es coincidencia pero sí le tenía bastante aprecio).</p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/sorteo-4-e-books-de-android/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>Construir aplicaciones Android desde la línea de comandos</title>
		<link>http://casidiablo.net/desarrollo-programas-android-consola/</link>
		<comments>http://casidiablo.net/desarrollo-programas-android-consola/#comments</comments>
		<pubDate>Sun, 09 May 2010 21:45:22 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[ide]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3776</guid>
		<description><![CDATA[Emacs es algo adictivo sin duda&#8230; a tal punto que a veces prefiero programar todo desde la línea de comandos en vez de usar un IDE como Eclipse o Netbans. En esta entrada, que sin duda es de esas que me sirve solo a mi y a unos pocos más, se detalla el proceso de [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Fdesarrollo-programas-android-consola%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fcasidiablo.in%2Fb2O28Q%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Construir%20aplicaciones%20Android%20desde%20la%20l%C3%ADnea%20de%20comandos%22%20%7D);"></div>
<p style="float: left;"><img class="alignnone size-full wp-image-3781" title="android-open" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/05/android-open.png" alt="android consola" width="166" height="200" /></p>
<p style="text-align: justify;"><a href="http://www.gnu.org/software/emacs/">Emacs</a> es algo adictivo sin duda&#8230; a tal punto que a veces prefiero programar todo desde la línea de comandos en vez de usar un IDE como Eclipse o Netbans. En esta entrada, que sin duda es de esas que me sirve solo a mi y a unos pocos más, se detalla el proceso de compilación e instalación de aplicaciones para Android sin usar más que el SDK y una línea de comandos. Esta guía es aplicable para cualquier sistema operativo, pero yo lo haré en mi equipo que corre <a href="http://www.funtoo.org/">Funtoo Linux</a>.</p>
<p style="text-align: justify;">
<h3>0. Configuración del entorno de trabajo</h3>
</p>
<p style="text-align: justify;">Lo primero es tener el SDK instalado, lo cual está explicado aquí: <a href="http://casidiablo.net/tutorial-basico-android/">Introducción a la programación con Android</a>. Una vez hayamos instalado y configurado el SDK (incluyendo la adición del directorio tools al path del sistema) y tengamos un proyecto que compilar podemos iniciar el proceso de compilación. Es posible también crear el proyecto desde la línea de comandos así:</p>
<div class="consola">android create project -t 1 -p /tmp/ejemplo -k net.casidiablo.ejemplo -a Ejemplo</div>
<p style="text-align: justify;">Donde <code>-t 1</code> es el id de la plataforma para la que vamos a desarrollar la aplicación (el target). Se puede usar el comando <code>android list targets</code> para ver el listado de targets disponibles. <code>-p</code> indica la ruta de creación del proyecto y -a el nombre de la actividad inicial.</p>
<p style="text-align: justify;">
<h3>1. Compilación</h3>
</p>
<p style="text-align: justify;">Es posible usar Ant para compilar y empaquetar todo automáticamente&#8230; pero me gusta hacer cada cosa y saber qué está pasando por debajo. Así que haremos todo manualmente. El siguiente comando generará el archivo <code>R.java</code> (si no sabes de lo que hablo: <a href="../../tutorial-basico-android/">Introducción a  la programación con Android</a>):</p>
<div class="consola">aapt p -m -J src -M AndroidManifest.xml -S res -I $ANDROID_DIR/android.jar</div>
<ul>
<li><code>p</code> = package</li>
<li><code>-m -j src</code> indicar el directorio de los archivos fuente</li>
<li><code>-M</code> indicar la ubicación del manifiesto</li>
<li><code>-S</code> indicar la ubicación del directorio de recursos</li>
<li><code>-I $ANDROID_DIR/android.jar</code> añade el paquete android.jar al classpath del proyecto. Importante: en mi caso <code>$ANDROID_DIR</code> apunta a <code>/opt/android/platforms/<strong>android-4</strong>/</code> y en el path del sistema se encuentra incluido <code>/opt/android/platforms/android-4/tools/</code> Es importante tener en cuenta que NO se usa la base del SDK como antiguamente se hacía, sino el correspondiente directorio bajo <em>platforms</em>.</li>
</ul>
<p>Ahora sí vamos a generar los archivos <code>.class</code> (por supuesto, es necesario tener el JDK de Java instalado):</p>
<div class="consola">javac -encoding ascii -target 1.5 -d bin -bootclasspath $ANDROID_DIR/android.jar src/net/casidiablo/ejemplo/*.java</div>
<p>Esto básicamente genera archivos .class en el directorio bin. Si la aplicación usara librerías de terceros, se debería agregar el parámetro <code>-classpath=libs/*.jar</code></p>
<p>Puesto que los archivos .class están generados para la JVM, es necesario convertirlos a archivos para la Dalvik VM:</p>
<div class="consola">dx &#8211;dex &#8211;output=bin/classes.dex bin # si existieran librerías externas se añade libs/*.jar</div>
<p>Ahora empaquetamos los recursos:</p>
<div class="consola">aapt p -f -M AndroidManifest.xml -S res/ -I $ANDROID_DIR/android.jar -F bin/ejemplo.ap_</div>
<p>Ahora empaquetamos usando los bytecodes de Dalvik que creamos (classes.dex) para generar el paquete final:</p>
<div class="consola">apkbuilder bin/ejemplo.apk -z bin/ejemplo.ap_ -f bin/classes.dex -rf src -rj libs</div>
<p>Finalmente podemos instalarlo tal como escribí en <a href="http://casidiablo.net/android-desde-linux/">Manipulación de smartphones con Android desde la consola de Linux</a>:</p>
<div class="consola">adb install bin/ejemplo.apk</div>
<p>Links interesantes: <a href="http://asantoso.wordpress.com/2009/09/15/how-to-build-android-application-package-apk-from-the-command-line-using-the-sdk-tools-continuously-integrated-using-cruisecontrol/">How to build Android application package (.apk) from the command line using the SDK tools + continuously integrated using CruiseControl</a> y <a href="http://benlynn.blogspot.com/2009/01/developing-android-without-eclipse-or.html">Developing Android without Eclipse or Ant</a></p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/desarrollo-programas-android-consola/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Conceptos básicos de interfaces gráficas con Android</title>
		<link>http://casidiablo.net/introduccion-ui-android/</link>
		<comments>http://casidiablo.net/introduccion-ui-android/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 13:04:42 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[button]]></category>
		<category><![CDATA[edittext]]></category>
		<category><![CDATA[eventos]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[interfaz grafica]]></category>
		<category><![CDATA[textview]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[toast]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3715</guid>
		<description><![CDATA[En esta entrada vamos a introducirnos en el desarrollo de interfaces gráficas para Android. Haremos un sencillo ejemplo paso a paso en donde la idea es que comprenda la filosofía con la que se trabaja al usar widgets y actividades. El resultado será una aplicación sencilla que pide una cadena de texto al usuario y [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Fintroduccion-ui-android%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fcasidiablo.in%2FcFUGgM%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Conceptos%20b%C3%A1sicos%20de%20interfaces%20gr%C3%A1ficas%20con%20Android%22%20%7D);"></div>
<p style="text-align: justify;"><img style="float: left; margin: 4px;" title="casidiablo-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/casidiablo-android1.png" alt="" />En esta entrada vamos a introducirnos en el desarrollo de interfaces gráficas para Android. Haremos un sencillo ejemplo paso a paso en donde la idea es que comprenda la filosofía con la que se trabaja al usar widgets y actividades. El resultado será una aplicación sencilla que pide una cadena de texto al usuario y la invierte. Es importante que ya tengas configurado el SDK y el Eclipse como se explica en <em><a href="http://casidiablo.net/tutorial-basico-android/">Introducción a la programación con Android</a></em>; aprenderemos a usar labels, cajas de texto, botones y eventos <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_cool.gif' alt='8-)' class='wp-smiley' /> </p>
<p style="text-align: justify;">Puesto que es la primera entrada de este tipo, voy a explicar detalladamente cada paso. En las siguientes iré un poco más rápido. Así que, si ya tiene experiencia con Android tal vez se aburra un poco <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_neutral.gif' alt=':-|' class='wp-smiley' /> </p>
<p><span id="more-3715"></span></p>
<h3>0. Crear un nuevo proyecto</h3>
<p style="text-align: justify;">Abrimos Eclipse y creamos un nuevo proyecto para Android:</p>
<p style="text-align: center;"><img class="aligncenter" title="Nuevo Proyecto ANdroid" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/nuevo-proyecto-android.png" alt="Nuevo Proyecto ANdroid" width="503" height="274" /></p>
<p style="text-align: justify;">Configuramos el proyecto de tal manera que quede así:</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-3718" title="proyecto-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/proyecto-android.png" alt="" width="600" height="635" /></p>
<p style="text-align: justify;">En este caso estoy usando la versión 1.6 de Android, pero puede escoger la versión que concuerde con el dispositivo sobre el que desea probar la aplicación. Esto se explica con más detalle en <em><a href="http://casidiablo.net/tutorial-basico-android/">Introducción a  la programación con Android</a></em>. Fíjese que no hemos creado ninguna actividad inicialmente (el checkbox <em>Create Activity</em> no está seleccionado); la idea es ver cómo se deben crear las actividades, los layouts con la interfaz gráfica, las clases que referencian a las actividades y la configuración del <code>AndroidManifest.xml</code>.</p>
<p style="text-align: justify;">
<h3>1. Crear y configurar una Actividad inicial</h3>
</p>
<p>Creamos una clase dentro del paquete <code>net.casidiablo.ejemplo</code>:</p>
<p style="text-align: center;"><img class="size-full wp-image-3719 aligncenter" title="nueva-clase" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/nueva-clase.png" alt="" width="598" height="264" /></p>
<p style="text-align: justify;">Y en el asistente de creación de clases de Eclipse le damos como nombre EjemploInvertir. Clic en <em>Finish</em> y editamos la clase para que luzca así:</p>
<pre class="brush: java; title: ; notranslate">package net.casidiablo.ejemplo;
import android.app.Activity;
import android.os.Bundle;
public class EjemploInvertir extends Activity{
    @Override
    public void onCreate(Bundle b){
        super.onCreate(b);
        setContentView(R.layout.main);
    }
}</pre>
<p style="text-align: justify;">Lo que hemos hecho es extender la clase <a class="external" href="http://developer.android.com/intl/de/reference/android/app/Activity.html"><code>Activity</code></a> y redefinir el método <code>onCreate</code>. Además, ejecutamos el método <code>setContentView</code> indicándole que usaremos el layout <code>main.xml</code> (Si tiene esta expresión en el rostro: <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_twisted.gif' alt=':twisted:' class='wp-smiley' />  es que no ha leído la entrada de <a href="http://casidiablo.net/tutorial-basico-android/">introducción  Android</a>).</p>
<p style="text-align: justify;">Puesto que deseamos que esta actividad sea mostrada al momento de ejecutar la aplicación, debemos editar el archivo <code>AndroidManifest.xml</code>, que se encuentra en la raíz del proyecto. Al hacer doble clic sobre este, vemos que es posible editarlo usando una interfaz gráfica. Para añadir la actividad que acabamos de crear, hacemos clic en la pestaña inferior <em>Application</em>, y en la sección <em>Application Nodes</em> hacemos clic en <em>Add&#8230;</em> Allí seleccionamos <em>Activity</em> y hacemos clic en <em>OK</em>.</p>
<p style="text-align: center;"><img class="size-full wp-image-3721 aligncenter" title="aniadir-android-activity" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/aniadir-android-activity.png" alt="" width="600" height="427" /></p>
<p style="text-align: justify;">Ahora debemos configurar la actividad. En la parte derecha ha aparecido un formulario llamado <em>Attributes for Activity</em>, en donde podremos hacerlo. Lo más importante es el nombre de la actividad, el cual debe ser el nombre de la clase que acabamos de crear. Es posible usar el botón <em>Browse&#8230;</em> para buscar las actividades actualmente disponibles&#8230;</p>
<p style="text-align: center;"><img class="size-full wp-image-3723 aligncenter" title="browse-activities" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/browse-activities.png" alt="" width="462" height="314" /></p>
<p style="text-align: justify;">Una vez hayamos seleccionado o escrito el nombre de la clase, debemos añadirle un <a href="http://developer.android.com/intl/de/reference/android/content/Intent.html" class="external"><code>Intent</code></a>; pero&#8230; ¿qué es un <code>Intent</code> <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_twisted.gif' alt=':twisted:' class='wp-smiley' /> ? Los componentes de una aplicación en Android se comunican a través de mensajes llamados <em>Intents</em> (objetos de la clase <code>android.content.Intent</code>). Se trata de una estructura de datos pasiva que contiene una descripción abstracta de una operación que será realizada, y se usa comúnmente para iniciar actividades <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_eek.gif' alt='8-O' class='wp-smiley' /> Sí ya se, es algo confuso al principio, pero de momento no es demasiado importante (más información <a class="external" href="http://developer.android.com/intl/de/guide/topics/intents/intents-filters.html">aquí</a>). Para añadir el <em>intent</em>, seleccionamos la actividad que acabamos de crear y hacemos clic en el botón <em>Add&#8230;</em> Seleccionamos <em>Intent Filter</em>, hacemos clic en <em>OK</em>. Y ahora, dentro del <code>Intent</code> crearemos dos componentes un <code>Action</code> y un <code>Category</code>.</p>
<p style="text-align: justify;">Un <code>Action</code> es un String que contiene el nombre de la acción a ser realizada. En este caso, el Action será <code>android.intent.action.MAIN</code>, el cual es usado para ejecutar la primera actividad de una aplicación. Entonces, seleccionamos el <code>Intent Filter</code> que acabamos de crear, y hacemos clic en <em>Add&#8230;</em> escogemos <em>Action</em>, clic en <em>OK</em> y escogemos el nombre del Action:</p>
<p style="text-align: center;"><img class="size-full wp-image-3725 aligncenter" title="action-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/action-android.png" alt="" width="600" height="146" /></p>
<p style="text-align: justify;"><code>Category</code> es un String que contiene información adicional acerca del tipo de componente que debería manipular el <code>Intent</code>. En este caso el <code>Category</code> que añadiremos será <code>CATEGORY_LAUNCHER</code> el cual indica que la actividad puede ser la principal (la que se ejecuta al iniciar la aplicación). Luego de añadir el <code>Category</code> veremos que queda así:</p>
<p style="text-align: center;"><img class="size-full wp-image-3726 aligncenter" title="category-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/category-android.png" alt="" width="600" height="135" /></p>
<p style="text-align: justify;">Hacemos clic en el icono de guardar en la barra de herramientas y listo <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  También es posible editar el archivo <code>AndroidManifest.xml</code> a mano, lo cual pienso que es mucho más rápido. Pero no esta de más saber cómo hacerlo con la interfaz gráfica <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  Si abrimos el archivo con el editor de XML veremos:</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    package=&quot;net.casidiablo.ejemplo&quot; android:versionCode=&quot;1&quot;
    android:versionName=&quot;1.0&quot;&gt;
    &lt;application android:icon=&quot;@drawable/icon&quot; android:label=&quot;@string/app_name&quot;&gt;
        &lt;activity android:name=&quot;EjemploInvertir&quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot;&gt;&lt;/category&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;
    &lt;uses-sdk android:minSdkVersion=&quot;4&quot; /&gt;
&lt;/manifest&gt;</pre>
<p style="text-align: justify;">Ahora que hemos configurado el <code>AndroidManifest.xml</code> podemos hacer una prueba de ejecución del programa&#8230; si todo va bien veremos algo como esto:</p>
<p style="text-align: center;"><img class="size-full wp-image-3728 aligncenter" title="hello-world-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/hello-world-android.png" alt="" width="600" height="389" /></p>
<p style="text-align: justify;">
<h3>2. Crear la interfaz gráfica</h3>
</p>
<p style="text-align: justify;">En este paso, crearemos una nueva interfaz gráfica que contendrá un label, una caja de texto y un botón. Aprenderemos a posicionar/agrupar los elementos en la pantalla, y darles un tamaño adecuado. Vamos a crear un nuevo layout dentro del directorio <code>res/layout/</code> (aunque podríamos haber usado el <code>main.xml</code> generado por asistente de Eclipse, pero prefiero que aprenda este proceso de una vez). Así que, hacemos clic en el botón de creación de nuevos archivos XML de Android:</p>
<p style="text-align: center;"><img class="size-full wp-image-3729 aligncenter" title="nuevo-xml-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/nuevo-xml-android.png" alt="" width="480" height="168" /></p>
<p style="text-align: justify;">Seleccionamos la opción layout y le damos un nombre al archivo. Por ejemplo, <code>interfaz_grafica.xml</code>:</p>
<p style="text-align: center;"><img class="size-full wp-image-3730 aligncenter" title="crear-xml-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/crear-xml-android.png" alt="" width="600" height="436" /></p>
<p style="text-align: justify;">¡Hacemos clic en <em>Finish</em> y listo! Al hacer doble clic sobre el archivo que acabamos de crear vemos que es posible editarlo usando una interfaz gráfica, pero en este caso usaremos el editor de XML, ya que es mucho más rápido hacerlo así <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Hacemos clic en la pestaña inferior que tiene el nombre del archivo (<code>interfaz_grafica.xml</code>) y veremos algo como esto:</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
 android:layout_width=&quot;wrap_content&quot;
 android:layout_height=&quot;wrap_content&quot;&gt;
&lt;/LinearLayout&gt;
</pre>
<p style="text-align: justify;">Por defecto se crea un objeto <a href="http://developer.android.com/intl/de/reference/android/widget/LinearLayout.html" class="external"><code>LinearLayout</code></a> que contiene contiene tres parámetros: un XML Name Space (en este caso <code>http://schemas.android.com/apk/res/android</code>), el tamaño que ocupará a lo ancho y el que ocupará a lo largo. Para estos dos ultimos parámetros se está usando <code>wrap_content</code> indicando que se debe usar el menor espacio posible. Los objetos <code>LinearLayout</code> funcionan de manera similar a los <code>JPanel</code> de <a href="http://casdiablo.net">Java</a>, pudiendo &#8220;contener&#8221; widgets de Android (labels, botones, menus u otros LinearLayout, etc.).</p>
<p style="text-align: justify;">Lo siguiente será crear la interfaz gráfica para nuestro programa de ejemplo, pero antes vamos a aprender un poco sobre el directorio <code>res/values</code> <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  Por defecto veremos que hay un archivo llamado <code>strings.xml</code> que contiene pares nomber&lt;=&gt;valor. Este archivo es usado para almacenar todas las variables &#8220;estáticas&#8221; de la aplicación. Si bien su uso no es estrictamente obligatorio, si es recomendado y es bueno saber usarlo. Para nuestro ejemplo entonces, tenemos dos cadenas de texto que podrían ser estáticas: el texto que aparecerá en el label y el texto que aparecerá en el botón. Para la primera vamos a asignar el texto directamente en el XML de la interfaz gráfica, mientras que para el botón lo haremos usando el archivo <code>strings.xml</code>; lo hago de las dos maneras con el fin de que quede clara la diferencia entre ambos métodos.</p>
<p style="text-align: justify;">Abrimos el archivo <code>strings.xml</code>, que se encuentra en el directorio <code>res/values</code>, para añadir una nueva cadena de texto que será usada por el botón de la aplicación. Solo debemos añadir algo como esto: &lt;string name=&#8221;texto_boton&#8221;&gt;Invertir!&lt;/string&gt;, de tal manera que quede así:</p>
<pre class="brush: xml; highlight: [5]; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;resources&gt;
    &lt;string name=&quot;hello&quot;&gt;Hello World!&lt;/string&gt;
    &lt;string name=&quot;app_name&quot;&gt;Ejemplo&lt;/string&gt;
    &lt;string name=&quot;texto_boton&quot;&gt;Invertir!&lt;/string&gt;
&lt;/resources&gt;</pre>
<p style="text-align: justify;">Ahora sí, vamos a modificar el archivo <code>interfaz_grafica.xml</code> de tal manera que quede así:</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
     android:layout_width=&quot;fill_parent&quot; android:layout_height=&quot;fill_parent&quot;
     android:orientation=&quot;vertical&quot;&gt;
    &lt;LinearLayout android:orientation=&quot;horizontal&quot;
     android:layout_width=&quot;fill_parent&quot; android:layout_height=&quot;wrap_content&quot;&gt;
        &lt;TextView android:text=&quot;Palabra: &quot; android:layout_width=&quot;wrap_content&quot;
         android:layout_height=&quot;wrap_content&quot; /&gt;
        &lt;EditText android:id=&quot;@+id/cajaTexto&quot; android:layout_width=&quot;fill_parent&quot;
         android:layout_height=&quot;wrap_content&quot; /&gt;
    &lt;/LinearLayout&gt;
    &lt;Button android=&quot;@+id/btnInvertir&quot; android:layout_width=&quot;fill_parent&quot;
     android:layout_height=&quot;wrap_content&quot; android:text=&quot;@string/texto_boton&quot;/&gt;
&lt;/LinearLayout&gt;</pre>
<p>Veamos qué hemos hecho arriba:</p>
<ul style="text-align: justify;">
<li>En la línea 3 podemos ver que cambiamos el ancho y alto del <code>LinearLayout</code> principal de tal manera que utilice toda la pantalla (usando <code>fill_parent</code>).</li>
<li>Puesto que el <code>LinearLayout</code> contendrá otros objetos, debemos indicarle el sentido en el que los irá poniendo. En este caso se deben poner verticalmente (<code>android:orientation="vertical"</code>).</li>
<li>En las líneas 5 y 6 creamos un nuevo <code>LinearLayout</code> que contendrá el label y la caja de texto. Puesto que queremos que estos dos objetos aparezcan en una sola línea, ponemos el parámetro <code>android:orientation="horizontal"</code>. Además, le indicamos que ocupe toda la pantalla a lo ancho, pero que la altura sea la más pequeña posible.</li>
<li>En las líneas 7 y 8 creamos un nuevo <code>TextView</code> (un label) con el texto <em>&#8220;Palabra: &#8220;</em>; esto lo indicamos con la propiedad <code>android:text</code>. Además queremos que ocupe el menor espacio posible tanto en alto como en ancho (<code>wrap_content</code> para <code>layout_width</code> y <code>layout_height</code>).</li>
<li>En las líneas 9 y 10 creamos un <code>EditText</code> (una caja de texto), que es donde el usuario pondrá la palabra que desea invertir. Intentará ocupar el mayor ancho posible en la pantalla. Además, puesto que este es un objeto del cual necesitaremos datos, debemos asignarle un ID para que podamos acceder a él desde el programa en Java que crearemos en breve.</li>
<li>En la línea 11 cerramos el <code>LinearLayout</code> que contiene el label y la caja de texto.</li>
<li>En las líneas 12 y 13 creamos un objeto <code>Button</code>. Este objeto también tiene un ID puesto que debemos obtener una referencia del mismo desde el programa en Java. Además, a la propiedad <code>android:text</code> se está asignando <code>@string/texto_boton</code> que es la referencia a la variable que creamos en el <code>strings.xml</code></li>
</ul>
<p style="text-align: justify;">Ahora que hemos creado la interfaz gráfica, vamos a ejecutar la aplicación para ver si ha quedado bien. Pero antes, debemos indicarle a nuestra Actividad que el layout que debe ejecutar es <code>interfaz_grafica.xml</code>. Esto lo hacemos modificando la clase <code>EjemploInvertir.java</code> para que quede así:</p>
<pre class="brush: java; title: ; notranslate">package net.casidiablo.ejemplo;
import android.app.Activity;
import android.os.Bundle;
public class EjemploInvertir extends Activity{
    @Override
    public void onCreate(Bundle b){
        super.onCreate(b);
        setContentView(R.layout.interfaz_grafica);
    }
}</pre>
<p style="text-align: justify;">Si todo va bien, al ejecutar la aplicación veremos algo como esto:</p>
<p style="text-align: center;"><img class="size-full wp-image-3733 aligncenter" title="interfaz-grafica-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/interfaz-grafica-android.png" alt="" width="600" height="389" /></p>
<h3>3. Programación de objetos de la interfaz gráfica</h3>
<p style="text-align: justify;">Ahora que hemos construido la interfaz gráfica, debemos programar la parte de &#8220;invertir la cadena de texto&#8221;. Para ello necesitamos extraer el texto que se ponga en la caja de texto y manejar los eventos que genera el botón; en cualquier caso, necesitamos referencias a dichos objetos. Así que, de momento, vamos a hacer que nuestra clase <code>EjemploInvertir.java</code> luzca así:</p>
<pre class="brush: java; title: ; notranslate">package net.casidiablo.ejemplo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
public class EjemploInvertir extends Activity{
    //declarar objetos
    private EditText texto;
    private Button boton;
    @Override
    public void onCreate(Bundle b){
        super.onCreate(b);
        setContentView(R.layout.interfaz_grafica);
        //iniciar los objetos
        texto = (EditText) findViewById(R.id.cajaTexto);
        boton = (Button) findViewById(R.id.btnInvertir);
    }
}</pre>
<p style="text-align: justify;">Veamos qué ha pasado allá arriba <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_idea.gif' alt=':idea:' class='wp-smiley' /> </p>
<ul style="text-align: justify;">
<li>En las líneas 4 y 5 importamos las clases <code>Button</code> y <code>EditText</code> del paquete <code>android.widget</code>.</li>
<li>En las líneas 9 y 10 declaramos objetos de tipo <code>EditText</code> y <code>Button</code>, los cuales los usaremos para manipular los que hemos creado en la interfaz gráfica.</li>
<li>En la líneas 17 iniciamos el objeto <code>EditTexto</code> usando el método <code>findViewById</code>, a la cual le enviamos como parámetro el ID de la caja de texto (¿recuerdas? pusimos esto dentro del XML: <code>android:id="@+id/cajaTexto"</code>).</li>
<li>De igual manera creamos el objeto botón usando el ID <code>btnInvertir</code> que definimos en el XML.</li>
</ul>
<p style="text-align: justify;">Hasta el momento solo hemos creado los objetos, pero no estamos haciendo nada con ellos. Para esto, vamos a asignar un listener al botón, que ejecutará ciertas acciones al momento de presionarlo. Esto lo hacemos con el método <code>setOnClickListener</code> el cual recibe como parámetro un objeto de tipo <code>android.view.View.OnClickListener</code>. Veamos cómo debe quedar la clase y luego explico cada componente nuevo:</p>
<pre class="brush: java; title: ; notranslate">package net.casidiablo.ejemplo;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class EjemploInvertir extends Activity{
	//declarar objetos
	private EditText cajaDeTexto;
	private Button boton;
	@Override
	public void onCreate(Bundle b){
		super.onCreate(b);
		setContentView(R.layout.interfaz_grafica);
		//iniciar los objetos
		cajaDeTexto = (EditText) findViewById(R.id.cajaTexto);
		boton = (Button) findViewById(R.id.btnInvertir);
		boton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				invertir();
			}
		});
	}
	//metodo para invertir el texto
	private void invertir(){
		//obtener el string de la caja de texto
		String txt = cajaDeTexto.getText().toString();
		//verificar que haya texto por invertir
		if(!txt.equals(&quot;&quot;)){
			//invertir texto
			String resultado = &quot;&quot;;
			for (int i = txt.length()-1; i&gt;=0; i--)
				resultado += txt.charAt (i);
		    //asignamos el string invertido a la caja de texto
			cajaDeTexto.setText(resultado);
		}
		else Toast.makeText(this, &quot;No hay nada que invertir&quot;, Toast.LENGTH_LONG).show();
	}
}</pre>
<p>Veamos que fue todo eso&#8230;</p>
<ul style="text-align: justify;">
<li>En la línea 5 se importan la interfaz <code>OnClickListener</code>. Dicha interfaz es usada en la línea 20 al crear un objeto que se enviará como parámetro al método <code>setOnClickListener</code>. Dentro, es necesario implementar el método <code>onClick</code> en donde pondremos las instrucciones que serán ejecutadas al momento de hacer clic en el botón (en este caso una llamada a la función <code>invertir()</code>, líneas 28 a 41).</li>
<li>El método invertir inicia una variable <code>String</code> con los datos que contenga la caja de texto, usando el método <code>getText</code> de la clase <code>EditText</code>.</li>
<li>En las líneas 35 y 36 se invierte la cadena, que posteriormente se pone de nuevo en la caja de texto usando el método <code>setText</code> (línea 38).</li>
<li>En la línea 40 mostramos un mensaje usando la clase <code>Toast</code>. Este mensaje aparece cuando no hay datos en la caja de texto. Lo he colocado puesto que es bastante sencillo de implementar. Basta con usar el método estático <code>makeText</code> pasándole como parámetros el contexto en el que se mostrará (se usa <code>this</code>, puesto que se mostrará en la Actividad actual), el texto a mostrar y cuanto tiempo durará el mensaje.</li>
</ul>
<p style="text-align: justify;">Al ejecutar la aplicación, escribir &#8220;<em>Estoy invertido</em>&#8221; en la caja de texto y presionar el botón, veremos algo así:</p>
<p style="text-align: center;"><img class="size-full wp-image-3734 aligncenter" title="texto-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/texto-android.png" alt="" width="600" height="389" /></p>
<p style="text-align: justify;">Si no ponemos texto y presionamos el botón <em>Invertir</em>, veremos:</p>
<p style="text-align: center;"><img class="size-full wp-image-3735 aligncenter" title="sin-texto-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/sin-texto-android.png" alt="" width="600" height="389" /></p>
<p style="text-align: justify;">La aplicación está lista para ser probada en un dispositivo real. En mi caso la instalé en una HTC Tattoo y se ve así:</p>
<p style="text-align: center;"><img class="size-full wp-image-3737 aligncenter" title="device" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/device.png" alt="" width="240" height="320" /></p>
<p style="text-align: justify;">
<h3>4. Descargar código</h3>
</p>
<p style="text-align: justify;">Este es el código fuente usado para este tutorial, espero le haya gustado. Cualquier duda o sugerencia no dude en comentarla.</p>
<p><a class="tooltip descargacodigo" title="Descargar archivo ZIP con el código fuente" href="http://casidiablo.net/descargar/Ejemplo+UI+Android">Descargar Proyecto Eclipse</a></p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/introduccion-ui-android/feed/</wfw:commentRss>
		<slash:comments>71</slash:comments>
		</item>
		<item>
		<title>Introducción a la programación con Android</title>
		<link>http://casidiablo.net/tutorial-basico-android/</link>
		<comments>http://casidiablo.net/tutorial-basico-android/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 06:15:05 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[ejemplos]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3669</guid>
		<description><![CDATA[Esta pequeña entrada servirá como base para las siguientes, en las que iré poniendo mis experiencias con Android, un estupendo sistema operativo para dispositivos móviles basado en Linux, y que nos proporciona un completo SDK para desarrollar nuestras propias aplicaciones de una manera rápida y divertida. Aprenderemos a instalar/configurar el SDK y el plugin para [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Ftutorial-basico-android%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fcasidiablo.in%2F90LU1T%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Introducci%C3%B3n%20a%20la%20programaci%C3%B3n%20con%20Android%22%20%7D);"></div>
<p style="text-align: justify;"><img style="float: left; margin: 4px;" title="casidiablo-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/casidiablo-android-e1269234829904.png" alt="" />Esta pequeña entrada servirá como base para las siguientes, en las que iré poniendo mis experiencias con <a class="external" href="http://es.wikipedia.org/wiki/Android">Android</a>, un estupendo sistema operativo para dispositivos móviles basado en Linux, y que nos proporciona un completo SDK para desarrollar nuestras propias aplicaciones de una manera rápida y divertida.</p>
<p style="text-align: justify;">Aprenderemos a instalar/configurar el SDK y el plugin para Eclipse.  Haremos el típico Hola Mundo, y explicaré un poco sobre la metodología de programación para esta plataforma (que es sobre <a href="http://casidiablo.net">Java</a>). ¡Manos a la obra!</p>
<p style="text-align: justify;">
<h3>1. Instalar y configurar el SDK de android</h3>
<p style="text-align: justify;">Vamos a la página del <a href="http://developer.android.com/intl/de/sdk/index.html">Android SDK</a> y descargamos la versión para nuestro sistema operativo. Yo uso Gentoo Linux, pero los pasos son prácticamente idénticos en Windows y en Mac. La última versión al escribir esta entrada es <code>android-sdk_r05</code>. Una vez que hayamos descargado el archivo, lo descomprimimos, entramos a la carpeta que se crea y ejecutamos (en Linux):</p>
<p style="text-align: justify;">
<p><span id="more-3669"></span></p>
<div class="consola">tools/android</div>
<p>En Windows:</p>
<div class="consola">SDK Setup.exe</div>
<p>Veremos algo como esto:</p>
<p style="text-align: center;"><img class="size-full wp-image-3672 aligncenter" title="Pantallazo-Android SDK and AVD Manager" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/Pantallazo-Android-SDK-and-AVD-Manager-.png" alt="" width="655" height="431" /></p>
<p style="text-align: justify;">Hacemos clic en <em>Available packages</em> y desplegamos el árbol que aparece bajo <em>Sites, Packages and Archives</em> para instalar el API sobre la(s) que deseamos trabajar, y una vez la(s) hayamos seleccionado hacemos clic en <em>Install Selected</em>. En este caso he seleccionado el API 7 (para la versión 2.1 de Android), la documentación del API 7, los ejemplos del API 7 y el SDK del API 4 (para la versión 1.6 de Android). Es importante elegir las APIs adecuadas teniendo el cuenta el tipo de dispositivo para el que estamos desarrollando la aplicación. Escogí en este caso el API 4 puesto que el equipo sobre el que pruebo los programas (<a href="http://www.htc.com/www/product/tattoo/overview.html">HTC Tattoo</a>) viene con Android 1.6 (Donut) [<a class="external" href="http://mundogeek.net/archivos/2010/03/19/versiones-de-android/">más información sobre las versiones y sus codenames</a>]. Por supuesto, si desarrollas con el API 4 tus programas tienen un 98% de probabilidades de correr sobre las versiones más recientes de Android sin modificación alguna.</p>
<p style="text-align: center;"><img class="size-full wp-image-3673 aligncenter" title="Pantallazo-Android SDK and AVD Manager -1" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/Pantallazo-Android-SDK-and-AVD-Manager-1.png" alt="" width="655" height="431" /></p>
<p style="text-align: justify;">Una vez haya terminado de descargar e instalar las APIs podemos crear un dispositivo virtual sobre el que probaremos nuestras aplicaciones. Hacemos clic en <em>Virtual Devices</em> al lado izquierdo, luego sobre el botón <em>New&#8230;</em> y configuramos el dispositivo:</p>
<p style="text-align: center;"><img class="size-full wp-image-3674 aligncenter" title="nuevo-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/nuevo-android.png" alt="" width="655" height="590" /></p>
<p style="text-align: justify;">Como puede apreciar en la imagen de arriba, debe poner un nombre al dispositivo, seleccionar el API sobre el que va a trabajar, darle un tamaño a la memoria ROM, escoger un tipo de pantalla y algunas configuraciones avanzadas que no se tratarán en este tutorial. Una vez tengamos esto, hacemos clic en <em>Create AVD</em> y si todo sale bien veremos algo como esto:</p>
<p style="text-align: center;"><img class="size-full wp-image-3675 aligncenter" title="Pantallazo-Android Virtual Devices Manager" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/Pantallazo-Android-Virtual-Devices-Manager-.png" alt="" width="613" height="206" /></p>
<h3>2. Instalar y configurar el plugin para Eclipse</h3>
<p style="text-align: justify;">Para este paso, necesitaremos Eclipse 3.5 (Galileo, recomendado) o 3.4. Abrimos eclipse, vamos a la <em>Window -&gt; Install New Software&#8230;</em></p>
<p style="text-align: center;"><img class="size-full wp-image-3676 aligncenter" title="new-software" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/new-software.png" alt="" width="561" height="328" /></p>
<p style="text-align: justify;">Hacemos clic en el botón <em>Add&#8230;</em> para añadir el repositorio de Android (<code>https://dl-ssl.google.com/android/eclipse/</code>):</p>
<p style="text-align: center;"><img class="size-full wp-image-3677 aligncenter" title="add" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/add.png" alt="" width="600" height="563" /></p>
<p style="text-align: justify;">Clic en OK y ahora seleccionamos los plugins a instalar, y seguimos el proceso de instalación:</p>
<p style="text-align: center;"><img class="size-full wp-image-3678 aligncenter" title="Pantallazo-Install" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/Pantallazo-Install-.png" alt="" width="705" height="666" /></p>
<p style="text-align: justify;">Una vez instalado, reiniciamos Eclipse y veremos que se han añadido algunos iconos extra en la barra de herramientas, y que además podemos crear proyectos para Android <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>3. Hola Mundo en Android</h3>
<p style="text-align: justify;">Ahora vamos a crear un nuevo proyecto y aprender un poco más sobre cómo funcionan las aplicaciones para Android.  Hacemos clic en el botón de creación de proyectos Android (o <em>File&#8230; -&gt; New Project -&gt; Android Proyect</em>):</p>
<p style="text-align: center;"><img class="size-full wp-image-3679 aligncenter" title="nuevo-proyecto-android" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/nuevo-proyecto-android.png" alt="" width="503" height="274" /></p>
<p style="text-align: justify;">Veremos el asistente de creación de proyectos para Android en donde debemos especificar: el nombre del proyecto (HolaParce), el API para el que vamos a desarrollar (1.6 en este caso), el nombre de la aplicación (Hola Parce en este caso), el nombre del paquete (se recomienda que sea un paquete nombrado con el estándar de Java, es decir, un dominio invertido), seleccionamos <em>Create Activity</em> y le damos un nombre (que cumpla las especificaciones de un nombre de clase en Java), y por último seleccionamos la versión mínima del API que deberán tener los dispositivos que corran nuestro aplicativo:</p>
<p style="text-align: center;"><img class="size-full wp-image-3680 aligncenter" title="android-parce" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/android-parce.png" alt="" width="600" height="744" /></p>
<p style="text-align: justify;">¡Clic en Finish y listo! Ahora podemos probar la aplicación&#8230; hacemos clic derecho sobre el Proyecto, seleccionamos <em>Run as&#8230;</em> -&gt; <em>Android Application</em>. Se cargará el emulador y después de un par de minutos podremos ver nuestra aplicación:</p>
<p style="text-align: center;"><img class="size-full wp-image-3682   aligncenter" title="Pantallazo-5554:Pruebas" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/03/Pantallazo-5554Pruebas.png" alt="" width="793" height="561" /></p>
<h3>4. Entendiendo el funcionamiento básico de las aplicaciones en Android</h3>
<p style="text-align: justify;">Las aplicaciones en Android funcionan bajo el esquema de &#8220;Actividades&#8221;. Una actividad presenta una interfaz gráfica (escrita en XML) que permite al usuario interactuar con la aplicación. Cada aplicación tiene varias actividades que se van mostrando al usuario según este las vaya necesitando. Una actividad llama a otra cuando sea necesario, y cada una de las actividades que se vayan mostrando se almacenan en una pila; es decir, cada vez que la aplicación lo requiera inserta una nueva actividad en la pila y, cuando esta ya no se necesite, se hace un push sobre esta lo cual deja en descubierto la actividad que estaba debajo. Importante leer <a class="external" href="http://developer.android.com/intl/de/guide/topics/fundamentals.html">esto para tener claro cada uno de los aspectos fundamentales de las aplicaciones Android</a>.</p>
<p style="text-align: justify;">Ahora, veremos detalladamente qué ocurrió en los pasos que seguimos arriba. Por ejemplo, al crear el proyecto se generan algunos archivos automáticamente. Veamos que hace cada uno de ellos&#8230;</p>
<p>Dentro del directorio <code>res</code> se han creado algunos subdirectorios:</p>
<ul>
<li style="text-align: justify;"><code>drawable-hdpi</code>, <code>drawable-mdpi</code>, <code>drawable-ldpi</code> en donde se almacenan las imágenes que va a utilizar nuestra aplicación. La diferencia entre ellas es que debemos colocar las imágenes que aparecerán según el tipo de pantalla del dispositivo. En <code>drawable-hdpi</code> se colocarán las imágenes para dispositivos con alta resolución (High) y en <code>drawable-ldpi</code> (Low) pondremos las imágenes para dispositivos con pantallas pequeñas.</li>
<li style="text-align: justify;"><code>values</code> contiene inicialmente el archivo <code>strings.xml</code>, que es donde declaramos las cadenas de texto que usará nuestra aplicación. No es obligatorio definir todas las cadenas de texto allí, pero es bastante recomendable hacerlo. En este caso simplemente contiene la definición de una cadena de texto (llamada <code>hello</code>), que es la que se muestra al ejecutar la aplicación:
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;resources&gt;
 &lt;string name=&quot;hello&quot;&gt;Hello World, HolaParce!&lt;/string&gt;
 &lt;string name=&quot;app_name&quot;&gt;Hola Parce&lt;/string&gt;
&lt;/resources&gt;
</pre>
</li>
<li style="text-align: justify;"><code>layout</code> contiene los archivos XML que representan interfaces gráficas. Si echamos un vistazo al archivo generado (<code>main.xml</code>) veremos algo como esto:
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
 android:orientation=&quot;vertical&quot;
 android:layout_width=&quot;fill_parent&quot;
 android:layout_height=&quot;fill_parent&quot;
 &gt;
&lt;TextView
 android:layout_width=&quot;fill_parent&quot;
 android:layout_height=&quot;wrap_content&quot;
 android:text=&quot;@string/hello&quot;
 /&gt;
&lt;/LinearLayout&gt;
</pre>
<p>De aquí podemos resaltar varias cosas:</p>
<ul>
<li style="text-align: justify;">Los layouts son XML estrictos, así que deben comenzar con el encabezado <code>&lt;?xml version="1.0" encoding="utf-8"?&gt;</code> y todas las etiquetas abiertas deben ser debidamente cerradas.</li>
<li style="text-align: justify;">Los <code>LinearLayout</code> representan contenedores de widgets (algo similar al <code>JPanel</code> de swing en Java). Es decir, es la manera de organizar cada grupo de elementos de la interfaz gráfica.</li>
<li style="text-align: justify;">En este caso, dentro del contenedor solo tenemos un <code>TextView</code> (que sería algo así como un <code>JLabel</code> de swing en Java).</li>
<li style="text-align: justify;">Sea cual sea el elemento que pongamos en el layout, debemos especificar su anchura (<code>android:layout_width</code>) y altura (<code>android:layout_height</code>). Para cada parámetro podemos usar el valor <code>fill_parent</code> o <code>wrap_content</code>. <code>fill_parent</code> hará que el widget ocupe todo el tamaño posible, mientras que <code>wrap_content</code> hará que ocupe el menos posible.</li>
<li style="text-align: justify;">El parámetro <code>android:text</code> permite asignar un texto al <code>TextView</code>. En este caso se usa <code>@string/hello</code> que indica que se usará una variable llamada <code>hello</code>. Esta variable puede ser encontrada en el archivo <code>strings.xml</code> dentro del directorio <code>values</code>. También podríamos especificar el texto directamente, por ejemplo: <code>android:text="Hola parcero!"</code></li>
</ul>
</li>
<li style="text-align: justify;">Como tal vez se dio cuenta, es posible editar los archivos XML gráficamente o con el editor de textos de Eclipse.</li>
</ul>
<p style="text-align: justify;">Dentro del directorio <code>gen</code> se encuentra un archivo llamado <code>R.java</code>. Este  archivo NO debemos modificarlo ya que es Eclipse quien se encargar de  poner el código allí dentro. Este archivo sirve básicamente para enlazar  las cosas que hagamos en XML con la programación en Java. Por ejemplo,  se crea una referencia a la variable hello creada en el archivo  <code>strings.xml</code>. Esto permite que podamos referenciar dicha variable desde  Java (esto se explica con más detalle abajo).</p>
<p style="text-align: justify;">Bajo el directorio <code>src</code> se creó un paquete y dentro de él un archivo en Java que es nuestra primera actividad (fíjese cómo la clase creada extiende la clase <code>Activity</code> del paquete <code>android.app</code>):</p>
<pre class="brush: java; title: ; notranslate">package net.casidiablo.holaparce;
import android.app.Activity;
import android.os.Bundle;
public class HolaParce extends Activity {
/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}</pre>
<p style="text-align: justify;">Veamos en detalle cada línea:</p>
<ul style="text-align: justify;">
<li>Línea 1 define el nombre del paquete.</li>
<li>Líneas 2 y 3 importamos las clases que necesitamos para correr la actividad.</li>
<li>En la línea 4 podemos ver que la clase exitiende a <a class="external" href="http://developer.android.com/intl/de/reference/android/app/Activity.html"><code>Activity</code></a>.</li>
<li style="text-align: justify;">En la línea 7 redefinimos el método <code>onCreate</code> de la clase <code>Activity,</code> el cual es ejecutado al momento de iniciar la aplicación. Note que no es necesario tener un método <code>main</code>; en Android se define una actividad principal que será ejecutada al iniciar la aplicación (más adelante veremos donde se configura esto).</li>
<li style="text-align: justify;">En la línea 9 se usa el método <code>setContentView</code> que define cual de las interfaces gráficas creadas en el directorio layout serán usadas. Como parámetro usamos la variable <code>R.layout.main</code>. Esto es algo confuso al principio así que lea atentamente: <code>R</code>, como vimos anteriormente, es una clase generada por Eclipse automáticamente cada vez que creamos nuevos componentes para la aplicación; dentro de ella se crean clases estáticas con variables enteras que representan cada uno de estos componentes (<code>main.xml</code> es entonces una variable entera llamada <code>main</code>, dentro de la clase estática <code>layout</code>, que a su vez se encuentra dentro de la clase <code>R.java</code>). Por ejemplo, para usar la variable <code>hello</code> desde Java, tendríamos que usar una referencia de tipo <code>R.values.hello</code>.</li>
</ul>
<p style="text-align: justify;">Por último, tenemos el archivo <code>AndroidManifest.xml</code>. Todas las aplicaciones deben tener este archivo y no debe ser renombrado. En él se especifican las opciones generales del programa, como el paquete principal, la actividad que deberá ejecutarse al iniciar la aplicación (y deben incluirse allí TODAS las actividades que se van usar), el icono a usar, los permisos, etc.</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
 package=&quot;net.casidiablo.holaparce&quot;
 android:versionCode=&quot;1&quot;
 android:versionName=&quot;1.0&quot;&gt;
 &lt;application android:icon=&quot;@drawable/icon&quot; android:label=&quot;@string/app_name&quot;&gt;
 &lt;activity android:name=&quot;.HolaParce&quot;
 android:label=&quot;@string/app_name&quot;&gt;
 &lt;intent-filter&gt;
 &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
 &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
 &lt;/intent-filter&gt;
 &lt;/activity&gt;
&lt;/application&gt;
 &lt;uses-sdk android:minSdkVersion=&quot;4&quot; /&gt;
&lt;/manifest&gt;
</pre>
<h3>5. Operaciones avanzadas: acceder al dispositivo por consola y obtener una shell</h3>
<p style="text-align: justify;">Como sabemos, Android está basado en Linux, y como tal posee una interfaz de linea de comandos que podemos acceder usando las herramientas del sdk. Esto lo podemos hacer tanto para dispositivos virtuales, como el de este ejemplo, como para dispositivos reales. En este caso lo haremos con el dispositivo virtual que creamos para el ejemplo. Es tan sencillo como ejecutar esto en consola (en Linux):</p>
<p style="text-align: justify;">
<div class="consola">tools/adb -s emulator5554 shell</div>
</p>
<p style="text-align: justify;">Lo que hacemos con el comando anterior es indicarle al <code>adb</code> que queremos abrir una shell del dispositivo con serial emulator5554. Para ver los dispositivos conectados actualmente y sus seriales usamos el comando <code>adb devices</code>. Si todo va bien veríamos algo como esto:</p>
<p style="text-align: justify;">
<div class="consola">funtoo@larry tools % ./adb -s emulator-5554 shell<br />
# ls<br />
sqlite_stmt_journals<br />
cache<br />
sdcard<br />
etc<br />
system<br />
sys<br />
sbin<br />
proc<br />
init.rc<br />
init.goldfish.rc<br />
init<br />
default.prop<br />
data<br />
root<br />
dev</div>
</p>
<p style="text-align: justify;">Desde dicha shell podemos hacer bastantes cosas, pero la más interesante para mi, es poder usar el SQLite3 para acceder a las bases de datos de las aplicaciones que creemos, lo cual nos permite una depuración mucho más rápida.</p>
<p style="text-align: justify;">Eso es todo&#8230; espero les haya gustado. Cualquier comentario, duda o sugerencia no duden en comentarla.</p>
<h3>6. Links interesantes y fuentes de información</h3>
<ul>
<li><a class="external" href="http://developer.android.com/">Sitio oficial de Android para desarrolladores</a> (esta es prácticamente todo lo que vas a necesitar)</li>
<li><a class="external" href="http://www.xda-developers.com/">xda-developers, comunidad de desarrolladores de Android y Windows Mobile</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/tutorial-basico-android/feed/</wfw:commentRss>
		<slash:comments>79</slash:comments>
		</item>
		<item>
		<title>Usando el System Tray desde Java</title>
		<link>http://casidiablo.net/systray-java-ejemplo/</link>
		<comments>http://casidiablo.net/systray-java-ejemplo/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 13:55:04 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[ejercicios en java]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[area]]></category>
		<category><![CDATA[awt]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[jpoupmenu]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[notificacion]]></category>
		<category><![CDATA[system tray]]></category>
		<category><![CDATA[systray]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3625</guid>
		<description><![CDATA[En esta ocasión vamos a aprender usar el System Tray desde una aplicación hecha en Java. El System Tray o área de notificaciones, es el espacio en el escritorio en donde &#8216;residen&#8217; aplicaciones que el sistema está ejecutando, pero que no tienen en foco de lo que estamos haciendo. Antes se usaban librerías nativas + [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Fsystray-java-ejemplo%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fcasidiablo.in%2FckC2zY%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Usando%20el%20System%20Tray%20desde%20Java%22%20%7D);"></div>
<p style="text-align: justify;">En esta ocasión vamos a aprender usar el System Tray desde una aplicación hecha en Java. El System Tray o área de notificaciones, es el espacio en el escritorio en donde &#8216;residen&#8217; aplicaciones que el sistema está ejecutando, pero que no tienen en foco de lo que estamos haciendo.</p>
<p style="text-align: justify;"><strong>Antes</strong> se usaban librerías nativas + JNI para lograr esto, pero desde hace un tiempo se incluyeron en el API de Java 6 las clases SystemTray y TrayIcon (dentro del paquete java.awt) lo cual nos facilita mucho las cosas.</p>
<p style="text-align: center;"><img class="size-full wp-image-3638 aligncenter" title="windowsxp" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/02/windowsxp.png" alt="" width="325" height="173" /></p>
<h3>0. Entendiendo las clases SystemTray y TrayIcon + Prerrequisitos</h3>
<p style="text-align: justify;">Antes que nada, debes tener instalada una versión reciente del JDK6. La clase <code><a href="http://java.sun.com/javase/6/docs/api/java/awt/SystemTray.html">java.awt.SystemTray</a> </code>representa el System Tray del escritorio. Para manipular dicha clase es necesario obtener un objeto estático de esta usando el método <code>SystemTray.getSystemTray() </code> (es decir, no es posible crear instancias de dicha clase). Además, es necesario verificar que el uso de esta clase sea soportada en el sistema donde se ejecuta. Esto lo hacemos usando el método estático <code>SystemTray.isSupported()</code>. Si no hay soporte, este método retornará false. Si haces un llamado al método <code>getSystemTray</code> y tu sistema no está soportado, se lanzará la excepción <code>java.lang.UnsupportedOperationException</code>.</p>
<p style="text-align: justify;">La instancia de <code>SystemTray</code> contiene uno o más <code>TrayIcons</code>, los cuales son añadidos usando el método <code>add(java.awt.TrayIcon)</code>, y son eliminados con el método <code>remove(java.awt.TrayIcon)</code>.</p>
<p><span id="more-3625"></span></p>
<h3>1. Ejemplo de uso</h3>
<pre class="brush: java; highlight: [8,10,46,50]; title: ; notranslate">import java.awt.*;
import java.awt.event.*;
public class EjemploSystemTray {
    public EjemploSystemTray() {
        //se declara el objeto tipo icono
        final TrayIcon iconoSystemTray;
        //se verifica que el SystemTray sea soportado
        if (SystemTray.isSupported()) {
            //se obtiene una instancia estática de la clase SystemTray
            SystemTray tray = SystemTray.getSystemTray();
            //esta es la imagen de icono
            Image imagenIcono = Toolkit.getDefaultToolkit().getImage(&quot;icono.png&quot;);
            //este listener nos permite capturar cualquier tipo de evento
            //que se haga con el mouse sobre el icono
            MouseListener mouseListener = new MouseListener() {
                public void mouseClicked(MouseEvent e) {
                    System.out.println(&quot;Icono del System Tray - Mouse clicked!&quot;);
                }
                public void mouseEntered(MouseEvent e) {
                    System.out.println(&quot;Icono del System Tray - Mouse entered!&quot;);
                }
                public void mouseExited(MouseEvent e) {
                    System.out.println(&quot;Icono del System Tray - Mouse exited!&quot;);
                }
                public void mousePressed(MouseEvent e) {
                    System.out.println(&quot;Icono del System Tray - Mouse pressed!&quot;);
                }
                public void mouseReleased(MouseEvent e) {
                    System.out.println(&quot;Icono del System Tray - Mouse released!&quot;);
                }
            };
            //este listener se asociara con un item del menu contextual
            //que aparece al hacer click derecho sobre el icono
            ActionListener escuchadorSalir = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println(&quot;Saliendo...&quot;);
                    System.exit(0);
                }
            };
            //menu que aparece al hacer click derecho
            PopupMenu popup = new PopupMenu();
            MenuItem item = new MenuItem(&quot;Exit&quot;);
            item.addActionListener(escuchadorSalir);
            popup.add(item);
            //iniciamos el objeto TrayIcon
            iconoSystemTray = new TrayIcon(imagenIcono, &quot;Prueba System Tray&quot;, popup);
            //este tipo de listener captura el doble click sobre el icono
            ActionListener accionMostrarMensaje = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    iconoSystemTray.displayMessage(&quot;Titulo mensaje&quot;,
                            &quot;Este es el contenido del mensaje!&quot;,
                            TrayIcon.MessageType.INFO);
                }
            };

            iconoSystemTray.setImageAutoSize(true);
            iconoSystemTray.addActionListener(accionMostrarMensaje);
            iconoSystemTray.addMouseListener(mouseListener);

            //se debe capturar una excepción en caso que falle la adicion de un icono
            try {
                tray.add(iconoSystemTray);
            } catch (AWTException e) {
                System.err.println(&quot;No es posible agregar el icono al System Tray&quot;);
            }
        }
        else
            System.err.println(&quot;Tu sistema no soporta el System Tray&quot;);
    }
    public static void main(String[] args) {
        new EjemploSystemTray();
    }
}</pre>
<p>Así se ve en Linux (usando Gnome) y en Windows7:</p>
<p style="text-align: center;"><img title="en gnome" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/02/gnome.png" alt="" /> <img title="en-windows7" src="http://casidiablo.net/wordpress/wp-content/uploads/2010/02/windows7.png" alt="" /></p>
<p style="text-align: justify;">Del ejemplo anterior veamos las líneas más importantes:</p>
<ul>
<li style="text-align: justify;">Línea 8: verificamos que tengamos soporte.</li>
<li style="text-align: justify;">Línea 10: obtenemos una instancia de la clase SystemTray.</li>
<li style="text-align: justify;">Línea 46: creamos el icono que vamos a añadir.</li>
<li style="text-align: justify;">Línea 50: invocación del método displayMessage para mostrar globos de notificación.</li>
<li style="text-align: justify;">Línea 62: añadimos el icono al systray.</li>
</ul>
<h3>2. ¿Cómo usar Swing en vez de AWT?</h3>
<p style="text-align: justify;">Si te fijaste bien, el SystemTray es una clase que pertenece al paquete AWT&#8230; por alguna razón no se tuvo en cuenta Swing en todo esto. Es por ello que no podemos usar directamente <code>JPopupMenu</code> en vez de <code>PopupMenu</code>. Además, <code>JPopupMenu</code> tampoco es una subclase de <code>PopupMenu</code> por lo cual no podemos usar polimorfismo <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_mrgreen.gif' alt=':mrgreen:' class='wp-smiley' /> </p>
<p style="text-align: justify;">Afortunadamente hay algunos trucos para hacerlo funcionar con Swing que nos proporciona varias ventajas: la apariencia del menú sería igual en cualquier sistema operativo, podemos añadir iconos a los items, etc.</p>
<p style="text-align: justify;">El truco más sencillo del cual tengo conocimiento lo leí en el blog de Artem Ananiev, en un post llamado <a href="http://weblogs.java.net/blog/2006/05/04/using-jpopupmenu-trayicon">Using JPopupMenu in TrayIcon</a>. He preparado entonces otro ejemplo sencillo en donde se muestra cómo lograr esto:</p>
<pre class="brush: java; highlight: [40,41,42,43,44]; title: ; notranslate">import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EjemploSystemTraySwing {
    public EjemploSystemTraySwing() {
        //se declara el objeto tipo icono
        final TrayIcon iconoSystemTray;
        //se verifica que el SystemTray sea soportado
        if (SystemTray.isSupported()) {
            //se obtiene una instancia estática de la clase SystemTray
            SystemTray tray = SystemTray.getSystemTray();
            //esta es la imagen de icono
            Image imagenIcono = Toolkit.getDefaultToolkit().getImage(&quot;icono.png&quot;);
            //este listener se asociara con un item del menu contextual
            //que aparece al hacer click derecho sobre el icono
            ActionListener escuchadorSalir = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println(&quot;Saliendo...&quot;);
                    System.exit(0);
                }
            };
            //menu que aparece al hacer click derecho
            final JPopupMenu popup = new JPopupMenu();

            //aniadir un menu con icono (swing)
            JMenuItem carita = new JMenuItem(&quot;casidiablo.net&quot;,  new ImageIcon(&quot;carita.png&quot;));
            popup.add(carita);
            popup.addSeparator();

            //aniadir el item de salir
            JMenuItem item = new JMenuItem(&quot;Exit&quot;, new ImageIcon(&quot;salir.png&quot;));
            item.addActionListener(escuchadorSalir);
            popup.add(item);
            //iniciamos el objeto TrayIcon
            iconoSystemTray = new TrayIcon(imagenIcono, &quot;Prueba System Tray&quot;, null);
            iconoSystemTray.setImageAutoSize(true);
            //iconoSystemTray.addMouseListener(mouseListener);
            iconoSystemTray.addMouseListener(new MouseAdapter() {
                public void mouseReleased(MouseEvent e) {
                    if (e.isPopupTrigger()) {
                        popup.setLocation(e.getX(), e.getY()-50);
                        popup.setInvoker(popup);
                        popup.setVisible(true);
                    }
                }
            });
            //se debe capturar una excepción en caso que falle la adicion de un icono
            try {
                tray.add(iconoSystemTray);
            } catch (AWTException e) {
                System.err.println(&quot;No es posible agregar el icono al System Tray&quot;);
            }
        }
        else
            System.err.println(&quot;Tu sistema no soporta el System Tray&quot;);
    }
    public static void main(String[] args) {
        new EjemploSystemTraySwing();
    }
}</pre>
<p style="text-align: justify;">El resultado es algo como lo que aparece en la primera imagen que acompaña esta entrada. Importante tener en cuenta las líneas resaltadas (40 a 44) que es donde se hace la <em>magia</em> <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  Como siempre, puedes descargar el código y probar tú mismo:</p>
<p><a href="http://casidiablo.net/descargar/Ejemplos+System+Tray+Java" class="descargacodigo">Descargar ZIP con ejemplos</a></p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/systray-java-ejemplo/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Recuperar archivos eliminados usando Foremost [configuración manual]</title>
		<link>http://casidiablo.net/restaurar-archivos-eliminados-accidentalmente/</link>
		<comments>http://casidiablo.net/restaurar-archivos-eliminados-accidentalmente/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 05:58:39 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[archivos]]></category>
		<category><![CDATA[carving]]></category>
		<category><![CDATA[eliminados]]></category>
		<category><![CDATA[ext2]]></category>
		<category><![CDATA[ext3]]></category>
		<category><![CDATA[ext4]]></category>
		<category><![CDATA[foremost]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[ntfs]]></category>
		<category><![CDATA[recovery]]></category>
		<category><![CDATA[recuperar]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[undelete]]></category>
		<category><![CDATA[videos]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3487</guid>
		<description><![CDATA[¡Hola a todos! Hace un par de días perdí la partición donde tenía mi /home. Afortunadamente pude recuperar el 98% de los archivos que necesitaba. Es decir, en realidad no me interesaba recuperar imágenes, música, etc&#8230; lo único importante era recuperar los archivos PHP con los que había estado trabajando. Aclaro esto puesto que esta [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Frestaurar-archivos-eliminados-accidentalmente%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Recuperar%20archivos%20eliminados%20usando%20Foremost%20%5Bconfiguraci%C3%B3n%20manual%5D%22%20%7D);"></div>
<p style="text-align: justify;">
<p style="text-align: justify;">¡Hola a todos! Hace un par de días perdí la partición donde tenía mi /home. Afortunadamente pude recuperar el 98% de los archivos <em>que necesitaba</em>. Es decir, en realidad no me interesaba recuperar imágenes, música, etc&#8230; lo único importante era recuperar los archivos PHP con los que había estado trabajando.</p>
<p style="text-align: justify;">Aclaro esto puesto que esta entrada se va a enfocar en la configuración manual de <a href="http://foremost.sourceforge.net/">Foremost</a>, un programa para hacer carving, de tal manera que rescatemos solamente aquello que realmente nos interesa. Existen otros programas, pero este fue el que realmente me ayudó en esos momentos de pánico.</p>
<p style="text-align: justify;">¿Cómo funciona? Foremost trabaja con imágenes generadas con dd o particiones directamente, y se basa en el análisis de encabezados y footers de los archivos para &#8216;extraer&#8217; lo que se pueda salvar.</p>
<div class="nota"><strong>Importante:</strong> si has eliminado accidentalmente algún archivo lo primero, después de blasfemar un rato, es evitar hacer cualquier tipo de escritura de datos sobre la misma. Esto es porque tus datos en realidad aún están allí, y el único riesgo que tienen de ser eliminados es que se sobrescriban datos en el mismo sector en donde se encuentran.</div>
<p><span id="more-3487"></span></p>
<p style="text-align: justify;">Dicho esto, tienes dos opciones:</p>
<ul style="text-align: justify;">
<li>Si tienes otra partición con suficiente espacio para almacenar un backup de la partición a ser tratada, puedes usar el comando dd y luego trabajar sobre esa imagen. <a href="http://casidiablo.net/crear-un-backup-o-imagen-del-disco-duro/">En esta entrada se explica con más detalle cómo hacer esto</a>.</li>
<li style="text-align: justify;">Si no tienes espacio (tal como me ocurrió a mi), puedes trabajar directamente sobre la partición (i.e. el archivo /dev/sdaX ó /dev/hdbX, etc.). Solo ten en mente que NO deberías montar dicha partición, al menos no en modo de lectura-escritura.</li>
</ul>
<p style="text-align: justify;">
<h3>Instalación de Foremost</h3>
<p style="text-align: justify;">La instalación es bastante sencilla ya que Foremost se incluye en prácticamente todos los repositorios de cualquier distribución. Así que puedes usar tu gestor de paquetes preferido. Siendo tan sencilla la instalación por repositorios, solo me queda mostrar la instalación manual que es incluso más sencilla&#8230; descargamos la última versión de Foremost (1.5.6 al momento de escribir esta entrada), descomprimimos, compilamos e instalamos:</p>
<div class="consola">wget http://foremost.sourceforge.net/pkg/foremost-1.5.6.tar.gz<br />
tar xfzv foremost-1.5.6.tar.gz<br />
cd foremost-1.5.6<br />
make &amp;&amp; make install</div>
<p style="text-align: justify;">
<h3>Ejemplo básico de uso de Foremost</h3>
<p style="text-align: justify;">El siguiente comando de ejemplo es un de los tantos cientos de miles que te encontrarás en la red&#8230; no me enfocaré mucho en este aspecto porque ya se encuentra muy bien documentado:</p>
<div class="consola">foremost -t pdf -i imagen.iso -o pdfs-recuperados</div>
<p style="text-align: justify;">Básicamente le estamos diciendo al Foremost que busque archivos de tipo PDF en el archivo de imagen (creado con dd) imagen.iso y que los guarde en pdfs-recuperados. Lo único que nos interesa recalcar en este punto es que Foremost tiene un set de archivos predefinidos de los cuales conoce su header y footer (como los PDFs en este caso); este set se compone de los archivos más comunes (imágenes  y videos en diferentes formatos, archivos de office, zips, etc.) Pero&#8230; ¿qué pasa con otro tipo de archivos menos comunes? Tranquilo, ya vamos para allá <img src='http://casidiablo.net/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: justify;">
<h3>Ejemplo de configuración del Foremost</h3>
<p style="text-align: justify;">Foremost puede ser configurado mediante un archivo (por defecto: <code>/etc/foremost.conf</code>) de tal manera que no tengamos que especificar el tipo de archivo a buscar y, lo que es mejor, podemos definir nuestros propios tipos de archivos. En nuestro ejemplo, te meterás en mis zapatos, te imaginarás que has perdido el trabajo de tres días y que tu objetivo es rescatar unos cuantos archivos de PHP.</p>
<p style="text-align: justify;">Entonces&#8230; ¿por donde comenzar? Bien&#8230; lo primero es echar un vistazo al archivo /etc/foremost.conf en donde puedes encontrar patrones de búsqueda para diferentes tipos de archivo (de hecho, son las que usa Foremost cuando usamos el flag <code>-t</code>). La sintáxis de estos patrones es sencilla y consta de una sola línea; esta línea tiene los siguientes parámetros separados por espacios o tabulaciones:</p>
<ul>
<li>Extensión del archivo&#8230; ¿debo explicar esto?</li>
<li>Definir si se debe hacer distinción entre mayúsculas y minúsculas al buscar el header y footer del archivo. Pon &#8216;y&#8217; si deseas que sea case-sensitive o &#8216;n&#8217; en caso contrario.</li>
<li>Tamaño máximo del archivo.</li>
<li>Encabezado: lo que se debe buscar en los encabezados de los archivos; puede ser especificado en texto plano o, mejor aún, en hexadecimal.</li>
<li>Footer (opcional): lo que se debe buscar al final de los archivos; puede ser especificado en texto plano o, mejor aún, en hexadecimal.</li>
</ul>
<p style="text-align: justify;">Por ejemplo, este es uno de los que se encuentra configurados por defecto en el Foremost:</p>
<p><code>jpg          y          20000000          \xff\xd8\xff\xe1          \xff\xd9</code></p>
<p style="text-align: justify;">Básicamente busca archivos con extensión .jpg y con un tamaño máximo de 20000000 bytes. Además especifica uno de los posibles encabezados que un archivo tipo JPEG puede tener (<code>\xff\xd8\xff\xe1</code>) y su footer (<code>\xff\xd9</code>).</p>
<p style="text-align: justify;">Como puedes ver, el encabezado y el footer pueden ser especificados en hexadecimal. Esto es bastante útil ya que en muchos casos no necesitamos simples archivos de texto sino que podríamos querer recuperar uno binario. En cualquier caso, es recomendable usar hexadecimal&#8230; pero ¿cómo se qué debo poner? Bien&#8230; recuerda que tu misión es recuperar los archivos PHP, así que&#8230; ¿qué tal si creamos uno para ver cómo se ve en hexadecimal?</p>
<p style="text-align: justify;">Creamos entonces un archivo con el siguiente contenido y lo guardamos como <em>test.php</em>:</p>
<pre class="brush: php; title: ; notranslate">&lt;?php
if($meLoTire){
	echo &quot;o_O mode-panic:on&quot;;
}
?&gt;</pre>
<p style="text-align: justify;">Ahora debemos abrir este archivo con algún editor hexadecimal. Si usas Gnome, Ghex es una buena opción (sino, también)&#8230; lo instalas desde los repositorios y con él abres el archivo que acabas de crear&#8230; este lucirá así:</p>
<p><a href="http://casidiablo.net/wordpress/wp-content/uploads/2009/12/ghex.png"><img class="aligncenter size-full wp-image-3499" title="ghex" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/12/ghex.png" alt="ghex" width="640" height="469" /></a></p>
<p style="text-align: justify;">¡Ahora ya podemos configurar Foremost como expertos, puesto que ya sabemos qué hexadecimales poner! Cada caracter del archivo que creamos equivale a un valor en hexadecimal y nos interesa enfocarnos en la representación hexadecimal de &#8220;&lt;?php&#8221; puesto que así comienzan los archivos en los que estamos interesados.</p>
<p style="text-align: justify;">Así que para este caso, los hexadecimales son 3C, 3F, 70, 68 y 70. Por lo tanto podemos crear un nuevo patrón dentro de /etc/foremost.conf que luzca algo así:</p>
<p><code>php y 100000 \x3C\x3F\x70\x68\x70</code></p>
<p style="text-align: justify;">Si queremos ser más precisos podemos especificar el footer:</p>
<p><code>php y 100000 \x3c\x3f\x70\x68\x70 \7d\0a\3f\x3e</code></p>
<p style="text-align: justify;">Fíjate que he definido un footer bastante concreto que hará que Foremost busque archivos que finalicen con un &#8216;}&#8217; seguido de un &#8216;Enter&#8217; (retorno de carro) y finalmente con &#8220;?&gt;&#8221;. Una vez hayamos terminado de configurar los patrones con los que queramos iniciar la búsqueda, guardamos y cerramos el archivo.</p>
<p style="text-align: justify;">Puesto que es el archivo por defecto no es necesario especificarlo al momento de ejecutar Foremost. Esto por supuesto implica que puedes crear un archivo con patrones en cualquier otro lado, y en tales casos debes referencialo con el flag -c. ¡Que comience el carving!</p>
<div class="consola">foremost -i /dev/sda1 -o ~/recuperados/</div>
<p style="text-align: justify;">Como puedes ver, no especificamos ningún tipo  de archivo así que Foremost se enfocará en aquellos configurados en el archivo .conf. Además, en este caso estamos especificando directamente la partición. Esto podría llevar un rato, así que tienes tiempo de leer algo entretenido ¿qué tal esta bonita <a href="http://www.gentoo.org/doc/en/vi-guide.xml">guía sobre Vi</a>? ¿o esta otra sobre un hermoso <a href="http://www.gentoo.org/doc/en/gentoo-freebsd.xml">Gentoo/BSD</a>?</p>
<p style="text-align: justify;">Una vez Foremost haya terminado su trabajo&#8230; el tuyo apenas comienza. Aunque Foremost es un excelente programa, los resultados no pueden ser 100% confiables (¿hay algo que lo sea?). Y para empeorar las cosas, Foremost NO recupera los nombres de los archivos. En vez de ello, crea una secuencia de archivos numéricos con la extensión; cosas como 8392383874.php ó 239492782.php ¿chévere, no?</p>
<p style="text-align: justify;">Todo parece que pasaremos un buen rato jugando con nuestro querido amigo GREP; y es que este maravilloso comando puede ser realmente útil en estos casos. Así que aquí van algunos comandos que te podrían servir:</p>
<ul>
<li style="text-align: justify;"><code>grep busqueda changos.ext</code><br />
Busca la cadena &#8216;busqueda&#8217; dentro del archivo changos.ext</li>
<li style="text-align: justify;">¿qué tal una búsqueda en todos los archivos? Esto podría servir para nuestro caso de los PHP:<br />
<code>cat *.php | grep -l cosa_a_buscar</code></li>
<li style="text-align: justify;">¿y si queremos buscar un string en varios archivos que se encuentran en diferentes directorios? Este comando es de los que más uso a diario:<br />
<code>find /ruta/ -exec grep -l cosa_a_buscar {} \;</code></li>
</ul>
<p style="text-align: justify;">
<h3>Cosas por considerar</h3>
</p>
<p style="text-align: justify;">
<ul>
<li style="text-align: justify;">Existe una gran probabilidad que los datos recuperados no estén del todo bien formados. Por ejemplo, podrían tener &#8220;basura&#8221; dentro. Esto es posible de corregir en archivos de texto, ya que solo necesitas un editor decente y un par de minutos para &#8220;ver qué te sirve&#8221;.</li>
<li style="text-align: justify;">Si los archivos recuperados tienen basura dentro, es mejor usar editores de texto en consola que no se quejan tanto al momento de editarlos. Gedit simplemente no los abre.</li>
<li style="text-align: justify;">Algunas veces los archivos quedan fragmentados; esto es, en un archivo recuperado queda una parte de lo que buscas, y en otro queda el restante. Por esto, es bastante útil que uses herramientas como Meld (excelente por cierto).  Considera este ejemplo de la vida real: en el archivo blablaa.php tenía parte inicial del archivo mientras que en blebelbel.php tenía el resto:</li>
</ul>
<p style="text-align: center;"><a href="http://casidiablo.net/wordpress/wp-content/uploads/2009/12/meld_1280.png"><img class="size-full wp-image-3501 aligncenter" title="meld_640" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/12/meld_640.png" alt="meld_640" width="640" height="331" /></a></p>
<p style="text-align: justify;">Esto es difícil de notar &#8216;a ojo&#8217;, por lo que puedo decir que Meld me salvó el trasero una vez más (y de paso se ganó una donación). Así, combinando el trabajo de Foremost y la ayuda de Meld pude recuperar prácticamente todo lo que necesitaba.</p>
<p style="text-align: justify;">Pero, te repito, si fuesen archivos binarios los que quieres rescatar la cosa sería mucho más difícil. En este caso, &#8216;la basura&#8217; se puede identificar fácilmente dentro del archivo, y de la misma manera se puede eliminar. En una archivo binario sin embargo es un poco más difícil.</p>
<p style="text-align: justify;">
<h3>Otros buenos programas con propósitos similares</h3>
</p>
<p style="text-align: justify;">
<ul>
<li><a href="http://www.cgsecurity.org/wiki/PhotoRec">TestDisk (aka, PhotoRec)</a></li>
<li><a href="http://www.digitalforensicssolutions.com/Scalpel/">Scalpel</a></li>
<li><a href="http://www.student.dtu.dk/~s042078/magicrescue/">Magic Rescue</a></li>
<li><a href="http://www.sleuthkit.org/autopsy/desc.php">Sleuth Kit y Autopsy</a></li>
<li><a href="http://www.sleuthkit.org/">Sleuthkit</a></li>
</ul>
<p><br/><br/><br/></p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/restaurar-archivos-eliminados-accidentalmente/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Ejecutar aplicación Java como servicio &#8211; Integración básica</title>
		<link>http://casidiablo.net/correr-programa-java-como-demonio/</link>
		<comments>http://casidiablo.net/correr-programa-java-como-demonio/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 01:16:20 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[ejercicios en java]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[demonio]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[servicio]]></category>
		<category><![CDATA[solaris]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3407</guid>
		<description><![CDATA[En esta entrada abordaremos un tema bastante interesante: cómo correr un programa en Java como servicio en Windows o demonio en UNIX/Linux. Puesto que el API de Java no proporciona nada para estos casos, utiliza remos una librería llamada Java Service Wrapper. Dicha librería nos ofrece una serie de scripts y binarios preparados para diferentes [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Fcorrer-programa-java-como-demonio%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Ejecutar%20aplicaci%C3%B3n%20Java%20como%20servicio%20-%20Integraci%C3%B3n%20b%C3%A1sica%22%20%7D);"></div>
<p style="text-align: justify;">En esta entrada abordaremos un tema bastante interesante: <strong>cómo correr un programa en Java como servicio en Windows o demonio en UNIX/Linux</strong>. Puesto que el API de <a href="http://casidiablo.net/java/">Java</a> no proporciona nada para estos casos, utiliza</p>
<p style="text-align: justify;">remos una librería llamada <a href="http://wrapper.tanukisoftware.org/">Java Service Wrapper</a>. Dicha librería nos ofrece una serie de scripts y binarios preparados para diferentes sistemas operativos y arquitecturas, que nos permitirán correr nuestros programas como un servicio; además ofrece diferentes versiones: Profesional, Estándar y Comunity. En este caso usaremos la versión Comunity que es libre y gratuita.</p>
<p style="text-align: justify;">La mejor manera de aprender a usar dicha librería es con un pequeño laboratorio, así que he preparado uno en donde explico la integración más simple que existe con Java Service Wrapper (existen 4 métodos; unos más avanzados que otros). La integración sencilla que he escogido nos permitirá ejecutar como servicio una aplicación que ya esté creada (probablemente ya empaquetada en un .jar) y a la que no podemos o es difícil hacerle modificaciones. Esta es la manera más sencilla de hacerlo, sin embargo tiene una desventaja: al detener el servicio se envía directamente un System.exit() a la JVM por lo que la aplicación no se cerrará limpiamente.</p>
<p style="text-align: justify;">Si quieres integrar tu aplicación de una manera más segura y estás en la capacidad de prepararla para ello, podrías intentar la integración avanzada en la que utilizas el API de Java Service Wrapper para implementar métodos de inicio, pausa y detención del servicio [<a href="http://casidiablo.net/descargar/Ejemplo+Servicio+Avanzado+Java+src&#8220;>descargar un ejemplo</a>].</p>
<h3>Laboratorio 1 &#8211; Integración Simple (Linux/Windows/Solaris)</h3>
<p style="text-align: justify;">Para este caso utilizaremos una aplicación de ejemplo que recibe un archivo como parámetro y escribe en él <a href="http://casidiablo.net/capturar-informacion-sistema-operativo-java/">información sobre la memoria del sistema</a>, cada 60 segundos. He escogido este ejemplo porque posee varios aspectos interesantes: requiere de librerías externas (tanto JARs como librerías nativas [.so, dll, etc.]) y recibe parámetros.</p>
<p style="text-align: justify;">Puedes descargar la aplicación de ejemplo de haciendo <a class="tooltip" title="Descargar los binarios del ejemplo" href="http://casidiablo.net/descargar/Ejemplo+Servicio+Simple+Java+bin">clic aquí</a>. Si la ejecutáramos de manera convencional veríamos algo de este tipo:</p>
<div class="consola">gentookde@larry bin % java -jar servicio.jar /tmp/log<br />
^C<br />
gentookde@larry bin % cat /tmp/log<br />
======Mon Oct 05 09:42:05 COT 2009=======<br />
Cantidad de memoria RAM: 3952MB<br />
Total: 4042664<br />
Usada: 3509516<br />
Disponible: 533148<br />
Memoria SWAP total: 1052248<br />
Memoria SWAP usada: 0<br />
Memoria SWAP libre: 1052248</div>
<p style="text-align: justify;">Como puedes ver se trata de una aplicación de consola común y corriente. La aplicación consta básicamente de:</p>
<ul style="text-align: justify;">
<li>El ejecutable servicio.jar ubicado en el directorio bin/</li>
<li>La librería sigar.jar en el directorio lib/</li>
<li style="text-align: justify;">Las librerías específicas de cada arquitectura de sigar en lib/</li>
</ul>
<h3>Pasos para la integración</h3>
<p style="text-align: justify; ">Lo primero es descargar el paquete de <a href="http://wrapper.tanukisoftware.org/doc/english/download.jsp">Java Service Wrapper</a> y descomprimirlo<span style="background-color: #ffffff;">. Supondremos que el directorio donde se encuentra Java Service Wrapper es $RUTA_JSW y que el directorio de la aplicación que  vamos a convertir en servicio es </span><span style="background-color: #ffffff;">$RUTA_APP</span><span style="background-color: #ffffff;">.</span></p>
<h4>1. Copiamos los siguentes archivos al directorio bin de nuestra aplicación de ejemplo&#8230;</h4>
<p style="text-align: justify; "><span style="background-color: #ffffff;"><strong>UNIX/Linux</strong><br />
</span></p>
<div class="consola">cp $RUTA_JSW/bin/wrapper $RUTA_APP/bin/<br />
cp $RUTA_JSW/src/bin/sh.script.in $RUTA_APP/bin/<br />
cp $RUTA_JSW/lib/* $RUTA_APP/bin/</div>
<p style="text-align: justify; ">El archivo $RUTA_JSW/bin/wrapper podría no existir; por lo tanto lo que debes copiar es el archivo wrapper-xxx específico para tu plataforma. Por ejemplo, en este caso estoy usando Gentoo Linux de 64bits por lo tanto copiaré el archivo $RUTA_JSW/bin/wrapper-linux-x86-64.</p>
<p style="text-align: justify; "><strong><span style="background-color: #ffffff;">Windows</span></strong></p>
<div class="consola">copy $RUTA_JSW/bin/ wrapper-windows-x86-32.exe $RUTA_APP/bin/<br />
copy $RUTA_JSW/src/bin/ App.bat.in $RUTA_APP/bin/<br />
copy $RUTA_JSW/src/bin/ InstallApp-NT.bat.in $RUTA_APP/bin/<br />
copy $RUTA_JSW/src/bin/ UninstallApp-NT.bat.in $RUTA_APP/bin/<br />
copy $RUTA_JSW/lib/* $RUTA_APP/bin/</div>
<h4>2. Renombramos algunos archivos&#8230;</h4>
<p><strong>UNIX/Linux&#8230;</strong></p>
<p style="text-align: justify;">Ahora debes renombrar el script sh.script.in con el nombre de la aplicación con la que haremos la integración y darle privilegios de ejecución. En este casó se llama simplemente &#8220;servicio&#8221;:</p>
<div class="consola">cd $RUTA_APP/bin<br />
mv sh.script.in servicio<br />
chmod a+x servicio</div>
<p><strong>Windows</strong></p>
<p style="text-align: justify;">Ahora debes renombrar los archivos .bat  para que concuerden con el nombre de la aplicación con la que haremos la integración. En este casó se llama simplemente &#8220;servicio&#8221; (lo puedes hacer usando el explorador si no te gusta usar la consola, pero a mi me daría pena):</p>
<div class="consola">cd $RUTA_APP/bin<br />
move App.bat.in servicio.bat<br />
move InstallApp-NT.bat.in InstallServicio-NT.bat<br />
move UninstallApp-NT.bat.in UninstallServicio-NT.bat</div>
<h4>3. editar archivo de configuración</h4>
<p style="text-align: justify;">Editamos el archivo wrapper.conf y lo dejamos en el directorio $RUTA_APP/conf/. El archivo para este ejemplo tendrá el siguiente contenido (<strong>importante</strong>! lee la explicación si usas Windows):</p>
<pre class="brush: plain; title: ; notranslate"># Comando de Java
wrapper.java.command=java
# Clase que ejecutara el Wrapper
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
# Librerias necesarias para ejecutar el programa
wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=servicio.jar
# Java Library Path (ubicacion de las librerias wrapper.dll o wrapper.so)
wrapper.java.library.path.1=../lib
# Java Bits.  On applicable platforms, tells the JVM to run in 32 or 64-bit mode.
wrapper.java.additional.auto_bits=TRUE
# Parametros del programa
wrapper.app.parameter.1=net.casidiablo.servicio.Servicio
wrapper.app.parameter.2=/tmp/log
#********************************************************************
# Wrapper General Properties
#********************************************************************
# Allow for the use of non-contiguous numbered properties
wrapper.ignore_sequence_gaps=TRUE
# Title to use when running as a console
wrapper.console.title=servicio
#********************************************************************
# Wrapper Windows NT/2000/XP Service Properties
#********************************************************************
# Name of the service
wrapper.name=jgossip
# Display name of the service
wrapper.displayname=Servicio
# Description of the service
wrapper.description=Monitor de memoria
# Mode in which the service is installed. AUTO_START or DEMAND_START
wrapper.ntservice.starttype=AUTO_START
# Allow the service to interact with the desktop.
wrapper.ntservice.interactive=false</pre>
<p>Explicación del archivo de configuración:</p>
<ul>
<li style="text-align: justify;"><code>wrapper.java.command=java</code> es el comando para ejecutar java. En este caso es simplemente java porque estoy en Linux y además tengo configurado correctamente el path. En Windows podría ser algo como: c:\archivos de programa\java\jdk1.6\bin\java.exe</li>
<li style="text-align: justify;"><code>wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp</code> indica el archivo a ejecutar es la clase WrapperSimpleApp que se usa en la integración sencilla. Esta clase envoltorio es la que permite ejecutar la aplicación como servicio.</li>
<li style="text-align: justify;"><code>wrapper.java.classpath.1=../lib/wrapper.jar<br />
wrapper.java.classpath.2=servicio.jar</code> indican las rutas o archivos del classpath.</li>
<li style="text-align: justify;"><code>wrapper.java.library.path.1=../lib</code> indica el directorio donde se encuentran las librerías a usar.</li>
<li style="text-align: justify;"><code>wrapper.app.parameter.1=net.casidiablo.servicio.Servicio<br />
wrapper.app.parameter.2=/tmp/log</code> estos son los parámetros que se pasarán al programa. <strong>Importante</strong>: como estamos haciendo la integración simple, el primer parámetro debe ser la clase que contiene el método main de nuestra aplicación.</li>
<li style="text-align: justify;"><code>wrapper.name=jgossip</code> esta opción es para Windows y define el nombre del servicio en el sistema.</li>
<li style="text-align: justify;"><code>wrapper.ntservice.starttype=AUTO_START</code> si estás en windows, define si el servicio quedará configurado para iniciar automáticamente.</li>
</ul>
<h4>4. Probar/Instalar el servicio&#8230;</h4>
<p style="text-align: justify;">Ahora veremos cómo podemos probar la aplicación para asegurarnos que ha quedado bien configurada antes de proceder con la instalación.</p>
<p><strong>UNIX/Linux</strong></p>
<p style="text-align: justify;">Ejecutamos el script &#8216;servicio&#8217; que configuramos en el paso 1 y 2 con el parámetro console:</p>
<div class="consola">./servicio console</div>
<p>Deberías ver algo como:</p>
<div class="consola">Running un servicio que escribe cosas&#8230;<br />
wrapper  | &#8211;&gt; Wrapper Started as Console<br />
wrapper  | Java Service Wrapper Community Edition 64-bit 3.3.6<br />
wrapper  |   Copyright (C) 1999-2009 Tanuki Software, Ltd.  All Rights Reserved.<br />
wrapper  |     http://wrapper.tanukisoftware.org<br />
wrapper  |<br />
wrapper  | Launching a JVM&#8230;<br />
jvm 1    | WrapperManager: Initializing&#8230;</div>
<p style="text-align: justify;">Lo detienes presionando Ctrl+C. Ahora, si queremos probarlo como demonio basta con ejecutar los comandos típicos de un demonio en UNIX/Linux:</p>
<div class="consola">$ ./servicio start<br />
Starting un servicio que escribe cosas&#8230;<br />
$ ./servicio stop<br />
Stopping un servicio que escribe cosas&#8230;<br />
Stopped un servicio que escribe cosas.</div>
<p style="text-align: justify;">Para instalarlo basta con crear un enlace simbólico del script en el directorio /etc/init.d y añadirlo al listado de servicios a iniciar; por ejemplo:</p>
<div class="consola">sudo ln -sv $RUTA_APP/bin/servicio /etc/init.d/servicio<br />
sudo rc-update add servicio default</div>
<p><strong>Windows</strong></p>
<p style="text-align: justify;">Para instalarlo en Windows basta con ejecutar el archivo InstallServicio-NT.bat. Puedes verificar que fue instalado correctamente accediendo a la consola de administración de servicios de NT (ejecutas el comando services.msc):</p>
<p><a href="http://casidiablo.net/wordpress/wp-content/uploads/2009/11/screenshot_001.png"><img class="aligncenter size-full wp-image-3460" title="servicio windows java" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/11/screenshot_001.png" alt="servicio windows java" width="778" height="566" /></a></p>
<h3>Fuentes y descargas</h3>
<p>Aunque en esta entrada no explico cómo hacer la integración avanzada, he preparado un ejemplo completo que puedes descargar en el listado de abajo.<strong><br />
</strong></p>
<ul>
<li><a href="http://wrapper.tanukisoftware.org/doc/">Puedes encontrar más documentación en la página oficial del proyecto</a></li>
<li><a href="http://casidiablo.net/descargar/Ejemplo+Servicio+Simple+Java+bin">Descargar el laboratorio de esta entrada</a></li>
<li><a href="http://casidiablo.net/descargar/Ejemplo+Servicio+Simple+Java+src">Descargar el código fuente del laboratorio</a></li>
<li><a href="http://casidiablo.net/descargar/Ejemplo+Servicio+Avanzado+Java+src"><strong>Descargar código fuente y laboratorio de la integración avanzada</strong></a></li>
</ul>
<p><br/><br/><br/></p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/correr-programa-java-como-demonio/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>Obtener información del sistema [memoria disponible, %CPU, espacio en disco] en Java</title>
		<link>http://casidiablo.net/capturar-informacion-sistema-operativo-java/</link>
		<comments>http://casidiablo.net/capturar-informacion-sistema-operativo-java/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 22:00:33 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[ejercicios en java]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[cpu]]></category>
		<category><![CDATA[disco]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[ejemplos]]></category>
		<category><![CDATA[ejercicio]]></category>
		<category><![CDATA[espacio]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[informacion]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[memoria]]></category>
		<category><![CDATA[ram]]></category>
		<category><![CDATA[sistema]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3382</guid>
		<description><![CDATA[En esta guía aprenderemos a obtener información de los recursos sistema en Java, usando la librería Sigar. Los datos que podremos extraer son los siguientes: Información de la CPU. Espacio en disco disponible. Cantidad de espacio que consume un directorio en específico. Cantidad de memoria RAM disponible y en uso. Información de red (dirección IP, [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Fcapturar-informacion-sistema-operativo-java%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Obtener%20informaci%C3%B3n%20del%20sistema%20%5Bmemoria%20disponible%2C%20%25CPU%2C%20espacio%20en%20disco%5D%20en%20Java%22%20%7D);"></div>
<p style="text-align: justify;">En esta guía aprenderemos a obtener información de los recursos sistema en Java, usando la librería Sigar. Los datos que podremos extraer son los siguientes:</p>
<ul style="text-align: justify;">
<li><strong>Información de la CPU.</strong></li>
<li><strong>Espacio en disco disponible.</strong></li>
<li>Cantidad de espacio que consume un directorio en específico.</li>
<li><strong>Cantidad de memoria RAM disponible y en uso.</strong></li>
<li>Información de red (dirección IP, nombre de la NIC, puertos abiertos, tablas de enrutamiento, etc.)</li>
<li>Información de los procesos que se están ejecutando en el sistema.</li>
<li>Asignación de <a href="http://casidiablo.net/obtener-variables-entorno-informacion-sistema-java/">variables de entorno</a>.</li>
<li><strong>Uptime, o cantidad de tiempo que el equipo ha estado encendido.</strong></li>
<li><strong>Nombre y versión del sistema operativo.</strong></li>
<li>Usuarios logueados actualmente.</li>
</ul>
<p style="text-align: justify;">Resaltadas en negrita está la información en la que nos concentraremos en el ejemplo. Pero antes aclaremos un poco que es Sigar: el API de Sigar nos proporciona una serie de métodos que nos permiten obtener información del sistema operativo; consta de una librería de Java (.jar) y otras librerías nativas específicas para cada sistema operativo soportado (<code>libsigar-amd64-linux.so</code>, para Linux de 64 bits o <code>sigar-x86-winnt.dll</code> para Windows de 32 bits, por poner un ejemplo).</p>
<p style="text-align: justify;">Teniendo esto en cuenta, para hacer funcionar dicha API en una de nuestras aplicaciones, bastaría con tener el archivo .jar y la librería específica de nuestro sistema operativo. En el desarrollo del ejemplo se usará Eclipse y, aunque se explicará cómo añadir las librerías en el proyecto, se da por conocido el funcionamiento del flag <code>--classpath</code> de los comandos <code>javac</code> y <code>java</code> (obligatorio si no se usa ningún IDE).</p>
<h3>El resultado&#8230;</h3>
<p style="text-align: justify;">Siempre pongo primero el resultado ya que nos aclara la visión de hacia donde vamos, y de paso saber si lo que está aquí es lo que buscamos. Esta es la salida del programa en mi Gentoo Linux:</p>
<p><span id="more-3382"></span></p>
<pre class="brush: plain; title: ; notranslate">====Informacion del sistema====
Descripcion del SO	Gentoo 2.1.6
Nombre del SO		Linux
Arquitectura del SO	x86_64
Version del SO		2.6.31-gentoo
Nivel de parches	unknown
Fabricante		Gentoo
Version SO		2.1.6
Encendido durante:	6:15

==== Informacion de la CPU ====
Fabricante:		Intel
Modelo			Core(TM)2 Duo CPU     T5750  @ 2.00GHz
Mhz			1994
Total CPUs		2
CPUs fisiscas		1
Nucleos por CPU		2
Tamanio cache		2048

Consumo de CPU 0	22.0%
Consumo de CPU 1	2.0%
Consumo total de CPU	6.0%

====Informacion del sistema de archivos====

dispos.|total|usado|disponible|%uso|dir|tipo

/dev/root|24042944|10698228|12123376|47%|/|ext4
/dev/sda1|175457764|155825380|10719932|94%|/home|ext3

====Informacion de la memoria====
Cantidad de memoria RAM: 3968MB
Total: 4056984
Usada: 2307076
Disponible: 1749908
Memoria SWAP total: 1052248
Memoria SWAP usada: 0
Memoria SWAP libre: 1052248</pre>
<h3>Descargar Sigar</h3>
<p style="text-align: justify;">Puedes descargar Sigar de la página oficial: <a href="http://support.hyperic.com/display/SIGAR/Home">http://support.hyperic.com/display/SIGAR/Home</a> que incluye además ejemplos para Java, Perl, C, Python, Ruby, y más. Puedes además descargar el código fuente que se encuentra licenciado bajo la GPL2.</p>
<h3>Creación del proyecto en Eclipse</h3>
<p style="text-align: justify;">Voy a usar este ejemplo para además enseñar a manipular librerías externas en Eclipse; si lo que te interesa es conocer el código, puedes saltarte a dicha sección directamente.</p>
<p style="text-align: justify;">Creamos un proyecto en Eclipse llamado InfoSistema:</p>
<p style="text-align: center;"><img class="size-full wp-image-3385 aligncenter" title="eclipse1" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/10/eclipse1.png" alt="eclipse1" width="457" height="381" /></p>
<p style="text-align: justify;">Ahora creamos una carpeta dentro del proyecto llamada lib, en donde guardaremos las librerías de Sigar (.jar, .so, .dll, etc.):</p>
<p style="text-align: center;"><img class="size-full wp-image-3386 aligncenter" title="eclipse2" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/10/eclipse2.png" alt="eclipse2" width="600" height="372" /></p>
<p style="text-align: justify;">Ahora descomprimimos el archivo que descargamos de Sigar, y copiamos los archivos que se encuentran en la carpeta <code>sigar-bin/lib</code> a la carpeta <code>lib</code> de nuestro proyecto. En mi caso la copia la hice con este comando:</p>
<div class="consola">cp sigar-bin/lib/* /home/compartido/workspace/InfoSistema/lib/</div>
<p style="text-align: justify;">Cabe resaltar que bastaría con copiar el archivo llamado <code>sigar.jar</code> y la librería del sistema donde vamos a correr nuestro programa (<code>libsigar-amd64-linux.so</code> en mi caso).</p>
<p style="text-align: justify;">Una vez hecha la copia, hacemos clic en la raiz del proyecto en Eclipse y presionamos F5 para actualizar el árbol de ficheros; de esta manera Eclipse sabrá de los nuevos archivos que hemos copiado. Y lo que haremos a continuación será enlazar la librería <code>sigar.jar</code> a nuestro proyecto, para lo cual hacemos clic derecho en el mismo, <em>Build Path</em> -&gt; <em>Configure Build Path&#8230;</em></p>
<p style="text-align: center;"><img class="size-full wp-image-3388 aligncenter" title="eclipse3" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/10/eclipse3.png" alt="eclipse3" width="600" height="345" /></p>
<p style="text-align: justify;">En la ventana que aparece, seleccionaremos la pestaña <em>Libraries</em> y hacemos clic en el botón <em>Add JARs&#8230;</em> Seleccionamos el archivo <code>sigar.jar</code> y hacemos clic en <em>OK</em>:</p>
<p style="text-align: center;"><img class="size-full wp-image-3389 aligncenter" title="eclipse4" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/10/eclipse4.png" alt="eclipse4" width="373" height="336" /></p>
<p style="text-align: justify;">Ahora que la librería se encuentra añadida, podemos utilizar el API que Sigar nos ofrece. ¡Pasemos entonces al código!</p>
<h3>Información del sistema&#8230;</h3>
<p style="text-align: justify;">La siguiente clase nos permite obtener información del sistema operativo, como el nombre, la versión, la arquitectura, etc. Creamos una nueva clase llamada <code>InfoSO</code> con el siguiente código:</p>
<pre class="brush: java; title: ; notranslate">import org.hyperic.sigar.OperatingSystem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;

public class InfoSO {
	private Sigar sigar = new Sigar();
	public void imprimirInfo() {
		OperatingSystem sys = OperatingSystem.getInstance();
		System.out.println(&quot;Descripcion del SO\t&quot; + sys.getDescription());
		System.out.println(&quot;Nombre del SO\t\t&quot; + sys.getName());
		System.out.println(&quot;Arquitectura del SO\t&quot; + sys.getArch());
		System.out.println(&quot;Version del SO\t\t&quot; + sys.getVersion());
		System.out.println(&quot;Nivel de parches\t&quot; + sys.getPatchLevel());
		System.out.println(&quot;Fabricante\t\t&quot; + sys.getVendor());
		System.out.println(&quot;Version SO\t\t&quot; + sys.getVendorVersion());
		try {
			imprimirUptime();
		} catch (SigarException e) {
			e.printStackTrace();
		}
	}
	public void imprimirUptime() throws SigarException {
		double uptime = sigar.getUptime().getUptime();
		String resultado = &quot;&quot;;
		int dias = (int) uptime / (60 * 60 * 24);
		int minutos, horas;
		if (dias != 0)
			resultado += dias + &quot; &quot; + ((dias &gt; 1) ? &quot;dias&quot; : &quot;dia&quot;) + &quot;, &quot;;
		minutos = (int) uptime / 60;
		horas = minutos / 60;
		horas %= 24;
		minutos %= 60;
		if (horas != 0)
			resultado += horas + &quot;:&quot; + (minutos &lt; 10 ? &quot;0&quot; + minutos : minutos);
		else
			resultado += minutos + &quot; min&quot;;
		System.out.println(&quot;Encendido durante:\t&quot; + resultado);
	}
}
</pre>
<p style="text-align: justify;">Aspectos importantes:</p>
<ul style="text-align: justify;">
<li>La clase que nos proporciona los métodos para recuperar información del sistema operativo es <code>OperatingSystem</code>.</li>
<li>Con los métodos <code>getName</code> y <code>getDescription</code> obtenemos el nombre del sistema operativo y descripción (por ejemplo: nombre = Linux; descripción = Gentoo 2.1.6).</li>
<li style="text-align: justify;">El método <code>getUptime</code> de la clase Sigar nos permite conocer cuanto tiempo ha estado prendido el equipo analizado.</li>
</ul>
<p style="text-align: justify;">
<h3 style="text-align: justify;">Información de la CPU&#8230;</h3>
</p>
<p style="text-align: justify;">La siguiente clase nos permitirá conocer el modelo del procesador, sus capacidades, la cantidad de núcleos y el uso de los mismos, etc. Creamos una nueva clase llamada <code>InfoCPU</code> con el siguiente código:</p>
<pre class="brush: java; title: ; notranslate">import org.hyperic.sigar.CpuInfo;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;

public class InfoCPU {
	private Sigar sigar;

	public void imprimirInfoCPU() {
		sigar = new Sigar();
		CpuInfo[] infos = null;
		CpuPerc[] cpus = null;
		try {
			infos = sigar.getCpuInfoList();
			cpus = sigar.getCpuPercList();
		} catch (SigarException e) {
			e.printStackTrace();
		}

		CpuInfo info = infos[0];
		long tamanioCache = info.getCacheSize();
		System.out.println(&quot;Fabricante:\t\t&quot; + info.getVendor());
		System.out.println(&quot;Modelo\t\t\t&quot; + info.getModel());
		System.out.println(&quot;Mhz\t\t\t&quot; + info.getMhz());
		System.out.println(&quot;Total CPUs\t\t&quot; + info.getTotalCores());
		if ((info.getTotalCores() != info.getTotalSockets())
				|| (info.getCoresPerSocket() &gt; info.getTotalCores())) {
			System.out.println(&quot;CPUs fisiscas\t\t&quot; + info.getTotalSockets());
			System.out
					.println(&quot;Nucleos por CPU\t\t&quot; + info.getCoresPerSocket());
		}

		if (tamanioCache != Sigar.FIELD_NOTIMPL)
			System.out.println(&quot;Tamanio cache\t\t&quot; + tamanioCache);
		System.out.println(&quot;&quot;);

		for (int i = 0; i &lt; cpus.length; i++)
			System.out.println(&quot;Consumo de CPU &quot; + i + &quot;\t&quot;
					+ CpuPerc.format(cpus[i].getUser()));

		try {
			System.out.println(&quot;Consumo total de CPU\t&quot;
					+ CpuPerc.format(sigar.getCpuPerc().getUser()));
		} catch (SigarException e) {
			e.printStackTrace();
		}
	}
}
</pre>
<p>Aspectos importantes:</p>
<ul style="text-align: justify;">
<li style="text-align: justify;">Se deben usar objetos de <code>CpuInfo</code> y <code>CpuPerc</code> que proporcionan los métodos para recuperar información del procesador. Dichos objetos se crean a partir de un objeto principal de tipo <code>Sigar</code>.</li>
<li style="text-align: justify;">Para extraer información acerca del  procesador usamos los métodos de la clase CpuInfo (por ejemplo <code>getVendor</code> o <code>getModel</code>).</li>
<li style="text-align: justify;">Los datos específicos de cada núcleo de nuestro procesador se extraen con los métodos de la clase <code>CpuPerc</code> (getUser para obtener el uso de un núcleo, por ejemplo).</li>
</ul>
<p style="text-align: justify;">
<h3>Información del sistema de archivos&#8230;</h3>
</p>
<p style="text-align: justify;">La siguiente clase nos permite obtener información del sistema de archivos: unidades montadas, espacio en disco, tipo de sistema de archivos, etc. Creamos una nueva clase llamada <code>InfoSistemaArchivos</code> con el siguiente código:</p>
<pre class="brush: java; title: ; notranslate">import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.FileSystem;
import org.hyperic.sigar.FileSystemUsage;
import org.hyperic.sigar.NfsFileSystem;
import org.hyperic.sigar.SigarProxy;
import org.hyperic.sigar.SigarProxyCache;

public class InfoSistemaArchivos {
	private SigarProxy proxy;
	private Sigar sigar;

	public InfoSistemaArchivos() {
		sigar = new Sigar();
		proxy = SigarProxyCache.newInstance(sigar);
	}

	public void imprimirInfo() throws SigarException {
		FileSystem[] listaSistemaArchivos = proxy.getFileSystemList();
		System.out.println(&quot;\ndispos.|total|usado|disponible|%uso|dir|tipo\n&quot;);
		for (int i = 0; i &lt; listaSistemaArchivos.length; i++)
			imprimirSistemaArchivos(listaSistemaArchivos[i]);
	}

	public void imprimirSistemaArchivos(FileSystem sistemaArchivos)
			throws SigarException {
		long usado, disponible, total, porcentaje;

		try {
			FileSystemUsage uso;
			if (sistemaArchivos instanceof NfsFileSystem) {
				NfsFileSystem nfs = (NfsFileSystem) sistemaArchivos;
				if (!nfs.ping()) {
					System.out.println(nfs.getUnreachableMessage());
					return;
				}
			}
			uso = sigar.getFileSystemUsage(sistemaArchivos.getDirName());

			usado = uso.getTotal() - uso.getFree();
			disponible = uso.getAvail();
			total = uso.getTotal();

			porcentaje = (long) (uso.getUsePercent() * 100);
		} catch (SigarException e) {
			// por ejemplo, si en al procesar D:\ en windows falla
			// con &quot;Device not ready&quot;
			usado = disponible = total = porcentaje = 0;
		}

		String porcentajeUso;
		if (porcentaje == 0)
			porcentajeUso = &quot;-&quot;;
		else
			porcentajeUso = porcentaje + &quot;%&quot;;

		System.out.print(sistemaArchivos.getDevName());
		System.out.print(&quot;|&quot; + total);
		System.out.print(&quot;|&quot; + usado);
		System.out.print(&quot;|&quot; + disponible);
		System.out.print(&quot;|&quot; + porcentajeUso);
		System.out.print(&quot;|&quot; + sistemaArchivos.getDirName());
		System.out.println(&quot;|&quot; + sistemaArchivos.getSysTypeName());
	}
}
</pre>
<p>Aspectos importantes:</p>
<ul style="text-align: justify;">
<li style="text-align: justify;">La clase que nos proporciona los métodos para obtener información de una unidad en específico es <code>FileSystem</code>.</li>
<li style="text-align: justify;">El método <code>getDevName</code> nos devuelve el nombre del dispositivo referenciado por el objeto de la clase <code>FileSystem</code>.</li>
<li style="text-align: justify;">Los métodos <code>getTotal</code> y <code>getAvail</code> devuelven un <code>long</code> que representa el espacio total del dispositivo y espacio disponible, respectivamente.</li>
<li style="text-align: justify;">Para conocer el tipo de sistema de archivos (ext4, ntfs, fat, btrfs, etc.) utilizamos el método <code>getSysTypeName</code>.</li>
</ul>
<p style="text-align: justify;">
<h3>Información de la memoria&#8230;</h3>
</p>
<p style="text-align: justify;">La siguiente clase nos permite conocer la cantidad de memoria RAM que tiene el equipo, así como la que se está usando actualmente (tanto memoria física como virtual, aka, swap). Creamos una nueva clase llamada <code>InfoMemoria</code> con el siguiente código:</p>
<pre class="brush: java; title: ; notranslate">import org.hyperic.sigar.Mem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.Swap;
import org.hyperic.sigar.SigarException;

public class InfoMemoria {
	private Sigar sigar = new Sigar();
	public void imprimirInfo() throws SigarException {
		Mem memoria = sigar.getMem();
		Swap intercambio = sigar.getSwap();

		System.out.println(&quot;Cantidad de memoria RAM: &quot;+ memoria.getRam() + &quot;MB&quot;);

		System.out.println(&quot;Total: &quot;+enBytes(memoria.getTotal()));
		System.out.println(&quot;Usada: &quot;+enBytes(memoria.getUsed()));
		System.out.println(&quot;Disponible: &quot;+enBytes(memoria.getFree()));

		System.out.println(&quot;Memoria SWAP total: &quot;+enBytes(intercambio.getTotal()));
		System.out.println(&quot;Memoria SWAP usada: &quot;+enBytes(intercambio.getUsed()));
		System.out.println(&quot;Memoria SWAP libre: &quot;+enBytes(intercambio.getFree()));

	}
	private Long enBytes(long valor) {
		return new Long(valor / 1024);
	}
}</pre>
<p style="text-align: justify;">Aspectos importantes:</p>
<ul style="text-align: justify;">
<li style="text-align: justify;">La clase <code>Mem</code> nos proporciona métodos para obtener información de la memoria del sistema.</li>
<li style="text-align: justify;">La clase <code>Swap</code> hace lo mismo que Mem, pero para la memoria virtual.</li>
<li style="text-align: justify;">Los métodos <code>getTotal</code> y <code>getUsed</code> nos devuelven un long que representa (en bits) la cantidad de memoria del equipo y lo que está usando, respectivamente.</li>
</ul>
<p style="text-align: justify;">
<h3>La clase main&#8230;</h3>
</p>
<p style="text-align: justify;">El main de nuestro proyecto estará contenido en la clase <code>InfoSistema</code>:</p>
<pre class="brush: java; title: ; notranslate">import org.hyperic.sigar.SigarException;
public class InfoSistema {
	public static void main(String[] args) {
		try {
			System.out.println(&quot;====Informacion del sistema====&quot;);
			new InfoSO().imprimirInfo();
			System.out.println(&quot;\n==== Informacion de la CPU ====&quot;);
			new InfoCPU().imprimirInfoCPU();
			System.out.println(&quot;\n====Informacion del sistema de archivos====&quot;);
			new InfoSistemaArchivos().imprimirInfo();
			System.out.println(&quot;\n====Informacion de la memoria====&quot;);
			new InfoMemoria().imprimirInfo();
		} catch (SigarException e) {
			e.printStackTrace();
		}
	}
}</pre>
<p>Eso es todo, solo nos queda ejecutar el proyecto y, opcionalmente, crear un archivo .jar para ejecutar en cualquier lado.</p>
<p style="text-align: justify;">
<h3>Descargas&#8230;</h3>
</p>
<ul style="text-align: justify;">
<li><a href="http://casidiablo.net/descargar/Informacion+Sistema+Java" class="tooltip" title="Proyecto de Eclipse comprimido en ZIP (contiene las librerías de Sigar)">Descarga del código fuente usado en esta entrada</a></li>
<li><a href="https://sourceforge.net/project/showfiles.php?group_id=172552">Descargar librerías de Sigar de SourceForge</a></li>
</ul>
<p><br/><br/></p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/capturar-informacion-sistema-operativo-java/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Trabajando con el Kernel Linux (III) &#8211; Buscando drivers de dipositivos PCI</title>
		<link>http://casidiablo.net/identificando-drivers-pci-kernel-linux/</link>
		<comments>http://casidiablo.net/identificando-drivers-pci-kernel-linux/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 19:30:57 +0000</pubDate>
		<dc:creator>Cristian</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[dispositivos]]></category>
		<category><![CDATA[drivers]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[pci]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://casidiablo.net/?p=3363</guid>
		<description><![CDATA[Contribuyendo a la excelente labor de mi amigo Cortex, vamos con este pequeño artículo. Una de las tareas más dispendiosas a la hora de configurar el kernel es determinar qué opción/driver activar para determinado dispositivo. La idea de este artículo es dar a conocer una excelente herramienta online que nos permitirá conocer mejor nuestro sistema, [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fcasidiablo.net%252Fidentificando-drivers-pci-kernel-linux%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Trabajando%20con%20el%20Kernel%20Linux%20%28III%29%20-%20Buscando%20drivers%20de%20dipositivos%20PCI%22%20%7D);"></div>
<p style="text-align: justify;"><em>Contribuyendo a la excelente labor de mi amigo <a href="http://casidiablo.net/author/c0rtex/">Cortex</a>, vamos con este pequeño artículo.</em></p>
<p style="text-align: justify;">Una de las tareas más dispendiosas a la hora de configurar el kernel es determinar qué opción/driver activar para determinado dispositivo. La idea de este artículo es dar a conocer una excelente herramienta online que nos permitirá conocer mejor nuestro sistema, y de paso saber los nombres de los drivers que podemos usar por cada dispositivo.</p>
<p style="text-align: justify;">La página en cuestión es <a href="http://kmuto.jp/debian/hcl/">http://kmuto.jp/debian/hcl/</a> y contiene una base de datos de IDs de dispositivos PCI, que nos permite consultar información acerca de nuestros dispositivos y los drivers que los controlan.</p>
<h3>Uso</h3>
<p style="text-align: justify;">Para usarlo debemos ejecutar el siguiente comando:</p>
<div class="consola">lspci -n</div>
<p style="text-align: justify;">y copiamos la salida en el area de texto que aparece al entrar a <a href="http://kmuto.jp/debian/hcl/">http://kmuto.jp/debian/hcl/</a>; hacemos clic en el botón Comprobar y obtendremos un listado de dispositivos vs. nombre del driver.</p>
<p style="text-align: justify;">Por ejemplo, mi laptop tiene una ranura para insertar memorias SD; el nombre de dicho dispositivo es <em>R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter</em> y el driver es <code>sdhci-pci</code>.</p>
<p style="text-align: center;"><img style="border:1px solid;" title="driver linux sdhci-pci" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/10/screenshot_030.png" alt="pantallazo del driver" /></p>
<p style="text-align: justify;">Con dicha información, podemos hacer una búsqueda (presionando la tecla /) en la configuración del kernel (cuando hacemos un <code>make menuconfig</code>):</p>
<p style="text-align: center;"><img class="size-full wp-image-3365 aligncenter" title="screenshot_031" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/10/screenshot_031.png" alt="screenshot_031" width="698" height="391" /></p>
<p style="text-align: justify;">El resultado es la ubicación exacta de la opción que debes habilitar para tener tu dispositivo funcionando:</p>
<p style="text-align: center;"><img class="size-full wp-image-3366 aligncenter" title="screenshot_032" src="http://casidiablo.net/wordpress/wp-content/uploads/2009/10/screenshot_032.png" alt="screenshot_032" width="689" height="386" /></p>
<p style="text-align: justify;">Eso es todo. Ahora podemos estar seguros de escoger el driver adecuado y podemos compilar nuestro kernel normalmente.</p>

]]></content:encoded>
			<wfw:commentRss>http://casidiablo.net/identificando-drivers-pci-kernel-linux/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

