¡Esta es una revisión vieja del documento!
Para desarrollar una aplicación para android necesitaremos tener:
La web oficial de desarrollo en Android es http://android-developers.blogspot.com/index.html.
La arquitectura de Android está estructurada por capas y cada capa utiliza los servicios de las que tiene por debajo. Las capas empezando por la más baja son:
doubles o floats es emulado por software.finalize es utilizar los métodos close o terminate.java.awt.font, java.io, java.lang, java.math…) y otras que no (java.applet, java.beans, javax.print, javax.sound…).org.apache.http, orj.json, org.xml.sax, org.xmlpull.v1.
Android trabaja únicamente con una aplicación a la vez (que no proceso), por ejemplo, al iniciar el sistema se inicia la aplicación Home (con menús, reloj, mensajes para el usuario…); cuando el usuario inicia otra aplicación la Home queda en segundo plano y, por lo tanto, recibe menos “atención”. A medida que se van iniciando aplicaciones estas son guardadas en la pila de aplicaciones (application stack) por el activity manager. El usuario podrá volver a la aplicación anterior como si de una navegación web se tratase.
Cada entorno (ventana, aplicación…) está representada por una clase Activity. Una aplicación realmente es una (o más) Activity enlazada a un proceso Linux, pero la aplicación no queda finalizada aunque el proceso Linux lo esté.
Las activities permanecen en un estado controlado por el sistema, no por el programador. Cuando el estado cambia avisa a la activity mediante eventos pudiendo ser las transiciones de la siguiente forma:
Es decir, se han de implementar los siguientes métodos y el sistema los llamará en el momento adecuado:
onCreate, cuando la activity inicia, sólo se llama una vez. Método adecuado para crear la interficie de usuario.onStart, indica que la activity va a mostrarse al usuario.onResume, indica que el usuario ya puede interactuar con la activity. Método adecuado para iniciar sonidos o animaciones.onPause, se inicia cuando la actividad está apunto de ir a un segundo plano. Aquí se debería guardar el estado interno actual de la aplicación.onStop, cuando la actividad va a finalizarse (si el sistema tiene suficiente memoria puede no ser llamado nunca).onRestart, cuando la actividad vuelve a un primer plano.onDestroy, cuando la actividad va a eliminarse.onSaveInstanceState y onRestoreInstanceState corresponden a métodos para guardar el estado de la interficie de usuario (lo que se está escribiendo en un cuadro de texto y tal), pero en las últimas versiones no es necesario debido a que ya lo hace el sistema por sí solo.
Las aplicaciones deberían guardar su estado en el método onPause debido a que no se sabe si continuarán en ejecución en un futuro.
Existen distintos tipos de bloques que el usuario puede aprovechar (heredando de ellos) en su código:
En el fichero llamado Android-Manifest.xml se indica a qué partes del sistema accederá la actividad y será el Package Manager quien dará esos permisos a partir de la aceptación del usuario.
INTERNET: Acceso a internet.READ_CONTACTS: Leer pero no escribir en los contactos del usuario.WRITE_CONTACTS: Escribir pero no leer los contactos del usuario.RECEIVE_SMS: Monitorear mensajes de texto que lleguen.ACCESS_COARSE_LOCATION: Saber la localización simple (a partir de antenas o wifi).ACCESS_FINE_LOCATION: Conocer la posición más concreta, a partir del GPS.
Un ejemplo del código en el Android-Manifest.xml es el siguiente que da la posivilidad de acceder a los SMS:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.app.myapp" > <uses-permission android:name="android.permission.RECEIVE_SMS" /> </manifest>
Cuando creamos un proyecto con Eclipse mediante la SDK de Android se generan varios directorios, entre ellos el res que contiene los recursos. Estos pueden ser archivos xml con textos que se utilicen en la aplicación, o xml que representen layouts (interficie), o sonidos, gráficos, iconos… Cuando se compila el proyecto aparece otro directorio, gen, el cual contiene la clase generada R que corresponde a los recursos y que, a su vez, contiene los identificadores (variables int estáticas) de los recursos creados.
Cuando utilizamos archivos xml como recursos de un proyecto Android estos han de comenzar con la siguiente declaración:
<?xml version="1.0" encoding="utf-8"?>
Los layouts son contenederes para objetos hijo, su función es posicionar estos objetos en la pantalla. Los más comunes son:
FrameLayout: Coloca los hijos a partir de la posición top-left.LinearLayout: Coloca los hijos en una columna o fila.RelativeLayout: Coloca los hijos en relación a las características de otros o del padre.TableLayout: Organiza los elementos en columnas-filas.Los parámetros comunes para ellos:
xmlns:android="http://schemas.android.com/apk/res/android": Debería estar definida en la primera tag del XML, define el namespace del XML para Android.android:layout_width=“” y android:layout_height=“”: Para indicar cómo se expandirá. Sus posibles valores son: fill_parent y wrap_content.
Para indicar un layout especial para el momento en el que se gire el teléfono crearemos una nueva carpeta, la layout-land, y en ella insertaremos los xml correspondientes, por ejemplo el main.xml.
Pero los layouts no son los únicos contenedores (ni tampoco los primeros que se han de poner en una aplicación). Por ejemplo, si queremos que un entorno tenga scroll añadiremos:
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/background" > <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/app_name" android:gravity="center" android:textColor="@color/green"/> <Button android:id = "@+id/btnState" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/State"/> </LinearLayout> </ScrollView>
Es decir…
ScrollView: Para entornos con scroll.WebView: Si queremos que sea código html.En una layout podemos añadir elementos, estos serán tags xml y se agregarán de la siguiente:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/app_name"/> </LinearLayout>
Para acceder a un control mediante código necesitamos indicar un identificador, para ello utilizamos la propiedad android:id=“@+id/identificador”. Esto hará que en la clase R se cree un identificador para ese elemento.
<TextView android:id="@+id/text_view1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/app_name"/>
android:text: Es el texto que aparece en el control. En un control podemos indicar su valor a partir de los recursos. Por ejemplo si queremos acceder a un valor dentro del strings.xml pondremos como su valor algo así como @string/nombre_variable. Pero también podremos poner el texto directamente lo.android:gravity: Es la posición de los elementos internos: center.android:textColor: Color del texto.TextView: Corresponde a un texto simple (algo así como una label) dentro de la layout.Button: Corresponde a un botón.ImageButton: Botón con imágen. La imágen ha de estar en res/drawable-xxx y para indicar cual será la que se mostrará lo haremos a partir de la propiedad src, indicando @drawable/nombre-de-archivo-sin-extensión. Por ejemplo: android:src=“@drawable/state”.
Un recurso es la parte de la aplicación que no es código (por ejemplo imagenes, sonidos, textos…) pero que se compilan con esta. Han de guardarse en el directorio res de la aplicación. Cuando lo hacen se crea una clase denominada R que contiene los identificadores a cada uno de los recursos para poder acceder a estos desde el código, para ello en el directorio res se crean subdirectorios, como por ejemplo el layout y dentro de este archivos como por ejemplo el main.xml, que sería el layout principal. Para acceder a este layout haríamos R.layout.main. La clase R la maneja automáticamente Eclipse.
Dentro del proyecto, en la carpeta res encontraremos la subcarpeta values con el fichero string.xml. Este corresponde a los textos de la aplicación.
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, Test!</string> <string name="app_name">Test</string> <string name="OnState">Apagar</string> <string name="OffState">Encender</string> </resources>
Podemos añadir código en formato html y con multilinia colocando el carácter \ al inicio:
<string name="about_text"> \ Un <b>recurso</b> es la parte de la aplicación que no es código (por ejemplo imagenes, sonidos, textos…) pero que se compilan con esta. Han de guardarse en el directorio res de la aplicación. Cuando lo hacen se crea una clase denominada R que contiene los identificadores a cada uno de los recursos para poder acceder a estos desde el código, para ello en el directorio res se crean subdirectorios, como por ejemplo el layout y dentro de este archivos como por ejemplo el <i>main.xml</i>, que sería el layout principal. Para acceder a este layout haríamos <i>R.layout.main</i>. La clase R la maneja automáticamente Eclipse. </string>
Por ejemplo colores, agregamos el fichero res\values\colors.xml y le añadimos el siguiente contenido:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="red">#BA030E</color> <color name="green">#1D7900</color> <color name="background">#EDF5FF</color> <color name="black">#000000</color> </resources>
Ahora en las propiedades que acepten colores podremos asignar estos valores como @color/black, por ejemplo.
Las activities son lo equivalentes a “ventanas” dentro de nuestra aplicación.
Para agregar una Activity a nuestra aplicación necesitamos:
/res/layout/ correspondiente.android.app.Activity.AndroidManifest.xml.Intent.
La siguiente sería una clase que hereda de Activity:
package my.test; import android.app.Activity; import android.os.Bundle; public class About extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.about); } }
Para agregarla al AndroidManifest.xml abriremos el archivo y añadiremos la siguiente línea dentro de la tag application:
<activity android:name=".About" android:label="@string/State" />
Siendo About el nombre de la clase y State el título que queramos darle.
Activity llamaremos a su método finish().
Los android.content.Intent son los que lanzan objetos Activity. Desde un objeto Activity crearemos un objeto Intent, en su constructor indicaremos el objeto que lo crea (this) y el objeto Class correspondiente a la clase Activity que queramos lanzar.
Intent i = new Intent(this, About.class); this.startActivity(i);
Cuando se crea la clase principal de un proyecto llamaremos al setContentView para indicar su layout.
package my.test; import android.app.Activity; import android.os.Bundle; public class Test extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Para acceder a los elementos desde un método de una clase Activity utilizaremos el findViewById() pasándole por parámetro el id asignado (mediante la clase R), nos devolverá un objeto View:
View continueButton = this.findViewById(R.id.continue_button); continueButton.setOnClickListener(this);
Para capturar el click en un botón, por ejemplo, debemos asignar un objeto android.view.View.OnClickListener. al método setOnClickListener.
View btn = this.findViewById(R.id.btnState); btn.setOnClickListener(this);
La clase donde se haga esto, evidentemente deberá implementar la interfaz OnClickListener.
Luego, el en método onClick:
@Override public void onClick(View arg0) { switch (arg0.getId()) { case R.id.btnState: android.content.Intent i = new Intent(this, About.class); startActivity(i); break; } }
En Android existen varios tipos de medidas:
px: Píxels, puntos en la pantalla.in: Inches.mm: Milimetros.pt: Points, 1/72 de una inch.dp: Density-Independent Pixels. ¿?dip, sinónimo de dp.sp: Scale-independent pixels. Como los dp pero escalados según la fuente configurada por el usuario.
Es aconsejable utilizar sp para los textos y dip para todo lo demás.
Los temas son como los CSS pero aplicados a los controles. Podemos definir los nuestros (en res/values/styles.xml), pero ya existen predefinidos.
Para indicar un tema para un objeto Activity en su tag correspondiente del AndroidManifest.xml agregaremos android:theme=“”.
Si vamos a agregar un estilo predefinido haremos el valor será: @android:style/estilo.
<activity android:name=".About" android:label="@string/State" android:theme="@android:style/Theme.Dialog" />
Theme.Dialog.
Android permite mostrar dos tipos de menús, el primero es el que aparece al pulsar sobre la tecla Menu (menú de opciones), el segundo tras dejar apretado el dedo sobre la pantalla.
Este menú lo guardaremos en el fichero res/menu/menu.xml. Y será del siguiente estilo:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item01" android:title="@string/Volume" /> <item android:id="@+id/item02" android:title="@string/Mute" /> </menu>
Para hacerlo aparecer necesitaremos sobreescribir el método onCreateOptionsMenu de la Activity, este se llama cada vez que se pulsa la tecla física Menu. Para llamarlo utilizaremos un objeto la clase MenuInflater (recogeremos el objeto de esta mediante el método getMenuInflater) llamando al método inflate:
@Override public boolean onCreateOptionsMenu(Menu menu) { android.view.MenuInflater inflater = this.getMenuInflater(); inflater.inflate(R.menu.menu, menu); return super.onCreateOptionsMenu(menu); }
Para detectar qué elemento se ha pulsado sobreescribiremos el onOptionsItemSelected:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.item01: break; } return super.onOptionsItemSelected(item); }
Las preferencias realmente son clases android.preference.PreferenceActivity y estas, como su nombre indica, heredan de Activity, utilizan un layout diferente a otras Activity. Como tal, para abrir unas preferencias necesitaremos un Intent:
startActivity(new Intent(this, Settings.class));
Este abre la clase Settings, que hereda de Activity que a su vez se enlaza al xml mediante el método addPreferencesFromResource:
package my.test; import android.os.Bundle; import android.preference.PreferenceActivity; public class Settings extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); } }
Y a la vez también necesitamos agregarla en el AndroidManifest.xml:
<activity android:name="Settings" android:label="@string/State" />
Lo que cambia más en cuanto a una Activity común es el fichero xml que colocaremos en res/xml/settings.xml:
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <CheckBoxPreference android:key="music" android:title="@string/Play" android:summary="@string/Stop" android:defaultValue="true" /> </PreferenceScreen>
En él podemos utilizar elementos que luego podrán ser preguntados a partir de su propiedad key, en el antiguo caso sólo hay un CheckBox y su key es music.
Los elementos que podemos encontrar son:
CheckBoxPreferenceEditTextPreference
Para leer los valores lo haremos utilizando el android.preference.PreferenceManager de la siguiente forma:
boolean b = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean("music", true);
Al método getBoolean se le pasa el key de una setting boolean y, si no estubiese definida, su valor por defecto.
android.app.AlertDialog
El SDK de Android agrega un visor de mensajes de log del teléfono (Window → Show View → Other → Android → LogCat). Este muestra los errores de las aplicaciones, pero además podemos escribir en él mediante la clase Log:
Log.(e): Errores.Log.(w): Warnings.Log.(i): Informacion.Log.(d): Debuggin.Log.(v): Verbose.Debug As → Android Application), debemos añadir en AndroidManifest.xml la siguiente propiedad a la tag application: android:debuggable=“true”.ctrl + f11 harán que el emulador cambie de horizontal a vertical.Para poder debugar desde el teléfono necesitaremos instalar los drivers.
Creamos el siguiente archivo.
nano /etc/udev/rules.d/51-android.rules
Escribimos lo siguiente.
SUBSYSTEM=="usb_device", SYSFS{idVendor}=="0bb4", MODE="0666"
Y el siguiente comando para activar el driver:
chmod a+r /etc/udev/rules.d/51-android.rules
Aunque en otros he visto: chmod a+rx /etc/udev/rules.d/51-android.rules
ddms del directorio tools nos abrirá el monitor de debug de Alvik, con él podremos hacer capturas de pantalla.