Page 144
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
adjuntado como un objeto Uri. Las URI relacionadas con recursos telefónicos han de
tener el formato “tel:numero” para poder funcionar correctamente con la acción
Intent.ACTION_CALL.
Tras la creación y configuración del objeto Intent ya se puede lanzar la actividad.
Como en este caso no se espera que esta retorne ningún valor que deba ser capturado, la
Activity se lanza sin más con el método startActivity(). En ese momento el
sistema abrirá el gestor de llamadas y marcará el número indicado.
__rendered_path__11Image_820_0
Figura 29. Llamada a un contacto
El acceso a las funciones telefónicas del dispositivo móvil requiere de su
correspondiente permiso en la declaración del manifiesto. El permiso es el siguiente:
Jaime Aranaz Tudela
144
Ingeniería en Informática

Page 145
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
__rendered_path__14
__rendered_path__14
<uses-permission android:name="android.permission.CALL_PHONE" />
__rendered_path__15
__rendered_path__14
__rendered_path__14
Código 51. Declaración en el manifiesto del permiso de llamada telefónica
__rendered_path__16
__rendered_path__16
4.2.16
Enviar un correo electrónico
__rendered_path__19
__rendered_path__19
Otras de las funcionalidades ofrecidas por ContactMap es la de enviar un correo
__rendered_path__14__rendered_path__21
electrónico a un contacto. Al igual que ocurre con la llamada telefónica, esta acción se
__rendered_path__11__rendered_path__14__rendered_path__21
llevará a cabo a través de un Intent de forma que sea el sistema el que se haga cargo a
__rendered_path__15
través de la aplicación más adecuada.
__rendered_path__14
__rendered_path__14
__rendered_path__14
__rendered_path__39__rendered_path__14
public class ContactMap extends MapActivity {
__rendered_path__15
__rendered_path__14
@Override
__rendered_path__14
public boolean onMenuItemSelected(int featureId, MenuItem item) {
__rendered_path__41
__rendered_path__41
switch (item.getItemId()) {
__rendered_path__42
__rendered_path__19
case 4: // Enviar email al contacto con el foco
__rendered_path__19
__rendered_path__42
// Crear Intent para enviar email
__rendered_path__19
Intent enviarEmail = new Intent(Intent.ACTION_SEND);
__rendered_path__19
__rendered_path__50
// Asociar al Intent la dirección y el tipo de dato
__rendered_path__53
enviarEmail.putExtra(
__rendered_path__53
Intent.EXTRA_EMAIL,mCurrent.getEmail());
__rendered_path__42
enviarEmail.setType("message/rfc822");
__rendered_path__19
__rendered_path__19
// Lanzar Activity que atienda este Intent
__rendered_path__42
this.startActivity(Intent.createChooser(
__rendered_path__19
enviarEmail,
__rendered_path__19
"Enviar un email a"
__rendered_path__42
+mCurrent.getName()));
__rendered_path__19
__rendered_path__19
return true;
__rendered_path__50
// (...)
__rendered_path__53
}
__rendered_path__53
}
__rendered_path__42
__rendered_path__19
__rendered_path__19
Código 52. Intent para enviar un correo electrónico
__rendered_path__42
__rendered_path__19
__rendered_path__19
El Código 52 enseña la parte del método onMenuItemSelected() de la clase
__rendered_path__50
ContactMap que permite enviar un correo electrónico. En primer lugar se crea el
__rendered_path__53
Jaime Aranaz Tudela
145
__rendered_path__53__rendered_path__74__rendered_path__80__rendered_path__80__rendered_path__50__rendered_path__53__rendered_path__53__rendered_path__50__rendered_path__53__rendered_path__53__rendered_path__74__rendered_path__80__rendered_path__80__rendered_path__50__rendered_path__53__rendered_path__53__rendered_path__42__rendered_path__19__rendered_path__19__rendered_path__42__rendered_path__19__rendered_path__19__rendered_path__50__rendered_path__53__rendered_path__53__rendered_path__42__rendered_path__19__rendered_path__19__rendered_path__42__rendered_path__19__rendered_path__19__rendered_path__42__rendered_path__19__rendered_path__19__rendered_path__50__rendered_path__53__rendered_path__53__rendered_path__42__rendered_path__19__rendered_path__19__rendered_path__42__rendered_path__19__rendered_path__19__rendered_path__50__rendered_path__53__rendered_path__53__rendered_path__74__rendered_path__80__rendered_path__80__rendered_path__50__rendered_path__53__rendered_path__53__rendered_path__39__rendered_path__14__rendered_path__14__rendered_path__15__rendered_path__14__rendered_path__14__rendered_path__41__rendered_path__41
Ingeniería en Informática

Page 146
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
objeto Intent
correspondiente,
en
este
caso
asociándole
la
acción
Intent.ACTION_SEND.
Después, como datos adjuntos a este Intent se incluyen tanto la dirección de correo
electrónico del contacto actualmente con el foco, como el tipo MIME del correo. A
continuación se lanza la Activity correspondiente con el método startActivity(), ya
que no se precisa manejar ningún resultado devuelto por ésta.
Una peculiaridad de esta llamada a starActivity() es que se utiliza como parámetro
el método createChooser() de la clase Intent. Este permite que, en caso de existir
varias aplicaciones capaces de hacerse cargo de dicho Intent, el sistema muestre al
usuario un menú donde puede elegir la aplicación para desarrollar la acción.
__rendered_path__11
Si en el caso de las llamadas telefónicas existe por defecto un gestor de las mismas en
Android, para el correo electrónico no hay instalado ningún cliente. Es por ello que, en
la versión considerada de Android para este proyecto, este Intent no podrá ser atendido
por ninguna aplicación, hecho que el sistema comunicará al usuario mediante el
correspondiente mensaje.
Image_832_0
Figura 30. Mensaje tras intentar enviar un correo electrónico
Jaime Aranaz Tudela
146
Ingeniería en Informática

Page 147
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
4.2.17
Enviar un SMS
El proceso de envío de un SMS es bastante similar al visto en el listado de contactos, en
el apartado 4.2.14. No se utilizará un Intent para delegar en el sistema dicha operación,
sino que nuevamente se utiliza para lanzar una nueva Activity que se corresponde con
una clase ya implementada en la propia aplicación ContactMap, de nombre
SMSWriter.
Esta clase muestra al usuario una nueva interfaz donde poder escribir el mensaje de
texto, tal y como exhibe la Figura 31. La interfaz consta de los siguientes elementos:
Una caja de texto para introducir el número, acompañada de su correspondiente
__rendered_path__11
etiqueta textual.
__rendered_path__33
Una caja de texto para introducir el mensaje, acompañada igualmente de su
__rendered_path__33
etiqueta textual.
Un botón para enviar.
__rendered_path__33
Un botón para borrar.
__rendered_path__33
Image_839_0
Figura 31. Interfaz para enviar un SMS
Jaime Aranaz Tudela
147
Ingeniería en Informática

Page 148
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
Lanzar una nueva Activity
El lanzamiento de una nueva Activity sigue siendo igual al visto en anteriores ocasiones.
En el método onMenuItemSelected() de la clase ContactMap, que es llamado cada
vez que el usuario selecciona una opción del menú principal, se crea un nuevo Intent y
se lanza la Activity correspondiente a este.
El objeto de la clase Intent está asociado a la clase SMSWriter, debido a que no se
quiere que el sistema se haga cargo y busque la aplicación instalada más adecuada, sino
que se desea explícitamente que se ejecute en esta clase implementada en la propia
aplicación ContactMap.
__rendered_path__11
Como datos asociados al Intent (recuérdese, un Intent consta de una acción y unos
datos) se encuentra únicamente el número de teléfono del contacto que cuenta en ese
momento con el foco, de forma que ya aparezca ese campo rellenado en la interfaz del
usuario.
Es necesario que la nueva Activity, una vez finalizada, devuelva a la Activity principal,
ContactMap el texto introducido por el usuario para poder enviar el mensaje. Por ello
se lanza con el método startActivityForResult(), que llamará a
onActivityResult() cuando la actividad termine.
En el siguiente código se muestra cómo lanzar la nueva Activity desde el método
onMenuItemSelected():
__rendered_path__77
__rendered_path__75__rendered_path__77
public class ContactMap extends MapActivity {
__rendered_path__78
@Override
__rendered_path__77
public boolean onMenuItemSelected(int featureId, MenuItem item) {
__rendered_path__77
__rendered_path__79
switch (item.getItemId()) {
__rendered_path__79
case 3: // Enviar SMS al contacto actual
__rendered_path__80
__rendered_path__87
// Crear Intent asociado a la clase SMSWriter
__rendered_path__87
Intent mandarSMS = new Intent(this, SMSWriter.class);
__rendered_path__80
__rendered_path__87
// Asociar al Intent el número del amigo actual
__rendered_path__87
mandarSMS.putExtra("number", mCurrent.getNumber());
__rendered_path__90
__rendered_path__97
// Lanzar Activity (SMSWriter) que atienda al Intent
__rendered_path__97
this.startActivityForResult(mandarSMS,1);
__rendered_path__80
__rendered_path__87
return true;
__rendered_path__87
}
__rendered_path__99
// (...)
__rendered_path__103
}
__rendered_path__103
}
__rendered_path__99
__rendered_path__103
__rendered_path__103
Código 53. Lanzar Activity para enviar un SMS
__rendered_path__80
Jaime Aranaz Tudela
148
__rendered_path__87__rendered_path__87__rendered_path__99__rendered_path__103__rendered_path__103__rendered_path__99__rendered_path__103__rendered_path__103__rendered_path__99__rendered_path__103__rendered_path__103__rendered_path__80__rendered_path__87__rendered_path__87__rendered_path__99__rendered_path__103__rendered_path__103__rendered_path__99__rendered_path__103__rendered_path__103__rendered_path__80__rendered_path__87__rendered_path__87__rendered_path__90__rendered_path__97__rendered_path__97__rendered_path__80__rendered_path__87__rendered_path__87__rendered_path__80__rendered_path__87__rendered_path__87__rendered_path__90__rendered_path__97__rendered_path__97__rendered_path__80__rendered_path__87__rendered_path__87__rendered_path__99__rendered_path__103__rendered_path__103__rendered_path__99__rendered_path__103__rendered_path__103__rendered_path__149__rendered_path__77__rendered_path__77__rendered_path__78__rendered_path__77__rendered_path__77__rendered_path__151__rendered_path__151
Ingeniería en Informática

Page 149
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
Crear la interfaz a partir de XML
Android ofrece la posibilidad, ya vista en anteriores apartados, de utilizar en el código
fuente los recursos externos declarados dentro de la carpeta “\res”. Hasta ahora se han
visto casos donde se declaraban externamente cadenas de texto para las opciones del
menú principal o ciertos avisos al usuario, facilitando así su utilización en otros
idiomas; también se ha enseñado como utilizar imágenes o iconos que después pueden
ser referenciadas en el código con una simple declaración que apunte a esta carpeta de
recursos externos.
Sin embargo, quizás la mayor utilidad de estas declaraciones externas al código resida
en la posibilidad de definir, de nuevo a través de documentos XML, interfaces de
__rendered_path__11
usuario completas. Dentro de la carpeta “\res\layout” pueden definirse cuantos
documentos XML se desee, cada uno de ellos representando una determinada interfaz
que se quiera implementar, o incluso diferentes versiones de la misma para según qué
casos.
Para la interfaz de usuario que debe mostrarse con la clase SMSWriter se utilizan estas
declaraciones externas, ubicadas en el fichero de nombre “sms.xml”. Dada la Figura 31
anteriormente enseñada, sabemos que hemos de utilizar los siguientes elementos del
paquete android.widget que, como se vio anteriormente, contiene numerosas clases
para construir interfaces de usuario:
Para las etiquetas textuales, la clase TextView.
__rendered_path__52
Para las cajas de texto, la clase EditText.
__rendered_path__52
Para los botones, la clase Button.
__rendered_path__52
Cada una de estas clases, ya sean instanciadas desde un documento XML externo o en
el código fuente de forma tradicional, tienen una serie de atributos que han de ser
configurados y que matizan su aspecto, colocación o comportamiento dentro de la
interfaz.
El siguiente ejemplo escrito en XML define dos de los elementos presentes en la
interfaz para escribir un SMS. Son la etiqueta y la caja de texto correspondiente a la
parte donde el usuario puede introducir el contenido del mensaje que desea escribir.
__rendered_path__83
__rendered_path__83
<TextView
__rendered_path__84
android:id="@+id/txt2"
__rendered_path__83
android:layout_width="wrap_content"
__rendered_path__83
android:layout_height="wrap_content"
__rendered_path__85
android:layout_marginTop="5px"
__rendered_path__85
android:text="Mensaje"
__rendered_path__87
android:textSize="18sp"
__rendered_path__87
/>
__rendered_path__89
__rendered_path__89
__rendered_path__89
__rendered_path__89
Jaime Aranaz Tudela
149
__rendered_path__87__rendered_path__87__rendered_path__93__rendered_path__93__rendered_path__87__rendered_path__87__rendered_path__89__rendered_path__89__rendered_path__89__rendered_path__89__rendered_path__87__rendered_path__87__rendered_path__89__rendered_path__89__rendered_path__100__rendered_path__100__rendered_path__101__rendered_path__100__rendered_path__100__rendered_path__85__rendered_path__85
Ingeniería en Informática

Page 150
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
__rendered_path__13
__rendered_path__13
<EditText
__rendered_path__14
android:id="@+id/message"
__rendered_path__13
android:layout_width="300sp"
__rendered_path__13
android:layout_height="250sp"
__rendered_path__15
android:layout_marginTop="5px"
__rendered_path__15
android:layout_marginLeft="10px"
__rendered_path__17
android:textSize="18sp"
__rendered_path__17
android:maxLength="160"
__rendered_path__17
/>
__rendered_path__17
__rendered_path__20
__rendered_path__20
Código 54. Construcción con XML de elementos de interfaz de usuario
__rendered_path__17
__rendered_path__11__rendered_path__17
__rendered_path__23
Cada elemento declarado tiene como nombre el propio de la clase a la que pretende
__rendered_path__23
instanciar, en este caso <TextView> y <EditText>. Dependiendo de dicha clase, los
__rendered_path__23
elementos podrán declarar unos atributos u otros, aunque aquí los atributos son muy
__rendered_path__23
similares entre ambos. Se pueden observar los siguientes atributos:
__rendered_path__17
__rendered_path__17
android:id: todo elemento declarado debe tener un identificador único,
__rendered_path__23
escrito en el atributo android:id. Este identificador es a través del cual se
__rendered_path__23
referencia el elemento en el código fuente, y es el nombre con el que aparece
__rendered_path__23
declarado el recurso dentro del fichero “R.java” (se recordará que dicho fichero
__rendered_path__23
mantiene una sincronización con cualquier elemento declarado como recurso en
__rendered_path__29__rendered_path__15
la carpeta “\res”, de forma que permite a las demás clases de la aplicación
__rendered_path__29__rendered_path__15
Android poder utilizar el recursos deseado simplemente nombrándolo).
__rendered_path__30
__rendered_path__29
android:layout_width: indica la anchura que debe tener este elemento. Si
__rendered_path__29
se especifica wrap_content, entonces ocupará tanto espacio como necesite;
__rendered_path__48
por otra parte, una configuración como fill_parent indica al widget que
__rendered_path__48
ocupe tanto espacio como tenga disponible. Otra alternativa, como ocurre en
<EditText> es especificar exactamente el tamaño deseado, ya sea en píxeles
(px), en píxeles escalados (ps), en pulgadas (in), milímetros (mm) u otros.
android:layout_height: indica la altura del elemento. Se comporta igual
__rendered_path__48
que el atributo layout_width.
android:layout_marginTop: especifica el margen superior que se desea
__rendered_path__48
establecer para el elemento. Se comporta igual que el atributo layout_width.
android:layout_marginLeft: especifica el margen izquierdo que se desea
__rendered_path__48
establecer para el elemento. Se comporta igual que el atributo layout_width.
android:Text: el texto que, por defecto, debe mostrar el elemento.
__rendered_path__48
android:textSize: el tamaño del texto.
__rendered_path__48
Jaime Aranaz Tudela
150
Ingeniería en Informática

Page 151
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
android:maxLength: el número máximo de caracteres.
__rendered_path__12
Cada elemento de interfaz cuenta con su propia familia de atributos, dando así un alto
grado de libertad al desarrollador para configurar sus widgets de la forma que considere
más oportuna.
Además de elementos de interfaz, Android también contempla algunas vistas, también
llamados diseños, que agrupan los distintos widgets y los ordenan siguiendo unos
patrones frecuentemente utilizados en las aplicaciones. En ocasiones anteriores hemos
nombrado Gallery, para los visores de fotografías, o ListView, utilizado aquí para
mostrar un listado de contactos. Para ordenar adecuadamente los elementos de la
interfaz de SMSWriter se usará el patrón llamado LinearLayout.
__rendered_path__11
La clase LinearLayout permite colocar los elementos de una interfaz de forma
consecutiva, ya sea imaginando para ellos unas columnas en la pantalla (orden
horizontal) o unas filas (orden vertical). Este patrón se utiliza en dos ocasiones dentro
del fichero “sms.xml”, donde estamos definiendo los widgets: en una ocasión para la
totalidad de los elementos, siguiendo un orden vertical, y en otra ocasión para colocar
los dos botones de envío y borrado siguiendo un orden horizontal. La declaración de
este patrón es la mostrada en el Código 55, donde se indican sólo a través de su nombre
los elementos completos de la interfaz:
__rendered_path__64
__rendered_path__64
<LinearLayout
__rendered_path__65
android:id="@+id/linearlayout1"
__rendered_path__64
android:orientation="vertical"
__rendered_path__64
>
__rendered_path__66
__rendered_path__66
<TextView android:id="@+id/txt1" … />
__rendered_path__68
__rendered_path__68
<EditText android:id="@+id/number" … />
__rendered_path__70
__rendered_path__70
<TextView android:id="@+id/txt2" … />
__rendered_path__70
__rendered_path__70
<EditText android:id="@+id/message" … />
__rendered_path__68
__rendered_path__68
<LinearLayout
__rendered_path__70
android:id="@+id/linearlayout1"
__rendered_path__70
android:orientation="horizontal"
__rendered_path__70
>
__rendered_path__70
__rendered_path__70
<Button android:id="@+id/button1" … />
__rendered_path__70
__rendered_path__68
<Button android:id="@+id/button2" … />
__rendered_path__68
__rendered_path__70
</LinearLayout>
__rendered_path__70
__rendered_path__70
</LinearLayout>
__rendered_path__70
__rendered_path__68
__rendered_path__68
Código 55. Uso del diseño LinearLayout
__rendered_path__81
Jaime Aranaz Tudela
151
__rendered_path__81__rendered_path__68__rendered_path__68__rendered_path__68__rendered_path__68__rendered_path__81__rendered_path__81__rendered_path__68__rendered_path__68__rendered_path__70__rendered_path__70__rendered_path__70__rendered_path__70__rendered_path__70__rendered_path__70__rendered_path__68__rendered_path__68__rendered_path__70__rendered_path__70__rendered_path__70__rendered_path__70__rendered_path__68__rendered_path__68__rendered_path__81__rendered_path__81__rendered_path__68__rendered_path__68__rendered_path__64__rendered_path__64__rendered_path__65__rendered_path__64__rendered_path__64__rendered_path__66__rendered_path__66
Ingeniería en Informática